リニアな思考、非線形なコスト
コーディングエージェントはAIワークフローの構築を容易にするが、非線形なコスト増大を隠蔽する。メモ化、枝刈り、動的計画法といった古典的な最適化手法が、反復作業と高コストを回避するために不可欠である。
多くのAIエージェントシステムは、技術的に印象的になるずっと前に経済的に持続不可能になる。チームは通常、モデル選択、プロンプト設計、ツール呼び出し、オーケストレーションに注力するが、これらはシステム設定の一部に過ぎない。より深い問題は、Claude Code、Codex、Julesなどのコーディングエージェントがエージェントワークフローの生成を容易にする一方で、実装が抽象化されると基礎となるメカニズムが見えにくくなることだ。かつては悪いエンジニアリングが遅いコードを生んだが、今では高価で遅いシステムを生む。
エージェントシステムを設計する際、コストが非線形に拡大することを覚えておく必要がある。単一のユーザーリクエストが1回のモデル呼び出しを引き起こすことは稀で、ルーティング、検索、推論、リフレクション、ガードレールチェック、ツール呼び出し、合成へと拡大する。各ステップで共有コンテキストの反復、状態の再読み込み、プランナー決定の再計算、失敗したパスの再試行が発生する可能性がある。一見インテリジェントなワークフローは、重複する部分問題を持つ再帰的でステートフルな計算のように振る舞う。これはバックトラッキング、動的計画法、メモ化のように聞こえるが、まさにその通りだ。
このようなシステムの最適化方法は既に知られている。問題は、コーディングエージェントがエージェントシステムの生成を容易にする一方で、最適化を必ずしも容易にしないことだ。基礎となるメカニズムを認識しない限り、システムを維持可能にする最適化パターンをコーディングエージェントに適用するよう依頼することはないかもしれない。
コーディングエージェントを使ってアーキテクチャを生成する際、「トレースが妥当に見える」で止まりがちだ。ツールはルーター、検索器、プランナー、評価器、ガードレール、ツールインターフェース、合成ステップを生成できる。キャッシュ、枝刈り、メモ化、状態モデリングについても知っているかもしれないが、これらの最適化層を明示的に要求しない限り、必ずしも実装されない。エージェントインストラクションを扱う場合でも、SKILL.mdやAGENTS.mdに反復コンテキスト、メモ化、キャッシュ無効化、枝刈り、リクエストごとのコストに関する制約が含まれていなければ、結果として得られるシステムは機能的に正しくても経済的に無駄になる可能性がある。コードはレビューに合格し、単体テストもパスし、アーキテクチャも妥当に見える。インボイスが隠れた計算を明らかにする場所だ。
コスト乗数はまずレイテンシとして現れる。ユーザーはルーター、再試行、リフレクションループ、ツール呼び出しを見ず、エージェントが遅いと感じるだけだ。従来のアプリケーションでは、失敗した操作はエラーをスローしたりタイムアウトしたりするが、エージェントワークフローでは、失敗は信頼性向上のための努力のように見える。例えば、最も弱いステップの成功率が60%で、再試行で99%近くに引き上げようとすると、5回の再試行が必要になる: 1 - (1 - 0.60)^5 = 0.98976。この計算は各再試行が公平なサイコロの目であることを前提とするが、LLMはサイコロではない。モデルはプロンプトによって形成された同じ基礎分布からサンプリングしている。最初の「思考」が幻覚や論理エラーであれば、温度を上げても基礎状態は修正されない。独立した試行を購入しているのではなく、同じ欠陥のあるマップと状態を通る異なるパスをサンプリングしているだけだ。
ここで古典的なアルゴリズムの枠組みが重要になる。バックトラッキング問題では、同じ失敗した枝を進み続けて進歩とは呼ばない。最後の有効な状態に戻り、失敗したパスをマークし、失敗を次の選択の情報として使用する。ポイントは単に再試行することではなく、変更された状態で再試行することだ。エージェントワークフローにも同じ規律が必要である。再試行は「もう一度実行して祈る」という意味ではなく、前回の試行がなぜ失敗したかについて構造化されたフィードバックをモデルに与えるべきだ。どの制約が失敗したか、どのツール結果が無効か、どのスキーマが検証に合格しなかったか、どの仮定がサポートされていなかったか、どのブランチが何も追加しなかったか。次の試行では、プロンプト、ツール選択、取得された証拠、検証制約、プランナー状態など、意味のある何かを変更すべきである。
メモ化、枝刈り、動的計画法。プロンプトキャッシュは通常最初の最適化である。すべてのステップで同じシステムプロンプト、ツール定義、スキーマ制約、例、ポリシールールが繰り返される場合、共有プレフィックスをキャッシュすることは明らかな勝利である。しかし、プロンプトキャッシュはテキストの繰り返しのみを認識し、決定の繰り返しには気づかない。多くのエージェントシステムでは、高価な単位はテキストだけでなく、繰り返される決定である。同じまたは同等の状態が再び現れた場合、モデルが同じアクションを再発見するために支払うのは不要である。これがメモ化が行うことだ: 繰り返し計算をルックアップに変える。古典的なアルゴリズムでは、繰り返し計算は再帰的部分問題かもしれない。エージェントシステムでは、同じタスク、事実、ツール、制約に対するプランナーの決定かもしれない。プランナーは状態の関数として扱うことができる: πLLM(St) → at+1。メモ化なしでは、この関数はLLM呼び出しを通じて何度も評価される。メモ化があれば、システムはまず同じまたは同等の状態を以前に見たかどうかをチェックする。
しかし、メモ化はシステムがどの状態を再訪する価値があるかを知っている場合にのみ役立つ。枝刈りは問題の反対側を扱う: これ以上探索すべきでないブランチ。ただし、枝刈りをKVキャッシュ枝刈りや投機的デコードに限定してはならない。ツールが繰り返し新しい情報を返さない場合にも使用すべきである。次のLLM呼び出しは、同じクエリの言い換えバージョンであってはならない。リフレクションループが改善なく文体の変更を繰り返す場合、ループは停止すべきである。検索パスが制約に違反するか、サポートされていない仮定に依存する場合、非生産的としてマークされ、アクティブな探索空間から削除されるべきである。
動的計画法は、ワークフローの異なるブランチが重複する部分問題を解決する場合に関連する。研究エージェントが複数の文書にわたって類似の質問をするかもしれない。コーディングエージェントが異なるエントリポイントから同じ依存関係チェーンを検査するかもしれない。ビジネス分析エージェントが複数のレポートセクションに対して同じメトリクスを計算するかもしれない。すべてのブランチがこれらの部分問題をスクラッチから解決する場合、システムは既に完了した作業に対して繰り返し支払うことになる。これらのパターンは、メモ化による繰り返し決定の削減、枝刈りによる繰り返し失敗の削減、動的計画法による繰り返し部分問題解決の削減を通じて、エージェントシステムのコスト構造を軽減する。
最適化はトポロジーに従う。集中型ではオーケストレーターの決定をメモ化する。分散型では共有コンテキストのプロンプトキャッシュと情報を追加しなくなった交換の枝刈りが最初の勝利である。独立/スウォームでは、メモ化と枝刈りは最適化ではなく耐荷重である。ハイブリッドでは、クラスター内で動的計画法、クラスター間でメモ化を使用する。コーディングエージェントは形状を見ずに生成することを容易にしたが、クラフトはとにかくそれを見ることにある。