本番グレードの開発に向けたループ設計

2025 年後半、私たちはある 1 つの問いに答えるための実験を行いました。「コーディングエージェントは、本番グレードの問題をゼロから自律的に解決できるのか?」

このために、(当時)一般に利用可能だった最高のコーディングモデルを搭載した 2 つのエージェントに、実際の課題と実際の締め切りを与えました。この実験から生まれたのが toktoktok というトークナイザートレーナーで、現在 GitHub でオープンソースとして公開しています。

本記事では、エージェントが本番グレードの問題を自律的に解決できるようにする効果的なループの設計について、私たちが学んだことを共有します。具体的には、複数分野の専門家に向けたゴールの指定方法と、検証インフラの構築方法です。

自律性の検証に実在のターゲットが必要な理由

エッジ LLM における語彙サイズの影響に関する研究の一環として、私たちは 1 台のマシンで数兆トークンを処理できるバイトペアエンコーディング(BPE)トークナイザーのトレーナーを必要としていました。しかし、トークナイザー学習のツールは選択肢が限られています。sentencepiece は BPE 以外のトークナイザー向けに最適化されていて低速で、Hugging Face の tokenizers は私たちのコーパスではメモリ不足に陥り、tiktoken にはそもそも学習機能がありません。

そのため、私たちは本番グレードの BPE トークナイザートレーナーを構築する必要がありました。既存ライブラリを使った経験から、本当のボトルネックはメモリ容量であることもわかっていました。また、既存ライブラリには私たちが必要とする 2 つの機能、つまり既存トークナイザーからのウォームスタート(語彙の拡張)と言語ごとの語彙予算が欠けていました。こうして、実際の締め切りがある具体的なタスクが生まれました。これは、コーディングエージェントがタスクを自律的に解決できるほど信頼できるかどうかを確かめるうえで、効果的な題材でもありました。次の条件を満たしていたからです。

本番グレードであること。エージェントに問題を自律的に解決させる一般的な使い方では、この問いには答えられません。第一に、エージェントはプロトタイピングに使われることが多く、本番の基準を求められることはありません。第二に、「SQLite を Rust に移植する」や「Zig で C コンパイラを書く」のように、既存のものを別の言語で再実装するケースが多く、これはモデルが事前学習中に目にした可能性の高いものの翻訳にすぎません。私たちの課題はそのどちらとも異なり、本番環境への投入という明確なゴールがありました。さらに、BPE トークナイザーの学習は比較的新しい分野で公開されたリファレンス実装も少ないため、理想的な「テスト分布」の問題サンプルとなりました。

複数分野の専門知識が必要であること。Liquid AI の専門家はそれぞれ深い知見を持っていますが、その領域は 1 つに限られています。当社の ML 研究者は、OpenAI の cl100k がなぜ 3 桁のすべての数字にランクを予約しているのかを何も見ずに説明できますが、Rust のコードは 1 行も書いたことがありません。当社の Rust エンジニアは、この問題に必要なメモリを意識したマルチスレッドのシステムコードをまさに書けますが、トークナイザーを学習させたことはありません。

この 2 つのグループに重なりはなく、どちらも単独ではこの問題を解決できません。人間による回避策はどちらもロスを伴います。片方がもう片方の担当分野を先に学ぶか、共同プロジェクトとして人員を配置し、代わりに調整コストを負担するかです。私たちがエージェントに向けたのは、まさにこのギャップです。「当社のどのエンジニアも単独では持っていない専門領域の幅を、エージェントはカバーできるのか?」

外部から検証可能であること。成果物は tiktoken と Hugging Face の tokenizers で読み込めなければなりません。サードパーティ製ソフトウェアとのこの相互運用性があるため、エージェントが変更できないコードによって作業を検証できます。成功かどうかは自己申告ではなく、2 つのサードパーティ製ライブラリが正しいトークンを生成するかどうかで決まります。

何を構築する必要があったかの詳細もそれ自体興味深いものですが、本記事にとって重要なのは、真に本番グレードで、単一分野の専門家には難しく、外部から検証可能なタスクこそが、エージェントが人間の監督なしに仕事をやり遂げられるかどうかに正直に答える唯一の方法だという点です。

実験の準備

