首页
/ ECC Hook 故障规避实战指南:Claude Code 上游 Hook 相关 Bug 的高信号修复方案

ECC Hook 故障规避实战指南:Claude Code 上游 Hook 相关 Bug 的高信号修复方案

2026-09-08 18:28:01作者:沈韬淼Beryl

导读:本文围绕 ECC(Everything Claude Code)仓库中 docs/hook-bug-workarounds.md 记录的社区验证型规避方案展开,聚焦 Claude Code 上游行为对 Hook 重度使用场景造成的五类干扰:误报的 Hook Error 标签、比预期更早发生的上下文压缩、压缩后 MCP 认证看似存活实则失效、Hook 修改不热重载,以及高负载下的反复 529 Overloaded。读完本文,你将掌握每类问题的可落地操作步骤、正确的 Hook 退出码语义、相关环境变量的取值与作用,以及如何借助 ECC 的 strategic-compact 技能和 Token 优化配置降低问题触发概率。


1. 先厘清问题边界:上游 Claude Code 行为,而非 ECC 缺陷

ECC 是一套为 Claude Code、Codex、Opencode、Cursor 等 Agent Harness 提供 skills、instincts、memory、security 与 research-first 开发能力的插件体系。由于 ECC 大量使用 Hook 做自动化守卫(详见仓库根的 hooks/README.md),Claude Code 自身的任何 Hook 相关缺陷都会被放大。

本文记录的五类问题有一个共同前提:它们是上游 Claude Code 的行为,不是 ECC 的 Bug(原文表述为 "upstream Claude Code behaviors, not ECC bugs")。因此在修复思路上不应对 ECC 本身做破坏性改动,而是采用"临时规避 + 等待上游修复"的策略。与 docs/TROUBLESHOOTING.md 中更宽泛的排障面不同,本页面刻意保持窄聚焦,只收录社区验证过的高信号操作修复,不重复投机性、无依据的配置建议。

这些规避方案源自社区在 issue #644 中汇总的生产实测报告,测试环境为 Claude Code v2.1.79(macOS、重度 Hook 使用、启用 MCP 连接器),可作为方案适用性的参考前提。

何时使用本页:当你正在调试以下任一具体症状时——

  • 本来执行成功的 Hook 却被错误标记为 Hook Error
  • 上下文压缩比预期发生得更早;
  • MCP 连接器界面显示已认证,但压缩后调用失败;
  • 修改 Hook 后没有热重载生效;
  • 在 Hook/工具调用高压下反复收到 529 Overloaded 响应。

2. 高信号规避方案一:处理"假" Hook Error 标签

2.1 症状与根因

Hook 实际执行成功,但 Claude Code 仍会在转录(transcript)中显示 Hook Error。根据仓库 hooks/README.md 对 Hook 工作流的定义,Claude Code 会向 Hook 进程通过 stdin 传入 JSON,并期望进程按约定消费输入、以规定的退出码结束。当 shell Hook 没有消费 stdin 管道时,父进程会观测到"未被消费的管道",从而误判为异常。

2.2 推荐做法(四项规则)

  1. 在 Hook 开头立即消费 stdin:shell Hook 用 input=$(cat);Node 等语言 Hook 则监听 stdin 数据并在 end 事件中处理(后文给出 JS 示例)。
  2. 对简单的 allow/block Hook 保持 stdout 安静:除非 Hook 实现明确需要结构化 stdout,否则不要向 stdout 输出;把人类可读的诊断信息发送到 stderr
  3. 对无关紧要的子进程 stderr 做重定向:当子进程的报错不可操作时,将其丢弃,避免干扰 Hook 的判定。
  4. 使用正确的退出码0 表示放行(allow),2 表示阻止(block),其他非零退出码一律被当作错误处理

2.3 标准示例:阻止并附原因

# 好做法:消费 stdin → stderr 输出诊断 → exit 2 阻止
input=$(cat)
echo "[BLOCKED] Reason here" >&2
exit 2

这一退出码约定与仓库中 Hook 架构规范完全一致:rules/common/hooks.md 明确 PreToolUse Hook 可阻止(exit code 2)或警告(仅 stderr 不阻止)hooks/README.md 亦将退出码总结为:0 成功继续、2 阻止工具调用(仅 PreToolUse)、其他非零视为错误(记录但不阻止)。

2.4 Node Hook 对应的写法

ECC 的 Hook 逻辑大量以 Node.js 实现以保证跨平台(见 hooks/README.md 的 Cross-Platform Notes)。等价写法如下:

