成本优化指南
Claude Code token 用量:让工具输出远离上下文
PreToolUse 钩子和 context-mode 插件如何让测试日志远离 Claude Code 的上下文,并附上过滤与不过滤的会话成本估算。

本页内容
你的 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 - 管道。这样 agent 只会看到失败项加上几行上下文,而不是 10,000 行绿点。文档说这可以把数万 token 变成几百 token。

这是该文档页面上的脚本(2026 年 10 月 23 日查看)。它需要 jq。用 mkdir - 创建文件夹,把脚本保存为 ~/,然后对它运行 chmod +x:
#!/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然后在 ~/ 中注册它:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "~/.claude/hooks/filter-test-output.sh" }]
}
]
}
}要检查是否生效,在 Claude Code 中打开 /hooks,查找 PreToolUse 条目,或者用 claude - 启动并让 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 中安装:
/plugin marketplace add mksglu/context-mode
/plugin install context-mode@context-mode重启或运行 /reload-plugins,然后用 / 验证。仅 MCP 的变体 claude mcp add context- 会添加工具,但没有自动路由。
该项目报告了大幅缩减: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/,180K 上下文,最多 8,192 输出 token)的实时价格见下图,它是最适合这种输入密集型 agent 循环的模型。
假设: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。简版如下,使用占位密钥:
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。
快速检查清单#
- 在长会话中运行
/context,看看什么在占用空间。 - 为测试命令添加 Bash 钩子;在
/hooks或调试日志中确认重写。 - 如果 MCP 工具返回大快照,试试 context-mode,并比较前后的
/context。 - 在不相关的任务之间
/clear,让旧日志不再随行。



