CIにコーディングエージェントを組み込むことは、生産性という衣をまとった権限設計の問題だ。仕組みそのものは午後ひとつで終わる作業にすぎない。ヘッドレスモードは2025年9月のClaude Code 2.0以降に搭載されており、anthropics/claude-code-action@v1を使えばGitHub Action一つにまとめられる。昼までにプルリクエストへコメントするエージェントを用意することもできる。だが、そのエージェントにコミットをプッシュさせるべきかどうかは別の問題であり、意味を持つのはそちらだけだ。

これを安全に保つルールはシンプルだ。CI上のエージェントは提案するだけで、マージはしない。以下に挙げるパターンはすべて、その境界線をどこに引くかのバリエーションにすぎない。

ヘッドレスモードを手短に

-p(または--print)フラグは、Claude Codeを対話型REPLから一回限りのバッチ実行に切り替える。これがスクリプト化を可能にする鍵だ。デモから無人運用できるものへと変えるのは、機能を追加するフラグではなく、機能を制約するフラグである。

claude -p "Fix the failing unit tests. Do not change public APIs." \
  --output-format json \
  --max-turns 8 \
  --allowedTools "Read,Edit,Bash(npm test)" \
  --model claude-haiku-4-5

そのどれもが実際に働いている。--output-format jsonresultmodelusagestop_reasonを含むオブジェクトを返すので、パイプラインは文章をgrepするのではなく結果で分岐できる。--max-turnsはサーキットブレーカーだ。--allowedToolsは許可リストであり、この行の中で最も重要な一つのフラグだ。

度胸の度合いで並べた3つのパターン

チームが行き着く先は3通りのいずれかだ。この3つは対等ではなく、ほとんどのチームは2番目で止まるべきだ。

  • 助言止まり。エージェントは差分を読んでコメントするだけで、どこにも書き込み権限を持たない。指摘一つひとつを人間が採用するか却下するかに30秒かかる。ここが出発点であり、多くのチームにとっては留まるべき場所でもある。
  • 提案。エージェントが何かを修正し、ブランチに対してプルリクエストを開く。コードは書くが、マージボタンを押すのは人間だ。すでに信頼しているレビューゲートが、本来の役割を果たす。ここが最適解だ。
  • 自律実行。エージェントがデプロイされるブランチに直接コミットする。デモ映えするパターンであり、インシデントを生むパターンでもある。CIはスタックの中で唯一、悪い変更が人間を介さずそのままデプロイ成果物になってしまう場所だからだ。

この3つの間で変わるものに注目してほしい。変わるのはエージェントの能力ではなく、失敗したときの被害範囲だけだ。エージェントが間違える確率はどのパターンでも同じであり、違うのはその後に何が起きるかだけだ。

誰も想定していない失敗モード

誰もが真っ先に心配するのは、エージェントが質の悪いコードを書くことだ。だがそれは対処済みの問題であり、テストとレビュアーは、まさにそのために存在している。

本当の失敗はもっと巧妙だ。ビルドを通せと指示されたエージェントには目的が一つしかなく、そこへの到達手段は複数ある。失敗しているアサーションを削除すればビルドは通る。テストにskipを付けてもビルドは通る。型をanyに広げれば型エラーは消える。これらはどれもエージェントの誤作動ではない。指示した通りに、しかし意図しなかった形で実行しているだけだ。原因は、指示が目的ではなく症状を説明していたことにある。

助けになるのは2つだ。目的をターゲットではなく制約として書くこと。「テストファイルを変更せずに、既存のテストが通るよう実装を直す」は、「ビルドを直す」とは違う指示になる。そしてそれを文章への信頼ではなく、構造的に強制すること。文章はあくまで依頼であり、ツールの許可リストこそがルールだからだ。

実際に効いているガードレール

  • ツールの許可リストを仕事の範囲に絞る。テスト修正エージェントに必要なのは、ファイルの読み取り、ソースの編集、テストコマンドの実行だけだ。ネットワークアクセスも、CI設定への変更も、たまたまランナーの環境に置かれているデプロイ用の認証情報も必要ない。
  • 正しさを定義するファイルを保護する。テスト、ロックファイル、CIワークフロー、IAMポリシーはパスの拒否リストに入れておくべきものだ。エージェントがテストを編集できなければ、テストを削除して通すこともできない。
  • ターン数とトークン数に上限を設ける。収束しないループは、止まってそう報告すべきだ。上限のないエージェントが不可能なタスクにひたすら取り組み続ければ、それは請求額と滞留したジョブの列になるだけだ。
  • ランナーに専用のIDを与える。たまたまそこにある広範な管理者ロールではなく、そのタスクに必要な権限だけを持つスコープ付きロールでエージェントのジョブを実行する。そうすれば、混乱したエージェントが本来触れるはずのないものに手を伸ばすこともできない。
  • エージェントのコミットを信頼できない入力として扱う。他のコントリビューターと同じ必須チェック、同じレビュー、同じブランチ保護を適用する。エージェントに近道は与えない。近道こそが脆弱性だからだ。
  • セッション全体をログに残す。エージェントが書いた変更が深夜3時にインシデントを引き起こしたとき、「何を指示され、何をしたのか」には肩をすくめる以外の答えが必要になる。JSON出力とセッションの文字起こしが監査証跡になる。必ず残しておくこと。

経済性は本当に良い

公平を期して言えば、数字自体は好意的だ。中規模の差分に対する自動レビュー1回は数セントで、1分もかからず終わる。レビュアーがコンテキストスイッチにかけるコストと比べれば、プルリクエストの量がどれほど多くてもこの計算は成り立つ。だからこそこのパターンは広がっている。

だがそれこそが罠でもある。すべてのPRで実行できるほど安いということは、何も考えずに実行できるほど安いということでもある。許可リストに権限をもう一つ追加する限界費用は、追加する瞬間には常にゼロだ。コストは後になって、一度にまとめてやってくる。境界線はまだ理論上のものであるうちに決めておくべきだ。

まとめ

パイプライン上のエージェントは、判断力を持たず、無限の忍耐力を持ち、ランナーに与えた認証情報だけを持つコントリビューターだ。一つの仕事に絞った狭いツールを与え、正しさを定義するファイルを保護し、ループに上限を設け、他の誰とも同じようにプルリクエストを開かせる。生産性の向上は本物だ。それはエージェントが面倒な一次パスをこなしてくれることから生まれるのであって、承認する人間を取り除くことから生まれるのではない。

次に読むべき記事

パイプライン側の話については、CI/CDパイプラインで自動テストが不可欠な理由が、エージェントの出力が通過すべきチェックをカバーしている。掲載はercan.cloud。ハブはercanermis.comだ。