Alternatives for the EDIT tool of LLM agents

Salvatore Sanfilippo

LLMエージェントのEDITツールの代替案

原文は Salvatore Sanfilippo により に公開されました。 このブログを購読する

追記:もちろんこれは過去にすでにやられていたことです!薄々そうだろうとは思っていましたが、みんながTwitterで教えてくれました :) でも、このまま読み進めてください。最後に出てくるCRC32による妥協案は面白いトレードオフですし、これは一般的に議論する価値のある話題です。

今、DS4プロジェクト向けのエージェントに取り組んでいます。ローカル推論はトークンが貧弱で、最適化の一つひとつがものを言う戦場です。みんなが今使っているEDITツールが、LLMにテキストの旧バージョンを一字一句そのまま出力させているという事実にはかなり驚きました。このCAS(check and set)方式の動作、つまり EDIT old="foo" new="bar" のように指定するやり方は、衝突する編集が頻繁に起こるため(ユーザーが同時に編集していたり、別のブランチをチェックアウトしていたりなど)、そしてLLMがある行に特定の内容があったと平気でハルシネーションする可能性があるために必要とされています。

つまり、基本的に行番号だけを使うのは非常に脆いということです。たとえば「22行目を new="foobar" に変更して」と言うだけではダメなのです。一方で、毎回古いテキストを書き直させることでローカルのLLMにトークンを無駄遣いさせたくはありません。しかも、古いテキストには特殊文字や空白が多く含まれていることがあり、モデルがそれを間違えることもあるからです。そうなるとツールは失敗し、LLMは同じ編集をやり直す羽目になります。そこで私は、CAS方式は維持しつつ、よりトークン効率の良いタグベースのEDITツールを(再)設計しました。

READツールとSEARCHツールは、こんな感じの結果を返します。

10:Q8fA int count = 10;
11:rA3_ if (count > limit) {
12:Kq9z     count = limit;
13:PX0b }

行番号とタグが付いています。タグは4文字で、平均するとLLMの2.5トークンほどで、行のチェックサムを表しています。これでLLMは次のように編集できます。

{
  "tool": "edit",
  "path": "/tmp/example.c",
  "line": 10,
  "tag": "Q8fA",
  "new": "int count = 11;"
}

あるいは、複数行の場合はこんな感じです。

{
  "tool": "edit",
  "path": "/tmp/example.c",
  "lines": "11:rA3_\n12:Kq9z\n13:PX0b",
  "new": "if (count > limit)\n    return limit;"
}

節約効果は、エージェントが大量のテキストを削除するときに特に大きいですが、一般的なケースでも有効です。ただ、行番号とタグがある分、オーバーヘッドもかかります。トレードオフの余地はあります。タグを8文字にして行番号もハッシュに含めるべきかもしれませんし、衝突の可能性やトークン化を正確に検証して、どれだけ得なのかを見極める必要があります。ただ、私は line:tag という形式が気に入っています。というのも、後々LLMが行番号の情報をさまざまな形で活用できるからです。たとえば、後続のツール呼び出しで範囲を指定するといった具合です。タグについても、他に活用方法があるかもしれません。たとえば「この行はまだ dj4_ のままか?」といった使い方です。

面白いことに、DeepSeek v4 Flashはこのツールを非常に効果的に使いこなせます。どうやら彼にとっては自然な使い方のようです。正確な節約量は測っていませんが、現場では編集がはるかに高速になり、信頼性さえ向上しているのを実感しました。

これに対する代替案は、毎回ファイル全体のCRC32だけを返す方法です(基本的に、部分的な読み込みであってもタグがファイルタグになります)。そうすれば行番号+CRCだけで作業でき、編集時には 11,12,13,14 のように指定するだけで済みます。もちろんトークンはさらに少なくなります。ただし、この場合は毎回ファイルのCRC32を再計算する必要がありますが、常識的なサイズのファイルであれば十分安いコストです。しかし、このアプローチには限界があります。無関係な箇所に変更があっただけでも編集が失敗してしまうため、大きなトレードオフが存在します。ファイル全体方式を公平に評価するなら、10:23 のように範囲指定ができるのは大きな利点だと言えます。

どちらが優れているかは、2つの方式で ds4-agent を複数セッションにわたって使ってみて、十分な実践的な証拠が集まってからでないと判断できない気がしています。今のところ、編集モードを切り替えるコマンドラインオプションを用意するのが、まず取るべき正しい一歩かもしれません。

この記事は「muse-spark-1.2-contributor」を使用して翻訳されました。

コメント