テック技報最新号へ →
AIコーディング

Claude Code の動きを Hooks で Langfuse に送り、ツール呼び出しやサブエージェントを追う

Claude Code の OpenTelemetry 出力はメトリクスとログだけで、トレース(span)は出さない。一方 Langfuse はトレースしか受けない。そこで全 hook イベントに同じシェルスクリプトを登録し、Langfuse の Ingestion API に直接送ると、1つの指示ごとのツール呼び出し・サブエージェント・LLM の応答までを1画面で追える。

@minorun365 · 投稿 2026-04-24
#claude-code#hooks#observability#langfuse#トレース

どんな場面で使う?

  • どの指示でどのツールが何回呼ばれ、どこで失敗したかを振り返りたいとき
  • 自作エージェントの設計の参考に、Claude Code の内部の動き(サブエージェントの入出力など)を観察したいとき

手順

  1. Langfuse を用意する(OSS なのでセルフホストも可)
  2. settings.json の hooks で、SessionStart・UserPromptSubmit・PreToolUse・PostToolUse・PostToolUseFailure・SubagentStart・SubagentStop・Stop・PreCompact・Notification などに、同じスクリプトを登録する
json
{ "hooks": {
  "PreToolUse":  [{ "matcher": "", "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/scripts/langfuse-logger.sh", "timeout": 10 }] }],
  "PostToolUse": [{ "matcher": "", "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/scripts/langfuse-logger.sh", "timeout": 10 }] }],
  "Stop":        [{ "matcher": "", "hooks": [{ "type": "command", "command": "bash ~/.claude/hooks/scripts/langfuse-logger.sh", "timeout": 10 }] }]
} }
  1. スクリプト側で Claude Code の概念を Langfuse の型に対応させる
    | Claude Code | Langfuse |
    |---|---|
    | session_id | Session |
    | ユーザーの1指示(UserPromptSubmit) | Trace({session_id}-turn-{n}) |
    | ツール実行(Pre→Post、tool_use_id で対応付け) | Tool |
    | サブエージェント(SubagentStart→Stop) | 親 Span(中のツールの親にする) |
    | LLM 呼び出し | Generation(後述) |
    | 通知・圧縮 | Event |
  2. LLM の応答は Stop のときに transcript から拾う。hooks には LLM の入出力が来ないので、transcript_path の JSONL のうち、その指示以降に増えた行から type: "assistant" を読み、stop_reason(null=途中経過、tool_use、end_turn=最終回答)ごとに Generation にする
  3. 状態(今のトレースID、ターン番号など)は /tmp/claude-langfuse/{session_id}/ にファイルで持ち、イベント間で共有する

注意点

出典

X の元の投稿を開く