LLMエージェントに長いタスクを任せると、モデルは推論し、ツールを呼び、その応答を受け取るという作業を何百回も繰り返す。この過程で生まれるすべてのテキスト — プロンプト、モデルが書いたメッセージ、ツールが返した結果 — を毎回ゼロから計算し直すのは遅く、そして高くつく。だからサービング系はKVキャッシュを使う。先に読んだ内容を再計算しないために保存しておく中間計算値のことだ。問題は、タスクが長引くほどこのキャッシュが際限なく膨らんでいく点にある。清華大学チームの計測では、このキャッシュを読むコストがAPIコスト全体の82.4%を占めていた(Figure 14)。
コストだけが問題ではない。モデルが一度に安定して扱えるトークン数には限界がある。参照すべきキャッシュが多くなりすぎたり、トークンが何番目の位置にあるかを示す番号(位置エンコーディング)が遠くまで広がりすぎたりすると、性能が落ちる。タスク履歴がモデルの最大入力長を超えれば、実行そのものが止まる。
これまでの解法は、会話履歴そのものを削ることだった。古いメッセージを切り落としたり、要約版に差し替えたりする。ところがここには隠れたコストがある。履歴の前のほうに手を触れた瞬間、その後ろに積み上がっていたキャッシュがすべて無効になるのだ。キャッシュは「前のトークンがこうだった」ことを前提に作った値なので、前が変われば後ろを計算し直すしかない。だから実務のハーネス(エージェントの実行を管理するプログラム)は限界に達するまで粘り、ある時点で大きく要約・削除して直近の数ラウンドだけを残す。直近だけ残せば途中の有用な情報が消え、多く残せば再計算の量が増える。コストと情報のあいだのトレードオフだ。
清華大学チームは、このトレードオフを回避した。会話履歴には手を触れず、モデルが参照するキャッシュだけを直接捨てる方式だ。そして驚くべきことに、要約するよりコストは安く、精度はむしろ高かった。
研究チームが「キャッシュエンジニアリング」と呼ぶ発想はシンプルだ。何を記憶から外すかはエージェントとハーネスが決め、サーバーはその決定を実際のキャッシュ上で実行する。これまでのキャッシュ管理がトークン位置やアテンションスコアといった低レベルのシグナルに委ねられてきたのとは違い、決定権がタスクの文脈を知っている側へと上がってくる。
この問題を扱う既存研究は大きく三つある。テキストレベルのコンテキストエンジニアリング(要約・トリム)、キャッシュレベルの圧縮・退避・再利用(低ランク表現、量子化、トークン位置やアテンション重要度に基づく退避、位置エンコーディング調整による再利用)、サービング系レベルのキャッシュ共有・スケジューリング(プレフィックスキャッシングなど)。前の二つは、捨てるか再利用するかの判断をトークン位置やアテンションスコアといった低レベルシグナルに委ねており、プレフィックスキャッシングは「同じプレフィックス = 同じキャッシュ」という等式の上に立っている。
ここで「捨てる」の意味をはっきりさせておく必要がある。キャッシュを捨てても原文の履歴は残る。ただ、次の応答を計算するときにモデルが直接参照する中間計算値から一部を外すだけだ。履歴を保管しておくことと、モデルがその内容に直接アクセスすることは別の話だ。
具体的には演算を二つ新たに定義する。
repositionが別途必要になる理由がある。位置番号はキャッシュを空にしてもタスクに沿って増え続ける。dropでキャッシュをいくら減らしても次のトークンの位置番号はリセットされず、キャッシュは小さいのに番号だけがモデルの限界まで跳ね上がる、という事態が起こる。repositionは位置番号をキャッシュサイズから切り離してこれを防ぐ。
RoPE(回転位置埋め込み)は、トークンの位置をキーとクエリを一定の角度で回転させて表現する。位置を動かすにはキーの回転角度だけを変えればよく、保存しておいた値(value)は回転の対象ではないのでそのままコピーする。おかげで隠れ状態を再計算せずに位置だけを調整できる。
dropにはひとつの性質がある。古い記憶を捨てても、残したキャッシュはその記憶が生きていたときに計算された値だ(Figure 1)。捨てた情報の影響が、残ったキャッシュにすでに染み込んでいるということだ。
どの記憶を残すかはデータから出てきた。アテンション分布を見ると、古いトークンは直近のトークンより、ツール応答は同じ位置のモデル推論メッセージよりアテンションを受けにくかった。そこでデフォルトの方針は「ツール応答のローリングドロップ」になった。すべての推論と直近のツール応答は残し、古いツール応答のキャッシュから押し出していく。
核心から。三つのモデルと四つのベンチマークの平均で、このツール応答ローリングドロップは、通常のしきい値要約方式に対して平均コストを27.7%削減し、ベンチマークスコアを平均1.7点引き上げた。コストと精度のどちらかを削るのではなく、両方が良くなった。
比較はむしろドロップに不利な形で揃えた。ベースラインはエージェントハーネスがよく使う要約ベースの方式二つ(Standard、そしてしきい値だけを48Kに下げたText Engineering)で、ドロップ側のコストはキャッシュヒット料率で課金して位置番号を振り直すコストをわざと大きめに見積もった。モデル規模やしきい値、料率といった詳細は下の表と掘り下げボックスにまとめた。
| 区分 | 設定 |
|---|---|
| モデル | MiniMax-M2.7(230B全体、10Bアクティブ) · GPT-OSS-120B(高推論強度) · MiroThinker-1.7-Mini(思考モード) |
| ベンチマーク | BrowseComp-Plus(BCP) · xbench-DeepSearch-2510 · GAIA-Text(103-task検証サブセット) · SWE-Verified |
| 指標 | 成功率(pass rate) · タスクあたり平均APIコスト(セント) |
• 料率:GPT-OSS-120BはGroq料率、MiniMax-M2.7は公式料率、MiroThinker-1.7-MiniはベースモデルQwen3-30B-A3Bの料率。
• Standardのしきい値:GPT-OSS-120B・MiniMax-M2.7 = 96Kトークン、MiroThinker-1.7-Mini = 192Kトークン。Text Engineering = 48K。
• AKVの方針:直近12個のツール応答のKVだけを残すツール応答ローリングドロップ、しきい値は各モデルのStandardと同一。
• サービング効率の指標:リクエスト遅延、TTFT(最初のトークンまでの時間)、TPOT(出力トークンあたりの時間)、入出力スループット。
• サービング実験:A800-80GB GPU 8枚(prefill 4 + decode 4、テンソル並列 4)、BF16。
詳細は、GPT-OSS-120BをBrowseComp-Plusの最初の100課題(課題あたり4回試行、最大100ラウンド)で回した分析が鮮明だ。
観測された事実は明確だ。同じコスト帯で、ドロップが要約よりスコアが高かった。なぜそうなるのかについての著者の説明は仮説に近い。要約は途中の情報を丸ごと飛ばすが、ドロップは残したキャッシュが捨てた情報の影響を抱えている、というものだ。性能差を実験で切り分けて確かめた結果ではない。だから、答えがツール応答の中に入っていた課題 — 過去の数字や制約をそのまま取り出し直して使わなければならない場合 — でもこの利点が保たれるのかは、まだ開かれた問いだ。
この方式は、サービング系の古い前提をひとつ崩す。普通は前のトークンが同じならキャッシュも同じだ。だから同じプレフィックスを持つリクエストどうしでキャッシュを安全に共有できた。ところがキャッシュエンジニアリングでは、同じテキストでも、どの時点で何を捨てたかによってキャッシュの値が変わる。Figure 5がその例だ。軌跡①と②はどちらもB・CのKVを残すが、①はCを計算するときにAが生きていて、②はCを計算する前にAを捨てている。トークンB・Cは同じでも、Cのキャッシュの値は違う。プレフィックスだけを見てもキャッシュを正しく再利用できず、トークン履歴とキャッシュ演算履歴を併せて追跡しなければならない。論文はこれを「履歴依存性(history dependence)」と呼ぶ。
この複雑さを引き受けるために設計したサービングエンジンがAKVだ。原則は「ステートレスなインターフェース、ステートフルなサービング」。エージェントはメッセージとキャッシュ演算の指示だけを送り、こみ入った状態管理はサーバーが内側で抱え込む。その中で三つを守る。演算履歴の違うキャッシュを誤って再利用しないよう拡張ラディックスツリーでdropのタイミングが異なる枝を区別し、まだ他のリクエストが使いうるキャッシュを勝手に空けないようdrop認識退避で回収のタイミングを遅らせ、メモリが逼迫してキャッシュが押し出されたあと再び必要になったらセグメント・バッチアテンションで一度のprefillに復元する。その分、サービングエンジンが抱える複雑さは増した。代わりにAKVサーバーを付けると、この方針は出力スループットを最大1.2倍に、P95リクエスト遅延を1.5倍速くした。
既存のAPIベースのサービングと互換になるよう設計された。messagesフィールドが論理トークン列全体を渡し、オプションのcacheフィールドがdrop・repositionを「演算適用地点(operate-after)」の文法で指定する。エージェントはどのKVがサーバーに残っているかを追跡する必要はなく、メッセージと演算指示だけを送り、状態管理はサーバーが内側で処理する。
prefillは前のトークン全体を一度に計算してキャッシュを満たす段階だ。普通の因果的(causal)prefillは「後ろのトークンが前のトークンを見る」という一方向のルールだけに従うので、途中の一部を捨てた状態をそのまま再現できない。セグメント・バッチアテンションはクエリをdrop地点で区切り、各区切りが自分のトークンと「前の区切りの生きているキャッシュ」だけにアテンションするようにする。アテンションだけを区切りに刻み、FFN(各トークンを独立に変換するニューラルネット層)は全体を一つのバッチで処理して、重みを読み直すコストを避ける。
キャッシュ演算はプログラムのように組み合わせられる。だからエージェントが自分のキャッシュ方針を自ら探索し、評価し、修正する再帰的自己改善(RSI)が可能になる。RSIが見つけ出した方針は、評価に使わなかった(held-out)課題で、専門家が手で設計した方針よりコストをさらに7.1%削減した。この7.1%の比較対象は専門家設計の方針であって、先の27.7%と同じ基準ではない。
著者たちが挙げた限界は、たった今見た履歴依存性そのものだ。プレフィックスさえ見ればよかった単純さが崩れ、サーバーはトークンと演算の履歴を併せて追跡しなければならなくなる。拡張ラディックスツリーとセグメント・バッチアテンションがこれを担うよう設計されているが、既存のSGLangの上に載せた実装なので、再現と比較には向いていても、どんな商用APIの裏にもそのまま挿し込めるわけではない。
もっと注意すべきは、ドロップ方針がどこでも通用するかだ。「直近12個のツール応答を保存」は、アテンションがツール応答をあまり見ないという観察から出てきた合理的なデフォルトだ。しかし、ツール応答に決定的な事実が詰まっているタスク — 検索結果そのものが答えであるディープリサーチのような — では、ドロップがかえって有害になりうる。過去のツール応答の数字や制約をそのまま取り戻さなければならない課題こそ、その失敗地点だ。RSIが方針を課題に合わせて探索し直す仕組みとして併せて提示されているのも、このためだと読める。また、コストを料率表で計算しているため、GPUを自前で回す環境と外部APIで課金される環境とで、体感できる利得は変わりうる。
ONTLEのAI PMが、ひとつのプロジェクトを数週間にわたって担当するとしよう。毎日タスクボードを照会し、ドキュメントを読み、担当者に状況を尋ねる。その間、作業履歴は際限なく長くなる。繰り返し照会したボードの一覧やドキュメント全文は、古いものからキャッシュを減らしても大きな問題はなさそうに見える。
問題は、その隙間に紛れた決定的な制約だ。たとえば「この機能は特定の取引先の要望で保留」という3週間前の会議の一行。ONTLEでこの研究を検証するなら、コストがどれだけ減ったかではなく、三つを評価項目に据えるべきだ。第一に、古く眠っていた保留理由を、PMが根拠とともにそのまま取り出し直せるか。第二に、その保留が、あとで覆された決定と混ざらずに区別されるか。第三に、この精度を保ちながらコストが実際にどれだけ減るか。ツール応答をあまり見ないという観察は、「制約は捨ててよい」という意味ではないからだ。
商用APIを使う立場なら、
サービングエンジンを自前で運用するなら、
論文は両者を代替として並べて比較している。ただしdrop・repositionはテキスト履歴に手を触れないので、概念的にはテキストレベルの処理と排他的ではない。抜粋の範囲で両者を組み合わせて計測した結果は確認できなかったので、断定は避ける。
抜粋の範囲で、モデルの再学習を要求するという言及はない。dropはキャッシュ項目を以降のアテンションから外す操作であり、repositionはキーを再計算せず位置番号だけを動かす操作だ。どちらも推論時にキャッシュを扱う演算だ。
公開されている。コードリポジトリは https://github.com/thu-nics/AKV で、ベースのサービング系はSGLangだ。