附录 C

故障排除

常见问题的诊断方法和解决方案

按症状组织。无冗余描述。直接查找你的问题。

Bash 环境变量不持久

症状: 在一个 bash 命令中设置的环境变量在后续命令中不可用。依赖 export 的脚本静默失败。

原因: 每个 bash 命令在全新的 shell 环境中运行。工作目录会保留;其他一切(变量、别名、shell 函数)都不会保留。

修复:

  • 使用 && 在单次 bash 调用中链式执行依赖命令
  • 将变量写入文件并 source 它:echo "export FOO=bar" > .env && source .env && echo $FOO
  • 在 CLAUDE.md 中记录所需的环境变量,以便 Claude 在每个命令中设置它们

上下文耗尽(Claude 遗忘指令)

症状: Claude 不再遵循 CLAUDE.md 规则,产生不一致的输出,放弃多步骤计划中的任务,或"遗忘"对话早期做出的决策。

原因: 上下文窗口已满或接近满。自动压缩已总结了之前的对话,丢失了细节。不在 CLAUDE.md 中的指令不会通过压缩保留。

修复:

  • 将关键规则移至 CLAUDE.md 的"Compact Instructions"部分(可在压缩中保留)
  • 降低常驻上下文开销:精简 CLAUDE.md、移除未使用的 MCP 服务器、将参考材料转换为技能
  • 为新任务开启新会话,而非无限延续
  • 在关键操作前手动使用 /compact 以受控摘要回收空间
  • 将冗长操作委托给子代理(隔离的上下文窗口)

自动压缩触发过晚(或过早)

症状: 会话在压缩启动前已降级,或在仍有工作空间时触发了压缩。

原因: 默认压缩阈值约为上下文容量的 95%。

修复:

  • 设置 CLAUDE_AUTOCOMPACT_PCT_OVERRIDE 环境变量
  • 较低值(如 80)= 更早压缩、更多余量、保留细节更少
  • 较高值(如 98)= 更晚压缩、保留更多细节、但有触发前降级的风险

claude doctor 诊断

症状: Claude Code 行为异常、无法启动或连接失败。

运行: claude doctor

检查内容:

  • 认证状态和令牌有效性
  • 到 API 端点的网络连通性
  • 配置文件语法错误
  • MCP 服务器可用性
  • 环境变量冲突
  • 二进制版本和更新状态

使用时机: 任何不明显是上下文或提示词问题的故障排查首选步骤。

Claude 重复相同的错误

症状: Claude 跨会话犯相同的错误——错误的导入路径、不正确的测试命令、已弃用的 API 用法、错误的模块引用。

原因: 错误模式未被捕获到持久上下文中。每个会话全新开始,没有之前失败的知识。

修复:

  • 在 CLAUDE.md 中添加针对特定错误的指令
  • 示例:"始终从 @app/db/utils 导入,不要从 @app/utils/db 导入(已弃用路径)"
  • 要具体:描述错误行为和正确行为
  • 放在项目级 CLAUDE.md 中,使所有团队成员受益

检查点恢复不会撤销更改

症状: Esc-Esc 回退未恢复预期的文件状态。由 bash 命令(rm、mv、cp、sed)修改的文件未被还原。

原因: 检查点仅跟踪通过 Claude Code 的 Write/Edit 工具进行的文件编辑。通过 bash 命令、外部编辑器或其他并发会话所做的更改不会被跟踪。

修复:

  • 使用 git 进行完整恢复:git checkout -- <file>git stash
  • 在风险操作前频繁提交
  • 尽可能优先使用 Claude Code 内置的文件工具而非 bash 进行文件修改
  • 对于破坏性操作,要求 Claude 先创建备份

决策:重新开始 vs. 中途纠正

症状: Claude 方向错误、产生不正确的代码或遵循糟糕的计划。不清楚应该重定向还是重新开始。

何时重新开始:

  • Claude 已用不正确的探索填满上下文
  • 根本方法错误,不仅仅是细节问题
  • 多次纠正尝试未收敛
  • 上下文接近压缩阈值

何时中途纠正:

  • 方法正确但细节有误
  • 你可以简洁地描述修复方案
  • 上下文还有充足的剩余容量
  • Claude 已积累了有用的理解,重新开始会丢失

模式: 在决定之前先将当前状态提交到 git。如果重新开始,提交保留了有用的片段。如果中途纠正,提交给了你回滚点。

WebSocket 扩展性限制

症状: 由 Claude Code 生成的实时功能(聊天界面、实时仪表板、流式推送)在负载下失败或断开连接。

原因: Claude Code 能生成正确的 WebSocket 脚手架,但不会自动处理生产规模的关注点:连接池、背压、重连逻辑、心跳保活。

扩展阈值:

并发数推荐技术栈
MVP(<50 并发)Python + FastAPI 足够
扩展(>100 并发)需要 Go 或 Node.js;Python 在此级别吃力
高规模(1000+)强烈推荐 Go

修复:

  • 在提示词中明确请求连接池和重连逻辑
  • 将负载测试要求添加到验收标准
  • 手动审查生成的 WebSocket 代码:最大连接限制、心跳间隔、优雅降级、未关闭连接导致的内存泄漏
  • 审查背压处理:Claude 可以搭建脚手架,但需根据你的延迟 SLA 进行验证
  • 考虑使用专用的实时消息库而非原始 WebSocket 处理

FIX 协议限制

症状: 生成的 FIX 协议消息构建器可以编译但产生不正确或不完整的消息,或未通过一致性测试。