この実験では、2025 年後半時点で一般に利用可能な最も強力なコーディングモデルである Claude Opus 4.5 と、GPT-5.2 を搭載した Codex をコーディングエージェントとして選び、どちらもプランニングモードで作業させました。どちらのエージェントもコードを 1 行も書かないうちに、私たちはその周囲に 2 つのものを用意しました。目指すべきゴールと、そこに到達したかどうかを検証する手段です。

ゴールは仕様ファイルに記述します。これはオペレーターが書いた 1 つの AGENTS.md / CLAUDE.md ドキュメントで、実装ではなく、求める成果とその制約を記述したものです。アーキテクチャ上の主要な制約はメモリです。設計上の複雑さの予算はメモリに費やし、RAM よりはるかに大きなコーパスでも偏りなく反映されるようにします。計算と I/O は二次的な要素であり、素直な扱いで十分です。システムレベルのプログラミング言語(Rust)とマルチスレッドがあれば足りるはずです。

エージェントが指定されたゴールに到達したかどうかを検証するために、エージェントが影響を及ぼせない 2 つのものを与えました。

  • 本番データ: エージェントには、サンドボックス化した環境で当社の本番学習データセットと、それを処理できるマシンへのアクセスを与えました。具体的には、128 コア、256 スレッド、2 TB のメモリを備えた AMD EPYC 9755 です。
  • 外部検証ハーネス: 学習した語彙は tiktoken と Hugging Face の tokenizers で読み込める必要があり、複数の言語、数字、通貨の書式、タブ、CRLF 改行、ソースコードにわたって、エンコードとデコードの往復の正しさと、両者の ID レベルでの一致の両方を検査しました。

これらの要素が揃ったことで、エージェントは指定されたゴールに向けて作業できるようになりました。

実験を実行して起きたこと

両方のコーディングエージェントで実験を実行しました。オペレーターは外部から監視し、ハーネスだけを読み、コードは 1 行も読みませんでした。

トイトレーナーはどちらもゼロショットで完成

両エージェントとも、30 分以内に動作するトレーナーを作成しました。 設定ファイルを解析し、コーパスを走査し、ハードコードされたマージを適用し、BPE 学習を実行し、自身のユニットテストに合格する有効な .tiktoken ファイルを出力しました。

どちらも数メガバイトのデータでトイトークナイザーを問題なく学習できました。 成果物は tiktoken で読み込めました。テストはすべて合格しました。評価をこの時点で終えていれば、どちらの実行も成功だという結論になっていたでしょう。

ループなしでは、どちらも本番規模に到達できず

しかし、どちらのトレーナーも本番データセット全体には耐えられませんでした。最初の実行では、すべての段階ですべてのユニットテストが合格していました。数メガバイトのクリーンなテキストでは、以下の問題はどれも発生しないからです。

発見する必要があったこと

どのように表面化したか

何が検出したか

修正の工数

ファイルエンコーディング。Parquet では、同じ論理列に対して複数のエンコーディングが許容されている

テストでは問題なく読めるファイルが、コーパスでは気づかれないまま誤って処理される

実際のコーパスファイル

数時間

メモリへの配慮。ドキュメントごとの Vec のオーバーヘッドがペイロードを圧倒する

目標コーパスの約 1% の時点でメモリ不足

フルスケールでの実行

2~3 日:チャンクのバッチ処理、センチネル、マルチセグメントの反復処理

不適切な並列化。クリティカルパスの一部だけを並列化すると、残りが逐次処理のまま残る

全コアがビジーなのに、スループットは依然として不十分

フルスケールでの実行

1~2 日

事前トークン化の速度。\s+(?!\S) によってバックトラック型の正規表現エンジンが必要になる

プロファイラーで事前トークン化が大半を占めていることが判明し、悪意のある空白文字では処理量が二次関数的に増大する

フルスケールでの実行

数時間に加え、正確性に関する判断が必要

ランクの順序。tiktoken はランク順からマージ順を導出するため、ランクは連続していなければならない

語彙はエラーなく読み込まれるが、意図とは異なるエンコードを行う

外部ハーネス

数時間

重複したマージ。学習したマージが既存のトークンと重複し、語彙が縮んでしまうことがある

