
Claude Code 被指存在严重的隐性 Token 消耗问题。自 2.1.232 版本(2026 年 8 月)起,该工具默认开启一项后台功能,导致高达 20% 的计算资源被无效占用,且官方未提供关闭入口。目前,技术社区已通过代码注入方式给出了解决方案。
核心问题:每 30 秒全量上传对话
该功能旨在更新代理面板的状态行。每隔约 30 秒,Claude Code 会将每个后台代理(Agent)的完整对话转录内容发送至专属模型(通常为 Opus),要求模型用 3-5 个字描述近期动作。这些摘要仅用于界面显示,不进入主对话,也不影响模型判断。
这一异常最初由用户通过 OpenTelemetry 导出数据发现。统计显示,agent_summary 产生的成本甚至超过了主对话本身。独立测量数据显示,该功能消耗的 Token 比例在 18%-26% 之间。对于订阅制用户而言,主要损失体现为速率限制额度的快速耗尽。
query_source = agent_summary | 启用前一周 | 禁用后两天 |
|---|---|---|
| 占 Claude Code 总花费比例 | 16.4% (主对话: 15.7%) | 0% |
| 占所有 API 请求比例 | 19.7% (约五分之一) | 0% |
| 其中 Opus 模型占比 | 96% | — |
| 输入 Token 与输出 Token 比率 | ≈ 9,000 : 1 | — |
屏蔽方案原理
由于 Claude Code 模块以预编译的 Bun 字节码形式分发,直接编辑 JS 文本无效,且 API 客户端不经过包装的 globalThis.fetch,因此常规的网络拦截或二进制修改难以生效。但 Function.prototype.toString 仍能返回回调函数的源码,这为识别特定定时器提供了可能。
解决方案基于一个名为 no-agent-summary.js 的 Bun preload 脚本(约 80 行代码)。该脚本拦截 setTimeout 和 setInterval:当检测到回调函数源码中包含特定摘要标识符(如日志行 [AgentSummary] Timer fired)时,脚本返回无效句柄以阻止定时器启动,同时不影响其他正常定时任务。
实施步骤
- 保存脚本:将
no-agent-summary.js存放于稳定位置,并记录其绝对路径。 - 设置环境变量:为确保全局生效,需设置
BUN_OPTIONS。可根据 Shell 环境选择以下任一配置:
# ~/.profile, ~/.bashrc, ~/.zshrc
export BUN_OPTIONS="${BUN_OPTIONS:+$BUN_OPTIONS }--preload /abs/path/no-agent-summary.js"# ~/.config/fish/config.fish
set -gx BUN_OPTIONS "--preload /abs/path/no-agent-summary.js"# ~/.config/environment.d/50-no-agent-summary.conf (systemd user env)
BUN_OPTIONS=--preload /abs/path/no-agent-summary.js或者创建一个优先于 PATH 加载的 claude 包装脚本:
#!/bin/sh
HOOK=/abs/path/no-agent-summary.js
case " ${BUN_OPTIONS-} " in
*" --preload $HOOK "*);;
*) export BUN_OPTIONS="${BUN_OPTIONS:+$BUN_OPTIONS }--preload $HOOK";;
esac
: "${CC_AGENT_SUMMARY_LOG:=${XDG_RUNTIME_DIR:-/tmp}/no-agent-summary.log}"
export CC_AGENT_SUMMARY_LOG
exec /path/to/the/real/claude "$@"- 重启服务:执行
claude daemon stop --any停止守护进程,并重启会话。
验证与注意事项
- 必须重启:旧进程会继承未设置
BUN_OPTIONS的环境,继续产生无用请求,因此安装后务必重启守护进程。 - 平台兼容性:该方案已在 Linux x64 上测试通过。macOS 和 Windows 尚未进行全面测试,Windows 上可能因文件系统路径差异导致挂钩失败。
- 效果验证:软件更新后,建议运行
claude --version并检查日志。若出现preload active mode=off字样,且后台代理状态不再更新、OpenTelemetry 中query_source = agent_summary请求归零,即表示屏蔽成功。
为何缺乏官方开关?
分析指出,该功能之所以无法通过常规配置关闭,原因包括:
- 代码逻辑强制开启:尽管 SDK 选项
agentProgressSummaries默认为 false,但代码中所有写入该变量的路径均强制设为 true,导致配置失效。 - 服务端控制间隔:定时器间隔由服务端标志位决定(30-240 秒),默认即为最小值,客户端无法通过配置禁用。
- 环境变量局限:常见的禁用变量如
DISABLE_NON_ESSENTIAL_MODEL_CALLS在二进制文件中不存在;其他变量如CLAUDE_CODE_FORK_SUBAGENT=0虽能阻止摘要,但会连带禁用后台代理功能。 - 缓存掩盖成本:虽然 98% 的请求命中缓存,但冷缓存请求成本显著,且这些请求未写入本地会话日志,普通监控工具难以察觉。
该功能自 2026 年 2 月首次出现在代码中,同年 8 月默认开启。目前,它已成为一个占用大量资源却对用户体验贡献有限的“隐形”负担。通过上述技术手段屏蔽该请求,可有效节省 Token 并提升响应效率。