← レポート一覧
TEST IMPACT ANALYSIS AT ANTHROPIC / ELI5

CI ジョブが半年で25倍になり、
テスト選択サービスを作り直した話

エージェントがコードを書き、レビューもするようになった Anthropic で、PR ごとに走らせるテストを選ぶサービスがどう行き詰まり、どう作り直されたか。

1 / どんな話か

詰まる場所が CI に移った

開発の流れは「計画 → 書く → レビュー → CI → リリース」です。人が書いていたころは、書くところが一番細い部分でした。

Claude がコードを書くようになると細い部分はレビューに移り、レビューも速くなると、次は CI が細い部分になりました。

エージェント以前 人がコードを書く 詰まる: 書く エージェントが書く Claude がコードの 80% を書く 詰まる: レビュー レビューもエージェント 6 か月で CI ジョブが 25 倍 詰まる: CI 計画書くレビュー CIリリース
記事の図「The bottleneck moves downstream」を日本語で描き直したもの

この記事は、その CI の中で「PR ごとにどのテストを走らせるか」を決めるサービスが負荷に耐えられなくなり、3回つぎはぎしたあとで作り直した記録です。

著者が伝えたいのは個々の対処法ではなく、負荷は指数的に増えると見込んで設計することです。
2 / 背景

CI ジョブが半年で25倍になった理由

記事に出てくる数字は次のとおりです。エンジニアの数はわずかにしか増えていません。

8
エンジニア1人が四半期に出すコードの量(2021〜2025年との比較)
80%
そのコードのうち Claude が書いた割合。PR のレビューと承認にも大きく関わる
10
コードベース全体のテストの数
25
6か月間での CI ジョブの数
コードが増える テストが増える PR が小さく、数が多くなる 夜間や週末にも push される CI ジョブ 6か月で 25 倍

Claude は小さく細かい PR を好むので、1日あたりの CI ジョブが増えました。エージェントが夜間や週末にも push するため、活動量の下限も上がっています。

25倍という数字は「全部の PR で全部のテストを走らせた」結果ではありません。走らせるテストを選んだうえで、なお25倍です。
3 / しくみ

テスト選択サービスのしくみ

変更のたびに全部のテストを走らせる組織もまだ多いです。ある規模までは動きますが、CI の待ち時間が長くなり、費用がかかり、結果も信用しにくくなります。

全部走らせる

自分と関係ない失敗が混ざる

人は「この失敗は自分の変更と関係ない」と見分けられます。エージェントはそのための文脈と指示をもっと多く必要とします。

選んで走らせる

意味のあるテストだけが並ぶ

有効なテストの集合を渡されると、エージェントは自分で結果を確かめて直すことを繰り返しやすくなります。

Anthropic のサービスは、過去の結果とパッケージの関連から、変更ごとに走らせるテストを決まった手順で選びます。部品は2つです。

CI の結果 毎秒たくさん listener(記録係) すべての実行の結果を記録する テストごとの履歴 selector (選択係) 履歴を読んで選ぶ PR 選ばれた テストを実行 テストが走ると、また結果が出る
選択係が正しく選べるかどうかは、記録係が最新の結果に追いついているかで決まります。
4 / 弱点

記録係が遅れると何が起きるか

毎秒いくつもの CI ジョブが終わるようになると、listener が処理しきれずに遅れていきます。記事では、20分の遅れで数万件のテスト結果の更新が selector に届かないと書かれています。

処理待ちの結果 listener 1プロセスだけ selector 古い履歴で選ぶ 20分の遅れ = 数万件の更新が selector に届いていない
悪い変更がマージされた

全員のテストが落ちる

他の人の PR でもテストが失敗し、必要のない調査がいくつも起きます。

依存先が不安定になった

不安定な失敗がマージを止める

たまに落ちるだけのテストの赤が、マージを止めてしまいます。

テストが直った・増えた

追いつくまで走らない

listener が追いつくまでそのテストが選ばれず、リグレッションを見逃す危険があります。

しかも最初の設計(v0)は1つのプロセスで動いていました。テストごとの履歴を持ち続けるには、結果を書き込む係が1つである必要があったからです。そのため、処理する係を横に増やすことができませんでした

5 / つぎはぎ

3回のつぎはぎと、それぞれがもった期間

CI ジョブの量と、つぎはぎを入れた時期を重ねると次のようになります。つぎはぎのたびに、稼げた期間は短くなりました。

0倍10倍20倍30倍 約10週 29日 1 2 3 4 5 2025/611月2026/1 3月5月7月
記事のグラフ「CI job volume, and the runway each patch bought」を元にした概略図。線の値はおおよそです
1 つぎはぎ1
マシンを大きくした(2025年10月末)
2 限界
大きいマシンでも吸収できない最初のバックログ(2026年1月初め)
3 つぎはぎ2
プロセスの中でシャードに分けた(2月)
4 つぎはぎ3
メモリ上限に当たるので毎日再起動しはじめた(3月)
5 作り直し
新しい構成が動きはじめた(5月)
1
コア数を2倍にする約70日
2025年10月、2日続けて呼び出しがかかりました。すぐできる対処で、長くはもたないこともわかっていました。傾向ははっきりしていましたが、このサービスの持ち主が決まっておらず、誰もインフラをもう1つ抱えたがりませんでした。
2
パッケージごとにシャードに分ける29日
必要なのは「全体で書き込む係が1つ」ではなく「パッケージごとに書き込む係が1つ」でした。そこで Claude が、パッケージごとの状態を専用ワーカー付きのシャードに分けるコードを書きました。それでも1つのプロセスの中の話で、29日しかもちませんでした。
3
毎日再起動する1日未満
3月には、平日の多くで午後の途中にメモリ上限に達しました。見つかったバグは4つだけで、メモリアロケータを替えても効果はなく、負荷の高い1台だけのプロセスでメモリの詳しい調査をするのは避けました。再起動を繰り返すうちに遅れはだんだん広がり、1時間以上遅れたときには多くの結果が記録されませんでした。