原因: FIX 协议高度复杂,具有领域特定的语义。Claude Code 可以生成 FIX 消息构建器,但缺乏生产级实现所需的深层领域知识。

修复:

  • 将 Claude 生成的 FIX 代码仅视为脚手架
  • 让 FIX 领域专家审查所有生成的消息构建器
  • 在生产使用前针对 FIX 一致性测试套件进行测试
  • 可能时使用 Claude Code 封装标准 REST/WebSocket 经纪商 API

MCP 服务器断连恢复

症状: MCP 工具在会话中停止工作。工具调用静默失败或返回错误。没有服务器已断连的警告。

原因: MCP 服务器连接可能在无通知的情况下断开。工具从 Claude 的可用工具集中消失。

修复:

  • 运行 /mcp 检查服务器状态和令牌开销
  • 如果 MCP 服务器崩溃则重启(检查其进程/日志)
  • 开启新的 Claude Code 会话以重新建立连接
  • 对于持续性问题,检查 MCP 服务器日志中的超时或内存错误
  • 为自定义 MCP 服务器添加健康检查逻辑
  • 考虑在关键操作前验证 MCP 可用性的 PreToolUse 钩子

崩溃或终端关闭后会话丢失

症状: 上一个会话的工作丢失。Claude 不记得它之前在做什么。

原因: 每个会话是独立的。上下文仅存在于会话内。关闭终端或崩溃会丢失未保存的上下文。

修复:

  • 恢复上一个会话:claude -c(继续最近的会话)或 claude -r <session-id>
  • 使用 claude --resume 浏览并从最近会话中选择
  • 对于关键的多会话工作,将状态持久化到文件:规格说明、任务列表(.claude/tasks/)、CLAUDE.md 更新
  • 使用 /rename 为重要会话命名以便恢复

子代理结果消耗过多主上下文

症状: 运行多个子代理后,主对话的上下文快速填满。压缩意外触发。

原因: 每个子代理将其结果返回到主上下文。多个子代理的详细输出会快速消耗主上下文。

修复:

  • 指示子代理返回简洁摘要而非完整细节
  • 减少并发子代理的数量
  • 将子代理结果写入文件而非在对话中返回
  • 在处理完不再需要留在活跃上下文中的子代理结果后运行 /compact

Claude 生成过度复杂的解决方案

症状: Claude 为简单问题生成繁琐的抽象、不必要的设计模式或复杂的架构。

原因: 默认行为倾向于全面的解决方案。在没有约束的情况下,Claude 会增加灵活性、可扩展性和抽象层。

修复:

  • 在 CLAUDE.md 中添加:"优先选择满足需求的最简方案。不要不必要的抽象。"
  • 明确范围:"这是一个一次性脚本,不是库"
  • 指定约束:"无新依赖"、"单文件"、"100 行以内"
  • 当出现复杂性时要求 Claude 给出理由
  • 在执行过程中打断并询问"你为什么要这样做?试试更简单的方案"

验证代理或网关配置

症状: 使用企业代理或 LLM 网关时 API 调用失败、认证错误或意外的模型路由。

原因: 代理 URL、基础 URL 或认证头配置错误或冲突。

修复:

  • 运行 /status 验证当前代理和网关配置
  • 检查 ANTHROPIC_BASE_URLHTTP_PROXYHTTPS_PROXY 环境变量
  • 确保代理证书受系统信任
  • 对于处理认证的 LLM 网关,设置相应的跳过认证变量(CLAUDE_CODE_SKIP_BEDROCK_AUTH=1CLAUDE_CODE_SKIP_VERTEX_AUTH=1

使用详细输出进行调试

症状: 不清楚 Claude 为什么做出某决策、为什么工具调用失败或钩子接收到了什么数据。

原因: 默认输出隐藏了详细的工具使用、钩子执行和内部处理信息。

修复:

  • Ctrl+O 切换详细输出,显示详细的工具使用和执行信息
  • 运行 claude --debug 查看钩子执行详情,包括哪些钩子匹配、退出码和输出
  • 检查钩子的 stderr 输出(在详细模式下可见非阻塞错误)
  • 对于钩子,通过启用 Ctrl+O 检查原始 stdout 来验证 JSON 解析

钩子未触发

症状: 配置的钩子在预期时未执行。无输出,无错误。

原因: 常见原因包括脚本不可执行、匹配器不匹配工具名称或会话启动后修改的钩子未经审查。

修复:

  • 确保脚本可执行:chmod +x script.sh
  • 验证 shebang 行:第一行应为 #!/bin/bash#!/usr/bin/env bash
  • 检查匹配器是否匹配精确的工具名称(例如 Bash,而非 bash
  • 如果钩子在会话期间被修改,在 /hooks 菜单中审查更改
  • 检查 settings 中是否将 disableAllHooks 设为 true
  • 使用 claude --debug 查看哪些钩子被评估和匹配

钩子 JSON 解析错误

症状: 钩子返回退出码 0 但 JSON 输出未被处理。Claude 忽略钩子的决策。

原因: stdout 中的非 JSON 文本(通常来自 shell 配置脚本)干扰了 JSON 解析。

修复:

  • 确保退出码 0 时 stdout 仅包含 JSON 对象
  • 将任何非必要输出重定向到 stderr:echo "debug info" >&2
  • 检查 shell 配置文件(.bashrc.zshrc)是否在启动时打印文本污染了 stdout
  • 手动测试脚本并检查原始输出