エージェントのトレーシングと観測性 ─ 動きを「見える化」するデバッグ術
結論から言うと、エージェントのデバッグには観測性(Observability)の仕組みが欠かせない。単発のチャットと違い、エージェントは「考える→ツールを呼ぶ→結果を見る」を何度も繰り返す。どのステップで誤答が生まれたか、なぜループが止まらなかったか、確認なしには分からない。観測性ツールを入れると、エージェントの内部が「見える」ようになる。
なぜエージェントには観測性が必要なのか
通常のソフトウェアはログを追えば原因を特定できることが多い。しかしエージェントは非決定論的──同じ入力でも毎回出力が変わり得る。また複数ステップにまたがって「どのLLM呼び出し」「どのツール実行」が失敗の原因かを特定するのは、ログの羅列だけでは困難だ。
LangFuseは自社ドキュメントで「観測ツールなしのデバッグは当て推量に近い(debugging your application without any observability tool is more like guesswork)」と述べている。エージェントが複雑になるほど、この問題は深刻になる。
3つの観測シグナルとは何か
OpenTelemetry(オープンな観測性の標準仕様)は観測データを3種類に分類している。
| シグナル | 説明 | エージェントでの例 |
|---|---|---|
| ログ | タイムスタンプ付きの個別メッセージ | LLM呼び出しの入力プロンプト・出力テキスト |
| メトリクス | 一定期間の数値集計 | 平均レイテンシ、トークン消費量、エラー率 |
| トレース | リクエスト全体の旅の記録 | 「ユーザー入力→LLM→ツール→LLM→回答」の流れ |
この3つを組み合わせると、「何が起きたか(ログ)」「どれくらい頻繁に起きたか(メトリクス)」「どの順序で起きたか(トレース)」を立体的に把握できる。
トレースとスパンの構造を理解する
**トレース(Trace)は1つのリクエスト全体を記録したもので、複数のスパン(Span)**から成る。スパンは個々の処理単位──「LLM呼び出し1回」「ツール実行1回」──で、開始時刻・終了時刻・入出力・エラーを記録する。
Trace: "ユーザー: 今日の天気を教えて"
└─ Span: LLM呼び出し(思考) 200ms
└─ Span: ツール呼び出し(天気API) 450ms
└─ Span: LLM呼び出し(回答生成) 180ms
この木構造を見ると「天気APIが遅い」「どのLLM呼び出しが高コストか」が一目で分かる。
LLMエージェント固有の観測対象は何か
一般的なWebアプリの観測と違い、LLMエージェントでは以下を特に記録することが推奨される。
- プロンプトとレスポンス全文: 不正確な出力の原因究明に必須
- モデル名・温度(temperature)などのパラメータ: 実験管理に役立つ
- トークン数(入力・出力): コスト把握の基礎(レッスン15参照)
- ツール名と引数・戻り値: どのツール呼び出しが失敗したかを追跡
- セッションID: マルチターン会話の流れをまとめて把握
実践: どのツールを使えばよいか
代表的なオープンソースの観測プラットフォームとしてLangFuseがある。エージェントのコードにSDKを数行追加するだけで、上記のシグナルを自動収集できる。ダッシュボードでは「どのLLM呼び出しが遅いか」「どのトレースでエラーが起きたか」をフィルタリングできる。
標準仕様としてはOpenTelemetryがあり、AIエージェント向けの「GenAI Semantic Conventions(GenAI観測規約)」が現在策定・整備されている。ツールやプロバイダーを横断した共通フォーマットが普及すると、観測データの互換性が高まるとされる。
まとめ
- エージェントは非決定論的・多ステップのため、ログだけのデバッグには限界がある
- 観測性の3シグナル(ログ・メトリクス・トレース)を組み合わせると内部を立体的に把握できる
- トレースはスパンの木構造で「どのステップが遅いか・失敗したか」を可視化する
- LLMエージェント固有の記録対象(プロンプト全文・トークン数・ツール呼び出し)を意識する
- LangFuseのようなオープンソースツールで低コストに始められる