// my-hook.js —— 消费 stdin,输出诊断到 stderr,回写原数据到 stdout
let data = '';
process.stdin.on('data', chunk => data += chunk);
process.stdin.on('end', () => {
  const input = JSON.parse(data);
  const toolName = input.tool_name;   // "Bash"、"Edit"、"Write"...
  const toolInput = input.tool_input; // 工具专属参数

  console.error('[Hook] Warning message shown to Claude'); // 警告(不阻止)
  // process.exit(2);  // PreToolUse 阻止时使用
  console.log(data);                  // 原样回写 stdout
});

排查验证:可手动把一条工具调用 JSON 通过管道喂给 Hook 脚本,确认退出码与输出符合预期,例如:

echo '{"tool_name":"Bash","tool_input":{"command":"echo test"}}' | bash path/to/hook.sh
echo "exit code: $?"

3. 高信号规避方案二:压缩比预期更早发生

3.1 症状与反直觉行为

在部分当前 Claude Code 构建版本中,降低 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 非但没有延后自动压缩,反而让压缩更早发生("Lowering causes compaction to happen sooner, not later")。

从仓库证据看,这个变量在 ECC 的 Token 优化推荐里默认被设为 50(默认行为为 95),见 README.md 的推荐 settings;但 docs/token-optimization.md 特别添加了"Community note on auto-compaction overrides":部分新版 Claude Code 中该覆盖值只能下调压缩阈值,即低于默认值会提前压缩。

3.2 推荐做法

  1. 如果你希望获得更多工作空间,直接移除 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE,不要试图通过把它设得更低来延后压缩。
  2. 在自然的任务边界手动执行 /compact,掌握压缩时机的主动权。
  3. 改用 ECC 的 strategic-compact 指导,而不是强制压低自动压缩阈值(详见第 6 节)。

3.3 在哪里配置 / 移除

该变量位于 ~/.claude/settings.jsonenv 块,或当前 shell 环境变量:

{
  "model": "sonnet",
  "env": {
    "MAX_THINKING_TOKENS": "10000",
    "CLAUDE_CODE_SUBAGENT_MODEL": "haiku"
  }
}

即从 env 中删去 "CLAUDE_AUTOCOMPACT_PCT_OVERRIDE" 一行即可让 Claude Code 回到原生压缩行为。


4. 高信号规避方案三:MCP 认证看似存活、压缩后却失败

4.1 症状

以 Gmail、Google Drive 等 MCP 工具为例:会话压缩之后工具调用开始报错,但连接器在界面中仍然显示已认证。这属于压缩后认证态失效的恢复问题,而非永久性损坏。

4.2 推荐做法

  1. 压缩后将该连接器关闭再重新打开(toggle off / back on),强制刷新认证状态。
  2. 如果当前 Claude Code 构建支持 PostCompact 事件,可添加一个轻量级提醒 Hook,在每次压缩后提醒你复查连接器认证。仓库的插件清单测试已把 PostCompact 纳入受支持的 Hook 事件枚举,见 tests/plugin-manifest.test.js
  3. 把它当作"恢复提醒"而非"永久修复"——上游修复落地前,每次压缩后都需人工或靠提醒 Hook 复查。

一个轻量提醒 Hook 的示意(写入你的 Claude Code settings,或用 ECC 插件方式注册):

{
  "hooks": {
    "PostCompact": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"[ECC] After compaction, re-check MCP connector auth state (toggle off/on if needed)\""
          }
        ],
        "description": "PostCompact reminder to re-verify MCP connector auth"
      }
    ]
  }
}

说明:ECC 自身的 PreCompact Hook 承担的是压缩前保存状态的职责(见 hooks/hooks.jsonpre:compact 条目与 hooks/README.md 的 Lifecycle Hooks 表),与上述"压缩后提醒"的诉求互补。Hook 输入均为 JSON 且通过 stdin 传入、stdout 输出 JSON,符合第 2 节描述的统一契约。


5. 高信号规避方案四:Hook 修改不热重载

5.1 症状

修改 settings.json 中的 Hook 后不生效,直到重启会话。这与 Claude Code 会话加载 Hook 配置的时机有关——Hook 定义在会话启动阶段被读取。

5.2 推荐做法

  1. 修改 Hook 后重启 Claude Code 会话,这是文档确认的可靠手段。
  2. 高级用户有时会借助 shell 本地重载辅助手段(例如在 /reload 命令周围封装 kill -HUP $PPID),但 ECC 没有内置这样的脚本——因为这类做法与 shell、平台强相关(原文:"ECC does not ship that because it is shell-dependent and not universally reliable")。请不要期待在 ECC 中找到一键重载命令。

5.3 如何避免频繁手改 Hook 配置

ECC 推荐用环境变量做运行时控制而非每次编辑 hooks.json(详见 hooks/README.md 的 Runtime Hook Controls 小节):

