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)时,脚本返回无效句柄以阻止定时器启动,同时不影响其他正常定时任务。

实施步骤

  1. 保存脚本:将 no-agent-summary.js 存放于稳定位置,并记录其绝对路径。
  2. 设置环境变量:为确保全局生效,需设置 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 "$@"
  1. 重启服务:执行 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 并提升响应效率。