GitHub Actions Matrix戦略 × ClaudeCodeActions

2025-11-23 | DevOps

GitHub Actions Matrix戦略 × ClaudeCodeActions

この記事をシェア

この記事は、10月25日の記事(人間とAIの非同期ワーク)の再掲です。Google Gemini 3 Proに、わずか数行のプロンプトで、サムネイル込みで作ってもらったものをお見せします。人類はものすごい道具を手に入れました。

序章:終わらないCI、積み上がるタスク、そして絶望

金曜日の午後4時。あなたは週末のリリースに向けて、最後のプルリクエストをマージした。あとはCIが通るのを待つだけだ。

しかし、あなたの表情は晴れない。なぜなら、このCIパイプラインが完了するまでに、たっぷり3時間はかかることを知っているからだ。

あなたのチームが開発しているプロダクトは、ここ数年で急成長した。コードベースは肥大化し、Markdownで書かれたドキュメントは数千ファイルに及び、多言語対応の要望も日々増えている。さらに最近では、「AIを活用してコードレビューを自動化したい」「ドキュメントの翻訳をClaudeにやらせたい」「PRの内容からリリースノートを自動生成したい」といった、LLM(大規模言語モデル)を活用したタスクがCIに次々と追加された。

当初は素晴らしいアイデアに思えたこれらのAIタスクだが、現実にはCIのボトルネックとなっていた。

# これまでの絶望的な直列処理ワークフロー
jobs:
  ai-tasks:
    runs-on: ubuntu-latest
    steps:
      - name: 全ファイルの翻訳
        run: |
          for file in $(find docs -name "*.md"); do
            # 1ファイルずつClaude APIを叩く…終わらない…
            python translate_with_claude.py "$file"
          done
      - name: 全コードのレビュー
        run: # これも直列…

1つのファイルに対してClaude APIを呼び出し、応答を待ち、次のファイルへ移る。この直列処理(シーケンシャル実行)が、あなたの貴重な時間を奪っていたのだ。しかも、GitHub-hostedランナーの課金タイマーは、ただAPIの応答を待っている間も無情に回り続ける。

「このままでは、開発スピードが維持できない……」

あなたは気付く。問題はAIの性能ではない。「処理のさせ方」そのものが間違っていたのだ。

転機:Matrix戦略という「思考の転換」

週末、あなたは悶々としつつも、以前読んだブログ記事(人間とAIの非同期ワーク)のことを思い出していた。そこには「人間とAIの非同期ワーク」についての概念が書かれていた。

「待てよ。これをCIの世界に適用したらどうなる?」

CIにおける「非同期」とは何か。それは、一つの巨大なジョブが終わるのを待たずに、複数のジョブを同時に走らせることだ。

そこであなたが目をつけたのが、GitHub ActionsのMatrix戦略(Matrix Strategy)だった。

Matrix戦略は、一般的には「複数バージョンのNode.jsでテストする」あるいは「UbuntuとWindowsで動作確認する」といった、クロスプラットフォームテストの文脈で語られることが多い。

しかし、あなたの脳裏に閃きが走る。

「Matrixは、単なるテスト環境の切り替え機能じゃない。タスクを無限に分割し、並列実行するための『分散コンピューティングエンジン』なんじゃないか?」

もし、1000個のドキュメント翻訳タスクがあるなら、1つのジョブで1000回ループするのではなく、1000個のジョブを同時に立ち上げて、それぞれに1ファイルずつ処理させればいい。

理論上、処理時間は1/1000になるはずだ。

実装:ClaudeCodeActions × Matrix の融合

あなたは早速、アーキテクチャの再設計に取り掛かった。

目指すは、巨大なデータを個別のチャンク(塊)に分割し、それぞれを独立したGitHub Actionsジョブとして並列起動し、その中でClaude(ClaudeCodeActions)に処理させるシステムだ。

1. 動的Matrixの生成

まず必要なのは、「何を並列化するか」を定義するMatrixの配列を動的に生成することだ。静的に [file1, file2, ...] と書くわけにはいかない。

最初のジョブで、対象となるファイル一覧を取得し、それをJSON配列として出力する。

jobs:
  # 1. 並列化の「種」を作るジョブ
  setup-matrix:
    runs-on: ubuntu-latest
    outputs:
      # ここで生成したファイルリストを次のジョブに渡す
      matrix-files: ${{ steps.set-matrix.outputs.files }}
    steps:
      - uses: actions/checkout@v4
      - id: set-matrix
        run: |
          # 例えば、変更があったMarkdownファイルだけを抽出
          files=$(git diff --name-only HEAD^ HEAD | grep '.md' | jq -R -s -c 'split("\n")[:-1]')
          echo "files=$files" >> $GITHUB_OUTPUT

このジョブは一瞬で終わる。重要なのは、ここで作られた ["docs/A.md", "docs/B.md", "docs/C.md", ...] という配列だ。

2. Matrixによる爆発的並列実行