# 主开关。显式环境值优先于插件偏好。
export ECC_HOOKS_ENABLED=true

# minimal | standard | strict(默认:standard)
export ECC_HOOK_PROFILE=standard

# 按逗号分隔禁用指定 Hook ID
export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"

# 在 setup/恢复期间单独关闭 GateGuard
export ECC_GATEGUARD=off

# 限制 SessionStart 附加上下文(默认 8000 字符)
export ECC_SESSION_START_MAX_CHARS=4000

# 完全关闭 SessionStart 附加上下文
export ECC_SESSION_START_CONTEXT=off

# 保留上下文/范围/循环警告,仅关闭 API 费率成本估算提示
export ECC_CONTEXT_MONITOR_COST_WARNINGS=off

Windows PowerShell 设置用户级环境变量:

[Environment]::SetEnvironmentVariable('ECC_CONTEXT_MONITOR_COST_WARNINGS', 'off', 'User')

Hook profile 含义(同样来自 hooks/README.md):

  • minimal —— 只保留必要生命周期与安全 Hook;
  • standard —— 默认档,均衡的质量 + 安全检查(suggest-compact 等 Hook 在此档激活);
  • strict —— 额外提醒与更严格的护栏。

插件安装场景可直接在 hooks/hooks.json 中看到这些 Hook 的注册方式:例如 pre:edit-write:suggest-compact 通过 run-with-flags.js 限定在 standard,strict 档生效。注意:手动安装场景下不要把仓库内的原始 hooks.json 直接粘贴进 ~/.claude/settings.json,请使用 ECC 安装器(bash ./install.sh --target claude --modules hooks-runtime --enable-hooks 或 Windows 的 pwsh -File .\install.ps1 ...),安装器会把 Hook 命令重写到你的真实 Claude 根目录(hooks/README.md 的 Installing Hooks Manually 一节)。


6. 高信号规避方案五:反复出现 529 Overloaded

6.1 症状

在 Hook/工具调用/上下文高压下,Claude Code 开始频繁返回 529 Overloaded。本质是单请求的"工具定义 + 隐藏思考 Token + 上下文"压力过大,导致服务端过载或配额紧张。

6.2 推荐做法(按优先级)

手段 配置 作用原理 / 出处
降低工具定义压力 ENABLE_TOOL_SEARCH=auto:5(若你的构建支持) 减少每次暴露给模型的工具定义数量,前提是你的 Claude Code 版本开放该开关
例行工作降低思考预算 MAX_THINKING_TOKENS=10000(默认 31,999) Extended Thinking 每请求最多预留 31,999 个输出 Token 做内部推理,调低约可削减 ~70% 隐藏成本(README.mddocs/token-optimization.md
子代理路由到廉价模型 CLAUDE_CODE_SUBAGENT_MODEL=haiku(若暴露该旋钮) Subagent(Task 工具)用 Haiku 跑探索、读文件、跑测试,成本约低 ~80%
按项目禁用无用 MCP 服务器 运行 /mcp 关闭,或用 ECC_DISABLED_MCPS 每个启用的 MCP 服务器都会向上下文加入工具定义;docs/token-optimization.md 提醒每项目启用数尽量控制在 10 个以下,优先用 CLI(ghaws)替代 MCP
在自然断点手动压缩 手动 /compact 避免等自动压缩在任务中途触发,降低峰值上下文压力(详见第 7 节)

一个贴合 ECC 推荐的整体配置(加入 ~/.claude/settings.json):

{
  "model": "sonnet",
  "env": {
    "MAX_THINKING_TOKENS": "10000",
    "CLAUDE_CODE_SUBAGENT_MODEL": "haiku"
  }
}

对应快捷命令:/model sonnet(日常主力)、/model opus(复杂架构推理)、/clear(无关任务之间)、/compact(逻辑断点)、/cost(监控花费)。

6.3 关于 MCP 的补充细节

  • 运行时即时开关请使用 /mcp 命令(Claude Code 会把运行时禁用持久化在 ~/.claude.json);不要在 .claude/settings.json / .claude/settings.local.json 里试图禁用已加载的 MCP 服务器。
  • ECC_DISABLED_MCPS 仅影响 ECC 在安装/同步流程(如 install.shnpx ecc-universal install、Codex MCP 合并)中生成的 MCP 配置输出,不是运行时的 Claude Code 开关。
  • ECC 自带的 memory MCP 默认被配置但当前不被任何 skill/agent/hook 使用,可考虑禁用。

7. 纵深:用 strategic-compact 取代"强制压低阈值"

ECC 为"何时压缩"提供了比手动经验更精确的实现:skills/strategic-compact/ 中的 suggest-compact.js 脚本在 PreToolUse(Edit/Write)上运行,综合两个信号给出 /compact 建议:

  1. 上下文体积(主信号):读取会话转录中最新 usage 记录,求和 input_tokens + cache_read_input_tokens + cache_creation_input_tokens(该轮的真实上下文大小),并按窗口缩放阈值触发建议——200K 窗口约 160K Token,1M 窗口约 250K Token(从 [1m] 模型标记检测,或当观测 Token 已超 200K 时推断),之后每再增长 60K Token 重复提醒。
  2. 工具调用次数(次信号):统计会话内工具调用,默认达到 50 次给出首次建议,此后每 25 次再提醒。

其插件侧注册可见于 hooks/hooks.jsonpre:edit-write:suggest-compact(Hook ID 同名字段,激活于 standardstrict 档)。相关可调环境变量:

变量 含义 默认
COMPACT_THRESHOLD 首次建议前的工具调用次数 50
COMPACT_CONTEXT_THRESHOLD 上下文建议触发的 Token 阈值(0 关闭该信号) 200K 窗口 160000 / 1M 窗口 250000
COMPACT_CONTEXT_INTERVAL 重复提醒的额外 Token 增长量 60000
COMPACT_STATE_TTL_DAYS 临时目录中过期会话状态文件的清理天数 14
ECC_CONTEXT_WINDOW_TOKENS 显式指定上下文窗口 Token 数,覆盖自动检测 未设置
CLAUDE_CODE_AUTO_COMPACT_WINDOW Claude Code 原生窗口大小覆盖(前项未设时的回退) 未设置

压缩决策速查(何时该压缩 / 何时不该):

  • 该压缩:研究 → 规划完成后;里程碑完成后;调试结束、转向新工作前;大上下文切换前。
  • 不该压缩:多文件相关改动实现中途;正在调试活跃问题时;多文件重构期间。

压缩前务必把重要状态写入文件或 memoryCLAUDE.md 指令、磁盘文件、Git 状态、memory 文件在压缩后保留;中间推理、已读过的文件内容、多轮对话上下文会丢失)。这条纪律与第 3 节"移除自动压缩覆盖 + 手动断点压缩"互为补充,共同构成 ECC 语境下对抗过早/无序压缩的完整策略。


