Coding Agentは前回の修正を覚えればTokenを節約できるのか?Singularityの検索ロジックを調べた
同じリポジトリで、昨日Coding Agentにキーボードショートカットを追加してもらい、今日は似た機能を頼んだとする。するとエージェントは、昨日調べたファイルをまた検索し、テストを読み直し、同じ落とし穴にはまるかもしれない。最初の探索にコストがかかるのは仕方ない。では、なぜ二度目も同じ費用を払う必要があるのだろうか。
Show HNの投稿で、Singularityというオープンソースプロジェクトを知った。完了したコード変更を再利用可能なワークフローへ変換し、どのファイルを調べるか、どのように検証するか、以前何に失敗したかを記憶しようとするものだ。次のタスクで使えそうな手順を検索して、エージェントに渡す。
発想自体は魅力的だ。ただ、私が気になったのは別の問題だった。記憶が見つかったとして、それが現在のタスクにも有効だと何を根拠に判断できるのか。
Singularityのソースをコミット 9d241f2に固定して確認し、モデルを呼び出さない小さな合成テストを実行した。最初に限界を明確にしておく。SingularityのCLIをインストールして動かした統合テストではなく、Claude CodeやCodexの実際のToken費用を比較したものでもない。 ソースを参考に独立して作り直した照合ルールがどう振る舞い、どこで不適切な記憶を呼び出しうるかを調べた。
会話全文ではなく、作業の道筋を記憶する
固定したバージョンのREADMEによると、Singularityは成功した変更の経験を蓄積し、モデルを使って複数の経験をワークフローにまとめる。ワークフローには、ある機能を変更するときに触ることの多いファイル、確認すべきテスト、過去に失敗した場所などが含まれうる。
これは会話履歴を丸ごと長期記憶に入れる方法とは違う。チャットにはその場限りの試行錯誤が大量に含まれる。ワークフローでは、繰り返し利用する価値のある手順を残そうとする。ここで調べるのはワークフローの手順と検索用の手がかりであって、プロジェクトのほかのキャッシュ機構が存在するかどうかを網羅的に調査したわけではない。以前の記憶が正確なファイル名を指していても、リポジトリが変われば再確認が必要だ。
費用も二つに分けて考えたい。ワークフローを学習する段階ではモデル呼び出しが必要になりうる。一方、生成済みの手がかりから利用する手順を選ぶだけなら、モデルなしで済む場合がある。workflows-cuesは後者の方式だ。
ただし、Singularityのすべての経路がモデル不要という意味ではない。固定した評価コードのStepSelector.tsは、どの手順が適切かを判断するためにモデルを呼ぶ。一方、Memory.tsはworkflows-cuesをモデル不要の手がかり選択として説明している。評価コードには、モデルに選ばせる経路と、事前生成した文字列で選ぶ経路がある。コスト構造は異なるが、実タスクの処理時間やTokenを比較していない以上、総合的にどちらが優秀かは言えない。
モデル不要の照合は何をしているのか
続いてapps/cli/src/workflows/Cues.tsを読んだ。
基本は単純だ。タスクの文字列を大文字・小文字を統一した形にし、not、never、withoutなどを含む否定節を取り除こうとする。その後、残った文章にワークフロー用に生成された手がかりの語句が含まれるかを確認する。許可側の手がかりに一致し、除外側には一致しなければワークフローを選ぶ。個別のステップも、さらに手がかりで絞り込める。
この部分では、モデルに「二つのタスクの意味は似ているか」と質問していない。よく整理された文字列ルールの表に近い。安価で高速、同じ条件なら再現しやすい。しかし、言葉が重なることと意図が同じことは別だ。
たとえばkeyboard shortcutという手がかりを考える。「Add a keyboard shortcut」なら一致してよい。だが「Review keyboard shortcuts in documentation only」も同じ語句を含む。こちらは実装を変更してほしいという指示ではない。
コードは一部の明示的な否定を処理している。ただし、複雑な否定、暗黙の条件、複数文にまたがる意図まで理解できるわけではない。照合器は候補の記憶を返すが、その操作が正しいことまで証明しない。
五つの人工入力で境界を確かめた
固定コミットのCues.tsを参考に、文字列の正規化、否定節の除去、許可・除外の手がかりに関する中心部分を、手作業で独立してNode.js標準ライブラリのテストに置き換えた。公式テストスイートではなく、元の実装の全境界条件をカバーする保証もない。Singularityのインストール、モデルへの接続、実リポジトリでの操作は行っていない。
スクリプトと機械可読の結果記録は非公開の研究資料に保存しており、公開ダウンロードは提供していない。以下が五つの観測結果だ。これはソースから作った合成的な再現であって、上流CLIのエンドツーエンド検証ではない。
| 人工タスク | 照合結果 | 見たい点 |
|---|---|---|
| キーボードショートカットを追加する | 一致 | 関連する記憶を呼び出す |
| データベース接続を修正する | 不一致 | 無関係なタスクを除外 |
| ショートカットを追加しないと明示する | 不一致 | 単純な否定を処理 |
| ドキュメント中のショートカット表現だけを確認する | 一致 | 文字列の重複による誤検索 |
| ショートカットを追加するが、記憶中の旧ファイルは削除済み | 一致 | ファイルの実在確認はしない |
期待結果は実行前に、この簡略化した照合規則から設定した。関連タスクは一致、無関係なタスクと明示的否定は不一致。一方、ドキュメント確認だけでも引き金となる語句があれば一致するはずだと予測した。削除済みファイルのケースも、ファイルシステムを照会しないので一致すると予想した。
五つのアサーションはいずれも予測どおりだった。しかし、最後の二つは意図して用意した望ましくない結果だ。「5/5成功」は精度でも、五つの実タスクに正しく対応できた証拠でもない。この独立した簡略照合器について、予測と観測が一致したという意味しかない。
とくに古いパスが重要だ。文字列だけを照合するcueChoiceでは、ファイルの移動、削除、リファクタリングは分からない。後続のエージェントが実ファイルを調べて誤りに気付く可能性はある。それでも、古い手順が先に提示されること自体は起こりうる。記憶へのヒットは手がかりであり、現在のリポジトリ状態の証明ではない。
READMEのToken削減率をどう読むか
作者はExcalidrawのタスクを用いた比較を公開している。学習済みの記憶が特に役立ちそうな長いタスクでは、報告値としてTokenが約190万から42.3万、費用が約0.81ドルから0.30ドル、ターン数の中央値が28.5から9.5になったという。ただし各条件はおよそ3~4回の実行で、対象リポジトリも少ない。
注目に値する数字だが、あくまで作者が特定タスクについて報告した結果だ。未知の種類の変更や一度限りの小さな修正では、効果がほとんど出ないかもしれない。ワークフローを学習する段階にも費用がかかる。
ファイルを読むTokenが減ることと、エンジニアリング全体の費用が減ることも同義ではない。誤った記憶を呼び出せば修正のための調査が増え、大きなリファクタリング前の手順がかえって作業を遅くすることもある。
私は作者のモデル比較を再実行しておらず、実際のTokenや料金も測っていない。したがって、この記事には独立した削減率を載せない。意味のある推定には、同じ実タスクを記憶あり・なしで実施し、学習時の呼び出し、誤検索の修正、最終的な完了コストまで含める必要がある。今回のテストにはそのデータがない。
私ならどう使うか
同じ種類の変更が多く、ディレクトリ構造が比較的安定し、検証コマンドが明確なリポジトリなら、ワークフロー記憶を試す価値はある。私は記憶を確認すべき索引として扱い、エージェントに無条件で従わせる命令にはしない。
各ワークフローには、元となったコミット、対象パス、最終検証日、適用条件を添えるとよい。利用前にファイルの存在とテストコマンドの有効性を確認する。何度も不適切な記憶を呼び出して人の修正が必要になるなら、学習し直すか無効にする。これは私の提案であり、現行のSingularityに完全な失効検知が実装済みだと主張しているわけではない。
導入するかどうかも、宣伝されるToken削減率よりタスクの反復性で決めたい。毎回違うリポジトリ、言語、問題に取り組むなら、記憶の維持費用が思ったほど割に合わない可能性がある。
次に見たいのは、同一の実タスク群に対し、有効な呼び出し率、誤検索の回数、古い記憶の回数、学習費用、最終的な総費用を並べた公開比較だ。それがあって初めて、記憶が繰り返しの探索を省いているのか、その費用を記憶の保守へ移しているだけなのかを判断できる。
参考:Singularityリポジトリ · 固定した照合ソース · 作者の評価と制約