※本記事は、AI Engineer Summit 2025のAgent Engineering Session Dayでニューヨークにてライブ録画されたJohn Crepezzi氏による講演「AI Engineering at Jane Street」の内容を基に作成されています。動画の詳細情報はhttps://www.youtube.com/watch?v=0ML7ZLMdcl4 でご覧いただけます。本記事では、講演の内容を要約しております。なお、本記事の内容は原著作者の見解を正確に反映するよう努めていますが、要約や解釈による誤りがある可能性もありますので、正確な情報や文脈については、オリジナルの動画をご視聴いただくことをお勧めいたします。
登壇者について: John Crepezziは、Jane Streetのエンジニアで、LLMを活用したコーディングアシスタントの構築と、大規模言語モデルを活用したアプリケーション作成を可能にするインフラストラクチャの開発に従事しています。彼の業務は、特にJane StreetのOCaml中心の環境における開発者の生産性向上に焦点を当てています。Jane Street入社以前は、GitHubでプリンシパル・ソフトウェア・エンジニアとして勤務し、Codespaces、Merge Queues、Contribution Graphsなど、開発者生産性領域での影響力のあるプロジェクトに貢献しました。開発者の働き方を改善することにキャリアを捧げるJohnは、エンジニアがより効果的に複雑な問題を解決できるツールを作ることに情熱を注いでいます。
AI Engineer Summitの詳細については https://ai.engineer をご覧いただき、次回イベントである6月3-5日サンフランシスコ開催のAI Engineer World's Fairのチケットは https://ti.to/software-3/ai-engineer-... でご購入いただけます。
1. Jane StreetにおけるAI活用の背景と独自の課題
John Crepezzi: 私の名前はJohn Crepeziで、Jane StreetのAI assistantと呼ばれるチームで働いている。私たちのグループは、Jane Streetが大規模言語モデルから得られる価値を最大化することを目的として存在している。私は開発ツール分野でキャリア全体を過ごしており、Jane Streetで働く前は長い間GitHubにいて、その前も様々な開発ツール企業で働いていた。
大規模言語モデルは、非常にオープンエンドな性質を持っているため、想像できるものは何でも構築できるという本当に素晴らしい機会を提供している。現在、モデルの進歩よりも速く動いているように見えるのは、それらをどのように活用するかという私たちの創造性だけである。
しかし、Jane Streetでは、既製のツールの採用を他の企業よりも少し困難にするいくつかの選択をしている。私たちがこの問題を抱えている最大の理由は、開発プラットフォームとしてOCamlを使用していることである。OCamlに馴染みのない人のために説明すると、これは関数型の非常に強力な言語だが、同時に信じられないほど曖昧な言語でもある。この言語はフランスで構築され、最も一般的な用途は定理証明や形式検証などの分野である。また、プログラミング言語を書くためにも使用されている。
私たちはJane StreetでOCamlをあらゆることに使用している。いくつかの簡単な例を挙げると、Webアプリケーションを書く際、もちろんWebアプリケーションはJavaScriptで書かなければならないが、代わりに私たちはOCamlを書き、JS of OCamlと呼ばれるライブラリを使用している。これは本質的にOCamlバイトコードからJavaScriptへのトランスパイラである。Vimプラグインを書く際、それらはVimスクリプトで書かなければならないが、実際にはVamlと呼ばれるライブラリを使用している。これも再びOCamlからVimスクリプトへのトランスパイラである。さらに、会社でFPGAコードに取り組んでいる人々も、Verilogを書いているのではなく、Hard Camelと呼ばれるOCamelライブラリで書いている。
なぜ市場で利用可能なツールがOCamlでの作業に適していないのか。これはいくつかの主要な理由に集約されると思う。最初で最も重要な理由は、モデル自体がOCamlがあまり得意ではないということである。これはAIラボの責任ではなく、訓練用に存在するデータの量の副産物である。Jane Street内に持っているOCamlコードの量が、私たちの壁の外の世界に存在するOCamlコードの総計よりも多いという可能性が非常に高い。
二番目の理由は、私たちが自分たち自身にとって物事を非常に困難にしていることである。これは部分的にOCamlで作業することの副産物として、私たち自身のビルドシステムを構築しなければならなかった。私たちは自分たちの分散ビルド環境を構築し、Ironと呼ばれる独自のコードレビューシステムまで構築した。私たちはすべてのソフトウェアを巨大なmonorepoアプリケーションで開発しており、さらに楽しいことに、そのmonorepoをgitに保存する代わりに、Mercurialに保存している。最後の集計では、会社の67%がvs codeのような通常のエディタの代わりにEmacsを使用している。vs codeを使用している人もいるが、Emacsが最も人気である。
最後に、私たちは夢想家である。この部屋の皆さんもある意味で夢想家だと思う。私が意味するのは、私たちは大規模言語モデルを取って、開発フローの異なる部分に適用し、異なる部分を活性化する能力を望んでいるということである。マージコンフリクトを解決したり、より良い機能記述を構築したり、機能のレビュアーが誰であるべきかを把握したりするために大規模言語モデルを使用したいと考えているかもしれない。そして、そうする際に異なるシステム間の境界によって妨げられたくないのである。
2. カスタムモデル訓練への転換とデータ収集戦略
John Crepezzi: 一見すると、モデルを訓練すること自体が良いアイデアであることは明らかではない。それは非常に高価な提案であり、多くの時間がかかり、様々な方法で失敗する可能性がある。この場では、以前にモデルを訓練したことがある人、あるいは基盤モデルを取ってその上で訓練を試みたことがある人はいるだろうか。私たちがより確信を持ったのは、この論文を読んだ後だった。これはCode Composeと呼ばれるプロジェクトについてのMetaの論文で、この論文で彼らはHackでの使用に特化してモデルをファインチューニングした結果を詳述している。
Hackは実際にOCamlと非常に似ている。構文や機能においてではなく、主に一つの会社で使用され、オープンソースであってもその会社の外ではあまり使用されていないという事実においてである。面白い事実として、HackはOCamlで実装されている。これは完全に偶然の一致だと思うが。
私たちは初期の頃非常に素朴だった。この論文を読んで、結果を複製することができれば本当にクールだろうと決めた。私たちは棚からモデルを取ってきて、大量の私たちのコードを見せれば、元のモデルのように動作するが私たちのライブラリやイディオムについて知っているモデルを得られると考えた。しかし、それはそのような仕組みではないことが判明した。それはそれほど簡単ではない。
良い結果を得るためには、モデルに質問したいタイプの質問の形状をした多くの例をモデルに見せる必要がある。そのため、まずゴール、つまりモデルができるようになってほしいことを作成する必要があった。私たちの世界では、考え出したゴールは次のようなものだった。プロンプトが与えられたときに差分を生成できるようになりたいと考えた。
これが意味するのは、エディタ内のユーザーが何をしたいかの説明を書くことができ、その後モデルが潜在的にマルチファイルの差分を提案できるようになることである。テストファイル、mlファイル、そしてヘッダーファイルのようなmliを変更したいかもしれない。私たちは差分がきれいに適用され、適用された後にタイプチェックを通る良い可能性を持つことを望んでいた。私たちは最大100行の範囲を、LLMが実際に対応可能だと思われる理想的なゾーンとしてターゲットにしていた。
これが機能するためには、私が先ほど話したように、データを収集する必要があった。訓練の形状がテストの形状とまったく同じに見えるデータが必要だった。このタスクでは、この形状がどのようなものかが分かる。モデルが事前に持っていたであろうコンテキストの例を多数収集し、次に人間が書くのと同じ方法で書かれたモデルに何をしてほしいかのプロンプト、そしてそのゴールを達成する差分を収集する必要がある。つまり、コンテキスト、プロンプト、差分である。そして、これらの例を多数必要とする。
では、これらの訓練例をどのように得るのか。最初に見るべき場所は機能である。機能は、私が述べたように、内部で構築したコードレビューシステムである。これがどのようなものかというと、Ironと呼ばれている。機能はプルリクエストと非常に似ており、頭の中でその用語を置き換えて考えることができる。機能は一見すると、私たちが望むデータを正確に持っているように見える。説明タブには変更の人間が書いた説明があり、差分タブには開発者のゴールを達成するコードがある。
しかし、よく見ると、それらは私たちが望むものとは正確には一致していない。機能記述やプルリクエスト記述を書く方法は、エディタ内で言いたいことと本当に非常に異なっている。エディタでは複数の段落を書くのではなく、「今起こっているエラーを修正して」のような単純なことを言うだけである。それは機能記述を書く方法ではない。
これらの機能やプルリクエストのもう一つの問題は、それらが本当に大きいということである。機能は500行や1000行であることが多い。したがって、それを訓練データとして使用するためには、機能を訓練可能な個別の小さなコンポーネントに分解する自動化された方法が必要になる。
機能よりも小さなものが必要である。それらは何か。おそらくコミットである。コミットは機能よりも小さなチャンクである。これがJane Streetでの典型的なコミットログの様子である。これはgit shortlogのようなものではなく、文字通り実際のgitログとして見てほしい。サマリーのZとあるところ、それが私のコミットメッセージである。私たちは世界の他の場所と同じようにコミットを使用していない。私たちはコミットを主に、開発サイクルの異なる部分間のチェックポイントとして使用し、それらに戻りたい場合に使用している。コミットには説明がなく、それらが孤立した変更ではなく、変更のコレクションであるという同じ問題もある。
私たちが最終的に採用したのは、ワークスペーススナップショッティングと呼ばれるアプローチだった。その仕組みは、一日を通じて開発者のワークステーションのスナップショットを取ることである。20秒ごとに開発者が何をしているかのスナップショットを取ると考えてほしい。スナップショットを取る際に、ビルドステータスのスナップショットも取る。ボックス上で実行されているビルドで、エラーが何かを確認したり、ビルドが緑かどうかを確認できる。
これらの小さなパターンに気づくことができる。緑から赤、そして緑に戻るパターンがあれば、それは開発者が孤立した変更を行った場所に対応することが多い。コードを書き始め、ビルドを壊し、その後緑に戻す。それが変更を行う方法である。このパターンの赤から緑の部分は、開発者がエラー(タイプエラーや コンパイルエラーなど)に遭遇し、その後それを修正した場所である。赤の状態でビルドエラーをキャプチャし、赤から緑への差分を取得すれば、モデルがミスから回復できるように支援する訓練データとしてそれを使用できる。
次に必要なのは説明である。その方法として、大規模言語モデルを使用した。大規模言語モデルに変更の非常に詳細な説明を可能な限り多くの言葉で書かせ、その後人間が書くであろう適切なレベルになるまでフィルタリングを続けた。これで訓練データができた。
3. 強化学習による品質向上と評価システム
John Crepezzi: 訓練データはモデルを訓練する際の半分の要素でしかない。教師あり訓練データがあり、次に2番目の部分である強化学習を行う必要がある。これは実際にモデルが多くの力を得る場所である。私たちはモデルの能力を、人間が実際に良いコードだと考えるものに合わせるのである。
では、良いコードとは何か。表面的には、良いコードはコードであるということである。つまり、コードの一片がOCamlパーサーを通過して緑のステータスで出てこない場合、それはほとんどの定義において良いコードではないと言えるだろう。OCamlにおける良いコードは、静的型付けされているため、タイプチェックを通るコードである。私たちは良いコードを、ベースリビジョンの上に適用されたときにタイプチェッカーを通過し、タイプチェッカーがそのコードが有効であると同意するコードにしたい。
そしてもちろん、ゴールドスタンダードは、良いコードがコンパイルしてテストに合格するコードであることである。理想的には、モデルの強化学習フェーズ中に、検証可能なタスクの束をモデルに与えることができるだろう。モデルに何らかの編集を実行させ、その後コードに適用されたときに実際にテストに合格するかどうかをチェックする。
私たちはそれを行った。私たちの訓練サイクルの一部としてこれを行い、CESと呼ばれるものを構築した。これはCode Evaluation Serviceである。これを、ずっと高速にするためのわずかな変更を加えたビルドサービスのようなものだと考えることができる。その変更とは、まず私たちがビルドを事前ウォームすることである。それはリビジョンに座って緑の状態にある。その後、一日中、モデルから差分を取り、それらを適用し、ビルドステータスが赤か緑かを判定するワーカーがいる。その後、そのエラーまたは成功をビルド機能に報告する。
数ヶ月にわたってこのサービスを継続的に使用することで、私たちは実際にコンパイルしてテストに合格するコードを書くようにモデルをより良く調整することができる。この全く同じセットアップが評価に使いたいものであることが判明した。強化学習データの一部を保留しておけば、コードを書くモデルの能力を評価するためにもそれを使用できる。
これは次のような感じである。モデルに問題を与え、コードを書かせ、その後そのモデルが書いたコードが実際に動作するかどうかを評価する。訓練は困難で、破滅的だが陽気な結果をもたらすことがある。ある時点で、私たちはコードレビューモデルを訓練していた。これは完全に別のモデルだが、アイデアとしては、このモデルに何らかのコードを与えて、人間が行うような最初のパッシブなコードレビューを行わせ、コードレビューの苦労の一部を省こうということだった。
このモデルを訓練し、大量のデータを投入し、数ヶ月間作業し、本当に興奮していた。自動化エージェントを通じて最初のコードをコードレビューに投入した。それは少し回転し、「明日やります」のような内容で戻ってきた。もちろん、それは人間の例の束で訓練されており、人間は「明日やります」や「これは明日やります」のようなことを書くからである。これは全く驚くべきことではない。
このような評価を持つことで、モデルがこのようにレールから外れないようにし、時間とお金を無駄にしないことを確保する礎石となる。しかし最終的に、モデルの本当のテストは、それらが人間にとって機能するかどうかである。
4. エディタ統合アーキテクチャの設計と実装
John Crepezzi: 私はJane Streetの開発者にこれらのモデルを公開するために構築したエディタ統合について少し話そうと思う。これらの統合を構築し始めた時、私たちの心には3つのアイデアがあった。
最初のアイデアは、私たちが3つのエディタをサポートしているということだった。Neovim、VS Code、そしてEmacsを持っており、同じことを3回書きたくないということだった。理想的には、すべての同じコンテキスト構築戦略と同じプロンプティング戦略をすべて一度だけ書きたかった。2番目は、柔軟性を維持したかったということである。当時使用していたモデルがあり、それはファインチューンされていないモデルだった。ファインチューンされたモデルが私たちの将来にあることを確信していたので、モデルを交換したり、プロンプティング戦略を交換したりする能力を求めていた。最後に、メトリクスを収集できるようにしたかった。開発者のエディタにおいて、開発者はレイテンシーと差分が実際に適用されるかどうかを気にするので、差分が実際に人々にとって意味があるかどうかの現場での実際の経験を得たかった。
これが、このサービスのために私たちが決定したアーキテクチャの簡略版である。AI開発環境では、本質的に片側にLLMがあり、AiDがプロンプトの構築とコンテキストの構築、ビルドステータスの確認の能力をすべて処理し、その後個別のエディタのためにAiDの上に本当に薄いレイヤーを書くことができる。
これについて本当に素晴らしいことは、AiDが開発者のマシン上でサイドカーアプリケーションとして座っていることである。つまり、AiDに変更を加えたい時、個別のエディタに変更を加えて人々にエディタを再起動してもらうことを期待する必要がない。すべてのボックス上でAiDサービスを再起動するだけで済み、その後すべての人が最新のコピーを手に入れる。
これがVS Code内で動作するAiDの例である。これはVS Codeのサイドバーで、Co-pilotのようなものに非常に似ているが、このものはマルチファイル差分を要求して取り戻すことができる。VS Codeでは期待するような見た目になっており、物事を本当にうまくレイアウトする視覚的なインターフェースである。
しかし、これが私たちがEmacsで構築したものである。Emacsでは、開発者はテキストバッファで作業することに慣れており、ファイル間を移動し、通常の方法で物事をコピーしたいと思っている。そこで、実際にEmacsでのAiD体験をマークダウンバッファに構築した。ユーザーはこのマークダウンバッファ内を移動し、質問をすることができ、マークダウンバッファの下部に追加のコンテンツを本質的に付加するキーバインドがある。
AiDのアーキテクチャにより、私が述べたように、様々な部分を差し込んだり外したりできる。新しいモデルを交換したり、コンテキスト構築に変更を加えたり、新しいエディタのサポートを追加したりできる。これは遠く離れたことのように聞こえるかもしれないが、これは実際に今まさに行っていることである。さらに、ドメイン固有のツールを追加することもできるので、会社の異なる領域がエディタ内で利用可能なツールを提供でき、個別の統合を書く必要なく、すべてのエディタに現れることになる。
AiDはまた、異なるアプローチのA/Bテストを可能にする。会社の50%を一つのモデルに、50%を別のモデルに送り、どちらがより高い受け入れ率を得るかを判定するようなことができる。AiDは時間をかけて投資回収する種類の投資である。大規模言語モデルで何かが変わるたびに、エディタの下流の一箇所でそれを変更し、その後どこでも利用可能にできる。そして物事は本当に頻繁に変わり、物事が変わる時に準備ができている必要がある。
5. 将来展望と継続的な改善アプローチ
John Crepezzi: 今日お見せする時間があったのは、私のチームが行っていることのほんの一部分に過ぎない。私たちには他にも多くのことが進行中である。私たちはエディタ内でRAGを適用する新しい方法を見つけており、ここで見てもらったものと類似のアプローチを大規模なマルチエージェントワークフローに適用している。私たちは推論モデルとますます多く作業しているが、すべてを通じてアプローチは同じである。
私たちは物事をプラガブルに保ち、その上に構築する強固な基盤を敷き、会社の他の部分が私たちの経験に追加できる方法を構築している。それは、その上にさらにドメイン固有のツールを追加することによって行われる。
もし私が話したことが興味深いと思い、これについてもっと話したいと思うなら、ぜひお聞きしたい。外で私を見つけてもらえれば、お時間をいただき、ありがとうございました。