CIの失敗に対してClaude Codeを使う方法:失敗出力を引用し、最小限の修正を提案し、再発を防ぐ回帰テストを追加するように促します。

CIの失敗は通常、謎めいているわけではありません。ログには停止した箇所、失敗したコマンド、エラーメッセージが示されています。スタックトレース、ファイルと行番号付きのコンパイラエラー、どのアサーションが失敗したかを示すテストレポートなどがあれば良いサインです。時には「expected X, got Y」のような差分スタイルの手がかりや、lint、build、migrate database のような明確に失敗したステップが出ることもあります。
問題は、人(とAI)がログを背景ノイズとして扱いがちなことです。長いログを貼って「修正して」と頼むと、多くのモデルは最後の意味ある行を読む代わりに馴染みのある説明に飛びつきます。エラーが一般的に見える(module not found、timeout、permission denied)ほど推測は悪化し、大掛かりな書き換え、不要な依存追加、あるいは「全部アップデートしてみて」といった実際の失敗に合わない答えになります。
目的は「なんとか通す」ことではありません。もっと単純です:
実務では「最小の修正」は多くの場合、次のいずれかです:一箇所の数行のコード変更、足りないインポートや間違ったパス、CI環境に対して明らかに間違っている設定値、あるいは大規模な設計変更ではなく偶発的な破壊的変更を元に戻すことです。
フォローアップのテストも重要です。一度CIが通ったからといって再発を防げるわけではありません。失敗がエッジケース(null入力、タイムゾーン、丸め、権限)に起因するなら、修正前には失敗し修正後に通る回帰テストを追加してください。これにより一度きりの救出がガードレールになります。
多くの悪い修正はコンテキスト不足から始まります。最後の赤い行だけを貼ると、モデルは前に何が起きたか推測せざるをえず、その推測が大掛かりな書き換えにつながります。
誰かが失敗を追えるだけの詳細を提供することを目指してください。可能なら逐語で次を含めます:
go test ./..., npm test, flutter test, golangci-lint run)。制約を平易に書いてください。もし最小修正が欲しいならその旨を明記します:リファクタ禁止、振る舞い変更は必要な場合のみ、パッチは失敗した箇所に限定、など。
単純な例:依存関係の更新後にリンターが通らなくなった。最初の警告から貼り、CIが使ったコマンドと、変更したパッケージのバージョンを一つだけ添えれば、1行の設定調整や小さなコード修正を提案するのに十分です。リポジトリの半分を再フォーマットするような回答を避けられます。
コピー&ペーストできる構成は通常これで十分です:
CI command:
Failing output (full):
Recent changes:
Constraints (smallest fix, no refactor):
Flaky? (runs attached):
モデルがCIの不具合を外す原因は、プロンプトが推測を許してしまうことです。モデルに失敗出力を使って「証拠を示す」ように強制し、そのうえで通すための最小変更にコミットさせるのがあなたの仕事です。
証拠と小さな計画を要求してください。良いプロンプトは次の5点を強制します:
不確実性は問題ではありません。隠された不確実性が時間を浪費します。
質問の先頭にこれを貼ってください:
Use ONLY the evidence in the CI output below.
1) Quote the exact failing lines you are using.
2) Give ONE sentence: the most likely cause.
3) Propose the smallest fix: 1-3 edits, with file paths.
4) Do NOT do formatting/renames/refactors or "cleanup".
5) List uncertainties + the one extra detail that would confirm the diagnosis.
ログに「expected 200, got 500」や user_service.go:142 のようなスタックがあるなら、この構成はその関数と小さなガードやエラーハンドリングの変更へ応答を導きます。設計のやり直しではなく、まずは症状を直す方向です。
最速の成果は、ログの引用を強制し、制約内に留め、不足があれば止めるプロンプトから生まれます。
You are helping me fix a CI failure.
Repo context (short):
- Language/framework:
- Test/build command that failed: <PASTE THE EXACT COMMAND>
- CI environment (OS, Node/Go/Python versions, etc.):
Failing output (verbatim, include the first error and 20 lines above it):
<PASTE LOG>
Constraints:
- Propose the smallest possible code change that makes CI pass.
- Do NOT rewrite/refactor unrelated code.
- Do NOT touch files you do not need for the fix.
- If behavior changes, make it explicit and justify why it is correct.
Stop rule (no guessing):
- If the log is incomplete or you need more info (missing stack trace, config, versions, failing test name), STOP and ask only the minimum questions needed.
Your response format (follow exactly):
1) Evidence: Quote the exact log lines that matter.
2) Hypothesis: Explain the most likely cause in 2-4 sentences.
3) Smallest fix: Describe the minimal change and why it addresses the evidence.
4) Patch: Provide a unified diff.
5) Follow-up: Tell me the exact command(s) to rerun locally to confirm.
Then, write ONE regression test (or tweak an existing one) that would fail before this fix and pass after it, to prevent the same failure class.
- Keep the test focused. No broad test suites.
- If a test is not feasible, explain why and propose the next-best guardrail (lint rule, type check, assertion).
二つの細かい点がやり取りを減らします:
時間を失う最速の方法は、5つのことを一度に変える「クリーンアップ」変更を受け入れることです。事前に「最小」を定義してください:失敗したジョブが通る最小の差分で、リスクが最も低く検証が速いもの。
単純なルールが有効です:まず症状を直し、その後で本当に必要なら大きなリファクタを検討する。ログが1ファイル、1関数、1つの欠けたインポート、または1つのエッジケースを指しているなら、そこを狙ってください。「ついでに」編集は避けます。
本当に選択肢が必要なら、安全性を重視した「最小の修正」と、最速の「最小の修正」を2つだけ求めてください。選択肢は2つに絞るのが鍵です。
また、ローカル検証はCIと同じコマンドで行うよう要求してください。そうすれば数分で確認できます:
# CIが実行するのと同じユニットテストターゲットを走らせる
make test
# またはCIで使う正確なスクリプト
npm test
大きな変更を提案されたら、こう問い返してください:「問題のアサーションを直す最小のパッチを示して、無関係なフォーマットやリネームは含めないでください。」
テストなしの修正は、同じ問題が再び起きないという賭けです。常に、修正前に失敗し修正後に通るフォローアップテストを依頼してください。
「良い」テストの要件を具体的に示します:
追加の指示例:
例:APIハンドラーが空文字のIDを受け取るとパニックするケース。単にその行のテストではなく、空文字・空白・不正フォーマットなど複数の不正IDを検証するテストを求めます。最小の修正は 400 を返すガード句で、フォローアップテストは複数の無効IDに対する期待を検証して、将来のパースの掃除で同じ問題が戻らないことを保証します。
プロジェクトにテストの慣習があるならそれに従うよう指示し、ないなら近傍のテストに倣って可読で最小限のテストを書くように依頼してください。
エラーを含むログと、その上20~40行を貼り付けてください。失敗した正確なコマンドと主要な環境情報(OS、ランタイムのバージョン、重要なフラグ)も添えます。
その後、モデルに「何がどう失敗したか」を平易な英語(またはチームの言語)で要約してもらい、出力中のどの行がそれを証明するかを指させてください。ログを引用できなければ、十分には読んでいません。
失敗したコマンドが通るための最小変更を提案させ、リファクタは拒否します。適用前に次を列挙させてください:
パッチを適用してCIと同じコマンドを再実行します。まだ失敗するなら新しい失敗出力のみを貼って繰り返します。コンテキストを小さく保つと応答が集中します。
グリーンになったら、修正前に失敗し修正後に通る1つの回帰テストを追加します。ターゲットを絞った1テストにしてください。
その後、テストを含めた状態で同じコマンドを再実行して、単にエラーを隠しただけでないことを確認します。
短いコミットメッセージとPR説明を求めます:何が失敗したか、何を変えたか、どう検証したか、どのテストが再発を防ぐかを含めるとレビューが速くなります。
よくある失敗:ローカルでは動いていたのに小さな変更でCIが落ちるケース。GoのAPIで、ハンドラーが日付のみ(2026-01-09)を受け入れるようになったが、コードがRFC3339のみをパースしていた場合の例です。
貼るべき短い抜粋の例:
--- FAIL: TestCreateInvoice_DueDate (0.01s)
invoice_test.go:48: expected 201, got 400
invoice_test.go:49: response: {"error":"invalid due_date: parsing time \"2026-01-09\" as \"2006-01-02T15:04:05Z07:00\": cannot parse \"\" as \"T\""}
FAIL
exit status 1
FAIL app/api 0.243s
このログに対して、証拠を使うことと最小修正とテストを強制するプロンプトを使います:
You are fixing a CI failure. You MUST use the log to justify every claim.
Context:
- Language: Go
- Failing test: TestCreateInvoice_DueDate
- Log snippet:
<PASTE LOG>
Task:
1) Quote the exact failing line(s) from the log and explain the root cause in 1-2 sentences.
2) Propose the smallest possible code change (one function, one file) to accept both RFC3339 and YYYY-MM-DD.
3) Show the exact patch.
4) Add one regression test that fails before the fix and passes after.
Return your answer with headings: Evidence, Minimal Fix, Patch, Regression Test.
良い応答はパースレイアウトの不一致を指摘し、parseDueDate のような1関数(例えば invoice.go)を小さく変えて RFC3339 をまず試し、失敗したら 2006-01-02 のフォーマットにフォールバックする、という最小修正を示します。
回帰テストは防御的です:due_date: "2026-01-09" を送って 201 を期待するテストを書けば、将来フォールバックを消すとCIが同じ失敗で止まります。
問題を切り取りすぎると時間を失います。CIログはノイズが多いですが、有用な部分は通常最終エラーの上20行程度にあります。
落とし穴の一つは最後の赤い行だけを貼ること(例:exit 1)。実際の原因はもっと前にあるかもしれません(環境変数の欠如、スナップショットの失敗、最初にクラッシュしたテスト)。対処法:最初のエラー行とそれより上のウィンドウを含めてください。
別の時間泥棒はモデルに「ついでに綺麗にしておいて」と許すことです。フォーマットや依存更新、リファクタはレビューしにくく副作用を生みます。対処法:最小の変更をロックし、無関係な変更は拒否します。
注意すべきパターン:
フレークを疑うならリトライで隠すのではなく、ランダム要素を削除してください(固定時刻、シード化されたランダム、分離された一時ディレクトリ)。
プッシュ前に短い正気のチェックを行ってください:変更が本物で最小で再現可能かを確認するのが目的です。
最後に、元の失敗ジョブより少し広めのセット(例:lint とユニットテスト)を走らせて、修正が他のターゲットを壊していないことを確かめてください。
これを継続的に時間節約にするには、プロンプトと応答フォーマットをチームのプロセスにしてください。目的は再現可能な入力、再現可能な出力、そして「何でも直した」ように見せかける一時的な修正を減らすことです。
優れたプロンプトをリポジトリスニペットとして保存し、チームチャットにピン留めします。ワークフローの骨子:
チャット中心のワークフローが好みなら、Koder.ai内で同じ修正とテストのループを回し、実験中はスナップショットを使い、準備ができたらソースをエクスポートして通常のリポジトリにマージできます。
最初に見るべきは最後の exit 1 ではなく、最初の「本当の」エラーです。
モデルにログを読んだことを証明させましょう。
制約例:
失敗ステップを通過させるための最小パッチをデフォルトとします。
通常は以下のいずれか:
CIが安定するまで“クリーンアップ”変更は控えてください。
失敗を再現するのに十分なコンテキストを貼ってください。最後の赤い行だけでは不十分です。
含めるべきもの:
go test ./...、npm test、flutter testなど)。はい。制約を平易に記述して繰り返し伝えれば良いです。
例:
こうすることで応答の範囲が狭まり、レビューもしやすくなります。
最初に発生した実際の失敗を優先して修正します。
迷う場合はモデルにログの「最初の失敗ステップ」を特定させ、それに従ってください。
不安定さ(フレーク)はリトライでごまかすのではなく、ランダム要素を取り除く合図です。
よく使う安定化策:
これで決定論的にすると、最小修正が明確になります。
CIが実行したのと同じ正確なコマンドを使ってローカルで再現することです。
ローカルで再現が難しい場合は、リポジトリ内で同じエラーを引き起こす最小の再現テストを作ってもらいましょう。
修正前に失敗し、修正後に通るような集中した回帰テストを1つ書くのが理想です。
良い対象:
ビルドやリンターの失敗なら、等価のチェックを強める(ルール追加)ことで同様のガードレールを作れます。
スナップショットやロールバックを使い、実験が簡単に元に戻せるようにすることです。
実用的なループ:
Koder.aiのような環境ではスナップショットで試行錯誤し、最終的なパッチだけをエクスポートできます。