語彙が N 個不足し、以降のすべてのランクがずれる

外部ハーネス

数時間

数値のエンコード。Rust の regex クレートは {1,3}+ を ({1,3})+ として再解析する

tokenizers と tiktoken の結果が、数値以外のすべてで一致する

外部ハーネス

1 行

そこで、エージェントに実データに対してループさせました。実行し、壁にぶつかり、症状を報告し、エージェントに診断と修正を任せ、再度実行するというサイクルです。

5 回以上反復してもほとんど進展が見られなかったため、学習のスループットに依然として苦戦していた Codex/GPT-5.2 のトラックは作業を打ち切りました。これはリソース配分上の判断です。オペレーターは 1 人、締め切りは現実のものであり、その時点では同じターン数で Claude Opus 4.5 のトラックのほうが先に進んでいました。私たちの見立てでは、Claude は仕様のニュアンスや制約の背後にある意図を GPT-5.2 よりも確実に汲み取っていたため、最初のバージョンの出発点がより良かったのだと考えています。

Claude Opus 4.5 は、さらに数回の反復で残りの問題を解決し、本番構成の全体を実行できるトレーナーを完成させました。多言語データとコードデータからなる数兆トークンを、複数フェーズにわたって 1 台のマシンで処理し、数日で完了します。出力は外部ハーネスを問題なく通過しました。

ループが必要だった理由

私たちがこの実験を行ったのは、「コーディングエージェントは、本番グレードの問題をゼロから自力で解決できるのか?」という問いに答えるためでした。「どちらのエージェントもゼロショットでは解決できなかった」という結果を、モデルの能力の話として読みたくなるかもしれませんが、それは誤った結論です。私たちが最初に設定した基準に照らせば、実験は成功しました。ただし、そこに到達できたのは、ある 1 回の巧みなターンのおかげではなく、ループのおかげでした。

このリポジトリにある 2,000 行のコードは、ゼロショットの応答による産物ではなく、反復的なプロセスの積み重ねです。自明でない行のほとんどは、書く必要があるとわかってさえいれば簡単に書けます。コストがかかるのは、そもそもそれを書く必要があると気づくことです。

つまり、エージェントが人間の監督なしにゴールを達成できるかどうかは、実環境の制約に対して収束する反復ループがあるかどうかにかかっています。このループによって、エージェントは現実世界の複雑さを反復的に発見し、経験できるのです。

自律ループの運用から得た教訓

この実験から、コーディングエージェントはループがあればタスクを自律的に解決できることがわかりました。しかしそれ以上に重要なのは、効果的なループを設計するための 2 つの貴重な教訓を得たことです。これらは現在、当社のエンジニアリングチームで日常的なプラクティスになっています。

複数分野の専門家に向けたゴールの指定

この実験から、コーディングエージェントは複数分野の専門家であり、当社のどのエンジニアも持っていない幅広い専門知識をカバーしていることがわかりました。実際、エージェントは OpenAI の cl100k の正規表現を知っていましたし、Rust の rayon も知っていました。この仕事に配置できた人の中に、両方を知っている人はいませんでした。これによってゴールの指定方法が変わります。自分のチームの領域にもたまたま詳しい、別チームの同僚と話している感覚に近いのです。

トークナイザーの経験がない優秀なソフトウェアエンジニアにこの問題を任せるには、実際に何が必要かを考えてみてください。すぐに思いつくのは、詳細な仕様書を書くことです。これは専門知識の移転における古典的なジレンマです。仕様が短すぎれば、エンジニアはそのすべてを時間をかけて自力で見つけなければなりません。本当に実行可能なほど長く書けば、それは擬似コードを書いたことになり、その時点で自分自身がドメイン知識を必要としており、ほとんど自分で作業できたことになります。

LLM はそのジレンマに陥りません。最初から背景知識を備えているからです。これにより、仕様というものの性質が変わります。私たちの仕様は短いものでした。仕組みではなく、成果と制約を記述しました。

