返回博客

成本优化指南

Claude Code token 用量:让工具输出远离上下文

PreToolUse 钩子和 context-mode 插件如何让测试日志远离 Claude Code 的上下文,并附上过滤与不过滤的会话成本估算。

作者:CheapTokens Team发布于 5 分钟阅读

终端显示测试命令通过 grep 和 head 管道,只有失败项到达 Claude Code
本页内容
  1. 为什么一份日志要付很多次钱
  2. 方案 1:用 PreToolUse 钩子过滤测试输出
  3. 方案 2:用 context-mode 处理大型工具结果
  4. 一次长会话的成本,过滤与不过滤
  5. 在 CheapTokens 模型上运行 Claude Code
  6. 快速检查清单

你的 agent 运行了三次测试套件,账单却比任务本身还大。原因很少是它写的代码,而是测试日志:一旦某个工具结果进入 Claude Code 的上下文,之后每一次请求都会再次携带它。解决办法是在模型看到工具输出之前就把它缩小。官方做法是在 Bash 上挂一个 PreToolUse 钩子;第三方做法是 context-mode 插件。下面两种都有,并附上在 CheapTokens 模型上跑一次长会话的成本估算。

为什么一份日志要付很多次钱#

根据 Claude Code 成本页面(https://code.claude.com/docs/en/costs,2026 年 10 月 23 日查看),Claude Code 每次请求都会发送完整对话,而每次工具调用都会触发另一次请求,并携带工具结果。提示缓存会以更便宜的缓存价格重新读取历史,但 token 仍然在那里。

假设 agent 运行 npm test 并得到一份 10,000 行的日志。文档说这种日志可能有数万 token。假设是 30,000 token。无论你接下来做什么,这 30,000 token 都会成为第 11 步、第 12 步、第 13 步……直到你 /clear 或压缩之前的输入的一部分。问题就在这里:日志只对一步有用,你却要为它付三十步的钱。

方案 1:用 PreToolUse 钩子过滤测试输出#

同一份文档页面建议用钩子做预处理:在 Bash 上挂一个 PreToolUse 钩子,重写测试命令(npm test、pytest、go test),让它们通过 grep -A 5 -E '(FAIL|ERROR|error:)' | head -100 管道。这样 agent 只会看到失败项加上几行上下文,而不是 10,000 行绿点。文档说这可以把数万 token 变成几百 token。

钩子生效前后 agent 看到的内容
原始 npm test 输出与仅失败项对比

这是该文档页面上的脚本(2026 年 10 月 23 日查看)。它需要 jq。用 mkdir -p ~/.claude/hooks 创建文件夹,把脚本保存为 ~/.claude/hooks/filter-test-output.sh,然后对它运行 chmod +x:

bash
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')

pattern='^(npm test|pytest|go test)( [^;&|<>`$#\\[:cntrl:]]*)?$'

if [[ "$cmd" =~ $pattern ]]; then
  filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
  echo "$input" | jq --arg filtered "$filtered_cmd" '{hookSpecificOutput: {hookEventName: "PreToolUse", updatedInput: (.tool_input + {command: $filtered})}}'
else
  echo "{}"
fi

然后在 ~/.claude/settings.json 中注册它:

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/filter-test-output.sh" }]
      }
    ]
  }
}

要检查是否生效,在 Claude Code 中打开 /hooks,查找 PreToolUse 条目,或者用 claude --debug-file ./claude-debug.txt 启动并让 agent 运行 npm test。当钩子重写了命令时,文件中会有一行 modified tool input keys,带有 command 字段。如果测试通过,输出为空,agent 会得到一个安静的成功;如果你的测试运行器打印失败的方式不同,请调整模式。

方案 2:用 context-mode 处理大型工具结果#

