Anthropicのマージは5月の1日2,500件ほどから9月には3万件を超えるまでに増え、最大のボトルネックはバージョン管理、つまりgitになりました。7人のチームが5か月で、モノレポをgitから自社製のバージョン管理システムScionに移しています。10月13日にAnthropicのエンジニアリングブログで公開された「Redesigning source control at Anthropic」は、「Anthropicでは、コードを書くことはもはやシステム開発や研究のボトルネックではない」という一文で始まります。何を変えたのかをたどり、Hacker Newsのコメントがどこに引っかかったのか、私たちのような小さなチームが何を取り入れられるのかもまとめました。

コードを書くことがボトルネックでなくなったとき
元記事によると、Claudeは研究のループを自分で回し、複雑なプログラムを細かく最適化し、新しいサービスをゼロから作ります。するとボトルネックは、人の速さに合わせて作られた開発インフラに移りました。バージョン管理、ビルド、CIです。Anthropicはコードをマージしたいという需要を「事実上、際限がない」と見ています。ボトルネックを1つ取り除くたびに、コードがすぐさま増えるというのです。
モノレポの大きさを見ると、gitが苦しんだ理由がわかります。mainブランチの履歴だけで100GB近くあり、作業ツリーは圧縮しても25GBを超えます。CIがコードをチェックアウトする回数だけで1日2,500万回ほどです。開発環境やエージェントのサンドボックス、研究ジョブは数に入っていません。これをそのままgitで取得すると、1日600PBを超える通信量になるそうです。

もちろんgitにも、リポジトリの一部だけを扱う道具があります。浅いクローン(shallow clone)、必要なディレクトリだけを展開するsparse checkout、足りないオブジェクトをその都度取ってくるpromisor remoteです。大きなモノレポでよく使われる回避策もあります。社内にgitミラーを置いたり、リポジトリのスナップショット(seed)をBlobストレージに置いたりする方法です。Anthropicはそのすべてを使い、多いときには社内のgitミラーを数百台動かしていました。それでもマージが速くなるほど、スナップショットは作り直すまでのあいだに、mainの最新コミットからどんどん遅れていきました。部分クローンでdiffやblameのように履歴が必要な操作をきちんと動かすにも、だんだん手間がかかるようになりました。
常にオンラインのクライアントのためのバージョン管理
gitは分散システムです。クローンの1つ1つが完全なリポジトリなので、オフラインでもdiffを取り、履歴やblameを読み、どのリビジョンでもチェックアウトできます。ほとんどのリポジトリにとって正しい設計で、gitが標準になった大きな理由でもあります。ところが振り返ってみると、Anthropicも多くの会社と同じように、正本を1つ置いた中央集権型としてgitを使っていました。クライアントのほとんどは、そもそも常にオンラインであるエージェントやジョブでした。gitをオフラインの分散作業に強くしている性質が、リポジトリが大きくなるほど足かせになっていました。
エージェントが常にオンラインだという事実を最初から念頭に置いてバージョン管理を設計したら、どんな姿になるだろうか。
Anthropic「Redesigning source control at Anthropic」
巨大なモノレポのためのバージョン管理には先例があります。GoogleのPiperと、MetaのSaplingです。Anthropicは特に、Saplingのサーバー部分であるMononokeと、そのデータモデル(Bonsai)から多くの手法を取り入れたと明かしています。その上に立てた原則は6つです。
クライアントは常にオンライン。リポジトリ全体を持ち歩かず、必要なときにサーバーから取ってきます。
サーバーとクライアントは非対称。ファイルの履歴やblameに答え、コミット・マージ・リベースを作るのはサーバーです。クライアントは大きさの決まったローカルキャッシュと作業ツリー、ファイル変更の監視だけを受け持ちます。
バージョン管理がそのままAPI。クライアントが使う問い合わせを、すべてAPIとしても公開しました。CIのジョブはローカルリポジトリなしで「この行を最後に変えたのは誰か」を問い合わせます。自動bisectや自動revertのパイプラインもこれで動いています。
すべてが水平に拡張できる。リポジトリのデータは分散していて、サーバーにすら完全なコピーはありません。packfile(gitがオブジェクトを圧縮してまとめたファイル)がないので、リポジトリの保守も要りません。
コミットは安く、ロックがない。コミットのコストはリポジトリの大きさに関係なく、変更の量だけに比例しなければなりません。全サーバーが合意すべきグローバルな状態を減らすため、ref(ブランチ・タグ)もmainとリリースブランチ以外はなるべく使いません。
作業ツリーはなくてもよく、あっても一部だけ。diffが1つ欲しいだけのCIジョブは、チェックアウトせずにサーバーに尋ねます。ファイルが必要な場合も、頼んだディレクトリだけを取得するか、読んだ瞬間にファイルを埋める方式なので、実際に読んだ分しか取ってきません。
コミットの代わりにチェンジセット
Scionの作業単位は「チェンジセット」です。データベースのログ先行書き込み(WAL)のように、順に積み重なっていく記録の1項目です。gitのコミットがツリー全体を指すのに対し、チェンジセットは最初の親と比べて変わったファイルの一覧と、その内容を指すコンテンツアドレスだけを持ちます。処理するpackfileも、かけるロックも、動かすrefもないので、チェンジセットをとても速く取り込めます。refを動かすのは、Spannerの1行に対するcompare-and-swapとして別に行います。変わったものしか記録しないので、「この行を最後に直したのは誰か」といった問いにはそのままでは答えられません。そこでblame・パスの履歴・コミットグラフ用のスキップリストといった「派生データ」をチェンジセットから作ります。派生データはすべて再帰的に定義されていて、あるチェンジセットの値を親の値から計算します。おかげで3つのことが楽になったといいます。派生データの種類を新しく足すこと、種類ごとに先に計算するか後回しにするかを選ぶこと、クライアントに触れずに最適化することです。

