主题
8. 故障排查
1. UI 里看不到任何 Trace
检查清单
| # | 检查项 | 命令/方法 |
|---|---|---|
| 1 | TRACE_TO_LANGFUSE=true | echo $TRACE_TO_LANGFUSE |
| 2 | 密钥正确 | 检查 CC_LANGFUSE_PUBLIC_KEY / SECRET_KEY |
| 3 | Host 正确 | 自托管需设 CC_LANGFUSE_BASE_URL |
| 4 | SDK 版本 | pip show langfuse → 应为 2.x |
| 5 | Watcher 在运行 | ps aux | grep claude_langfuse_watcher |
| 6 | transcript 有内容 | wc -l ~/.claude/projects/.../xxx.jsonl |
| 7 | 日志有报错 | tail ~/.claude/state/langfuse_*.log |
常见原因
SDK v3/v4 不兼容
Langfuse SDK x.x.x 不兼容:需要 langfuse>=2,<3bash
pip install 'langfuse>=2,<3' --force-reinstallWatcher 未跟踪到文件
bash
# 确认文件路径和命名(必须是 UUID.jsonl)
ls ~/.claude/projects/*/2. Trace 重复
原因:Hook 和 Watcher 同时启用。
解决:只保留一种方案。
bash
# 停 Watcher
pkill -f claude_langfuse_watcher
# 或移除 Hook 注册(settings.json)3. Latency 显示 0.00s
原因:旧版实现未传时间戳;当前版本已从 jsonl timestamp 提取。
排查:
- 确认用的是最新版
langfuse_transcript.py - 检查 jsonl 行是否有
timestamp字段 - 流式模式下 Generation 进行中
end_time=None是正常的,finalize 后应有值
4. Token 显示为空
原因:
- 流式进行中 Generation 故意不传
usage_details(finalize 时才写) - trpc 拆行时前几行 usage 全零,被
get_usage()跳过
排查:
bash
# 看 jsonl 最后一行 assistant 是否有非零 usage
grep '"usage"' session.jsonl | tail -35. 子代理内容缺失
| 检查项 | 说明 |
|---|---|
CC_LANGFUSE_INCLUDE_SUBAGENTS | 必须为 true |
| 子代理文件存在 | ls <sessionId>/subagents/agent-*.jsonl |
| 工具名匹配 | 必须是 Task 或 Agent |
| 时间窗口 | CC_LANGFUSE_SUBAGENT_TIME_WINDOW_S 默认 10s,太大匹配失败可调整 |
| agentType 匹配 | 检查 agent-*.meta.json 的 agentType 与 tool input 的 subagent_type |
日志关键字:
streaming subagent linked type=Explore tool=toolu_...
subagent emit failed for ...6. flush 失败 / 上报卡住
现象:日志出现 langfuse.flush failed,turn_count 不推进。
原因:网络问题、Langfuse Server 不可达、密钥过期。
行为:下次轮询/Stop 会重试,不会丢数据(at-least-once)。
bash
# 测试连通性
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Basic $(echo -n 'pk:sk' | base64)" \
"$CC_LANGFUSE_BASE_URL/api/public/health"7. offset 回退 / 重复处理
现象:日志 partial run: emitted_ok=1/3, flush_ok=False; rolling back offset
原因:部分 Turn 上报失败或 flush 失败,故意不推进 offset。
解决:修复根因(网络/SDK)后自动重试,无需手动清状态。
手动重置(慎用):
bash
# 删除状态文件,下次从头处理(可能重复上报已成功的 Turn)
rm ~/.claude/state/langfuse_watcher_state.json
rm ~/.claude/state/langfuse_hook_all_agents_state.json8. 文件截断后数据异常
现象:transcript 被覆盖或截断。
自动处理:
python
if size < ss.offset:
ss.offset = 0
ss.buffer = ""日志:transcript truncated, reset offset
9. Claude Code 被 Hook 拖慢
设计保证:Hook 必须快速返回;任何异常 return 0。
如果感觉慢:
- 检查 Langfuse flush 超时(网络延迟)
- 减小
CC_LANGFUSE_MAX_CHARS降低 payload - 改用 Watcher 方案(完全异步)
10. 敏感信息泄露
默认 CC_LANGFUSE_REDACT=true 会脱敏:
sk-/pk-开头的 key- Bearer Token
- password/secret 赋值
- PEM 私钥
验证:
bash
export CC_LANGFUSE_REDACT=true
# 在 Langfuse UI 检查 Span input 中是否出现 [REDACTED]11. 调试技巧
bash
# 最大 verbosity
export CC_LANGFUSE_DEBUG=true
# 单次处理看完整流程
python3 claude_langfuse_watcher.py \
--transcript /path/to/demo.jsonl \
--once
# 单元测试
cd langfuse_trace
python3 -m unittest discover -s tests -q
# 检查 SDK API
python3 -c "
from langfuse import Langfuse
p = Langfuse(public_key='pk', secret_key='sk', host='http://localhost')
print('v2 API:', callable(getattr(p, 'trace', None)))
"12. 问题定位流程图
看不到 Trace?
├─ TRACE_TO_LANGFUSE != true → 设环境变量
├─ 密钥错 → 检查 pk/sk
├─ Watcher 没跑 → 启动 run_watcher.sh
├─ 没有 jsonl → 先跑一轮 Claude Code
└─ SDK 版本错 → pip install 'langfuse>=2,<3'
Trace 有但内容不对?
├─ 无子代理 → 检查 INCLUDE_SUBAGENTS + agent jsonl
├─ 无 token → 等 finalize 或查 jsonl usage 字段
├─ 时间 0s → 查 timestamp 字段
└─ 重复 → Hook+Watcher 同时开了
上报中断?
├─ flush failed → 查网络/Langfuse 服务
└─ partial emit → 自动重试,修好后无需手动干预13. 获取帮助
- 完整设计文档:
langfuse_trace/方案实现说明.md - Langfuse 基础概念:
../langfuse/2_core_concepts.md - 源码:
langfuse_trace/common/langfuse_transcript.py