OpenTelemetry GenAI で Claude Code / OpenCode / ADK Go の可観測性向上
こんにちは。ジェダイパンくず🍞 です。 AI エージェントに作業を任せる時間が増えるほど、「いま何に時間がかかっているのか」「どの tool を何回呼んだのか」「token とお金をどれだけ使ったのか」が気になってきます。Hacker News でも LLM Observability in the Wild – Why OpenTelemetry Should Be the Standard というスレッドで、LLM アプリの可観測性を OpenTelemetry (OTel) に寄せるべきかが議論されていました。「エージェントの処理は tool 呼び出しを含む分散コールグラフなので OTel に向いている」という意見がある一方、「属性を足すだけではマルチエージェントのデバッグには足りない」という声もあります。 OTel には生成 AI 向けの semantic conventions (以下 GenAI semconv) があり、普段使っている Claude Code、OpenCode、そして以前の記事 Google ADK Go 2.x の Dynamic Workflow とその為のガードレール で触った Google ADK Go も OTel の出力に対応しています。ただ、どれも「OTel 対応」とだけ書かれていて、実際に何が出てくるのか、互いに比較できる形なのかは分かりませんでした。そこで 3 つを同じ backend に流して比べてみました。 コードは下記に置いてあります。 https://github.com/jedipunkz/otel-genai-playground 結論 エージェント GenAI semconv との距離 対応 ADK Go ほぼ準拠。semconv v1.44 の span 名・属性がそのまま出る traces, logs OpenCode 属性だけ準拠。span 名は内部の関数名で、gen_ai.operation.name が無い traces, logs Claude Code 独自の claude_code.* スキーマに gen_ai.* 属性を追加した形。token 数は独自名 traces (beta), metrics, logs 3 つとも OTLP で出せるので、backend を 1 つにそろえるだけで「LLM 呼び出しのレイテンシ p95」「tool ごとの呼び出し回数と遅延」を同じ TraceQL で横断して見られました。一方で token 数の属性名や finish_reasons の値はエージェントごとにばらばらで、そのまま集計できるのは一部だけです。GenAI semconv はまだ Development ステータスなので注意が必要と思いました。 ...