8. 一张速查表:症状 → 首选动作

症状 首选动作 次选/补充动作
Hook Error Hook 开头 input=$(cat) 消费 stdin stdout 保持安静;诊断走 stderr;只用 0/2/其他非零对应放行/阻止/错误
压缩过早 移除 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 任务边界手动 /compact;用 strategic-compact 提示
MCP 压缩后失效 压缩后 toggle 连接器 off/on PostCompact 提醒 Hook;当作恢复提醒而非永久修复
Hook 不热重载 重启 Claude Code 会话 ECC_* 环境变量做运行时控制,减少改配置频率
反复 529 Overloaded ENABLE_TOOL_SEARCH=auto:5 MAX_THINKING_TOKENS;子代理用 haiku;按项目关无用 MCP;手动断点压缩

关键原则回顾:上述全部属于上游 Claude Code 行为,ECC 侧的正确动作是"临时规避",等待上游修复;不要用删除/重写 ECC Hook 文件的方式来"修"这些上游问题。若修改过 ECC 安装或 Hook 后出现漂移,可先运行 ecc doctor / ecc repair 这类 ECC 自身的诊断修复命令进行核对(详见 docs/TROUBLESHOOTING.md)。


9. 延伸阅读(仓库内)

  • docs/TROUBLESHOOTING.md —— 更完整的 ECC 排障面(本页对应的较完整版本,含 Dashboard、OpenCode/Termux、Cyber Safeguards 等更多主题);
  • docs/token-optimization.md —— Token 优化与上下文管理设置详解(含 MCP 管理、成本提示开关);
  • hooks/README.md —— ECC 的 Hook 生命周期、退出码约定、运行时环境变量与自定义 Hook 编写规范;
  • hooks/hooks.json —— ECC 实际注册的 Hook 图(含 pre:compactpre:edit-write:suggest-compact 等条目);
  • skills/strategic-compact/ —— 战略压缩技能与其 Hook 实现说明;
  • rules/common/hooks.md —— Hook 架构层面规范(PreToolUse/PostToolUse/Stop、权限与 TodoWrite 最佳实践);
  • scripts/hooks/ —— 各类 Hook 脚本的实际实现目录;
  • README.md —— Token 优化推荐设置与日常命令速查。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.76 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
858
1.35 K
docsdocs
暂无描述
Markdown
899
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
923
1.85 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.83 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
532
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.03 K
524
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.37 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
393