Claude Code后台摘要功能致成本激增,开发者发布抑制脚本

Claude Code后台摘要功能致成本激增,开发者发布抑制脚本。该功能自2.1.232版起默认开启且无法关闭,额外开销占比达18-26%。Flamerix AI推出Bun预加载脚本,通过拦截定时器实现抑制。

近日,开发者 Flamerix AI 发布了一项针对 Claude Code 的技术分析,揭示了该工具在后台运行时的一个隐蔽行为:每隔 30 秒,Claude Code 会将每个后台代理的完整记录发送至其底层模型(通常为 Opus),要求模型用 3-5 个单词总结近期行动。这一过程不仅消耗大量计算资源,且自版本 2.1.232(2026 年 8 月)起已默认开启,用户无法通过常规设置关闭。

额外开销占比达18–26%

TL;DR

curl -fsSL https://gist.githubusercontent.com/flamerix-ai/c3905705cc4205e5de3011fa2e74efce/raw/no-agent-summary.js -o ~/.local/share/no-agent-summary.js
claude daemon stop --any
BUN_OPTIONS="${BUN_OPTIONS:+$BUN_OPTIONS }--preload $HOME/.local/share/no-agent-summary.js" claude

上述命令旨在通过预加载脚本抑制该行为,需在每个 Claude Code 进程中生效。

问题背景与成本影响

测试显示,在 Linux 系统上运行的 Claude Code 2.1.257–2.1.312 版本中,二进制文件未被修改时,该“代理摘要”功能依然活跃。尽管生成的摘要仅用于更新代理面板的状态行,从未进入模型上下文或用户对话历史,但其产生的 API 请求成本高昂。