私たちの仕様にあった実例を見てみましょう。「学習開始前に、2 桁と 3 桁のすべての数字に語彙を予約する」。背景知識のないエンジニアにとって、これは恣意的な要件に見えます。文字どおりに実装しても、なお間違える可能性があります。この一文は、それ自体の動機を伝えていないからです。この要件の目的は、モデルに一貫した数値表現を与え、算術がコーパス内でたまたま頻出した桁の組み合わせに左右されないようにすることです。たとえば GPT-2 のトークナイザーには、学習データでの出現頻度の違いから、2019 という固有のトークンはあっても 2029 のトークンはありません。それを知らなければ、指示のどの部分が重要なのか、パイプラインのどこに組み込むべきか、自分の設計にほかにどんな影響があるのかを判断できません。

現実世界の制約に照らした検証

当社のオペレーターは、生成されたコードを 1 行も読みませんでした。それが許容できたのは、成功基準がエージェントには操作できないものだったからです。ループ設計でよく見られる誤りは、検証が弱いことです。トイ規模のデータに対して実行していたり、自身のユニットテストを編集するなど、エージェントが影響を及ぼせる状態になっていたりします。

最も重要な教訓は、次の要素によって、現実の制約に対して収束するループを設計することです。

  1. 本番規模の実データで反復する。重要だった障害はテストスイートでは見えず、フルスケールの本番データでしか発見できませんでした。
  2. 外部ハーネスで検証する。これこそが自律性を許容可能にするものです。オペレーターはコードを一度も読みませんでしたが、それが許容できたのは、正しさが tiktoken と Hugging Face の tokenizers、つまりエージェントが書いておらず影響も及ぼせないソフトウェアによって定義されていたからです。もしエージェント自身のテストスイートを証拠として受け入れていたら、どちらもテストに合格しながら、微妙に異なる語彙を生成する 2 つの実装ができあがっていたでしょう。成果物を第三者が判定できるように問題を構造化してください。

今日の日常業務とこれから

以上が、2025 年後半に実施した実験の結果と教訓です。答えはイエスです。コーディングエージェントは、人間の監督なしに、本番グレードの問題をゼロから自力で解決できます。ただし、ループの中で動かす場合に限ります。

得られた教訓は、現在、当社のエンジニアリングチームの日常的なプラクティスになっています。半年が経った今、私たちが最も注意を払っているのはゴールの指定であり、実データと外部検証を用いたループの構築は標準的なプラクティスになりました。

現在では、トークナイザートレーナーのような単発の開発をはるかに超えてループを運用しています。トークナイザートレーナーには、ループが収束していく明確で検証可能な最終ゴールがありました。一方、現在運用しているループの多くはオープンエンドで、唯一の正解がない目標に向かって山登り的に改善を続けます。カーネルのチューニング、継続的インテグレーションの監視、届いたプルリクエストのトリアージ、本番ログの異常検知などです。いずれの場合も、私たちはコードではなく指標を確認しています。

今日のモデルは大きく進歩していますが、これを日常業務にしたのは、ループ全体を任せられるほど信頼性が高まったことです。これが一般化すれば、純粋なコーディング能力のどんな向上よりも大きな、ML とソフトウェアエンジニアリングの進め方の転換になるでしょう。

提供状況

toktoktok は Apache 2.0 ライセンスのもと、https://github.com/Liquid4All/toktoktok でオープンソースとして公開しています。tiktoken 互換の BPE 語彙をゼロから学習することも、既存の語彙を拡張することもでき、.txt と .parquet を読み込み、複数フェーズの学習を通じて言語やドメインに語彙予算を割り当て、指定したメモリ予算の範囲内で動作します。Hugging Face 向けの変換スクリプトは双方向に対応しており、書き込む前に等価性を検証します。

そのすべての行をエージェントが書き、私たちは 1 行も読んでいません。

謝辞

執筆:Mathias Lechner、協力:Leonie Monigatti。

本実験のハードウェアを提供いただいたパートナーシップに対し、AMD に感謝いたします。

引用

本記事を引用する際は、以下をご利用ください:

Liquid AI, "Designing Loops for Production-Grade Work", Liquid AI Blog, Aug 2026.

@article{liquidAI2026loops,
  author  = {Liquid AI},
  title   = {Designing Loops for Production-Grade Work},
  journal = {Liquid AI Blog},
  year    = {2026},
  note    = {www.liquid.ai/blog/agent-loops},
}