跑长轨迹的 Agent 会不断调用工具、积累观测,KV 缓存的 I/O 与存储很快变成主要开销。为省成本,主流做法是「上下文工程」——把历史裁剪或摘要压缩。但改动轨迹前缀会让后续缓存全部失效、保留的上下文不得不重新预填充;而为了少付重填的钱把上下文砍得太狠,准确率又会掉。
不改文本,直接动缓存
论文的做法是换一层控制面:不修改文本轨迹,而是让 Agent 直接操作活跃的 KV 缓存,并形式化两个算子。
- drop:把选中的缓存条目从后续 attention 中排除,K/V 不再参与计算但仍留在系统;
- repos:调整保留下来的 key 的位置编码。配合旋转位置编码(RoPE),repos 把 key 从位置 p 搬到位置 q。
收益很直接:被丢弃条目之外的所有 KV 状态都能复用。这打破了「省成本必然伤准确率」的绑定——不改文本,也就没有前缀失效。
论文还量化了传统做法的代价:只保留最近 12 轮工具响应的裁剪式做法,成本是全上下文基线的 1.85 倍;48k 阈值触发的摘要式做法省约 7% 成本,但准确率掉了 5 个百分点。而直接丢弃较旧的工具响应缓存可复用其余缓存,同时改善准确率与成本。
工程上的真实难点:历史依赖
论文点出一个容易被忽略、但对 serving 系统很致命的问题:历史依赖。同样一串 token,在不同的缓存操作序列下可能产生不同缓存状态。这意味着传统的 prefix matching 不足以保证正确的缓存复用。
AKV 的系统侧为此协同设计了三样东西:无状态接口、扩展 radix tree、以及 segment-batch attention。对外暴露兼容现有 serving API 的无状态接口,内部管理缓存复用、驱逐与恢复。
Agent 侧用 CachePolicy 决定丢什么、何时压实位置,内置按轮次、按 token 数、让模型自行决定三种触发方式。头条配置是「工具响应滚动丢弃」:保留最近 12 个工具响应的 KV 状态。
实验怎么做的
评测覆盖 MiniMax-M2.7、GPT-OSS-120B 和 MiroThinker-1.7-Mini;基准覆盖深度检索方向的 BrowseComp-Plus、xbench-DeepSearch-2510、文本版 GAIA 验证子集,以及软件工程方向的 SWE-Verified。Serving 侧用八张 A800-80GB,四张 prefill、四张 decode。
对照实验里,AKV 在三个模型上都取得最高平均成功率,相比两个基线分别提升 1.3–2.1% 与 0.9–8.7%;推理成本相对 Standard 基线降低 27.7%,相对 Text Engineering 基线降低 21.9%。此外让策略在留出任务上递归自我迭代,再降 7.1% 成本。
我的看法
这篇论文的价值不在某一个跑分数字,而在它把「缓存由谁管」摆到了正确的高度。此前 KV 缓存基本被视作 serving 系统的内部实现细节;而这篇的论点是:Agent 和 harness 比系统更知道哪些中间步骤没用了。
历史依赖这个发现尤其值得留意。如果不同操作序列会产出不同缓存状态,那么今天很多基于前缀匹配的增量缓存机制,在 Agent 这种高并发、长轨迹的场景下其实并不可靠。这也解释了为什么 AKV 需要定制引擎,而不是在现有系统上加个开关。
如果这条路线成立,Agent harness 与 serving 引擎之间的接口约定,可能成为下一个值得关注的工程标准。仓库 https://github.com/thu-nics/AKV ,论文 https://arxiv.org/abs/2610.28577 。