gitのコミットはルートツリーを指し、ツリーはすべてのファイルにつながります。
だからコミットが1つあれば、その時点のリポジトリ全体を作り直せます。

Scionのチェンジセットは、最初の親と比べて変わったファイルだけを記録します。
中身はBlobストレージにあり、チェンジセットはそのアドレスだけを持ちます。refの移動は別に行います。

「この行を誰が直したか」に答えるデータは別に作ります。
派生データはどれも、親の値に今回の変更を足して再帰的に計算します。
持っているものを伝えず、欲しいものを尋ねる
チェックアウトの仕組みもgitとは違います。gitの交渉では、クライアントがすでに持っているものをサーバーに伝え、サーバーが足りない分を計算して1つのpackfileにまとめて送ります。Scionのクライアントscnは、欲しいものだけを尋ねます。ルートツリーから始めて、ローカルにないツリーを順に要求し、同じやり方でBlobを受け取ります。どの要求も決して変わらないオブジェクト1つを指すので、どのキャッシュでも答えられます。ノードごとにscion-daemonがオブジェクトをためておきます。地域ごとにあるscion-cacheは、オブジェクトをメモリから直接返します。それでもなければscion-serverがSpannerやクラウドストレージから読みます。3つの階層は同じRPCに答えますが、地域キャッシュの障害がサーバーにまで広がらないよう、階層を飛ばせないようにしています。


元記事が示した結果はこうです。どの階層もキャッシュヒット率が99%を超え、長く保持すべき状態がないので、増やすのも簡単です。CPUとメモリで比べると、インフラの規模は以前のgitミラーの200分の1になりました。CIと研究ジョブのチェックアウトは2桁速くなり、分単位から秒単位になりました。CIだけでCPUの容量を25%取り戻したそうです。

