mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-22 16:25:51 +00:00
317 lines
13 KiB
Markdown
317 lines
13 KiB
Markdown
# 第十章:可观测性与排错 -- 卡住了怎么办
|
||
|
||
> Claude 报错、卡住、行为不对?本章帮你快速定位原因并解决。
|
||
|
||
## 第一步永远先跑:`claude doctor`
|
||
|
||
遇到任何不明原因的问题,第一件事是跑 `/doctor`(或在终端输入 `claude doctor`)。这个命令会自动检查你的安装环境、配置文件、MCP 连接状态、插件加载情况、版本是否最新,并给出一份结构化的诊断报告。
|
||
|
||
在 REPL 中输入:
|
||
|
||
```
|
||
/doctor
|
||
```
|
||
|
||
或在终端直接运行:
|
||
|
||
```bash
|
||
claude doctor
|
||
```
|
||
|
||
Doctor 会逐项检查并标记状态。常见检查项包括:
|
||
|
||
- 版本是否过期(与 npm 远程 `latest` / `stable` 标签对比)
|
||
- 配置文件 (`settings.json` / `settings.local.json`) 是否有语法错误
|
||
- MCP server 是否成功连接
|
||
- 插件是否有加载失败
|
||
- Sandbox / 权限相关检测
|
||
- Keybinding 冲突警告
|
||
|
||
另一个快速自检命令是 `bun run health`,它会检查运行时依赖是否齐全。如果你在开发模式下使用(`bun run dev`),这个命令可以在不启动完整 REPL 的情况下快速验证环境。
|
||
|
||
## Provider 报错对照表
|
||
|
||
API 调用失败时,Claude Code 会显示错误信息。以下是常见错误码的含义和应对方法。
|
||
|
||
### 401 / 403 -- 认证失败
|
||
|
||
**401 Unauthorized**:API key 无效、过期或未设置。检查你当前的 Provider 配置:
|
||
|
||
```
|
||
/provider
|
||
```
|
||
|
||
确认 key 已正确设置。如果你使用 OpenAI 兼容层,确认 `OPENAI_API_KEY` 环境变量已填入有效值。
|
||
|
||
**403 Forbidden**:通常表示地区限制或账号权限不足。某些 API 端点对特定地区不可用,或者你的订阅计划不包含所请求的模型。
|
||
|
||
### 429 -- 限流
|
||
|
||
当请求频率超过 API 的速率限制时,你会收到 429 错误。Claude Code 会自动解析 OpenAI 兼容层的限流响应头:
|
||
|
||
- `x-ratelimit-remaining-requests` / `x-ratelimit-limit-requests` -- 每分钟请求数
|
||
- `x-ratelimit-remaining-tokens` / `x-ratelimit-limit-tokens` -- 每分钟 token 数
|
||
- `x-ratelimit-reset-requests` / `x-ratelimit-reset-tokens` -- 重置时间
|
||
|
||
限流发生时,最直接的做法是等一会儿再试。如果你是 Anthropic 订阅用户,可以在 REPL 中输入 `/rate-limit-options` 查看可用的升级方案。
|
||
|
||
### overloaded_error(1305) -- 上游过载
|
||
|
||
这是 Anthropic API 返回的 `overloaded_error`(错误码 1305),表示服务端暂时过载。与限流不同,这不是你的请求频率问题,而是 Anthropic 服务本身在排队。等几分钟再重试即可。
|
||
|
||
### 模型不存在
|
||
|
||
当你请求的模型名称无法被 Provider 识别时,请求会失败。例如使用 Gemini 兼容层时,如果 `GEMINI_MODEL` 和 `GEMINI_DEFAULT_SONNET_MODEL` / `GEMINI_DEFAULT_OPUS_MODEL` 都没有设置,模型映射可能找不到匹配项,Gemini 客户端会直接抛出异常。
|
||
|
||
确认你当前使用的模型:
|
||
|
||
```
|
||
/model
|
||
```
|
||
|
||
## 兼容层特有坑
|
||
|
||
使用 OpenAI / Gemini / Grok 兼容层时,除了上述通用错误,还可能遇到以下兼容层特有的问题。
|
||
|
||
### DeepSeek `reasoning_content` 缺失
|
||
|
||
DeepSeek 在启用思维模式时会返回 `reasoning_content` 字段。如果某次请求的响应中缺少这个字段(即使是空值),下一次请求会被 DeepSeek API 拒绝并返回 400 错误。这是因为兼容层在流适配过程中,如果未回显 `reasoning_content: ''`(空字符串),会导致 DeepSeek 的会话状态不一致。
|
||
|
||
如果你使用 DeepSeek 且频繁遇到 400 错误,尝试切换到普通模型(关闭思维模式),或检查你的 DeepSeek 端点版本是否支持思维模式。
|
||
|
||
### OpenAI 客户端缓存
|
||
|
||
`getOpenAIClient()` 使用模块级缓存:第一次调用后客户端实例被缓存,后续调用直接返回缓存实例。这意味着如果你在运行期间修改了 `OPENAI_API_KEY` 或 `OPENAI_BASE_URL`,新值不会生效。
|
||
|
||
解决方法:重启 Claude Code。在脚本或自动化场景中,需要中途更换 key 的,可以调用 `clearOpenAIClientCache()` 清除缓存。同样的问题也存在于 `getGrokClient()`。
|
||
|
||
### Gemini 模型映射失败
|
||
|
||
Gemini 是唯一在模型映射链全部缺失时直接抛出异常的 Provider。映射优先级为:`GEMINI_MODEL` > `GEMINI_DEFAULT_SONNET_MODEL` / `GEMINI_DEFAULT_OPUS_MODEL` > 默认映射表。如果默认映射表中找不到匹配项,你会看到类似以下错误:
|
||
|
||
```
|
||
Gemini API request failed (404 Not Found): ...
|
||
```
|
||
|
||
设置明确的模型名称可以避免这个问题:
|
||
|
||
```json
|
||
{
|
||
"env": {
|
||
"GEMINI_MODEL": "gemini-2.5-pro"
|
||
}
|
||
}
|
||
```
|
||
|
||
## Bedrock Opus 4.7 的 400 错误
|
||
|
||
如果你使用 AWS Bedrock 作为 Provider,调用 Opus 4.7 模型时可能遇到 400 "invalid beta flag" 错误。这是一个已知的上游 SDK bug:`@anthropic-ai/bedrock-sdk`(版本 0.26.4 至 0.28.1)会将 `anthropic-beta` HTTP 头的值错误地复制到请求体的 `anthropic_beta` 字段中,而 Bedrock 的 Opus 4.7 端点会拒绝请求体中包含此字段的请求。
|
||
|
||
Claude Code 通过自定义的 `BedrockClient`(继承自 `AnthropicBedrock`)自动修补这个问题:在 SDK 构建 `buildRequest` 完成后,删除请求体中的 `anthropic_beta` 字段,同时保留 HTTP 头中的正确值。
|
||
|
||
项目提供了 probe 脚本用于验证 SDK 状态:
|
||
|
||
```bash
|
||
bun run scripts/probe-local-wiring.ts
|
||
```
|
||
|
||
## MCP server 连不上
|
||
|
||
当 MCP server 无法连接时,检查以下几点:
|
||
|
||
**stdio 模式**:确认命令路径和参数正确。
|
||
|
||
```bash
|
||
claude mcp list
|
||
```
|
||
|
||
检查已配置的 MCP server 列表。确认 `command` 指向的可执行文件存在且可执行。
|
||
|
||
**SSE 模式**:确认 URL 可达、超时设置合理。如果 MCP server 启动较慢,可能需要调整超时时间。
|
||
|
||
**OAuth 认证**:某些 MCP server 需要 OAuth 授权。在 REPL 中使用 `/mcp-auth` 进行认证。如果认证失败,检查回调 URL 是否正确配置。
|
||
|
||
**MCP 配置语法错误**:`claude mcp list` 会显示解析警告。如果添加 server 后出现 `McpParsingWarnings`,说明配置 JSON 有格式问题,需要修正。
|
||
|
||
## 权限被拒、工具被禁用、延迟工具没加载
|
||
|
||
Claude Code 使用权限模式控制工具的使用。如果你发现某个工具被禁用或权限被拒:
|
||
|
||
1. **确认当前权限模式**:在 REPL 中输入 `/permissions` 查看当前权限规则。
|
||
2. **权限规则配置**:在 `settings.json` 中配置 `allow` / `deny` 规则,使用工具名匹配和 glob 模式。例如:
|
||
|
||
```json
|
||
{
|
||
"permissions": {
|
||
"allow": [
|
||
"Bash(npm test*)",
|
||
"FileReadTool"
|
||
],
|
||
"deny": [
|
||
"Bash(rm -rf*)"
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
3. **延迟工具加载**:60 个内置工具中,只有 38 个核心工具是始终加载的(`CORE_TOOLS` 白名单)。其余工具通过 `SearchExtraTools` 按需搜索和加载。如果你需要的工具没有被自动加载,可以在对话中明确提及工具名,触发搜索和加载过程。
|
||
|
||
## 内存膨胀与长会话
|
||
|
||
长时间运行的会话(daemon 模式、`/loop` 循环、大量工具调用)可能导致内存膨胀。这是因为 Bun 使用的 JSC 引擎的 `Performance` 对象将 marks/measures 存储在一个永不收缩的 C++ Vector 中。
|
||
|
||
Claude Code 通过 `performanceShim` 解决这个问题:它在启动时将 `globalThis.performance` 替换为 JS Map 支持的实现,`performance.now()` 仍然走原生(精确且快速),但 `mark` / `measure` / `getEntries` 操作存储在 GC 可回收的 JS 内存中。
|
||
|
||
如果你仍然感觉到长会话变慢,可以:
|
||
|
||
1. 使用 `/compact` 压缩上下文,减少内存中的消息量。
|
||
2. 使用 `/force-snip` 强制裁剪更早的消息。
|
||
3. 重启 Claude Code 会话。
|
||
|
||
## 调试模式
|
||
|
||
### `BUN_INSPECT` 调试器
|
||
|
||
使用 Bun 内置的调试器来排查运行时问题:
|
||
|
||
```bash
|
||
BUN_INSPECT=9229 bun run dev:inspect
|
||
```
|
||
|
||
然后连接 Chrome DevTools(打开 `chrome://inspect`)或使用 VS Code 的调试面板连接到 `ws://localhost:9229`。
|
||
|
||
### `--dump-system-prompt`
|
||
|
||
查看当前构建版本生成的完整系统提示(需要 `DUMP_SYSTEM_PROMPT` feature 启用):
|
||
|
||
```bash
|
||
FEATURE_DUMP_SYSTEM_PROMPT=1 claude --dump-system-prompt --model claude-sonnet-4-20250514
|
||
```
|
||
|
||
这会将渲染后的系统提示打印到终端,适合调试 prompt 组装逻辑。
|
||
|
||
### `/debug-tool-call` 查看工具调用
|
||
|
||
在 REPL 中输入 `/debug-tool-call` 查看最近 5 次工具调用的输入和输出。指定数字可以查看更多:
|
||
|
||
```
|
||
/debug-tool-call 10
|
||
```
|
||
|
||
它会从当前会话的 transcript 日志中读取最近的工具调用对,显示工具名、输入参数和返回结果。
|
||
|
||
### `/perf-issue` 性能快照
|
||
|
||
当遇到性能问题时,使用 `/perf-issue` 生成一份详细的性能报告:
|
||
|
||
```
|
||
/perf-issue
|
||
```
|
||
|
||
报告保存到 `~/.claude/perf-reports/` 目录,包含:
|
||
|
||
- 进程内存使用(RSS、heap、external)
|
||
- CPU 使用统计
|
||
- Token 用量分解(input/output/cache_creation/cache_read)
|
||
- 缓存命中率
|
||
- 费用估算(基于 Anthropic 公开定价)
|
||
- 工具调用次数和平均执行时间
|
||
- 会话挂钟时间
|
||
|
||
支持三种输出格式:
|
||
|
||
```
|
||
/perf-issue --format=json
|
||
/perf-issue --format=csv
|
||
/perf-issue --format=md
|
||
```
|
||
|
||
### `/heapdump` 堆快照
|
||
|
||
当怀疑内存泄漏时,使用 `/heapdump` 导出 V8 堆快照文件:
|
||
|
||
```
|
||
/heapdump
|
||
```
|
||
|
||
快照文件会保存到桌面(`~/Desktop/`),可以用 Chrome DevTools 的 Memory 面板加载分析。
|
||
|
||
## Langfuse 追踪
|
||
|
||
如果你想深入了解每次 API 调用的细节(模型、Provider、token 消耗、工具执行链路),可以启用 Langfuse 追踪。Langfuse 是一个开源的 LLM 可观测性平台,支持自部署或使用 Langfuse Cloud。
|
||
|
||
在 `settings.json` 中配置三个必填环境变量:
|
||
|
||
```json
|
||
{
|
||
"env": {
|
||
"LANGFUSE_PUBLIC_KEY": "pk-xxx",
|
||
"LANGFUSE_SECRET_KEY": "sk-xxx",
|
||
"LANGFUSE_BASE_URL": "https://cloud.langfuse.com"
|
||
}
|
||
}
|
||
```
|
||
|
||
可选参数包括 `LANGFUSE_TRACING_ENVIRONMENT`(环境标签,默认 `development`)、`LANGFUSE_FLUSH_AT`(批量发送阈值,默认 20)、`LANGFUSE_FLUSH_INTERVAL`(定时刷新间隔秒数,默认 10)等。
|
||
|
||
未配置时,所有追踪函数为 no-op,零开销。
|
||
|
||
启用后,每次查询会创建一个 Trace(agent 类型),其中包含:
|
||
|
||
- **LLM Generation** -- 记录 API 调用,按 Provider 映射为不同名称(`ChatAnthropic`、`ChatOpenAI`、`ChatGoogleGenerativeAI`、`ChatXAI` 等)
|
||
- **Tool Observation** -- 记录每个工具调用的输入输出和耗时
|
||
- **子 Agent Trace** -- 通过 Agent 工具派生的子代理有独立的 Trace
|
||
|
||
所有上传的数据会自动脱敏:API key、token、password 等敏感字段被替换为 `[REDACTED]`,文件读写工具的输出被完全遮蔽,Shell 工具输出截断至 500 字符。
|
||
|
||
## 导出会话
|
||
|
||
当你需要把对话记录分享给同事、存档或提交 bug 报告时,可以使用以下命令:
|
||
|
||
- `/export` -- 导出当前会话为文件
|
||
- `/share` -- 分享会话(具体格式取决于实现)
|
||
- `/recap` -- 生成会话摘要
|
||
|
||
注意隐私边界:导出的内容可能包含你对话中的代码片段和文件内容,但不会包含 API key 等凭证。在分享前检查导出内容,确保不包含敏感信息。
|
||
|
||
## 反馈与上报 bug
|
||
|
||
### `/feedback` 提交反馈
|
||
|
||
在 REPL 中输入 `/feedback` 可以提交产品反馈。你可以在描述中附上遇到的问题,也可以引用 `/perf-issue` 生成的报告。
|
||
|
||
### `/bughunter` 自动排查
|
||
|
||
`/bughunter` 命令在当前版本中为 stub(`isEnabled` 返回 `false`),尚未实现。
|
||
|
||
### GitHub Issues
|
||
|
||
如果以上方法都无法解决问题,可以在项目 GitHub 仓库提交 Issue。提交时建议附上:
|
||
|
||
- `/perf-issue` 生成的性能报告
|
||
- `/debug-tool-call` 的输出
|
||
- 具体的错误信息和复现步骤
|
||
- 你使用的 Provider 和模型
|
||
|
||
## 已知禁用的 feature flag
|
||
|
||
以下 feature flag 在构建时被禁用,启用可能导致核心功能异常:
|
||
|
||
- `CONTEXT_COLLAPSE` -- 上下文折叠(反编译丢失)
|
||
- `HISTORY_SNIP` -- 历史剪裁(反编译丢失)
|
||
- `FORK_SUBAGENT` -- 分叉子代理(反编译丢失)
|
||
- `UDS_INBOX` -- Unix Domain Socket 收件箱(反编译丢失)
|
||
- `LAN_PIPES` -- 局域管道(反编译丢失)
|
||
- `REVIEW_ARTIFACT` -- 代码审查产物(反编译丢失)
|
||
- `SKILL_LEARNING` -- 技能学习(原本即为 stub)
|
||
- `TEAMMEM` -- 团队成员(原本即为 stub)
|
||
|
||
除非你清楚知道后果,否则不要通过 `FEATURE_<NAME>=1` 启用这些 flag。
|
||
|
||
## 下一步
|
||
|
||
- 想配置 Provider 和模型,看 [第二章](./02-providers.md)
|
||
- 想理解 slash 命令,看 [第四章](./04-slash-commands.md)
|
||
- 想配置 MCP server 和插件,看 [第五章](./05-mcp-plugins-skills.md)
|
||
- 想省钱和优化性能,看 [第九章](./09-budget-cache-hooks.md)
|