编码 Agent 每轮都会重新发送旧的工具输出,用更小的内容替换看起来是显而易见的节省。我将其做成了一个 Torana 插件,曾经弄坏过一次,重新构建并进行了测量。在 DeepSeek V4 Pro 上,节省大约每会话 2%,这比普通的运行间波动还小,因为提示词缓存已经让重复输出几乎免费。
本文介绍了该想法、出现的问题、最终设计、实验设置与方法、结果以及后续工作。
编码 Agent 如何重新发送工具输出
编码 Agent 背后的模型自身无法读取文件或执行命令。它会请求一次工具调用,Agent 在本地运行该调用,并将输出追加到对话中。在随后的每一轮,Agent 会把完整的可见对话发回给模型,其中包括所有之前的工具结果。
每次请求都会把日志作为输入重新发送。上下文会被填满,且输出在每一轮都会再次计费。
这适用于会重新发送可见历史记录的 harness,通常通过 Chat Completions 或 Messages‑style API 实现。当提供方拥有历史记录(例如 OpenAI Responses 带有 previous_response_id)时,Torana 无法修改之前的条目;原生提供方的压缩是另一种机制。
想法:为托管模型提供更便宜的助手
如果托管模型是进行实际工作的“大脑”,那么一个更便宜的模型可以在大脑读取之前对工具输出进行摘要。只有当摘要知道什么重要时才有用,因此 Torana 的插件会修改模型所看到的工具定义,使其在每次工具调用时请求一个简短的原因,随后在 harness 见到调用之前删除该字段。压缩器利用捕获的 intent 决定保留什么。
原因字段:在发出的工具模式中添加,在返回的工具调用中移除。Agent 永不会看到它。
尝试 1:对每个大输出进行摘要
第一个压缩器会对超过 2,000 字符的任何工具输出进行摘要。它立即导致编码 Agent 出现问题(问题 #166)。编码 Agent 通过精确搜索和替换来编辑文件;当文件读取返回为自然语言摘要时,编辑不再匹配。该 Agent 重新读取文件,再次失败,并陷入循环,消耗了 token 而不是节省它们。
尝试 2:默认精确,仅压缩较旧的输出
第二种设计默认保持一切精确。策略按顺序、首匹配且不区分大小写;未匹配的工具永不更改:
- 精确:永不更改。变异工具、diff、失败命令、错误、栈跟踪和非零退出被强制设为精确,即使有更广泛的规则匹配它们。
-
确定性:保留有限的头部和尾部证据,此外还有大小、SHA-256、被省略字节计数以及重新运行指令。在
first_pass下,它从模型首次看到输出时开始应用,因此提示词永不需要后续重写。 -
关键字 (
keyword_compactor):保留意图匹配的行,仅在至少有一次精确暴露之后。 -
模型 (
compactor):意图引导的摘要,仅在至少有一次精确暴露之后,并且仅当经济网关预测有净节省时。 - 来源 (文件读取):在配置中被接受,但表现为精确(参见 什么导致了问题)。
关键字/模型:首次暴露时精确,如果网关允许,则从下一个请求开始有资格进行压缩。确定性带有 first_pass:从首次暴露开始压缩,避免后续前缀重写。缓存的压缩版本在后续请求中保持相同的字节。
重写较旧的消息会从该点开始更改提示词前缀。因此,带有模型网关的压缩器会运行两个经济网关:一个预检,用于检查即使是最佳情况下的减少是否能偿还缓存重写(在支付摘要之前),以及对实际候选者的最终检查。仅当估计的净节省为正时,才会应用一批。
实验设置和方法论
环境
- 日期: 2026年7月21日.
- 工具链: OMP 16.2.9 (编码智能体).
-
目标模型: DeepSeek V4 Pro 通过
https://api.deepseek.com/beta(OpenAI 兼容格式). - 摘要器(模型门控臂): DeepSeek V4 Flash 在同一端点。
- Torana: 提交 e09d225 来自 PR #179。该 PR 是实验分支;后来插件被移至 torana-plugins,当前版本有所不同。这是历史运行所使用的实现;下面未公开的任务提示词和运行产物阻止仅凭本文进行精确复现。
使用的价格(2026年7月,每百万 token)
历史测试输入,非当前价格。缓存命中价格是 V4 Pro 缓存未命中价格的 0.83%。
| 模型 | 输入(缓存未命中) | 缓存命中 | 输出 |
|---|---|---|---|
| DeepSeek V4 Pro | $0.435 | $0.003625 | $0.87 |
| DeepSeek V4 Flash | $0.14 | $0.0028 | $0.28 |
方案
- 对照组: 请求路径中的 Torana,未使用压缩插件。
-
确定性:
schema_translator → intent → keyword_compactor,摘要器已禁用。这是已提交的config.dogfood.json。运行本身使用了https://api.deepseek.com/beta端点来调用目标模型。
确定性方案配置(JSON)
{
"providers": {
"deepseek": { "url": "https://api.deepseek.com", "format": "openai" },
"deepseek-anthropic": { "url": "https://api.deepseek.com/anthropic", "format": "anthropic" }
},
"plugins": {
"order": ["schema_translator", "intent", "keyword_compactor"],
"config": {
"keyword_compactor": {
"tool_policies": [
{ "match": "read*", "mode": "exact" },
{ "match": "view*", "mode": "exact" },
{ "match": "web_search", "mode": "deterministic", "first_pass": true,
"rerun": "Repeat the search to recover every result." },
{ "match": "grep*", "mode": "keyword" }
]
}
}
},
"offload": { "enabled": false, "provider": "deepseek", "model": "deepseek-v4-flash" },
"limits": { "concurrency": 10, "rpm": 100 }
}
-
模型门控:
schema_translator → intent → compactor, 具有明确价格,并且 V4 Flash 作为摘要器。 类似 Grep 的输出有资格获得模型摘要;否则应用相同的精确和首 pass 规则。 从运行记录中根据已提交示例的形式重建(已提交文件仅覆盖确定性分支)。
DeepSeek 不单独收取缓存写入费用,因此缓存写入费率与输入费率相同:重写的片段按缓存未命中计费。模型门控分支配置 (JSON)
{
"providers": {
"deepseek": {
"url": "https://api.deepseek.com/beta",
"format": "openai",
"pricing": {
"deepseek-v4-pro": { "input_usd_per_mtok": 0.435, "output_usd_per_mtok": 0.87,
"cache_read_usd_per_mtok": 0.003625, "cache_write_usd_per_mtok": 0.435 },
"deepseek-v4-flash": { "input_usd_per_mtok": 0.14, "output_usd_per_mtok": 0.28,
"cache_read_usd_per_mtok": 0.0028, "cache_write_usd_per_mtok": 0.14 }
}
}
},
"plugins": {
"order": ["schema_translator", "intent", "compactor"],
"config": {
"compactor": {
"expected_applications": 6,
"tool_policies": [
{ "match": "read*", "mode": "exact" },
{ "match": "view*", "mode": "exact" },
{ "match": "web_search", "mode": "deterministic", "first_pass": true,
"rerun": "Repeat the search to recover every result." },
{ "match": "grep*", "mode": "model" }
]
}
}
},
"offload": { "enabled": true, "provider": "deepseek", "model": "deepseek-v4-flash" }
}
实验设计
- 任务:使用 OMP 运行五个仓库任务:架构、经济性、回归审查、安全(覆盖变更、补丁、报错和非零退出码等情形),外加一个压力任务。
- 设计:五次重复 × 三个分组 = 75 次会话。在每个配对区块(任务 × 重复)内,三个分组的执行顺序随机打乱。
防护措施、成本核算、统计方法与未公开的内容
prompt_cache_hit_tokens。
结果
每个分组 25 次运行的中位数。
| 分组 | 完成数 | 循环终止 | 成本中位数 | 输入 token 中位数 | 请求数中位数 | 缓存命中率 |
|---|---|---|---|---|---|---|
| 对照组(无压缩) | 23/25 | 2 | $0.024820 | 450,810 | 16 | 92.23% |
| 确定性 | 24/25 | 1 | $0.026699 | 479,087 | 19 | 91.68% |
| 模型门控 | 24/25 | 1 | $0.022465 | 444,625 | 17 | 92.75% |
确定性压缩组:25次运行中有15次成功转换了内容;399次应用(34次新转换,365次缓存复用)共移除了4,809,164字节。成对比较的成本节省中位数为$0.000524(约2.1%),95%区间为−$0.003714至+$0.003725。平均节省−$0.0000559;25组中有13组成本更低。成对输入token节省的中位数为29,117(区间−57,989至+60,161)。仅统计发生过转换的运行,成本变化中位数为−$0.000262,略有增加。
模型门控组:只有4次运行转换了输出,且全部通过确定性规则完成(6次转换,79次复用)。成对节省中位数为$0.000478(约1.9%),区间−$0.000998至+$0.004973;平均节省$0.001569,25组中有15组成本更低。预检阶段对Flash的调用为零:按DeepSeek的缓存命中价格计算,6次预期应用中,没有任何一次改写前缀能够弥补其导致的缓存未命中。这衡量的是门控本身的效果,而非模型生成的摘要。
循环中止(达到请求上限而终止)出现在对照组和没有发生转换的实验组运行中,因此反映的是Agent自身的波动,而非压缩的影响。
每项任务的成本中位数。工具调用次数和答案长度的差异,其影响超过了移除缓存token所带来的价值。各任务的成本中位数
任务
对照组
确定性压缩
模型门控
架构
$0.026040
$0.022984
$0.025993
经济
$0.024820
$0.026717
$0.021742
回归审查
$0.033672
$0.034278
$0.032411
安全
$0.017640
$0.015142
$0.017297
压力测试
$0.022256
$0.027260
$0.021505
为什么不划算:提示词缓存的经济账
三组实验中约92%的输入token都是缓存命中,而在V4 Pro上,缓存命中的价格仅为未命中的0.83%——便宜约120倍。被移除的重复工具输出本来就近乎免费。改写会从该位置起改变提示词,此后所有内容在缓存重建之前都要按新输入计费。

只有当后续轮次节省的成本超过它引发的缓存未命中成本时,移除字节才有意义。在92%缓存命中率和120倍价差的条件下,这些被移除的字节几乎一文不值。
这是 DeepSeek 定价的一个属性。对缓存输入收费更高或根本没有 prompt 缓存的提供商可能会改变结果。这是下一个实验 (issue #193)。
盈亏平衡条件
令 N 为未来轮次,R 为重写的缓存片段,W 为提供商的写入/输入速率,C 为其缓存读取速率,D 为每轮未来移除的 token 数,以及 S 为摘要器的成本。压缩需要:
N > (R × max(0, W − C) + S) / (D × C)
这个简化模型假设D × C为正且单位一致:S以美元计价时,费率按每 token 计算。它没有覆盖各家服务商的缓存规则差异,也没有模拟 Agent 行为的变化。当经济输入缺失或预期净收益不为正时,闸门不会做任何事——这本身就是正确的结果。
过程中踩过的坑
- 文件读取标记引发重读循环。早期一次被排除的试点用"重读"标记替换了旧的文件读取操作,结果 Agent 不停地抓取同一文件的不同行区间,直到撞上请求上限;由于偏移量一直在变,对相同参数去重也无济于事。现在源文件读取一律采用精确定位(#178 正在跟进一种有边界的替代方案)。
- 闸门漏算了一笔成本。一个未命中缓存的摘要候选被误标为缓存复用,导致预检漏掉了前缀重写的溢价。Torana 为 Flash 摘要买了单,最终却被闸门否决。现在未命中缓存的候选一律按重写处理;修正后的运行没有产生任何不经济的摘要调用。
-
缓存命中不可见。DeepSeek 报告缓存用量用的字段是
prompt_cache_hit_tokens,而不是 OpenAI 风格的prompt_tokens_details.cached_tokens。现在 Torana 在流式、JSON 和模型服务响应中会同时读取两者,并且/stats会报告摘要器的 token 用量。
局限性
- 只测了一家服务商、一套测试框架、五个任务、每个任务重复五次,且采用 2026 年 7 月的价格。
- 各次运行之间 Agent 轨迹有差异,许多实验组的会话实际上没有触发任何操作。
- 字节数不等于分词器计数;token 节省量来自服务商报告。
- 质量启发式低估了语义质量,仅用于初筛。
- 被排除的那次试点只作为反面安全证据保留。
- 在缓存昂贵或不可用的场景,以及 Agent 上下文耗尽时,压缩仍然有价值。
下一步计划
缓存读取昂贵的服务商。先用固定的对话记录回放来把定价因素与 Agent 行为隔离开,再在那些缓存定价不会让历史记录几乎免费的服务商上做实时配对运行(#193)。
按工具调用决定,而非按大小 某些输出必须保持精确:文件读取、编辑、错误。 某些输出根本不需要留在对话中:npm install 日志、构建输出、脚本运行。 像 Jev 和 Laya 这样的小型本地决策模型可以把工具调用划分到固定的选项集合中。 我正在构建一个版本,在每次工具调用时决定其输出是保持精确还是可以被压缩。 这项工作正在进行中,尚未得到测量结果。
试用或在此基础上构建
compactor、keyword_compactor 和 intent 是 Torana 插件。 按名称安装它们,检查权限,并按照 compactor 指南绑定摘要器。 在您自己的工具组合和价格上进行成对运行测量,使用提供方报告的 token 数并计入摘要器成本。
相同的插件 SDK 驱动本地 PII 检查。 要构建自己的插件,请从 plugin-authoring 指南开始。 欢迎其他提供方的结果,尤其是在 #193 上的结果。
此实验如何成为 Torana: 转折故事 →


