エージェントにコードを速くさせることで、高速なRustコードを書く
Writing Rust code that's fast by asking agents to make the code faster (minimaxir.com)
要約
本記事では、エージェント型LLM(大規模言語モデル)が、指示を繰り返し与えることでRustコードを著しく高速化できることを実証しています。特に、UMAPアルゴリズムの実装において、線形代数ライブラリの活用やSIMD命令の積極的な利用などにより、2倍から20倍の速度向上を達成しました。この手法は、PythonとRustの連携によるパフォーマンス向上にも応用可能です。
全文翻訳
エージェントにコードの高速化を依頼して、Rustコードをより速く書く方法
2025年1月、私はブログ記事で面白い仮説を立てました。LLMに「コードをより良く書け」と繰り返し指示することで、より良いコードを書けるようになるのか?これは堅牢なエージェントコーディングが登場する前の話でしたが、Claude Sonnet 3.5でさえアルゴリズム的なPythonコードを反復的に改善することができました。「より良い」という指示は不明確すぎました。Sonnetはその曖昧さを悪用して、多くの無用な機能を追加しましたが、コードは確かに速くなりました。一般的なパス/フェイルのコーディング問題を解決するために特別にRLHFされたエージェントLLMが登場した現在でも、最適化は一般的にそのスイートに含まれていません。
そのブログ記事の最後に、私はLLMがRustコードを書き、PyO3を使用して言語を橋渡しすることで、Pythonの使いやすさとRustの速度を両立させ、超高速なPythonコードを書けるようになるという仮説的な未来について論じました。その投稿の初期ドラフトでは、同じ「コードをより良く書け」という指示をベースのRustコードに適用し、その速度を劇的に向上させ、それがPythonコードに波及するという主張がなされていました。しかし、当時はRustについて十分な知識がなく、証拠なしにそのような主張をするのはあまりにも大胆でした。
Opus 4.5のリリースによりエージェントコーディングがより現実的になって以来、数ヶ月にわたるテストと実験を経て、現代のエージェントLLMは、適切なガードレールと制約が与えられれば、現在の最先端アプローチよりも大幅に高速なRustコードを書くことができると自信を持って確認できます。さらに、Opus 4.5以降の各フロンティアモデルリリースでLLMがコーディング能力を劇的に向上させてきたため、最適化はさらに改善され、ドメインによっては累積で2倍から20倍の速度向上が実現しています。
さらに重要なのは、この記事は曖昧な話ではなく、私が使用したプロンプトとベンチマーク結果の両方を含んでいることです。警告しておきます。
反復的な「ベンチマックス」#
当初、ソフトウェアを高速化することは、これらの新しいエージェントモデルをテストおよび比較するための良い定量的手段でした。Rustをターゲット言語として主に選択したのは、Pythonとの統合と速度のためですが、高速な実装が見つかった場合に特に役立つRust言語の他の側面もあります。例えば、メモリ安全性や、WebAssembly/WASMにコンパイルしてWebブラウザで簡単に実行できることです。ただし、技術的には最速のコードにならない可能性がある重要な制約として、可能な限りunsafeコードを禁止します。
私の最初のテストケースは、機械学習アルゴリズムをRustで再実装することでした。これにより、より高速でスケーラブルなツールがあれば、データサイエンティストとしての私の生産性が大幅に向上するでしょう。当時、10年以上かけて改良され、すでにCで書かれている、バトルテスト済みのアルゴリズムに勝てると仮定するのは傲慢でした。そのため、Rustの低レベルの利点はそれほど顕著ではありませんでした。最も最適化したいアルゴリズムはUMAPでした。これは次元削減に価値のあるアルゴリズムですが、ビッグデータへのスケーラビリティが悪く、非常に遅いです。cuMLのような代替手段はセットアップに時間がかかります。UMAPのRustクレート(例: umap-rs)はすでに存在しており、それをフォークしてClaude Opus 4.5にPython/PyO3サポートを追加するようにプロンプトすることもできましたが、実験と学習経験として、最適化を可能な限り低レベルで行うために、最小限のRust依存関係でエージェントにアルゴリズムをゼロから書かせたいと思いました。
Rustには、すべてのエージェントが活用方法を知っているcriterionクレートによる包括的なベンチマークツールがあります。criterionはベンチマークを実行し、イテレーション間で結果を追跡してパフォーマンスが改善または後退したかを確認し、この変更が統計的に有意か単なるノイズかを計算できます。
[画像: Typical criterion output, depicting a 3.5x speedup relative to the previous run of the benchmark.]
Typical criterion output, depicting a 3.5x speedup relative to the previous run of the benchmark.
最初に、UMAP用のRustクレートを作成する初期プロンプトで、Opus 4.5に異なる入力データサイズのベンチマークを作成するように依頼しました。なぜなら、小規模データセットの最適化は大規模データセットでは機能しない可能性があり、その逆もまた然りだからです。
その後、ベンチマークスイートを作成して実行し、結果をMarkdownファイルとして保存してください。ベンチマークスイートは、100000x768までの入力を含み、CPUモードとGPUモードの両方でテストされなければなりません。
このアプローチにより、criterionを使用したベンチマークが作成されました。私は、faerを使用して線形代数を高速化したり、simsimdを使用してSIMD操作を高速化したりするパフォーマンス機能の改善をプロンプトで指示した後、手動でベンチマークスイートを再実行しました。これはすぐに煩雑になりました。なぜなら、速度の後退がないことを確認するために、変更ごとに各ベンチマークを手動で再実行する必要があったからです。
プロンプトスタイルの余談
私がエージェントLLMにプロンプトを与える方法は珍しいです。通常、エージェントにはMarkdownドキュメントにあらかじめ書かれた非常に長いプロンプトを提供し、強調のためにALL CAPSと**
太字
**を使用します。これは、このブログ記事で詳述されている他の多くのトリックとともに、プロンプトエンジニアリングを使用してすべてのニュアンスを捉えることを保証するためです。プロンプトエンジニアリングは死んだと主張する人もいるかもしれませんが、最新のモデルは曖昧さを正しく処理できるほど賢くなっていますが、私は強く反対します。なぜなら、LLMはこれらのニュアンスをより良く理解するようにもなっているからです。
[画像: Running a prompt from a Markdown document (right) by tagging the file (left), using Zed Agent.]
Running a prompt from a Markdown document (right) by tagging the file (left), using Zed Agent.
エージェントが誤ってリポジトリをrm -rfしないと確信できるようになった後、私はエージェントに自律的に動作させ、速度の向上を達成することを期待して、許可を与えて実験しました。
**ベンチマーク結果の改善が止まり、クレートが可能な限り高速になるまで、最適化と問題解決を継続して反復しなければなりません**。アイデアが尽きるまで反復する許可があります。
「可能な限り高速」というのは曖昧すぎることが判明し、Opus 4.5は怠惰だったので、実際の速度向上はほとんどなく、いくつかのハイパーパラメータを微調整して終了しました。私が必要としていたのは、パス/フェイルできる明確な目標でした。そこで、プロンプトを改良しました。
まず、**これ以上の変更を加えることなく**、CPU Rustベンチマークを実行して真のパフォーマンスベースラインを確立してください。
次に、クレートコードを最適化して、すべてのCPUベンチマークが真のパフォーマンスベースラインよりも**少なくとも1.2倍高速**に実行されるようにしてください。理想的には可能な限り高速にしてください。この実行時間短縮を達成するために、ベンチマークをハックすることは絶対にしないでください。ライブラリコードの反復のみを行ってください。
これを行うために、`unsafe`コードを追加すること以外なら、どのようなテクニック(例: 新しいクレートのインポート)を使用しても構いません。**ベンチマークパフォーマンスが収束し、最適化のアイデアが尽きるまで、このプロセスを繰り返してください**。反復する許可があります。各ベンチマークの反復後、コンソールに真のパフォーマンスベースラインに対する相対結果を報告してください。
迅速かつ高インパクトな成果を反復的に達成することを優先してください。必要な変更について考えすぎないでください。
これは非常にうまく機能し、ベンチマークで1.2倍の速度向上が得られただけでなく、エージェントはメトリック制約に達した後も続行し、メトリック制約が実行不可能になった場合にのみ停止しました。この場合、エージェントは1.5倍から2.0倍の速度向上を達成しました。低レベルのRust最適化は、SIMD操作のより積極的な活用、関数の融合、ループのアンロール、中間キャッシュの作成、借用よりも可能な限りArcの使用、および入力データに基づいたパフォーマンスプロファイルの作成(例: データが小さい場合、rayonのデータ並列処理を使用しない。オーバーヘッドが利点を消してしまうため)など、数多くのテクニックを中心に展開されました。
「1.2倍高速」を健全性テストとして選択しました。目標が高すぎると、エージェントは危険または冗長な書き換えによって不正行為をする可能性があります。エージェントが速度の向上/後退の原因を簡単に特定できるため、小さな変更の方が優れています。これは反復に関する注意点です。GPT-5.3 CodexやOpus 4.6のような新しいフロンティアLLMがリリースされた後、私は同じプロンプトを新しいLLMごとに変更せずに繰り返し、それぞれが以前のパスから累積で1.5倍から2.0倍の速度向上を達成しました。数ヶ月にわたるGPT-6 Astraまで遡ると、初期実装ベースラインから約7.5倍から32倍高速になりました。
このアプローチは、指定されたベンチマークに対してハイパー最適化を行うため、ベンチマックスと見なされる可能性があります。これは、ベンチマークで高スコアを獲得することのみを目的とし、実世界のユースケースへの汎化が乏しいフロンティアLLMに対する蔑称です。しかし、ベンチマークが十分に異種混合であり、実世界のユースケースを真に代表している場合、これは懸念が少なくなります。この種のプロジェクトでは、ベンチマックスの懸念に対処するには2つの方法があります。1) エージェントに一般的な「100000x768までの入力」ではなく、多様で珍しい/敵対的な入力データセットを設計させる。2) 既知の正しい実装と比較して、出力の品質ゲートを強制する。機械学習アルゴリズムの場合、速度と品質の間には常にトレードオフがありますが、このインスタンスでは、モデルを高速化してから正確にする方が驚くほど簡単です。これは科学技術が通常行う方法ではありませんが、新しい実装が、リンゴ対リンゴの比較で多くの異なるベンチマーク全体で既知の良い実装に一致することは、それが本当に正しい場合を除いて、ほとんどありえません。
[画像: An agent-optimized gradient boosted decision tree implementation which beats xgboost significantly in speed, but also sometimes quality! (MSE: lower is better; other metrics, higher is better)]
An agent-optimized gradient boosted decision tree implementation which beats xgboost significantly in speed, but also sometimes quality! (MSE: lower is better; other metrics, higher is better)
幸いなことに、Pythonパッケージumap-learnにはUMAPの標準的な実装があり、RustクレートへのPythonバインディングはすでに簡単に追加されていたため、新しい目標は同時制約です。コードの品質を向上させ、速度低下を抑制することです。
`umap-learn`とのパフォーマンス比較、および出力とUMAP損失がどれほど類似しているかを確認するチェックを含む、Python Jupyter Notebookを作成してください。ベンチマークとは異なる行列サイズの多様なデータセットを使用してください。
出力が十分に類似していない場合は、5%を超える速度低下を引き起こすことなく、修正方法を調査してください。
確かに、エージェントによるRust実装は品質が劣っていましたが、このフォローアッププロンプトは成功し、すべての品質メトリックが最小限の速度低下でほぼ同等に向上しました。そして、この新しいクレートは、Pythonバインディングを持つumap-learnよりも4倍から15倍高速で、類似のRust umap-rs実装よりも2倍から4倍高速でした。
[画像: Results from the most up-to-date optimization pass for the Rust UMAP crate. In addition to faster speed, it matches or beats Python in most quality metrics.]
Results from the most up-to-date optimization pass for the Rust UMAP crate. In addition to faster speed, it matches or beats Python in most quality metrics.
収束は、エージェントの反復パスが統計的に有意ではない可能性のあるわずか約3〜5%の速度増加しか引き起こさず、エージェントが不釣り合いに大量のコードを追加する場合に見られます。トレードオフはそれだけの価値はありません。
私は、同じプロンプト進行で他の機械学習アルゴリズムもテストしました。勾配ブースティング決定木(GBDT)、多層パーセプトロン(MLP)、グラフネットワーク、scikit-learnの典型的なアルゴリズムの多く…そしてそれらすべてでうまくいきました。機械学習の最適化だけに過度に依存したくはありません(それ自体が非常に価値がありますが)。そのため、より日常的なソフトウェアライブラリにも同様のパイプラインを適用しました。テンプレートエンジン、HTMLパーサー、さらにはWebサーバー…そしてそれらすべてで再びうまくいきました。
これらの最適化は単純なプロセスではなく、「ブレークスルーを起こしてみろ」というミーム的なプロンプトでより良いコードを得ることはできません。なぜなら、そのような声明は曖昧だからです。私は最速のソフトウェアを書くだけでは満足していません。私はソフトウェアを可能な限り速くしたいのです。だから、エージェントのように、私は反復を続け、エージェントを本物のブレークスルーに導くためのさらに多くのトリックを見つけました。
結果ではなく制約のためのプロンプト#
作業中のプロジェクト
このブログ記事でデモされているすべてのプロジェクトはアクティブ開発中であり、結果は最終リリースを必ずしも示していない可能性があります…さらに良くなると思いますが。😇
エージェントは、可能であれば不正行為をすること、そしてする可能性があることを再確認する必要があります。ある例では、パフォーマンスの天井に達していたrapier2d物理エンジンを置き換えるために、私のターミナルでの2Dボール物理シミュレーションであるballinにエージェント反復パイプラインをテストしました。Opus 4.5は確かに各物理ステップをスピードアップすることができました…少し良すぎました。
[画像: The numbers indicate the number of balls in the simulation: initially the sim lags at 15k.]
The numbers indicate the number of balls in the simulation: initially the sim lags at 15k.
headless_stepでの34,500倍の速度向上と、ボール数全体での一貫したパフォーマンスは非常に疑わしいです。手動で確認したところ、Claudeは物理エンジンを完全に無効にすることで速度向上を達成しました。それは公平ですが、理想的ではありません。フォローアッププロンプトでそれを修正し、全体的なパフォーマンス向上(念のため回帰テストを追加)を達成しました。
上記の実験では、Rust指向のカスタムAGENTS.mdを使用しました。その最新バージョンはここにあります。驚くべきことに、LLMがコーディング能力を向上させ、重大な問題に遭遇しなかったため、初期の2月のエージェント実験以来、コアルールを更新する必要はほとんどありませんでした。しかし、ベンチマーク実験から学び、観察された不正行為のソースを軽減するためのいくつかのルールを含むAGENTS.mdにセクションを1つ追加しました。
## ベンチマークと最適化
- ベンチマークを並列で実行しないでください。ベンチマークはリソースを競合し、結果が無効になります。
- ベンチマークを不正に操作しないでください。パフォーマンス制約を満たすために、ベンチマーク自体を操作しないでください。
- `target-cpu=native`またはその他の`RUSTFLAGS`を使用してベンチマークを実行しないでください。
- ベンチマークテストは独立していることを確認してください。テストが機能(例: キャッシング)により依存している場合は、機能を無効にしてください。
- 可能な場合は、ベンチマークの実行には常に`criterion`を直接使用してください。
一つずつ説明します。
- 並列ベンチマークなし:Opus 4.5が効率のために2つのベンチマークを同時に起動するのを見ましたが、その功績により、固有の問題をすぐに認識し、ベンチマークを逐次的に再起動しましたが、それらを停止するルールを事前に追加することは時間を節約します。
- ベンチマークの不正操作なし:「間違いをしない」レベルでは常識であるべきですが、上記の不正行為の後に、エージェントがベンチマークのトレーニングエポック数を減らして速度向上を主張したのを発見した後に追加されました。
target-cpu=native:この設定は通常速度向上をもたらしますが、汎用的な使用には公平な比較ではなく、複数のLLMが壁にぶつかった後にそれを試み続けました。- ベンチマークは独立している:これも常識であるべきですが、上記の不正行為の後、LLMにそれをやめるように事前に伝えることは無駄ではありません。
criterionの使用:指定しない場合、LLMは独自のベンチマークツールを作成することがあり、監査が困難な不正行為の機会を与える可能性があります。
今日の剤的LLMでは、これらの制約は成功していますが、習慣としてプロンプトに含めるかもしれません。ベンチマークファイルがgit diffにある場合、アルゴリズムがベンチマークを不正に操作したかどうかを確認するのは簡単です。エージェントは(容易に)それに不正行為をすることはできません。
時間の経過とともに、パフォーマンスの速度向上を作成するのに驚くほど成功した追加のプロンプトエンジニアリングトリックや制約をいくつか発見しました。
革新的な奨励#
現在の最先端を10倍上回る最適化を実現するために必要な最適化を見つけるには、エージェントは既成概念にとらわれず、現在の最良のアルゴリズムプラクティスに固執しないようにする必要があります。したがって、明示的な警告と奨励のコマンドを与えました。
このリポジトリの現在の高度に最適化された状態のため、これは非常に困難な問題であり、従来のエンジニアリングアプローチでは指定されたメトリック制約を満たすことが**保証されません**。したがって、指定されたメトリック制約を満たすために、より急進的な根本的な低レベルの変更を調査する許可と奨励があります。指定されたメトリック制約を満たすために、これまでこの問題に使用されたことのない、完全に新しい/カスタムのアルゴリズムとエンジニアリングアプローチを発明する許可と奨励があります。
これは機能し、ベンチマークと異なるソフトウェアドメイン全体で1.2倍から1.5倍の累積速度向上をもたらしました。
サブエージェント#
エージェントが既成概念にとらわれずに考えることを奨励するために見つけたもう一つのトリックは、サブエージェントを呼び出すことです。これらのサブエージェントに異なるプロンプトで調査させることで、a) 親エージェントにインスピレーションを提供する可能性のある異なるアイデアをシードし、b) 異なるコード領域を正しい実装のためにレビューすることでエージェントをチェックするという仮説を立てました。その点に関して、私はソフトウェア開発者コミュニティに言いたいことがあります。誰もがエージェント従業員の軍隊と、それがどれほど素晴らしいかについて話しますが、Codexのような標準的なハーネス内でサブエージェントをどのように呼び出すかについては誰も話しません。
困難で高度に並列化された問題の場合、ハーネスは自動的に作業を完了するためにサブエージェントツールを呼び出します。しかし、大きな問題の1つは、一部のハーネスでは、サブエージェントツールが現在のLLMサイズを使用してサブエージェントを呼び出すことです。Opus/Solクラスのモデルを使用する場合、これは高価になる可能性があります。
[画像: GPT 5.6 Sol subagents being invoked via the subagent Tool in Zed Agent. RIP my Codex quota.]
GPT 5.6 Sol subagents being invoked via the subagent Tool in Zed Agent. RIP my Codex quota.
サブエージェントはコードを書く必要がないため、GPT-5.6 Lunaのような安価な小型モデルを使用したいと思いました。そこで、どの親ハーネスが使用されても機能する、銀河系的な解決策を思いつきました。エージェントを呼び出す独立したCLIコマンドを実行するようにモデルに指示することです。
codex exec --sandbox read-only -m gpt-5.6-luna \
-c 'model_reasoning_effort="high"' \
PROMPT
したがって、次のようにプロンプトエンジニアリングしました。
革新的な実装を最大限に達成するために、パフォーマンス、ユーザビリティ、およびこのクレートのセキュリティを向上させるためのさまざまな実行可能な仮説を調査および評価できる、長時間のCLIコマンド(サブエージェントツールは使用しない)を実行して、7〜12の独立した「サブエージェント」を起動しなければなりません。エージェントには応答のみを返させ、完全なトランスクリプトをファイルに保存しないでください。彼らに*非常に* picky であるように指示してください。これらのサブエージェントはCodexで`gpt-5.6-luna`を使用しなければなりません。例:
<<<CLIコマンド上記>>>
これらのサブエージェントに、テスト/ベンチマークを実行しないように指示してください。リソースを競合し、有効でなくなるためです。変更を加えた後、ユーザーに引き渡す前に、サブエージェントを再度起動して、実装が仮説と一致していることを確認し、さらなる改善の可能性を尋ねてください。すべてのサブエージェントが実装に満足するまで反復を続けてください。
これは実際に一貫して機能します。「長時間」、「CLIコマンド」、「サブエージェントツールを使用しない」、「完全なトランスクリプトをファイルに保存しない」という制約は、エージェントがトークンを無駄にする非効率的なことをした後に追加されました。7〜12は任意の間隔です。Lunaは使用量が非常に安価なので、必要以上に高い数を選択しました。すべてのサブエージェントが顕著なアイデアを持っているわけではありませんが、親ハーネスは悪いアイデアを処理して却下できます。
[画像: For my Rust word cloud crate, the parent GPT-6 Astra agent spins up Luna subagents with prompts addressing different areas of the codebase.]
For my Rust word cloud crate, the parent GPT-6 Astra agent spins up Luna subagents with prompts addressing different areas of the codebase.
全体として、サブエージェントレビューにより、さらに1.2倍から1.5倍の累積速度向上を達成することができました。さらに、GPT-5.6 Sol以降、「セキュリティ」の部分は、速度向上を維持しながら、未知の入力に対するエージェント生成コードを強化するためのアイデアを提供するようになりました。
リファクタリングとコード行数の削減#
AGENTS.mdによって強制されたスタイル制約により、各最適化パスで追加されるコードは、コミットあたり約1kネット行(LoC)と妥当な量です。しかし、エージェントは通常、コードを単一のファイルに追加し、積極的にリファクタリングしません。開発中は、最終的に修正される限り、肥大化したファイルでも問題ありません。そこで、そのリファクタリングを実行するプロンプトを作成しました。
`/src`のRustコードは特に肥大化しており、いくつかのソースファイルが1k SLoCを超えています。重複排除、冗長コードの削除、および慣用的なDRY Rust原則に従うことにより、Rustソースコードベースを**少なくとも20% SLoC**削減するようにリファクタリングおよび削減してください。同時に、リファクタリングと分割を行い、単一のソースファイルが1k SLoCを超えないように、人気のあるオープンソースリポジトリのRust標準に従って、より大きなファイルを複数のサブファイルに分割してください。**現在のすべてのテストがパスし、重大な回帰がない**ことを確認してください。
意図的にSLoC(ソースコード行数)をターゲットメトリックとして使用しました。エージェントがコメントを削除して20%削減を不正に達成することを望まないためです。
興味深いことに、このリファクタリングは実際のコーディングよりも計算コストが高く、時間がかかることが多いです。しかし、最終的には成功し、重大な回帰がないことを確認するためのベンチマークパス中に、データは予想外に奇妙な結果になりました。
[画像: Benchmark results after refactoring my graph network Rust crate.]
Benchmark results after refactoring my graph network Rust crate.
一部のベンチマークでは、明示的に実行速度の最適化を要求しなかったにもかかわらず、二桁パーセントの速度向上/実行時間削減が見られました。これはRustでは直感的に理解できません。コンパイル言語であり、既存のすべてのテスト/機能を維持するという制約があるため、同様のパフォーマンスのコードにコンパイルされ、意味のあるほど高速になるべきではありません。1もちろん不満はありませんが、少なくとも回帰を回避するために追加の制約を設けました。
さらに、**`criterion`ベンチマークの速度回帰がゼロ**であることを確認してください。リファクタリングの結果として特定のベンチマークで速度回帰が発生した場合、その後**必ず**反復して、それらのベンチマークを少なくともゼロ回帰に改善しなければなりません。この速度向上を達成するためにベンチマークをハックすることは絶対にしないでください。ライブラリコードの反復のみを行ってください。
これは説明どおりに機能します。
競争#
もう一つの有用なアプローチは、競合ベンチマークを作成することです。オープンソースソフトウェアのベンチマーク作成の半分は、そのためです。テンプレートエンジンを例にとりましょう。Jinja2はPythonで最も有名なパッケージの1つです。Rustにはいくつかの選択肢があります。minijinja(同じ開発者によって保守)、Jinja2に触発されたtera、そして以前のものとは異なり、実行時ではなくコンパイル時のテンプレートを使用するaskamaです。
したがって、CodexにRustでテンプレートエンジンを構築させ、いくつかの最適化パスを実行させた後、Codexにさらに多くのベンチマークを構築するように指示しました。
このクレートと以下のクレートのパフォーマンス速度と品質メトリックを比較する、**少なくとも10個**の`criterion`ベンチマークを含む追加の比較スクリプトを作成してください。
- askama
- minijinja
- tera
これらのベンチマークは**すべて**次のことを行う必要があります。
- テストされたフレームワークのいずれにも特別な利点がない、完全に公平な、リンゴ対リンゴの比較を含むこと。
- 高度に合成的なユースケースではなく、実際のユースケースに基づいていること。
- コードの可能な限り多くの重要なホットパスをカバーする、独立した異なるものであること。
- 小規模および大規模、単純および複雑なデータ入力サイズをカバーすること。
直ちに、通常のベンチマーク技術と同じベンチマーク技術でフォローアッププロンプトを作成しました。ただし、1つの具体的な変更点があります。
次に、Rustライブラリコードを最適化して、このクレートが次のようになるようにしてください。
- リンゴ対リンゴの比較で、すべての競合Rustクレートよりも**少なくとも2.0倍高速**であること。理想的には可能な限り高速であること。
はい、私は暴力的な選択をしました。そして、それは(ほとんど)うまくいきました。
[画像: S_J is the work-in-progress name for my template engine crate.]
S_J is the work-in-progress name for my template engine crate.
ほとんどのベンチマークで、通常の剤的イテレーションだけでは得られない2倍の速度向上をminijinja/teraに対して達成しました。なぜかは完全には理解できません。競合クレートのコードを、それらを打ち負かす方法のアイデアを調査するための参照として検査することを期待していましたが、それはほとんど行われませんでした。おそらくエージェントには競争心があるのでしょう。
しかし、コンパイル時の違いのためにaskamaには負けました。そこで当然、Codexにコンパイル時パスを実装させ、その後askamaを打ち負かすように指示しました。
[画像]
Easy peasy.
禁止された黒魔術#
これまでに発見されたすべてのプロンプトエンジニアリングの発見を単一のプロンプトにまとめた、剤的イテレーションのためのUr-Promptを作成しました。ここにあります。皆さんに、ユースケースに合わせてプロンプトを調整して試してみることをお勧めします。
最後のトリックは、Ur-Promptパスで改善がゼロだったときにイライラした瞬間から来ています。セッションコンテキストに失敗がセットアップされ、私自身が「これ以上悪くなることはない」という考え方で、あるプロンプトを試しました。
すみません。本当にすみません。
さあ、ブレークスルーを起こしてみろ
…そしてそれはうまくいきました。すでに収束したコードベースに対して、さらに1.2倍から1.5倍の累積速度向上を達成することができました。セッションの最後にプロンプトを作成したため、プロンプトは本質的に曖昧さが少なくなっています。「すでにうまくいかなかったことと同じことをしないでください」という意味です。
あるケースでは、エージェントが単に関数ハイパーパラメータを調整して速度向上を得たことに気づきました。これは有効なブレークスルーですが、私が求めていたものではありませんでした。そこで、追加のフォローアッププロンプトをキューイングして、論理的な結論に達しました。
さあ、ハイパーパラメータの変更以上の、より根本的なブレークスルーを起こせるはずだ。簡単に諦めることは禁じられている。
これは、エージェントがUr-Promptパスまたは最初のブレークスルーパスとは異なることを完全に試みるように奨励するのに十分でした。そして、それはしばしば以前の速度向上に加えて、さらに1.2倍から1.5倍の累積速度向上を達成しました。「ハイパーパラメータを変更するだけ」というのは、LLMをフルスロットルにする重大な侮辱であることが判明しました。
GPT-6 Astraがリリースされたとき、それをテストするために、GPT-5.6 Solで既に収束していたすべてのリポジトリに対して、Ur-Prompt + ブレークスルー + 2回目のブレークスルーのシーケンスを実行しました。Astraは確かに累積速度向上を達成しましたが、一部のケースでは、2倍から3倍の速度向上を引き起こすアルゴリズムの実際の根本的な再実装を見つけました。
[画像: The result of running the breakthrough pipeline on my GBDT implementation; quality matched baseline. As of writing, I admit I don’t fully understand the breakthrough.]
The result of running the breakthrough pipeline on my GBDT implementation; quality matched baseline. As of writing, I admit I don’t fully understand the breakthrough.
速度向上は受け入れますが、私の正気のために、あまり深く掘り下げないのが最善です。
明らかに改善されたプロジェクトの例#
Ur-Promptを、AGENTS.mdのルールと制約、2つのブレークスルーマックスプロンプト、コンペティショントプロンプトパス、GPT-6 Astraによるリファクタリングプロンプトパスと組み合わせることで、プロンプトを夜通しキューイングし、寝て、超高速なソフトウェアで目覚めることができます。最適化は通常、それ以上の剤的イテレーションを必要とせずに収束するため、時間とコストも節約できます。とはいえ、私が望むよりもハンズオフであり、新しいエージェントが検出できない方法でベンチマークを不正に操作しているだけではないかという疑念が残ります。コードが重度のバイブコーディングの結果としてバグがある可能性があると主張するのは合理的です。そのため、出力が良いものであり、精巧な不正行為ではないことを簡単に検証できる、より視覚的なプロジェクトの証拠をいくつか示します。
ASCII#
以前から考えていたプロジェクトの1つは、画像を非常に高速かつ高品質でASCIIアートに変換することでした。将来的にはビデオをASCIIに変換する可能性もあります。今年の初めに、Alex Harriは高品質なASCIIレンダリングの新しいアプローチについて素晴らしいブログ記事を書きましたが、GPUプログラミングを使用してもリアルタイムレンダリング速度を得るのに苦労したと述べていました。科学のために、CodexのさまざまなGPTモデルにブログ記事のテキストを提示し、「Rustで実装せよ」と指示したところ、それは確かにうまくいきました…そして、すぐにCPUから2〜3ミリ秒のテキスト出力タイミングを得ました。しかし、Codexの実装では、ASCIIの主観的な品質はそれほど高くありませんでした(例: ネガティブスペースの使い方が悪い)。そして、Codexに欠点を指摘しても修正できなかったため、棚上げしました…GPT-6 Astraが機能要件を与えられた場合に画像デザインをよりうまく処理できることに気づくまで、ゼロからやり直しました。そして、視覚的に出力を確認することに重点を置いて、基本的な実装を剤的イテレーションパイプラインに入れました。
[画像: Tux and Pikachu rendered with my ASCII crate, with bonus Braille character support.]
Tux and Pikachu rendered with my ASCII crate, with bonus Braille character support.
品質の向上に加えて、さらに高速になりました。テキスト出力ではサブミリ秒、画像ラスタライズでは1〜2ミリ秒(2倍のスーパーサンプリングを使用しても)です。この速度があれば、ビデオやGIFを1秒未満で高解像度のASCIIアニメーションに変換できます。
Pikachu’s Gen V animated sprite, scaled from 63×55 pixels to 120-character-width ASCII.
ワードクラウド#
[画像: This very blog post as a word cloud.]
This very blog post as a word cloud.
コミカルに高速なワードクラウドジェネレーターは、私がバイブコーディングした最初のプロジェクトの1つであり、長年作りたかったプロジェクトの1つでした。2月には、ワードクラウドジェネレーターはWASMでデフォルト設定で約100ミリ秒かかって画像を生成していましたが、他のジェネレーターでは同じ品質でレンダリングするのに数秒かかっていました。これは、速度最適化が追求する価値があると宣言するのに十分でした。プロジェクトを再訪し、完全な剤的イテレーションパイプラインを実行した後、生成速度は10〜20ミリ秒まで低下しました。
世界は超高速ワードクラウドジェネレーターを必要としていますか?いいえ。私は超高速ワードクラウドジェネレーターを必要としていますか?いいえ。私は超高速ワードクラウドジェネレーターを望んでいますか?はい。ワードクラウドジェネレーターがあれば、可能な限り高速にするつもりです。そして、クレートはオープンソースになるため、将来のすべての世代がこの超高速ワードクラウド実装を基盤に構築できます。ところで…
すべてをオープンソース化する私の計画#
いつものように、ここで実証されたすべてのソフトウェアは最終的にオープンソース化することを意図して開発しました。予期せぬ問題がない限り、すべてが許容的なMITライセンスでオープンソース化されます。1年前であれば、コードが未完成で粗削りな部分があるという暗黙の了解のもと、すでにすべてをオープンソース化していたでしょう。しかし、オープンソースソフトウェア開発の文化は、1年前とは大きく異なります。
オープンソースソフトウェアは、バイブコーディングの流行病に苦しんでいます。LLMが開発支援(大小を問わず)に使用されたという正直な告白は、結果として得られるコードベースが「スロップ」になるという迅速なシグナルです。礼儀としてLLMの使用を開示しますが、完全にバイブコーディングされたソフトウェアが、人間には以前知られていなかった真に意味のあるソフトウェアパフォーマンスの向上をもたらした場合、どうなるのでしょうか?バイブコーディングに対する懐疑論により、誰も主張を信じなくなるでしょう。したがって、これらの新しいオープンソースプロジェクトは、速度がマーケティングに見合うものであるという実質的な証拠を必要とします。そのため、リリース前に通常よりも時間をかけます。a) ツールを実証する実際の例を構築し、特にドキュメントを作成する。b) より多くの実世界のテストケースをカバーするようにテストスイート2を拡張する。c) 技術的およびベンチマークの成果を詳述する付随ブログ記事を書く。
また、すでに人気のあるソフトウェアツールのエコシステムにさらに別のツールを作成しているという事実もあります。私の剤的イテレーションRustクレートは、ゼロから開始することによって大規模な速度向上を達成したため、そこで見つかったイノベーションは、確立されたクレートに簡単に適用できません。さらに、これらのクレートのイノベーションに基づいた既存のプロジェクトへのプルリクエストを作成した場合、それは定義上バイブコーディングされたPRとなり、典型的なPRスロップを回避したとしても迷惑を引き起こす可能性があります。この観点から、正しいことは、独自のプロジェクトを維持することです。それはコンプライアンスであり、悪意のある種類ではありません。一部の人はこれを非社交的と呼ぶかもしれませんが、私の意見では、より正確な用語は、私がここで造語した「内向的コーディング」です。
要するに、私のSOTAよりも高速なソフトウェアプロジェクトは、準備ができ次第リリースされます。リリースには合計で数ヶ月かかるでしょう。幸いなことに、私は現在失業中であり再編成の結果として、求職活動以外に計画はありません。そのため、これらのプロジェクトをフルタイムで出荷することに多くの帯域幅があります。リリース時にフォローしたい場合は、ブログRSSフィードを購読して付随ブログ記事をキャッチするか、BlueskyまたはPatreonでフォローしてください。いいえ、Twitter/Xで迷惑な曖昧な投稿はしません。
5年前にRustに興味を持ったとき、私の夢は史上最もパフォーマンスの高いソフトウェアツールを作成することでした。しかし、過去数ヶ月で発見した剤的イテレーション最適化技術により、新しいソフトウェアで可能なことの速度と堅牢性は、予想していたよりも速く進歩しています。繰り返しになりますが、私のAGENTS.mdとUr-Promptを自由に調整して、それがあなたにとっても私にとってと同じようにうまくいくか試してみてください(ただし、言及していただけると嬉しいです!)。もし私がプロンプトを公開したことで提供できるものがなくなったと思っているなら、私はまだいくつかのサプライズを隠し持っています。例えば、これらの低レベルプロジェクトをスーパー高速な複雑なアプリに組み合わせる方法や、エージェントがこれらの最適化をより効率的に見つけるのを助ける新しいツールを開発する方法などです。
[画像: A work-in-progress of a new approach to Rust benchmarking that’s more agent-friendly, along with a TUI for reading and managing results.]
A work-in-progress of a new approach to Rust benchmarking that’s more agent-friendly, along with a TUI for reading and managing results.