钩子只能覆盖你能通过管道处理的命令。Playwright 的页面快照或二十个 GitHub issue 的列表来自 MCP 工具。这正是 context-mode 的目标。根据其 README(https://github.com/mksglu/context-mode,2026 年 10 月 23 日查看;未显示版本或日期),它是一个 MCP 服务器和插件,把原始工具输出挡在上下文窗口之外,将会话状态存储在 SQLite 中,并通过钩子路由工具调用。它需要 Claude Code v1.0.33 或更新版本,许可证是 Elastic License 2.0,这不是 OSI 开源许可证。

在 Claude Code 中安装:

text
/plugin marketplace add mksglu/context-mode
/plugin install context-mode@context-mode

重启或运行 /reload-plugins,然后用 /context-mode:ctx-doctor 验证。仅 MCP 的变体 claude mcp add context-mode -- npx -y context-mode 会添加工具,但没有自动路由。

该项目报告了大幅缩减:315 KB 变成 5.4 KB(98%),56 KB 的页面快照变成 299 字节,986 KB 变成 62 KB。这些是作者自己的数字:把它们当作上限,并在你自己的会话中用 /context 前后测量。

一次长会话的成本,过滤与不过滤#

以下是对一个假设会话的算术。这是一个 40 步的编码会话,平均基础上下文 20,000 token,每步输出 500 token,在第 10、20、30 步各运行一次测试。每份原始日志是 30,000 token;过滤后是 500。

  • 第 10 步的日志会在其后的 30 次请求中重新发送:30 × 30,000 = 900,000 token。第 20 步:20 × 30,000 = 600,000。第 30 步:10 × 30,000 = 300,000。额外输入:900,000 + 600,000 + 300,000 = 1,800,000。
  • 过滤后:(30 + 20 + 10) × 500 = 30,000 额外输入。
  • 基础输入:40 × 20,000 = 800,000。输出:40 × 500 = 20,000。
  • 因此,不过滤的会话是 800,000 + 1,800,000 = 2,600,000 输入 token,过滤后是 800,000 + 30,000 = 830,000,两种情况下输出都是 20,000 token。

该计算按全价计算每个输入 token。缓存会降低实际数字,但按同样的逻辑也会降低两种情况。MiniMax-M2.7(MiniMaxAI/MiniMax-M2.7,180K 上下文,最多 8,192 输出 token)的实时价格见下图,它是最适合这种输入密集型 agent 循环的模型。

MiniMax-M2.7 上的会话成本,40 步
  • 不过滤$0.133
  • 使用钩子$0.0445

假设:40 步,基础上下文 20,000 token,每步输出 500 token,三次 30,000 token 的测试运行(过滤后:500)。

在 MiniMax-M2.7 上,不过滤的会话成本为 $0.133,过滤后为 $0.0445,并且把输入和输出加在一起算,比 OpenRouter 的参考价格更便宜。不过滤情况下大约三分之二的输入是 agent 只读了一次的日志。

重点不是确切的美元数。而是过滤器在任何模型上都能从 2,600,000 输入 token 中移除约 1,770,000(2,600,000 − 830,000 = 1,770,000),而更便宜的模型会降低剩余每个 token 的价格。

在 CheapTokens 模型上运行 Claude Code#

Claude Code 使用 Anthropic Messages 协议,CheapTokens 支持它。Claude Code 的基础 URL 没有 /v1。完整设置见如何将 Claude Code 连接到 CheapTokens。简版如下,使用占位密钥:

bash
export ANTHROPIC_BASE_URL=https://api.cheaptokens.dev
export ANTHROPIC_AUTH_TOKEN=YOUR_CHEAPTOKENS_KEY
export ANTHROPIC_MODEL=MiniMaxAI/MiniMax-M2.7
claude

使用文档中的完整 id;价格表中的短名称不被 API 接受。所有模型的价格在定价页面上。其他削减 Claude Code 账单的习惯(/clear、/compact、/mcp、子 agent),见如何让 Claude Code 更便宜。要了解真实请求中如何计算输入和输出,请阅读一次 API 请求使用多少 token。

快速检查清单#

  1. 在长会话中运行 /context,看看什么在占用空间。
  2. 为测试命令添加 Bash 钩子;在 /hooks 或调试日志中确认重写。
  3. 如果 MCP 工具返回大快照,试试 context-mode,并比较前后的 /context。
  4. 在不相关的任务之间 /clear,让旧日志不再随行。