つぎはぎ2のころから、著者は社内版の Claude Tag でこのサービスを見張る長期の会話を続けていました。listener の遅れが 50,000 ジョブを超えると Claude が知らせてきて、前回の続きから相談できます。Claude はたびたび作り直しを勧めましたが、たいていは次のつぎはぎで落ち着きました。

記事内の会話(3月24日)では、pod が 395 GiB・79 コアを使っていて、Claude が「再起動すれば 14〜20 時間もつ」と答えています
起きていたこと

selector が古いデータで選んでいた

主に、すでにひどく不安定なテストや、全体で落ちているテストを走らせる形で表れました。

起きていなかったこと

CI が走らなかったわけではない

その PR で CI が走らなかったり、テストされていないコードが本番に出たりしたわけではない、と記事は書いています。

6 / 作り直し

状態をプロセスの外に出す作り直し

最後は Claude の助言どおり、テスト選択サービスにインメモリのデータストアを持たせました。1台のプロセスがメモリの中でやっていた処理の大部分を、外に出した形です。

CI ジョブ終了 キューのイベント listener は1プロセスだけ 全テストの履歴をメモリの中に持つ 増やし方: 大きいマシン → シャード → 再起動 selector PR ごとに選ぶ CI ジョブ 終了 listenerlistenerlistener 足せば 増やせる ジャーナル インメモリのデータストア consumer が数秒ごとに テストごとの履歴へ まとめる selector すぐ引ける
記事の図「CI test selection service」を日本語で描き直したもの
listener ワーカー
どのワーカーでもどの結果でも処理でき、ジャーナルに追記したら次へ進みます。メモリに何も持たない(ステートレス)ので、数を増やせます。
ジャーナル
届いた結果を追記していく場所。インメモリのデータストアに置きます。
consumer
別の小さなプロセス。数秒ごとにジャーナルをテストごとの履歴にまとめます。
selector
まとめられた履歴をすぐに引いて、PR ごとのテストを選びます。
分散した構成は動かす費用が上がります。それでも、不安定な1台のプロセスよりも増やすのもメモリを調べるのもずっと簡単になりました。
7 / 結果

作り直したあとの結果

listener のキューにたまった未処理の結果の数です。作り直す前は多くの日に山ができ、週を追うごとに大きくなっていました。5月9日に作り直しを出し、14日までにワーカー数などを調整したあとは、ほぼ平らになりました。

0100万200万 5/9 作り直しを出す 5/14 までにワーカー数などを調整 4/64/205/4 5/186/1
記事のグラフ「Listener backlog, before and after the redesign」を元にした概略図。山の高さはおおよそです
1
作り直しを担当したエンジニアの数
3週間
かかった期間。1年前なら1四半期近くかかっていた、と著者は書いています

ジャーナルのサイズやワーカー数の調整は、Claude がほぼ自律的に進めました。それ以降、サービスは安定しています。

8 / 学び

著者がやり直すならこうする

大きいマシン、並列化、再起動といった手法そのものは、よくあるものです。著者が強調しているのは、それぞれで稼げる時間が1年前より短くなったことと、作り直しにかかる時間も短くなったことです。

CI ジョブは、1人あたりのエージェントの数が増え、PR の承認が速くなるほど指数的に増えます。エージェントが夜も週末も動くので下限が上がり、人が承認する分の波も残ります。

週末も下がらない 人だけのとき 平日の山(人が承認する分)は残る
記事の説明から描いたイメージ図です。実際のデータではありません
1
2四半期で25倍の負荷になると想定する
自分たちで作る場合も、ベンダーから買う場合も同じです。
2
最初の設計で、想定の10〜20倍を見込む
予算が許すならという条件つきです。「作り込みすぎ」とされる基準は、ずっと高くなっているというのが著者の見方です。
3
サービスに計測を入れ、Claude の目と耳にする
計測があれば、Claude が少しずつ問題を直していけます。特に、入ってきた CI ジョブの数と出ていった数が同じであることを確かめられるようにします。
4
状態は最初からプロセスの外に置く
重要なサービスは、計測でき、カナリアでの変更も測れるのでない限り、1台だけで動かさないようにします。
9 / まとめ

まとめ

1
コードを書く速さが上がると、次に詰まるのは CI
Anthropic では6か月で CI ジョブが25倍になり、テスト選択サービスの記録係(listener)が追いつけなくなりました。
2
1台のプロセスのままのつぎはぎは、もつ期間がどんどん短くなった
マシンを大きくして約70日、シャードに分けて29日、毎日の再起動は1日未満でした。
3
状態を外に出してワーカーを増やせる形にしたら、安定した
エンジニア1人で3週間。負荷は指数的に増えると見込み、最初から状態をプロセスの外に置くことを著者は勧めています。
出典と用語メモ
用語メモ / CI=変更のたびに自動でビルドやテストを走らせるしくみ。テスト選択(test impact analysis)=変更に関係のあるテストだけを選んで走らせること。flaky=コードを変えていないのに、通ったり落ちたりする不安定なテスト。シャード=データや処理を分割した1つ分。ステートレス=処理する側が状態を持たないこと。どのワーカーに仕事を渡してもよくなる。ジャーナル=届いた記録を順に追記していくログ。カナリア=変更を一部にだけ先に出して様子を見るやり方。Claude Tag=Slack で Claude を使う Anthropic の製品(記事内に説明はないため補足)。
← レポート一覧