7人で、5か月
Scionと、コードレビューツールのAntiqueを作ったチームは7人でした。関連するシステムを6つほど追加で作り、移行を終えるまでにかかったのは5か月です。そのあいだに1日のマージ量は10倍になりました。元記事が挙げる場面が1つあります。gitからScionへデータを取り込むパイプラインの最初の版は、ほぼ人の手で書かれ、チームはよくできたと考えていました。Claude Mythos Previewの社内向け初期版に丸ごと書き直させたところ、ほかに指示をしなくても、メモリ使用量は20分の1、速度は4倍の版が出てきました。取り込みの順序やデータ構造にかかわる暗黙の条件も、そのまま守っていたといいます。
だからといって、エンジニアの仕事がなくなったわけではありません。元記事によると、このシステムを作ったエンジニア全員が、今ではコードを書くことについてはClaudeのほうが自分より上だと評価しています。代わりに人が担ったのは、システム同士がどう噛み合うかという全体像と、設計上のトレードオフの判断でした。エージェントは、そもそも許されるべきではなかったパターンに合わせようとして、中核の制約を破ることがありました。マージの時刻をコードレビューツールに尋ねず、コミットログを最初から読んで探そうとするシステムがいくつもありました。敵対的レビューが別の社内サービスを疑いすぎたせいで、Claudeが不要な検証を足してコードを複雑にしたこともあります。チームは今もすべての変更をレビューしていますが、1行ずつ読むより、変更の意図を見ています。
多くの場合、エンジニアの役割はClaudeに『ノー』と言うことだった。
Anthropic「Redesigning source control at Anthropic」
人の速さに合わせたほかの慣習も見直すことになったそうです。テストが走っているあいだに数百、数千の変更がマージされる場所で、CIとはそもそも何を意味するのかという問いです。マージキューにリポジトリ全体のロックをかける業界標準は、この規模では再現できませんでした。代わりにマージ後・デプロイ前の自動テストに投資しています。同時に入った変更どうしが衝突することはありますが、人が気づく前にたいていClaudeが直すといいます。構成要素ごとに、それだけを見守るClaudeをSlackのチャンネルに置き、「スーパーファン」と呼んでいるという話も出てきます。
1,012件のコメントが引っかかったところ
Hacker Newsでこの記事は894ポイントを集め、コメントは1,012件つきました。返信がいちばん多かったスレッド(199件)は、Scionではなくレビューの話でした。最初のコメントは「Claudeのコードのレビューを省くたびに、あとで雑なコードが見つかる」と書き、この速さでそれをどう避けているのかと尋ねていました。別のコメントは、1日3万件を意図だけでレビューするなら、モデルが近道をしたことにコードを読まずにどう気づくのかと問い返していました。
まずモノレポを疑うべきだったのではないか、というコメントもありました。「モノレポにすればマージが楽になる」から「マージが難しすぎるのでバージョン管理を設計し直そう」へ移るあいだに、「本当にモノレポである必要があるのか」という途中の問いを飛ばしている、という指摘です。先例を挙げる人も多くいました。SVNやPerforceのようなサーバー中心のバージョン管理を今風に作り直したものだ、という評がありました。OracleとGoogleを渡り歩いたある開発者は、Oracleで社内バージョン管理のプロジェクトを率いていた人物が、自分の名前を付けて呼んでいた「法則」を思い出していました。大きな会社はいつか必ず自前のバージョン管理システムを作る、というものです。East River Source ControlのSteve Klabnikは、自社の考えが正しかった裏付けだと歓迎しました。大きなチームとエージェントが一緒に働くモノレポは、いずれgitの限界に行き当たるというのです。GoogleとMetaは10年以上前にその壁にぶつかり、今はほかの多くの会社も同じところまで来ているとも書いています。
Anthropic自身も線を引いています。元記事は「Scionは決して汎用的なgitの代わりではない」と書きました。この考え方が意味を持つのは、エンジニアが何万人もいるか、エージェントの群れが大量のコードを書く巨大なモノレポだけだそうです。Anthropicが社内で使うトークンの量も、ほかの会社が現実的に使おうとする水準をはるかに超えているといいます。あるコメントは、みんなが同じことをしなければと焦ったあげく、自分はAnthropicでもGoogleでもないと気づく「見苦しい時期」が来るだろうと予想していました。
小さなチームが取り入れられること
Scionが必要なチームは、ほとんどありません。Anthropicも、これから6〜12か月のうちにこの種の問題がありふれたものになると見ています。それでも勧めるのは、gitの大枠を保ったまま、Scionでうまくいった部分だけをgitに取り入れる道です。gitにはすでにその部品があります。必要なオブジェクトだけを後から取ってくる部分クローン、欲しいディレクトリだけを展開するsparse checkout、バックグラウンドでリポジトリを保守するgit maintenanceです。Git 2.38からはMicrosoftが作ったscalarが標準で入っていて、これらの設定を一度に有効にしてくれます。このブログでAIの数学原稿の記事を書いたときも、原稿のリポジトリをBlobなしで取得して、必要なファイルだけを開きました。代償もあります。GitHubのDerrick Stoleeは、Blobなしで取得したクローンでgit diffやgit blameを初めて実行すると、そのときにファイルの中身をダウンロードすると説明しています。gitのドキュメントはさらに、部分クローンを使うにはユーザーがオンラインである必要があると書いています。「クライアントは常にオンライン」というScionの第一原則は、gitの中にもすでに少し入り込んでいるわけです。
# Blob(ファイルの中身)なしで取得し、作業ツリーには最上位のファイルだけを展開する
git clone --filter=blob:none --sparse https://example.com/big/monorepo.git
cd monorepo
git sparse-checkout set apps/web lib # 必要なディレクトリだけを展開
git maintenance start # バックグラウンドの保守
git config core.fsmonitor true # macOS・Windowsのファイル監視
# 上の設定を一度に(作業ツリーはmonorepo/src)
scalar clone https://example.com/big/monorepo.gitAnthropicがgitのエコシステムに向けた提案も、同じ方向を指しています。gitのサーバーがgitのクライアントとまったく同じように動く必要はない、ということです。GitHubやGitLabのようなホスティングサービスがScionのような豊富なサーバー側RPCを公開し、その形をそろえれば、gitのクライアントもそのRPCを使えるようになります。交渉プロトコルも今の形のままである必要はなく、sparseとshallowの機能がうまく組み合わさるように整えられるとしています。
コードを書くコストが下がると、そのコードを受け止めるインフラとレビュー、そして「ノー」と言う判断が高くつくようになりました。1日3万件は他人事でも、同じ流れは小さなチームにも押し寄せます。エージェントがプルリクエストを増やすほど、CIは頻繁に回り、レビューは積み上がります。何をサーバーに尋ね、何を人が見るのかを先に決めておくほうが、gitを離れるよりずっと安くつきます。