AIコーディングエージェントが作ったスパゲッティコードの始末とトークンコストの削減
エージェントにコーディングを任せたところ、コードが100万行に膨れ上がり、API利用料の請求書爆弾が返ってきた。この記事はその対処法についての話だ。
壊れたコードベースの片付け
エージェントが無限ループを回して生成した重複コードは、30分で削除できる。knipとjscpdを使えばよい。
プロジェクトのルートに knip.json を作成し、エントリポイントを記載しておく。ターミナルで npx knip を実行し、エージェントが使い捨てたゴーストパッケージを見つける。続いて npx jscpd ./src -t 1 を実行し、コピペで増殖した重複関数ブロックを抽出する。
158ファイル規模のモノレポで不要なコードを一度に一掃できる。その後 biome.json を開いて noUnusedVariables ルールを有効にし、デッドコードが再び入り込まないようにロックする。
サンドボックスでのトークンコストの封じ込め
コード全体を毎回エージェントに投げるとトークンが消え飛ぶ。Aiderスタイルの Repo-Map 構造を適用し、現在作業中のファイルだけを隔離すべきだ。
--map-tokens 1024 オプションを指定すれば、1,000を超えるファイルがあるプロジェクトでもリポジトリ構造の把握に使うトークンを2,000トークン以下に抑え込める。
コスト制限をかけるには LiteLLM Proxy が答えだ。litellm_config.yaml を設定し、セッションあたりの最大ループ回数を15回に制限する。コストの上限を2.50ドルに設定しておくと、エージェントが上限を超えた瞬間にプロキシが呼び出しを遮断してくれる。
宣言型テストによるエージェントの制御
マレー語で長いプロンプトを書いたところで意味がない。失敗するユニットテストコードを先に突きつけてこそ、エージェントは変な挙動をしなくなる。
SWE-bench Verifiedの研究によると、ユニットテストケースを先に注入する方法を用いた場合、回帰率が6.08パーセントから1.82パーセントに低下し、問題解決率は24パーセントから32パーセントに向上した。
失敗するテストファイルを先に作成し、エージェントにはそのテストを通過する実装部分だけを書くよう指示する。
検証スクリプトも自動化する必要がある。local_verifier.sh ファイルを作成し、npx tsc --noEmit、npx biome check ./src、npx vitest run のコマンドを順番に記述する。エージェントがコードを書き終えたと主張しても、このスクリプトの終了コードが0でなければコミットをブロックする。
人間が直接介入するハイブリッドワークフロー
エージェントが作成したコードは、プルリクエスト単位で分割して人間が直接確認する。
変更された行が200行を超えていないか、package.jsonに変なパッケージが追加されていないか、@ts-ignoreでエラーをごまかしていないかを確認する。Huskyと lint-staged を連携させておけば、コミット時点で重複コードが2パーセントを超える場合に即座にブロックされる。
作業を分割する際は3段階で行う。最上位モデルが作業を分割し、TODO.mdを作成する。次にコスパの良いモデルが各項目を実装する。最後にシニア開発者がgit diffを検証する。この構造を採用すれば、フロンティアモデル1つだけで押し進める場合と比較して、コストを70パーセント以上節約できる。