原文(日本語に翻訳)
claude_code.tool OTELスパンに agent_id および parent_agent_id 属性を追加し、バックグラウンドサブエージェントのスパンが dispatch した Agent ツールスパンの配下に正しくネストされるようトレースの親子関係を修正
原文(英語)
Added agent_id and parent_agent_id attributes to claude_code.tool OTEL spans, and fixed trace parenting so background subagent spans nest under the dispatching Agent tool span
概要
Claude Code v2.1.145では、OpenTelemetry(OTEL)のトレーシングが強化されました。claude_code.tool スパンに新たに agent_id と parent_agent_id 属性が追加され、複数エージェントが協調動作する際のトレース情報をより詳細に把握できるようになりました。また、バックグラウンドで動作するサブエージェントのスパンが、それを起動した Agent ツールスパンの子として正しく関連付けられるバグが修正されたことで、分散トレーシングの可視化が正確になりました。
基本的な使い方
OTEL連携を有効にした状態でClaude Codeを実行すると、ツールスパンに自動的に agent_id と parent_agent_id が付与されます。
# OTEL エンドポイントを設定してClaude Codeを起動
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_SERVICE_NAME="claude-code"
claude "複数エージェントを使ってタスクを処理して"生成されるスパン属性の例:
{
"name": "claude_code.tool",
"attributes": {
"tool.name": "Bash",
"agent_id": "agent-abc123",
"parent_agent_id": "agent-root456",
"session.id": "session-xyz789"
}
}実践例
Jaegerでのトレース可視化
JaegerをバックエンドにOTELトレースを収集して、エージェント間の呼び出し関係を可視化します。
# Jaegerをローカルで起動
docker run -d --name jaeger \
-p 16686:16686 \
-p 4317:4317 \
jaegertracing/all-in-one:latest
# Claude Codeの環境変数を設定
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4317"
export OTEL_SERVICE_NAME="claude-code"
export OTEL_EXPORTER_OTLP_PROTOCOL="grpc"
# エージェントを使うタスクを実行
claude "並行してファイルを分析して結果をまとめて"
# ブラウザで http://localhost:16686 を開いてトレースを確認agent_idを使ったフィルタリングと分析
特定のエージェントのみのスパンを抽出して分析します。
# otel_analysis.py - OTELスパンをフィルタリング
import json
def analyze_agent_spans(spans_file):
"""エージェントIDでスパンをグループ化して分析"""
with open(spans_file) as f:
spans = json.load(f)
# agent_idでグループ化
by_agent = {}
for span in spans:
attrs = span.get('attributes', {})
agent_id = attrs.get('agent_id')
parent_id = attrs.get('parent_agent_id')
if agent_id:
if agent_id not in by_agent:
by_agent[agent_id] = {
'spans': [],
'parent': parent_id
}
by_agent[agent_id]['spans'].append(span)
# 親子関係を表示
for agent_id, data in by_agent.items():
parent = data['parent'] or 'root'
span_count = len(data['spans'])
print(f"Agent {agent_id} (parent: {parent}): {span_count} spans")
analyze_agent_spans('otel_spans.json')Grafana Tempoでの長期モニタリング
Grafana Tempoと連携してエージェントのパフォーマンスをダッシュボードで監視します。
# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
# agent_idでスパンをフィルタリング
filter:
spans:
include:
match_type: strict
attributes:
- key: agent_id
value: ".*"
exporters:
tempo:
endpoint: "http://tempo:4317"
service:
pipelines:
traces:
receivers: [otlp]
processors: [filter]
exporters: [tempo]注意点
- この機能はOTELトレーシングを有効化している場合のみ動作します(
OTEL_EXPORTER_OTLP_ENDPOINT環境変数が必要) parent_agent_idはルートエージェントの場合はnullまたは未設定になります- バックグラウンドサブエージェントのスパンが正しくネストされるよう親子関係の修正が含まれています(以前のバージョンではフラットに表示されていた問題が解消)
- OTEL連携はClaude Code Enterprise機能の一部として提供される場合があります
- スパン属性の追加によって、トレースデータのストレージ使用量がわずかに増加する可能性があります