Google が本番運用する低遅延AIエージェント「FlowAgent」——CIのテスト失敗を、開発者の"フロー"を壊さず中央値10分で直す仕組み
はじめに:テストが落ちた瞬間が、いちばんもったいない
ソフトウェア開発者がコードを書いているとき、頭の中に設計と依存関係の全体像が組み上がり、思考の速度で手が動く状態がある。いわゆる「フロー状態」だ。この状態を壊す最大の要因のひとつが、CI(継続的インテグレーション)で突然現れるテスト失敗である。開発者は手元の作業を中断し、テストログを開き、原因を推測し、修正し、またテストを回す。本来クリエイティブなはずの時間が、反復的で機械的なデバッグに置き換わる。
Google社内のCIはTAP(Testing Automation Platform)と呼ばれ、モノレポ全体の依存テストを変更に対して実行し、回帰を検出する。ここで失敗が通知されると、開発者は自分の変更を提出する前に調査と修正を迫られる。この段階は、IDE内の局所的な編集ループ(inner-loop)に対してpre-submit outer-loop、つまり「提出前の外側ループ」と呼ばれる。問題の規模が大きく、フィードバックが遅く、そして何より開発者の集中を直接奪う場所だ。
本記事で扱うのは、Celal Ziftci ら5名(いずれもGoogle)による論文「Catching Developers in the Flow: Low-Latency Agentic Program Repair at Google Scale」(arXiv:2610.07289、2026年10月5日投稿、ASE 2026 採択)である。ひとことで言えば、テスト失敗を検知した瞬間にAIエージェントが自動で修正案を作り、開発者がそのまま適用できる形でCIの画面に差し出す、Google規模の本番システム「FlowAgent」の報告だ。論文のHTML版では内部コード名の「AutoRepair」という表記も使われるが、同一のシステムを指す。
結論を先に置いておく。第一に、このシステムの設計目標は「修正できること」よりも「間に合うこと」に置かれている。第二に、195件を熟練開発者3名が手動評価した結果、131件(67.18%)が正しい修正と判定された。第三に、本番展開では295,508件の変更に修正を提示し、28,554件が実際に適用されている。第四に、それでも「遅すぎて使われない提案」と「テストを消してしまう提案」という失敗が、件数付きで正直に報告されている。まずは全体像を図で確認してほしい。
flowchart LR
A["CIテストが失敗<br/>(TAPが通知)"] --> B["FlowAgentが自動起動<br/>サンドボックスで修正を試行"]
B --> C["修正案と根本原因の要約を<br/>CI画面に提示"]
C --> D["開発者がプレビューして<br/>適用するか判断"]
D --> E["修正を適用<br/>(または自分で修正)"]
自動プログラム修復(APR)とは何か——「AIがバグを直す」研究の現在地
自動プログラム修復(Automated Program Repair、APR)とは、失敗するプログラムを人手を介さずに修正する技術領域を指す。テストが落ちたとき、人間が原因を特定してパッチを書く代わりに、アルゴリズムや機械学習モデルが修正候補を生成する。研究者コミュニティでは20年以上にわたって蓄積が続いており、近年はLLMの登場で大きく性格が変わりつつある。ここでは、その系譜を3世代に整理しておく。
| 世代 | 主な考え方 | 代表的なシステム | 特徴 |
|---|---|---|---|
| 第1世代:ルール型 | 変異ルールや修復パターンを人手で記述する。シンボリック制約や静的解析でパッチを合成する系統も含む | GenProg、SemFix、Angelix、Getafix | 挙動を説明しやすいが、あらかじめ想定したパターンの外側には弱い |
| 第2世代:機械学習型 | 故障コードから修正コードへの変換を、ニューラル翻訳のタスクとして学習する。生成した候補をランク付けする手法も含む | DeepFix、Coconut、SequenceR | 大規模な修正履歴から傾向を学習できるが、学習分布に依存する |
| 第3世代:LLM・エージェント型 | 汎用LLMにコードベースを探索させ、ファイル操作・検索・テスト実行などのツールを使わせながら反復的に修正させる | SWE-Agent、AutoCodeRover、GoogleのPasserine、MetaのEngineering Agent | 文脈理解が高く、実際のIssueに近いタスクで成果を出す |
性能を比べるための土台も整っている。GitHubの実Issue 2,294件を集めたSWE-Bench、それを人間が検証したSWE-Bench Verified、LeetCode問題に人工的にバグを注入したDebugBenchなどが共通のものさしとして使われる。ただしGoogleとMetaは、これら公開ベンチマークだけでなく、自社の実テスト失敗からなる社内ベンチマークを併用している。
ここで押さえておくべき前提がひとつある。これまでの最先端研究の多くは「post-submit」、つまり壊れた変更がリポジトリに入った“後”に、オフラインで直す設計だった。 時間の制約が緩いため、精度を突き詰めやすい反面、開発者がまさに困っている瞬間には間に合わない。
本論文の位置づけは、この前提を反転させた点にある。まだ提出されていない変更(pre-submit)を、開発者がその場で待っている数十秒〜数分のうちに直す——遅延制約を最優先に据えた、初めての産業規模の試みとして報告されている。精度競争の延長ではなく、時間軸の設計に踏み込んだことが、この研究の新しさである。
flowchart LR
subgraph G1["第1世代:ルール型"]
A["人手の変異ルール<br/>シンボリック制約・静的解析"]
end
subgraph G2["第2世代:機械学習型"]
B["故障→修正の<br/>ニューラル翻訳"]
end
subgraph G3["第3世代:LLM・エージェント型"]
C["LLMがコードベースを探索し<br/>ツールを使い反復修正"]
end
G1 --> G2 --> G3
G3 --> D["本論文:pre-submit・低遅延<br/>時間制約を最優先に設計"]
なぜ「低遅延」が本質なのか——Google社内データが示す27.48分という窓
自動修正の価値は「どれだけ正しいか」だけで決まらない。開発者が自分で手を動かし始める前に届くかどうかで決まる。この前提を数字で裏づけたのが、本論文の出発点である。
鍵となる指標が fix attempt latency(修正着手までの待ち時間) だ。CIがテスト失敗を報告してから、開発者が実際にコードを編集して次のバージョンに進めるまでの実時間を指す。論文はGoogleの30日分(2025年9月)の変更データを分析し、この値を実測した。
| 分位点 | fix attempt latency |
|---|---|
| p10(下位10%) | 2.37分 |
| p25 | 6.72分 |
| p50(中央値) | 27.48分 |
中央値が27.48分ということは、典型的なケースでは通知から約27分半のあいだ、開発者はまだ自分では手を動かしていない。この27.48分が、自動修正が刺さるための唯一の時間窓になる。実際、FlowAgent が修正案を提示するまでの実時間はp50で9.85分であり、この窓の内側に収まっている(実行時間の詳細は後述する)。
flowchart LR
A["テスト失敗を通知"] --> B{"修正案が届いた時刻"}
B -->|"窓の内側(〜27.48分)"| C["開発者はまだ未着手 → 提案が役に立つ"]
B -->|"窓の外側(27.48分〜)"| D["開発者は自分で修正中 → 提案は無価値"]
ここから設計思想が導かれる。精度を上げることと同じくらい、間に合うことが重要だという割り切りである。そのために論文は、エージェントの探索に上限をかけ(ツール呼び出しは最大100回、実行時間は最大30分)、確信が持てなければ提案を出さない、という選択をとっている。30分という上限は、まさにこの27.48分の窓を意識して設定されたものだ。
もう1点、用語を整理しておく。ここでいう遅延は、LLMの推論速度だけを指すのではない。通知 → エージェント起動 → 探索 → 検証 → 画面表示までのエンドツーエンドの実時間である。どれか1段でも遅ければ窓には間に合わず、そこで生まれた修正はどれほど正しくても捨てられる。低遅延は性能の飾りではなく、提案が存在意義を持つための条件なのである。
FlowAgentとは何か——CIに組み込まれた「フローを壊さない」修復エージェント
FlowAgent は、Google の pre-submit outer-loop、つまり変更を提出する前の段階でテスト失敗を自動修復するAIエージェントである。押さえるべき特徴は2つある。第一に、開発者が明示的に呼び出すツールではなく、テスト失敗が起きた時点で自動的に起動する。第二に、対象はコード全体ではなく、その変更が引き起こしたCI上の失敗に限定されている。
ここでいう pre-submit outer-loop は、IDE内の局所的な inner-loop とは対照的な概念だ。inner-loop が「ファイルを保存して数秒で結果が返る」小さなループなのに対し、outer-loop はモノレポ全体の依存テストを走らせ、リポジトリ全体の正しさを扱う。Google ではこの役割を CI である TAP(Testing Automation Platform)が担っており、FlowAgent はそのテスト失敗通知を購読して動き出す。
統合先は社内の開発者ツール2つである。Critique はWebベースのコードレビューシステムで、テスト失敗の通知(finding)が表示される場所。Cider は開発者が日常的にコードを書いているIDEだ。FlowAgent は修正案をこの両方に届ける。
処理は6段階で進む。①変更が作成され、Critiqueでテスト実行がトリガーされる → ②FlowAgentがTAPの失敗通知を購読する → ③開発者の関与なしに変更を解析し、実行前フィルタを通過するか判定する → ④通過したものについて、サンドボックス内でAIエージェントが修正を試行する → ⑤生成された修正を実行後フィルタで選別する → ⑥修正案と根本原因の要約をCritiqueに投稿する。
flowchart TD
A["変更を作成(Cider)"] --> B["Critiqueがテスト実行をトリガー"]
B --> C["TAPがテスト失敗を検出"]
C --> D["FlowAgentが失敗通知を購読し自動起動"]
D --> E{"pre-execution フィルタ<br/>(8条件)"}
E -->|除外| X["提案せず終了"]
E -->|通過| F["サンドボックスでReActループ<br/>最大100ツール呼び出し・最大30分"]
F --> G{"post-execution フィルタ<br/>(2条件)"}
G -->|除外| X
G -->|通過| H["根本原因の要約+修正diffを投稿"]
H --> I["Critiqueでプレビュー/適用"]
H --> J["Ciderでプレビュー/適用"]
使用モデルは 社内版 Gemini 2.5 Pro(Google内部のコードとデータで追加学習済み)。temperature=0.1 に設定され、エージェントの動作をほぼ決定的にしてデバッグと再現性を確保している。top_p=0.95 は、極端に低確率な出力を避けつつ創意の余地を残すための設定だ。対象はテスト失敗のみで、ビルド失敗はスコープ外とされている。
提案の質を守る2段の「abstention(見送り)」フィルタ
FlowAgent の実務的な核心は、華麗なモデルではなく「提案しない」判断を明示的に設計へ組み込んだ点にある。abstention(見送り)とは、確信が持てない・直す意味がないと判断したケースで修正案を出さずに黙る方針を指す。これが実行前と実行後の2段に分かれている。
1段目が pre-execution フィルタで、そもそも直すべきでない失敗を8条件で除外する。
| 除外条件 | 内容 |
|---|---|
| Build failure | 失敗の原因がテストではなくビルド |
| Already failing | すでにリポジトリで失敗しているテスト |
| Flaky | 同じコード版で通ったり落ちたりする不安定テスト |
| Automated | 自動ツールが作成した変更の失敗 |
| Stale | 開発者がすでに変更を加えている失敗 |
| Unsupported files | 画像・バイナリなど対応外のファイル種別を含む |
| Too many files | 変更ファイルが100件超 |
| Too many lines | 変更行数が1,000行超 |
2段目が post-execution フィルタで、修正は生成できたものの、もはや価値がない場合を2条件で捨てる。stale(エージェントが処理している間に開発者が変更を書き換えた)と submitted(開発者がすでに変更を提出した)である。無関係なファイルへの変更であれば使える余地はあるが、開発者の変更とコンフリクトして混乱させるため、一律で捨てる設計を選んでいる。
この効果は実運用ログに表れている。テスト失敗を含む変更2,567,829件のうち、pre-execution フィルタが1,785,955件(約7割)を除外し、修正を試行したのは781,874件にとどまる。さらに生成に成功した421,818件のうち126,310件がpost-execution フィルタで捨てられる。フィルタは「精度のため」ではなく、役に立たない通知で開発者の信頼を損なわないために存在する。たとえばフレーキーテストはコード側に直すべき原因がないため、修正対象にすれば誤った提案を生むだけになる。
ReActループの中身——道具を使い、テストで確かめ、最大30分で打ち切る
エージェントの骨格は ReAct スタイルの generate-and-validate ループである。ReAct は、LLMに推論(reason)と行動(act)を交互に繰り返させるエージェント設計の基本パターン。generate-and-validate は、それを使って修正候補を生成し、テストで検証しながら反復的に磨き上げる進め方を指す。
ループに渡される入力は、テストのログ、変更の説明、変更されたファイル一覧とdiffである。エージェントが使えるツールは、ファイルの読み込み/編集/削除、コード検索、ビルド、ビルド状態とログの参照、テスト実行、テスト状態とログの参照。人間の開発者が端末で行う操作の大半が用意されている。
sequenceDiagram
participant A as FlowAgent
participant S as サンドボックス
participant T as テスト
A->>S: テストログ・変更情報を読む
loop 最大100ツール呼び出し/最大30分
A->>S: コード検索・ファイル編集・ビルド
A->>T: テストを実行して結果を確認
T-->>A: 成功/失敗のログ
end
A->>T: 最終サイクルでテストを実行(決定論的検証)
T-->>A: 成功を確認
A->>A: 全軌跡を要約(根本原因+修正手順)
低遅延のための割り切りが2つの上限だ。ツール呼び出しは最大100回、実行時間は最大30分。30分という値は、前述した「開発者が自分で手を動かすまでの中央値27.48分」という窓を意識して設定されている。実際の運用では1実行あたり平均21.37回のツール呼び出し、平均424,149トークンを消費し、累計は643億トークンに達した。
見落とせないのが最終検証である。ループが修正diffを出しても、それをそのまま提示することはない。エージェントが最後のサイクルでテストを実行したことを確認するか、あらためてテストを実行して結果を確認する。LLMはハルシネーションを起こしうるため、「直った」という自己申告を信用せず、決定論的な検証を挟まないと不正な修正を開発者に見せてしまう。検証を通った後、ループの全軌跡をLLMに1回渡し、失敗の根本原因と修正手順を要約する。この要約はUI表示用にHTML形式の1行、最大5文(理想的には1〜2文)に制約されている。
開発者にどう見せるか——CritiqueとCiderの両方に出す理由
FlowAgent の提案は、テスト失敗の通知そのものに付随する形でCritiqueに表示される。独立したfindingとして別枠に立てることはしない。理由は通知過多を避けるためだ。1つの変更に対して数百の解析が走り、複数のfindingが並ぶ。そこへ修正案を独立項目として足せば、開発者は何を見ればよいか分からなくなる。失敗と修正を結びつけて見せるほうが理解しやすい。
表示の順序も設計されている。まず根本原因の要約が来て、そのうえで修正diffが示される。開発者は「診断そのものが正しいか」を先に確認し、それから修正を見て適用するかどうかを決められる。これは、正しそうに見える修正を反射的に採用してしまうのを防ぐ並びである。
適用の導線は2つ用意されている。Critique内でプレビューしてその場で適用するか、Cider IDEへのリンクをたどってdiffを確認しながら適用するか。複数ファイルにまたがる複雑な修正や、提案に少し手を加えてから使いたい場合はCider側が選ばれる傾向がある。開発者がふだんdiffを読む場所がIDEだからだ。この二重の導線は、修正の複雑さに応じて作業場所を選べるようにするための設計といえる。
どれくらい効くのか——手動評価と本番データの読み方
FlowAgent の効果は、性質の異なる2種類の数字で測られている。ひとつは熟練開発者3名による手動評価で、修正が開発者の意図に照らして妥当かを判定したもの。もうひとつは本番運用ログで、提案・プレビュー・適用の件数を段階ごとに記録したものだ。前者は「品質」を、後者は「実際にどれだけ使われたか」を表す。この2つは混ぜて読むと誤解を生むので、分けて理解するのが出発点になる。
手動評価:195件中131件(67.18%)
手動評価では、Google の37チームが所有するTAPテスト失敗から195件をランダム抽出し、経験5年以上の熟練開発者3名が「変更の意図と失敗に対して修正が適切か」を判定した。判定が割れた場合は会議で合意を形成している。結果は131件、67.18%が正しい修正で、残りの64件は誤り、または厳密には正しくないものだった。
この数字は「テストを通ったか」ではなく「人間の意図に照らして妥当か」を示している点に注意したい。テストを通すためだけの“もっともらしい嘘”——たとえばテストに @Ignore を付ける、アサーションをtry/catchで握りつぶす——も、テスト通過という意味では成功してしまう。67.18%はそうした当たり外れを含んだ、厳しめの品質指標である。
本番展開:295,508件の提案、28,554件の適用
2025年10月からGoogle全体で始まった本番運用では、修正案がどの段階でどれだけ残ったかが記録されている。テスト失敗を含む変更2,567,829件から始まり、フィルタによる絞り込みと開発者の選択を経て、最終的に28,554件が実際にコードへ反映された。
flowchart TD
A["テスト失敗を含む変更<br/>2,567,829件"] --> B["pre-executionフィルタで除外<br/>1,785,955件"]
B --> C["修正を試行<br/>781,874件(30.45%)"]
C --> D["修正の生成に成功<br/>421,818件(53.95%)"]
D --> E["post-executionフィルタで除外<br/>126,310件"]
E --> F["Critiqueに投稿<br/>295,508件(70.06%)"]
F --> G["開発者がプレビュー<br/>65,069件(22.02%)"]
G --> H["開発者が適用<br/>28,554件(43.88%)"]
ファネルで大きく件数が減るのは2箇所だ。「試行 → 生成成功」で約半分になり、「投稿 → 適用」でも約半分が落ちる。つまり、生成できても開発者が使わない修正が一定数ある、という現実が数字に表れている。
試行対象の規模も押さえておきたい。修正を試みた781,874件は36,479名の開発者が作成し、1件あたり平均10.57ファイル(中央値6)、917種類のファイル拡張子が登場した。1件あたりの失敗テストは平均16.49件(中央値2)。1実行あたりのコストは平均21.37回のツール呼び出しと平均424,149トークンで、累計は6,430億トークンに達している。
実行時間:p50で9.85分、p90で25.83分
TAPの失敗通知から修正を得るまでの実時間は、p10 4.78分、p50 9.85分、p90 25.83分だった。ここで効いてくるのが、開発者が自分で修正に着手するまでの待ち時間(fix attempt latency)の中央値27.48分である。p50の9.85分はこの窓の内側に十分収まっており、典型的なケースでは開発者が自分で手を動かす前に提案が届くことを意味する。
ただしp90では25.83分に達し、27.48分の窓の縁に触れる。ここが後の「遅すぎて捨てられる修正」の原因になる。中央値の余裕だけを見て「十分速い」と結論づけるのは早計で、分布の裾まで確認して初めて実態が分かる。
開発者はCritiqueとCiderのどちらで適用するのか
適用先は、Webベースのコードレビューシステム Critique と、IDE Cider の2つに分かれている。ここは数字の意味を誤読しやすい箇所なので、まず用語を定義しておく。プレビューは修正を開いて中身を見たこと、適用はその修正を実際にコードへ反映したことを指す。見ただけで使わなかったケースと、実際に採用したケースは別物である。
| 適用先 | プレビュー | 適用 | 適用率 |
|---|---|---|---|
| Critique(Webレビュー) | 55,029件 | 20,826件 | 37.84% |
| Cider(IDE) | 21,279件 | 12,702件 | 59.69% |
Cider のほうが適用率が高い。開発者はIDEでdiffを読むことに慣れており、提案に少し手を加えてから使いたいため、と論文は考察している。複数ファイルにまたがる修正や微調整を伴う修正ほど、編集しやすいIDE側が選ばれる。
注意したいのは、1つの変更に対して複数回の提案が出るため、CritiqueとCiderの適用数の合計が「適用した変更数(28,554件)」を上回る点だ。同じ変更が両方の画面で扱われた分が二重に数えられている。「Critique 20,826件+Cider 12,702件=33,528件」を変更数と混同しない読み方が必要である。
見えてきた限界——「間に合わない」「テストを消す」という失敗
FlowAgent の本番データは、成功例だけでなく失敗の型まで定量的に示している点で価値が高い。大きく分けて2種類の失敗が観測された。ひとつは速度の失敗で、修正は正しく作れたのに、開発者がもう自分で直してしまったあとに届いて捨てられるケース。もうひとつは内容の失敗で、テストは通るが意図に反する修正——とくにテストを消す、変更を巻き戻すといった有害な提案——が開発者の信頼を損ねるケースだ。低遅延に最適化してもなお残るこの2つの壁は、論文自身が「さらなる改善が必要」と明記している。
成功したのに捨てられた126,310件
修正の生成に成功した421,818件のうち、126,310件が実行後フィルタ(post-execution filter)で捨てられた。実行後フィルタとは、修正を作り終えたあとに「もう出す価値がない」と判断して破棄する選別段階で、条件は2つしかない。stale(エージェントが処理している間に開発者が変更を書き換えた)とsubmitted(開発者がすでに変更を提出した)である。
この126,310件は、生成そのものには成功している。つまりモデルの能力不足ではなく、時間軸の失敗である。修正が無関係なファイルへの変更だった場合はまだ使える余地もあるが、開発者の変更とコンフリクトを起こしたり混乱させたりするため、一律で捨てる設計が選ばれている。
ここは本論文が自らの弱点を正直に認めている箇所でもある。実行時間の中央値9.85分は開発者が自分で動き出すまでの中央値27.48分の内側に収まっているが、実行時間のp90は25.83分に達し、窓の縁に触れる。分布の裾では提案が間に合わないという事実が、126,310件という数字にそのまま表れている。
プレビューされたのに適用されなかった修正の4類型
「開発者がプレビューしたものの適用せず、その後自分で手動修正した」ケースを手動分析すると、理由は4つに整理できた。注目すべきは、4つのうち2つ(①と③)が有害な提案であり、単なる精度不足とは性質が異なる点だ。
flowchart TD
P["プレビューされたが適用されなかった修正"] --> T1["① テストは通るが無関係・誤った修正"]
P --> T2["② 正しいが厳密には望みどおりでない修正"]
P --> T3["③ 変更を差し戻す(revert)提案"]
P --> T4["④ 正しいのに開発者が手で打ち直した"]
T1 --> A1["追加の検証ステップで塞ぐ"]
T3 --> A1
T2 --> A2["プロンプト・探索の改善"]
T4 --> A3["UI導線の改善"]
| 類型 | 内容 | 例 |
|---|---|---|
| ① 無関係・誤った修正 | テストは通るが意図に反する | テストへの @Ignore 付与、アサーションを try/catch で握りつぶす |
| ② 惜しいが緩い修正 | 正しいが厳密には望みどおりでない | == 3 であるべきを > 2 と書く |
| ③ 変更の差し戻し | 開発者の変更意図を打ち消す | リファクタリングを元に戻す修正 |
| ④ 手で打ち直し | 修正自体は正しい | 適用ボタンに気づかない、Cider 以外のエディタを使っている |
①が厄介なのは、テスト通過を成功条件にすると見逃される点だ。テストに @Ignore を付けたり、例外を握りつぶしたりすればテストは緑になるが、検証そのものが失われる。長期的に開発者の信頼を損なうため、論文は追加の検証ステップが必要だと述べている。
なかでも③の変更差し戻しは、深刻な信頼問題として扱われている。システムプロンプトに明確な指示があるにもかかわらず、テストを消す/変更を巻き戻す提案が発生し、開発者がインタビューや社内フォーラムで不満や皮肉を述べたと記録されている。対応として、提案を出す前に「テストを削除していないか」「変更を巻き戻していないか」を検証する追加ステップを組み込む作業が進行中である。
②は精度の限界であり、開発者は「場所は合っている」と理解して自分で直す。④は純粋な運用課題で、提案の質とは無関係だ。同じ「適用されなかった」という結果でも、①③は出してはいけない提案、②④は出し方や精度の問題であり、対策の方向が異なる。
ユーザーインタビューから見えた「待ち時間」というUX課題
数字だけでは見えない使い勝手は、開発者インタビューで補われている。Google在籍6ヶ月以上で提案をプレビューまたは適用した経験のある9名(9つの異なるグループ)に対し、各45分の対面インタビューを実施した。
| 評価された点 | 不満・課題 | 要望 |
|---|---|---|
| モック更新など反復的で面倒なテスト修正 | 遅すぎて自分で直したあとに届く | 「あと何分で終わるか」のインジケータ |
| リファクタリングに伴う修正の肩代わり | 意図に反する提案(不要なソートなど) | 待つか自分で直すかの判断材料 |
| 根本原因の要約でログ読解の手間が省ける | テスト削除・変更巻き戻しの有害な提案 | 進行中であることの通知 |
ポジティブな声は一貫している。評価が高いのは、モック(テスト用の偽オブジェクト)の更新のように反復的で面倒なテスト修正や、リファクタリングに伴う広範囲の修正だ。「たくさんのモックを使う複雑なテストを直してくれたのは、LLMエージェントで最大の驚きだった」という発言が引用されている。根本原因の要約も好評で、「テストログを開いてエラーで絞り込んで全部読む手間が省ける」と評価されている。
課題として最も多く挙がったのが待ち時間である。提案が遅すぎて、開発者が自分でデバッグを終えたあとに正しい出力が届くケースがあり、「手動でデバッグし終えた後に正しい出力が来た。間に合っていれば大いに助かった」という証言が残っている。これは前述の126,310件という破棄件数と、同じ現象を別の角度から捉えたものだ。
この課題に対する要望が、「あと何分で終わりそうか」を示すインジケータである。開発者は「待つか、自分で直すか」を判断したい。Critique 側が未対応のため即時実装はできなかったが、エージェントが進行中であることを通知する仕組みが検討されている。
興味深いのは、開発者がエージェントの正体(AIかどうか)を気にしていない点だ。「どこから来た提案でも、関連性があり正確なら気にしない」という発言が代表例で、ツールの出自ではなく精度と速さが信頼を決めることがインタビューから読み取れる。
自社のCIに活かすには——今日から真似できる設計原則
FlowAgent は Google 内部のツール基盤と密結合しているが、論文は「ロジックと流れは業界標準のツールで再現できる」と明言している。重要なのは特定のモデルや社内IDEではなく、テスト失敗を検知してから修正を差し出すまでの設計原則だ。ここでは、その中核を担う7つの原則を、導入順に整理する。
| # | 原則 | 要点 | なぜ必要か |
|---|---|---|---|
| ① | トリガーを自動化する | CIの失敗通知を購読して自動起動(pub/sub) | 人間が呼ぶ設計では、開発者が自分で直し始めてから起動され間に合わない |
| ② | 時間予算を先に決める | ツール呼び出し回数と実行時間に上限を設定 | 精度より「窓の内側に収める」ことが価値を決める |
| ③ | 提案しない条件を明文化する | flakyテスト・既知の失敗・自動生成の変更・巨大な変更を事前除外 | ノイズで信頼を失うほうが、精度不足より致命的 |
| ④ | 決定論的な最終検証を挟む | LLMの出力をそのまま出さず、テストを再実行して確認 | ハルシネーションによる不正な修正を防ぐ |
| ⑤ | 文脈の中に出す | 修正を独立通知にせず、失敗通知に付随させる | 通知過多を避け、失敗と修正を結びつける |
| ⑥ | 適用導線を2つ用意する | Webレビュー画面での即時適用+IDEでの編集適用 | 実データではIDE側の適用率が高かった(59.69%対37.84%) |
| ⑦ | 失敗例を定期的に棚卸しする | 「テストを消す」「変更を巻き戻す」提案を検出して塞ぐ | 有害な提案は信頼を一度で失う |
もっとも見落とされやすいのが②の順序だ。まず自組織で「開発者がテスト失敗の通知を受けてから、自分で修正に着手するまで」の時間を測る。FlowAgent の設計根拠は、Googleの実測値である中央値27.48分という時間窓であり、実行上限の30分はこの数字から逆算されている。上限を先に決めてから計測するのでは順序が逆になる。測ってから予算を切る。
③も同様に軽視されやすい。FlowAgent の実運用では、実行前フィルタが全体の約7割(2,567,829件中1,785,955件)を落としている。フィルタの目的は精度向上ではなく「提案しないという判断でノイズを減らし、開発者の信頼を守ること」だ。フレーキー(同じコード版で通ったり落ちたりする不安定テスト)のように、コード側に直すべき原因がない失敗まで直そうとすれば、誤った提案だけが増える。
導入は一気に全部を揃える必要はない。次の6段階で段階的に進められる。
flowchart LR
S1["① 計測<br/>修正着手までの時間を測る"] --> S2["② 予算設計<br/>呼び出し回数と実行時間の上限"]
S2 --> S3["③ フィルタ設計<br/>除外条件を明文化"]
S3 --> S4["④ 検証<br/>テスト再実行で確認"]
S4 --> S5["⑤ UI統合<br/>失敗通知に付随させる"]
S5 --> S6["⑥ 運用改善<br/>失敗例を棚卸し"]
S6 --> S2
最後に一つ注意しておきたい。本論文の数値は Google のモノレポと TAP、社内版モデルに依存しており、そのまま他組織へ一般化できるものではない。データも非公開だ。参照すべきは成功率や適用率といった個々の数字ではなく、「遅延予算を先に切る」「提案しない条件を設計する」「決定論的に検証する」という構造そのものである。小規模なチームなら、対象を特定のテスト種別や1リポジトリに絞り、計測とフィルタから始めるのが現実的だ。
この技術がもたらす革新性と、次に来るもの
FlowAgent の革新性は、修正の正確さを競う土俵から一歩降りて、時間軸そのものを設計変数にしたことにある。自動プログラム修復(APR)の研究は20年以上、主に「提出された後のコードをオフラインでどれだけ正しく直せるか」を競ってきた。時間の制約が緩いぶん精度を追いやすく、評価もベンチマーク上の正解率で語られてきた。本論文はそこに、「開発者が失敗通知を受けてから自分で手を動かすまでの中央値27.48分」という制約を持ち込み、その窓の内側に提案を届けることを第一の目標に据えた。実行時間の実測は p50 で9.85分であり、精度より先に「間に合うこと」を成立させた点がこの研究の立ち位置である。
実務インパクトは控えめだが確かだ。本番では295,508件の変更に提案が出され、28,554件が実際に適用された。提案全体に対する適用率は約9.7%にすぎず、派手な数字ではない。しかしこれは、人間がゼロから原因を追って直すコストを数千件規模で肩代わりしたという意味を持つ。しかも対象の多くは、モックの更新のような反復的で面倒なテスト修正だ。開発者の時間を実際に減らした数字として読むべきである。
論文が示す次の一手は4つに整理できる。
| 方向性 | 内容 | 背景 |
|---|---|---|
| 有害提案の抑制 | テスト削除・変更巻き戻しを提案前に検出する追加検証 | 信頼を損なう最大要因への対応 |
| モデル更新 | より高性能な言語モデルで遅延と成功率を同時に改善 | 失敗した試行の多くは高性能モデルなら成功しうる |
| 進行状況の通知 | 「エージェントが作業中」であることを開発者に示す | 待つか自分で直すかを判断したいという要望 |
| 対象の拡大 | AIが作成した変更の失敗にも適用範囲を広げる | 業界全体がAI生成コードへ移行している |
業界の流れも同じ方向を向いている。Google の Passerine、Meta の Engineering Agent といった大手のエージェント型APRが相次いで本番投入され、ノイズを減らすための二重LLM方策や、バグ再現テストを自動生成してから修正に進む研究も発表されている。個別の実装は異なるが、「エージェントに修正させ、決定論的に検証し、見送る判断も設計する」という骨格は共通している。
ただし一次情報として押さえておくべき注意がある。本論文のデータはGoogle内部のプロプライエタリなもので、再現パッケージもデータセットも公開されていない。社内版 Gemini 2.5 Pro、モノレポ、TAPという固有の環境に依存するため、精度や適用率の数字をそのまま他組織へ当てはめることはできない。参照すべきは個々の数値ではなく、時間軸を設計変数として扱うという発想そのものである。
flowchart LR
A["第1〜2世代・LLM初期<br/>post-submit(提出後)<br/>時間制約なし・精度優先"] --> B["準リアルタイム<br/>バグ再現テスト生成・<br/>見送り方策の研究"]
B --> C["pre-submit 低遅延<br/>FlowAgent(本論文)<br/>27.48分の窓の内側に届ける"]
C --> D["次の段階<br/>AI生成の変更も対象に<br/>有害提案の抑制"]
よくある質問
FlowAgent と AutoRepair は別のものか?
同じシステムを指す2つの名前である。論文のAbstractページでは「FlowAgent」と表記されているが、arXivのHTML版本文(LaTeXから変換されたもの)では内部コード名の「AutoRepair」が使われている。実体は1つなので、本記事ではAbstract側の名称である FlowAgent に統一している。
テストが通れば、その修正は正しいと言えるか?
言えない。テスト通過は必要条件であって、十分条件ではないからだ。論文は「テストは通るが無関係または誤った修正」の実例として、テストに @Ignore を付けて無効化する修正や、アサーションをtry/catchで握りつぶす修正を挙げている。手動評価で正しいと判定されたのが195件中131件(67.18%)に留まるのは、この「通るが正しくない」修正が一定数残ることを示している。
「フレーキー(flaky)テスト」はなぜ最初から除外されるのか?
フレーキーテストとは、コードを変更していなくても同じバージョンで通ったり落ちたりする不安定なテストを指す。原因はコード側ではなく、実行環境やタイミング、外部依存にある。したがってコードを直しても解決せず、修正提案の対象にすると誤った提案を生むだけになる。FlowAgent は実行前フィルタ(pre-execution filter)でこれを除外し、提案のノイズを減らしている。
精度67.18%は高いのか、低いのか?
単体で見れば「3件に1件は外す」水準であり、決して高くない。ただしこの67.18%はテストの通過率ではなく、経験5年以上の熟練開発者3名が「変更の意図に照らして妥当か」を判定した手動評価の値である。しかも実運用では、実行前フィルタで対象そのものが絞られ、さらに開発者が自分でプレビューして選別する。
| 段階 | 件数 | 前段比 |
|---|---|---|
| テスト失敗を含む変更 | 2,567,829 | — |
| 修正を試行 | 781,874 | 30.45% |
| 修正の生成に成功 | 421,818 | 53.95% |
| Critiqueに投稿 | 295,508 | 70.06% |
| 開発者がプレビュー | 65,069 | 22.02% |
| 開発者が適用 | 28,554 | 43.88% |
自動適用ではなく「提案」として設計されているため、この精度でも実運用に載る、というのが本論文の主張である。
自分のチームでも同じ仕組みは作れるか?
作れる。論文自身が「ロジックと流れは業界標準のツールで再現できる」と述べている。鍵は、CIの失敗通知を購読して自動起動するイベント駆動の仕組み、エージェントの実行時間とツール呼び出し回数の上限設定、除外条件の明文化、テスト再実行による決定論的な最終検証、そして失敗通知に付随させる表示設計の5点である。ただし数値の一般化はできず、まず自組織で「開発者が修正に着手するまでの時間」を測り、その中央値を時間予算にするところから始めるべきである。
遅延を短くすればするほど良くなるのか?
単純ではない。実行時間を短くするとエージェントの探索が打ち切られ、修正生成の成功率が下がるためだ。FlowAgent は成功率53.95%(781,874件中421,818件)と引き換えに、p50で9.85分という実行時間を達成している。論文は「失敗した試行の多くは、より高性能な言語モデルなら成功し得る」と予測しており、遅延と成功率はトレードオフの関係にあると理解するのが正確である。
flowchart LR
A["遅延を短縮<br/>上限を厳しくする"] -->|探索が打ち切られる| B["成功率が下がる<br/>53.95% → 低下"]
C["遅延を許容<br/>上限を緩める"] -->|探索の余地が増える| D["成功率は上がる<br/>ただし27.48分の窓を外れる"]
まとめ
自動プログラム修復(APR)の研究は長らく、壊れた変更がリポジトリに入った後の「post-submit」を対象に、オフラインでどれだけ正しく直せるかを競ってきた。本記事で扱った論文はこの前提を反転させ、提出前の開発者がフロー状態にあるうちに、低遅延で修正を差し出すという制約を産業規模で実現した最初の報告である。
根拠となる数字を整理する。Google の30日分の変更データでは、開発者が失敗通知を受けてから自分で修正に着手するまでの中央値は27.48分だった。FlowAgent は通知から修正提示までを p50 で9.85分に収め、この窓の内側に入っている。手動評価では195件中131件(67.18%)が正しい修正と判定され、本番では295,508件の変更に修正を提示し、28,554件が実際に適用された。提案全体に対する適用率は約9.7%であり、派手な数字ではない。それでも人間がゼロから直すコストを数千件規模で肩代わりしたという意味で、控えめだが確かな効果である。
この成果を支えているのは、華麗なモデルではなく「提案しない」設計だ。実行前と実行後の2段の除外フィルタ、ツール呼び出し最大100回・実行時間最大30分という上限、テスト再実行による決定論的な最終検証がその中身になる。精度を上げる努力と同じ重みで、ノイズを出さない努力に投資している点が設計上の核心だ。
flowchart LR
A["精度<br/>手動評価 67.18%"] --- D["開発者の信頼"]
B["遅延<br/>p50 9.85分(窓 27.48分の内側)"] --- D
C["見送り<br/>2段フィルタ+最終検証"] --- D
残る課題も定量的に見えている。処理中に開発者が自分で直してしまう「遅すぎた提案」が126,310件あり、テストを削除したり変更を巻き戻したりする有害な提案が信頼を損ねている。論文はこの両方の改善を明言しており、AIが作成した変更にも対象を広げる構想も示されている。ただしデータはGoogle内部の非公開環境に依存し、社内版 Gemini 2.5 Pro に固有の結果である点は、他組織へ流用を検討する際の前提として押さえておきたい。
AIエージェントを開発ワークフローに組み込むとき、精度だけでなく「間に合うか」と「黙るべきか」を設計変数として扱う。これが本論文から持ち帰れる最大の教訓である。
参考資料
- 論文: Catching Developers in the Flow: Low-Latency Agentic Program Repair at Google Scale — https://arxiv.org/abs/2610.07289 (HTML: https://arxiv.org/html/2610.07289v1)
- Evaluating Agent-based Program Repair at Google(Passerine)— https://arxiv.org/abs/2501.07531
- Abstain and Validate: A Dual-LLM Policy for Reducing Noise in Agentic Program Repair — https://arxiv.org/abs/2510.03217
- Agentic Bug Reproduction for Effective Automated Program Repair at Google — https://arxiv.org/abs/2502.01821
- Repairing Programs with AI Agents(Pekka Enberg,
rpCLI)— https://penberg.org/blog/rp.html