根据 OpenTelemetry 出口数据监测,标记为 query_source = agent_summary 的 claude_code.api_request 事件,其估算成本甚至高于主对话本身。这里的“Spend”指每次请求的内部估算成本(cost_usd)。在订阅模式下,这意味着速率限制额度的快速消耗。社区讨论(如 Issue #86879)汇总的四项独立测量结果显示,该功能导致的额外开销占比达 18–26%。

技术原理:如何通过 Bun Preload 拦截

Flamerix AI 提供的解决方案是一个约 80 行的 Bun 预加载脚本 no-agent-summary.js。其核心逻辑如下:

  • 包裹定时器函数:脚本重写了 setTimeout 和 setInterval。当回调函数的源文本中包含特定标识(如 [AgentSummary] 日志行)时,返回一个惰性句柄而非激活计时器。
  • 识别机制:由于 Claude Code 模块以预编译的 Bun 字节码形式分发,直接修改 JS 文本无效,且 API 客户端不经过包装后的 globalThis.fetch。然而,Function.prototype.toString 仍能返回从字节码运行的回调源码,因此可通过字符串匹配识别目标计时器。
  • 惰性延迟处理:被抑制的定时器使用接近 2^31−1 ms 的延迟值。Node 和 Bun 将超过此值的延迟视为 1 ms,从而实现“无限”延迟效果而不立即触发。

在 OpenTelemetry 导出中,被成功抑制的请求表现为 query_source = agent_summary 的事件消失。

安装步骤与环境配置

为确保在所有进程中生效,需执行以下步骤:

  1. 部署脚本:将 no-agent-summary.js 放置于稳定路径,并记录绝对路径。
  2. 配置全局环境变量:设置 BUN_OPTIONS 以包含预加载参数。根据不同 Shell 环境,配置方式如下:
    • Bash/Zsh (~/.profile, ~/.bashrc, ~/.zshrc):
      export BUN_OPTIONS="${BUN_OPTIONS:+$BUN_OPTIONS }--preload /abs/path/no-agent-summary.js"
    • Fish (~/.config/fish/config.fish):
      set -gx BUN_OPTIONS "--preload /abs/path/no-agent-summary.js"
    • Systemd User Environment (~/.config/environment.d/50-no-agent-summary.conf):
      BUN_OPTIONS=--preload /abs/path/no-agent-summary.js

    或者,创建一个名为 claude 的包装脚本置于 PATH 优先位置,以确保子进程继承该选项:

    #!/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 "$@"
  3. 重启服务:必须停止现有守护进程以清除旧环境:claude daemon stop --any。

注意事项与平台兼容性

  • 重启必要性:服务器、PTY 主机和预热的 bg-spare 会话会继承启动时的客户端环境。若在设置 BUN_OPTIONS 前启动的服务仍在运行,它们将继续产生未受抑制的会话。
  • 无头模式支持:该修复同样适用于 claude-p、cron 任务、CI 流程及编辑器集成。
  • 平台限制:目前仅在 Linux 上经过测试。macOS 和 Windows 尚未验证。在 Windows 上,/$bunfs/ 挂载点可能无法正确安装子模块。
  • 调试模式:设置 CC_AGENT_SUMMARY_MODE=summarize 可恢复原有行为,用于对比验证。
  • 后台进程检查:确保 daemon、pty host 和 bg-spare 的环境变量中包含 --preload 参数(Linux 下可通过 /proc/<pid>/environ 查看)。

验证方法

每次软件更新后,建议重新执行以下验证步骤:

  1. 预加载检查:
    BUN_OPTIONS="--preload $HOME/.local/share/no-agent-summary.js" CC_AGENT_SUMMARY_LOG=/tmp/nas.log claude --version && cat /tmp/nas.log

    预期输出应包含“preload active mode=off...”。若无输出,说明 BUN_OPTIONS 未传递至进程或路径非绝对路径。

  2. 定时器抑制检查:

    使用相同环境变量运行后台子代理 1-2 分钟。日志应显示类似 summary timer #1 suppressed (setTimeout, delay=30000) 的信息,且代理面板状态不再更新。若启用 OpenTelemetry 导出,query_source = agent_summary 计数应保持为零。这是捕获所有故障模式的唯一可靠指标。

潜在失效风险

该方案依赖于对回调源文本的字符串匹配。若 Anthropic 更新导致以下变化,抑制功能可能静默失效:

  • 日志行名称或查询源 ID 被更名。
  • 回调通过 fn.bind(...) 或其他包装器传递,导致 toString 无法获取原始源码。
  • 关键字符串移至回调外部的共享常量中。
  • 定时器逻辑迁移至未封装的 API(如原生 Timer/Promise 调度循环)。

实际效果与性能影响

  • 成本节约:在 Claude Code 2.1.301 版本的实测中,应用补丁后 agent_summary 请求完全消失,且无其他侧查询替代。
  • 功能完整性:副代理、后台代理、分叉技能和背景会议均正常运行,仅跳过摘要生成步骤。
  • 可见变化:代理面板的状态行停止更新;SDK 的 task_progress 字段不再包含摘要信息。
  • 性能开销:由于引入了 Function.prototype.toString 差异检查和 WeakMap 缓存,启动时间略有增加。实测 claude --version 耗时从约 10ms 增至约 17ms。

为何官方未提供开关?

分析指出,目前不存在有效的用户端配置来禁用此功能:

  • 文档误导:SDK 选项 agentProgressSummaries 默认值为 false,但在捆绑代码中它是 OR 逻辑的一项,且所有写入路径均强制设为 true。环境变量 CLAUDE_CODE_AGENT_PROGRESS_SUMMARIES 仅能启用摘要,无法禁用。
  • 服务器控制:该区间由服务器标志控制,源自每个模型的配置,并被硬编码在 30s 到 30.240s 之间。没有任何用户端值可以禁用计时器。
  • 无效的环境变量:某些第三方包装器设置的 DISABLE_NON_ESSENTIAL_MODEL_CALLS 在二进制文件中根本不存在。CLAUDE_CODE_FORK_SUBAGENT=0 和 CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1 虽能阻止该行为,但代价是同时禁用了分叉和后台代理功能。
  • 缓存局限性:虽然约 98% 的电话命中了缓存中的记录,但这并未显著降低成本,仍占总成本的三分之一以上。
  • 透明度缺失:这些请求不会写入磁盘上的会话日志(参见 Issue #104358),只有 OpenTelemetry 出口可见。文件关于后台代币使用的部分也未列出此项,而 Agent View 的行摘要记录为每隔几分钟更新的廉价类模型调用。
  • 更便宜的变种存在但未开放:版本 2.1.310 引入了一种发送简短提示(约 2k 笔记代码而非完整成绩单)并由较小模型撰写的变种,但该功能仅能通过服务器标志更改,用户无法自行切换。

支出趋势时间表 (2026)

远程测量数据显示,该功能的每周支出份额呈上升趋势:从 7 月份的 3.57%(当时分叉门控对用户开放)上升至 7.3%,随后在接收到的每周数据中增至 11.8%,并于 10 月中旬达到 16%。

许可与免责声明

该项目基于 MIT License © 2026 Flamerix AI。软件按“原样”提供,无任何明示或暗示的保证。使用者需自行承担风险,Flamerix AI 不对因使用本工具造成的损害、数据丢失或账户操作负责。

需要注意的是,修改客户端运行时行为可能与 Anthropic 的服务条款相冲突,用户应在使用前自行核实合规性。“Claude”和“Claude Code”是 Anthropic PBC 的商标。本项目独立开发,与 Anthropic 无任何关联、赞助或认可关系。

评论 0

0/500

评论需审核后展示,请文明发言

💬
还没有评论,来说两句

相关阅读