次に、この配列を受け取り、Matrix戦略を使ってジョブを「爆発」させる。ここで、仮称「ClaudeCodeActions」が登場する。これは、指定された入力を受け取り、Claude APIに投げ、結果を適切な形で保存するカスタムActionだ。

jobs:
  # ... setup-matrix ジョブは省略 ...

  process-with-claude:
    needs: setup-matrix
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false # 1つ失敗しても他は止めない
      matrix:
        # setup-matrixで生成したファイルリストを展開!
        file: ${{ fromJson(needs.setup-matrix.outputs.matrix-files) }}
    steps:
      - uses: actions/checkout@v4

      # ここが並列処理の核心!
      - name: ClaudeCodeActionsによる個別処理
        uses: my-org/claude-code-actions@v1
        with:
          task: "translate_to_english"
          target_file: ${{ matrix.file }} # Matrix変数を渡す
          api_key: ${{ secrets.CLAUDE_API_KEY }}

このワークフローをプッシュした瞬間、GitHub ActionsのUIは壮観な眺めとなった。10個、50個、いや100個を超えるジョブが同時に Queued になり、次々と In progress に変わっていく。

これまで3時間かかっていた翻訳タスクが、最も時間のかかる1ファイルの処理時間(例えば3分)で完了するようになったのだ。

障壁:コストとスケーラビリティの壁

しかし、ここで新たな問題に直面する。

GitHub-hostedランナー(GitHubが用意してくれる標準の実行環境)は便利だが、並列度を極端に上げると二つの問題が発生する。

APIレート制限: 短時間に数百のジョブから同時にClaude APIを叩けば、当然レート制限に引っかかる。(これはリトライ処理である程度カバーできるが、効率は落ちる)

従量課金の恐怖: GitHub Actionsの無料枠はすぐに使い果たされる。数百並列でジョブを走らせれば、課金額は青天井だ。APIの待ち時間にも課金されるモデルは、AIタスクとは相性が悪い。

「並列化はできた。だが、このままでは破産する」

ここで、最後のピースが必要になる。「定額」と「Self-Hosted」だ。

到達点:Self-Hostedランナーによる「俺たちの計算資源」

この巨大並列システムをサステナブル(持続可能)にする唯一の解は、Self-Hostedランナーの導入だった。

AWS EC2、Google Kubernetes Engine (GKE)、あるいはオフィスに転がっているハイスペックPCでもいい。自分たちが管理するインフラ上にGitHub Actionsのランナーエージェントをインストールし、ジョブの実行をそちらに向けるのだ。

Self-Hostedのメリット:

実質的な「定額」化: インフラ費用はかかるが、ジョブの実行時間に応じた従量課金からは解放される。APIの応答を待つだけのアイドルタイムに怯える必要はもうない。

圧倒的なスケーラビリティ(K8sの場合): Kubernetes上で actions-runner-controller などを利用すれば、キューに溜まったジョブの数に応じて、ランナー(Pod)を自動的に数百、数千単位でスケールアウト・スケールインできる。

セキュリティと実行環境の制御: プライベートネットワーク内のリソースへのアクセスや、AIモデルのキャッシュなども自由自在だ。

ワークフローの修正は簡単だ。runs-on を書き換えるだけ。

  process-with-claude:
    needs: setup-matrix
    # 自前で構築した強力なランナー群を指定
    runs-on: [self-hosted, high-cpu, k8s-scale-set]
    strategy:
      matrix:
        file: ${{ fromJson(needs.setup-matrix.outputs.matrix-files) }}
    # ... (以下同じ) ...

結実:非同期×並列×定額×SelfHosted がもたらす未来

こうして構築されたシステムは、もはや単なるCIツールではなく、巨大な分散AIデータ処理基盤へと進化した。

非同期: 開発者はPRを投げたら、あとはシステムが裏でよしなにやってくれる。完了通知をSlackで受け取るだけ。

並列 (Matrix): 1000ファイルの処理も、1ファイル処理するのとほぼ同等の時間で完了する。

定額 & Self-Hosted: インフラコストは予測可能範囲内に収まり、自分たちの支配下にある計算資源をフル活用できる。

金曜日の夕方。再びプルリクエストがマージされた。

以前なら絶望していたその瞬間、あなたの目の前のダッシュボードでは、Kubernetesクラスタが唸りを上げて数百のPodを立ち上げ、Matrix戦略によって分割されたClaudeへのリクエストが同時多発的に飛んでいく。

ほんの数分後。全てのステータスがグリーンに変わった。

あなたはコーヒーを一口飲み、定時でPCを閉じる。週末は、このシステムを使って次に何を自動化しようかと、ワクワクした空想に耽りながら。

さあ、次はあなたの番だ。直列処理の呪縛から解き放たれ、GitHub Actions Matrixという名の武器を手に取ろう。あなたのリポジトリは、まだその真価を発揮していないだけなのだから。

この記事が役に立ったらシェアしてください

GitHub ActionsとAI自動化に関心のある方へ共有をお願いします

カテゴリ

DevOps

公開日

2025-11-23

お気軽にご相談ください

記事に関するご質問や、AI・IT技術導入のご相談など、お気軽にお問い合わせください。