← 返回
AI技术

压缩工具输出是否能降低编码 Agent 的 API 费用?

✍️ zhirenhun 📅 2026/10/8 👁 225 阅读 ⏱ 27 分钟
压缩工具输出是否能降低编码 Agent 的 API 费用?

编码 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:默认精确,仅压缩较旧的输出

第二种设计默认保持一切精确。策略按顺序、首匹配且不区分大小写;未匹配的工具永不更改:

这张图展示了一个基于Web搜索的图形输出的例子

关键字/模型:首次暴露时精确,如果网关允许,则从下一个请求开始有资格进行压缩。确定性带有 first_pass:从首次暴露开始压缩,避免后续前缀重写。缓存的压缩版本在后续请求中保持相同的字节。

重写较旧的消息会从该点开始更改提示词前缀。因此,带有模型网关的压缩器会运行两个经济网关:一个预检,用于检查即使是最佳情况下的减少是否能偿还缓存重写(在支付摘要之前),以及对实际候选者的最终检查。仅当估计的净节省为正时,才会应用一批。

实验设置和方法论

环境

使用的价格(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

方案

确定性方案配置(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 }
}

模型门控分支配置 (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" }
}

DeepSeek 不单独收取缓存写入费用,因此缓存写入费率与输入费率相同:重写的片段按缓存未命中计费。

实验设计

防护措施、成本核算、统计方法与未公开的内容
  • 防护措施:超过 25 次请求、150 秒无进展、出现三次相同的语义工具意图,或总花费达到 $15 上限即停止。实际总花费:$1.90。
  • 成本:按上述价格、基于供应商上报的缓存未命中、缓存命中和输出 token 数计算,外加摘要环节的用量。DeepSeek 将缓存命中上报为 prompt_cache_hit_tokens。
  • 统计方法:配对节省 = 同一任务、同一重复下对照组成本减去实验组成本,共覆盖全部 25 对。95% 区间采用 10,000 次 bootstrap 重采样(固定随机种子 166)得到的百分位区间。
  • 质量:用关键词启发式方法做初筛,并人工复核全部 15 份安全任务的回答。
  • 未公开:具体的任务提示词和各会话原始记录,出于隐私审查考虑暂缓发布。汇总数据见 DEEPSEEK_RESULTS.md。

结果

每个分组 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 行为的变化。当经济输入缺失或预期净收益不为正时,闸门不会做任何事——这本身就是正确的结果。

过程中踩过的坑

  1. 文件读取标记引发重读循环。早期一次被排除的试点用"重读"标记替换了旧的文件读取操作,结果 Agent 不停地抓取同一文件的不同行区间,直到撞上请求上限;由于偏移量一直在变,对相同参数去重也无济于事。现在源文件读取一律采用精确定位(#178 正在跟进一种有边界的替代方案)。
  2. 闸门漏算了一笔成本。一个未命中缓存的摘要候选被误标为缓存复用,导致预检漏掉了前缀重写的溢价。Torana 为 Flash 摘要买了单,最终却被闸门否决。现在未命中缓存的候选一律按重写处理;修正后的运行没有产生任何不经济的摘要调用。
  3. 缓存命中不可见。DeepSeek 报告缓存用量用的字段是prompt_cache_hit_tokens,而不是 OpenAI 风格的prompt_tokens_details.cached_tokens。现在 Torana 在流式、JSON 和模型服务响应中会同时读取两者,并且/stats会报告摘要器的 token 用量。

局限性

下一步计划

缓存读取昂贵的服务商。先用固定的对话记录回放来把定价因素与 Agent 行为隔离开,再在那些缓存定价不会让历史记录几乎免费的服务商上做实时配对运行(#193)。

按工具调用决定,而非按大小 某些输出必须保持精确:文件读取、编辑、错误。 某些输出根本不需要留在对话中:npm install 日志、构建输出、脚本运行。 像 Jev 和 Laya 这样的小型本地决策模型可以把工具调用划分到固定的选项集合中。 我正在构建一个版本,在每次工具调用时决定其输出是保持精确还是可以被压缩。 这项工作正在进行中,尚未得到测量结果。

试用或在此基础上构建

compactor、keyword_compactor 和 intent 是 Torana 插件。 按名称安装它们,检查权限,并按照 compactor 指南绑定摘要器。 在您自己的工具组合和价格上进行成对运行测量,使用提供方报告的 token 数并计入摘要器成本。

相同的插件 SDK 驱动本地 PII 检查。 要构建自己的插件,请从 plugin-authoring 指南开始。 欢迎其他提供方的结果,尤其是在 #193 上的结果。

此实验如何成为 Torana: 转折故事 →

——

广告 广告
🧑‍💻

zhirenhun

一个热爱技术的程序员,喜欢分享前沿AI知识和开发经验。

ai llm opensource deepseek