Skip to content

0. 方案总览


1. 要解决什么问题?

Claude Code 在本地编程时,你和 AI 的每一轮对话、每一次工具调用、每一个子代理任务,都发生在终端里。默认情况下:

  • 你看得到终端输出,但无法结构化回溯
  • 出了问题不知道哪次 LLM 调用、哪个 Tool 出了错
  • 无法统计 token 用量和成本
  • 子代理(Task/Agent)内部的执行过程对主会话不可见

Langfuse 是 LLM 可观测平台,能把这些过程变成可搜索、可分析的 Trace 树。

难点:Claude Code 官方没有内置 Langfuse 集成。

本方案的思路:Claude Code 本来就会把全过程写到 jsonl transcript 文件里——我们旁路读取这个文件,翻译成 Langfuse 能理解的结构再上报。


2. 生活类比:餐厅后厨录像

真实世界本方案
顾客点菜(你输入 prompt)jsonl 里的 user
厨师做菜(AI 推理)jsonl 里的 assistant
去冷库取食材(Tool 调用)tool_use + tool_result
外包帮厨(子代理 Task/Agent)subagents/agent-*.jsonl
手写流水账(transcript)~/.claude/projects/.../xxx.jsonl
会计录入 ERP(Langfuse)emit_main_turn()
一整单外卖(Trace)一轮用户问答 = 1 条 Trace

核心原则:不改厨房运作方式,只读流水账。


3. 端到端数据流

Claude Code 端到端数据流

┌──────────────────────────────────────────────────────────────────┐
│ 1. 数据源:Claude Code session jsonl                              │
│    ~/.claude/projects/<hash>/<sessionId>.jsonl                   │
│    + 可选 subagents/agent-<id>.jsonl                             │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 2. 触发:Hook(Stop 事件)或 Watcher(轮询)                       │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 3. 增量读取:read_new_jsonl()                                     │
│    - 基于文件 offset,只读新增行                                   │
│    - 半行缓冲,处理写入中的不完整 JSON 行                           │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 4. Turn 切分:build_turns()                                       │
│    user(真人) → 新 Turn                                           │
│    assistant  → 追加当前 Turn                                     │
│    tool_result → 归档到当前 Turn,不新开 Turn                      │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 5. 子代理发现:discover_subagent_files() + match_subagent()       │
│    Task/Agent 工具调用 → 匹配 agent-*.jsonl → 嵌套上报             │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 6. Langfuse 上报:emit_main_turn() / process_turn_streaming()    │
│    Trace → Generation(s) + Tool Span(s) + 嵌套 Subagent           │
└────────────────────────────┬─────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────┐
│ 7. 可靠投递:langfuse.flush() 成功后才推进 turn_count/offset       │
└──────────────────────────────────────────────────────────────────┘

4. Langfuse 概念映射

Claude Code 概念映射

Claude Code 概念Langfuse 概念说明
整个 coding sessionSessionsession_id 聚合多轮 Trace
一轮用户问答Trace名称 Claude Code - Turn N
模型回复(assistant)Generation含 model、token、真实时间戳
工具调用(Bash/Read/...)Span名称 Tool: <name>
子代理 Task/Agent嵌套 Span父 Span 下挂 Subagent Turn
子代理内部对话Generation/Span递归 _emit_turn()

5. 两种方案怎么选

Hook vs Watcher 方案对比

维度Hook(langfuse_transcript.pyWatcher(claude_langfuse_watcher.py
触发方式Claude Code Stop 事件独立进程每 1s 轮询
侵入性需配置 settings.json hooks零配置 Claude Code
实时性每轮结束上报默认流式:Turn 开始就建 Trace
适用场景与 CC 深度集成CI、旁路监听、不便改 Hook
状态文件langfuse_hook_all_agents_state.jsonlangfuse_watcher_state.json

默认推荐 Watcher + 流式模式run_watcher.sh),体验最接近「实时看到 AI 在干什么」。


6. 关键设计原则

6.1 fail-open(绝不影响 Claude Code)

python
# SDK 导入失败 → 静默退出
except Exception:
    sys.exit(0)

# 任何未预期异常 → return 0
except Exception:
    return 0

追踪挂了可以忍,编程助手挂了不行。

6.2 可靠投递(at-least-once)

flush() 成功后才推进 turn_countoffset。失败则下次重读、重报,保证顺序不丢 Turn。

6.3 真实时间戳

所有 observation 的 start_time / end_time 来自 jsonl 的 timestamp 字段,UI 不再显示 Latency 0.00s

6.4 SDK 版本锁定

使用 Langfuse Python SDK v2langfuse>=2,<3)有状态 API:trace()generation()span(),原生支持显式时间戳。


7. 下一步