ユーザーから、昨日午後エージェントが「奇妙なことをした」との報告がありました。ログを開くと、次の内容が見つかります。 ``` INFO agent run started INFO calling tool: updateOrder INFO tool returned 200 INFO agent run completed ``` エージェントは`updateOrder`を呼び出しました。どの引数で、どの注文に対して、なぜそのツールを選んだのか、何が返されたのか、あなたには分かりません。記録されたすべての指標によれば実行は成功しており、エージェントが行った単一の決定も再現できません。 エージェントシステムは、後から振り返って初めて意味が分かるような方法で失敗します。これは、ログがその成果物であることを意味します。このガイドでは、すべてのツール呼び出しで何を記録すべきか、モデルの決定を生成されたHTTPリクエストと関連付ける方法、何を編集(リダクト)すべきか、そしてトレースをテストに変える方法について説明します。APIオブザーバビリティに関する弊社の記事ではサービス側をカバーしていますが、この記事ではその上に位置するエージェントレイヤーを扱います。 トレースがあれば、Apidogは非常に役立ちます。なぜなら、問題のある呼び出しを理解する最も速い方法は、同じエンドポイントに対してそれをリプレイし、何が起こるかを確認することだからです。
3つのレイヤー、1つのトレース
エージェントは3つのレベルでイベントを生成しますが、ほとんどのチームは中間のレベルのみをログに記録しています。 **推論レイヤー**は、モデルが決定を下す場所です。どのようなコンテキストにあったか、どのツールが提供され、どれが選択され、どのような引数が使われたかなどです。 **ツールレイヤー**は、あなたのエクゼキュータです。引数を検証し、ポリシーを適用し、呼び出しをHTTPリクエストにマッピングし、結果を処理します。 **HTTPレイヤー**は、通信線です。メソッド、URL、ヘッダー、ボディ、ステータス、レイテンシーが含まれます。 デバッグはほとんどの場合、複数のレイヤーをまたがります。「エージェントが間違った顧客IDを送信した」というのは、HTTPレイヤーでしか見えない推論の問題です。「APIが空のボディで200を返した」というのは、3ステップ後に奇妙な推論として現れるHTTPの問題です。もしこれら3つのレイヤーが共通の識別子で結びつけられていない場合、タイムスタンプで相関付けを行うしかなく、2つの実行が重なった瞬間に機能しなくなります。 したがって、最初のルールは次のとおりです。エージェントの実行ごとに1つのトレースID、ツール呼び出しごとに1つのスパンIDを持ち、これら両方をすべてのレイヤーのすべてのレコードにスタンプすることです。OpenTelemetryトレースはすでにこの形状を正確にモデル化しており、データをポータブルにするための属性命名のためのGenAIセマンティック規約のセットが増えつつあります。
すべてのツール呼び出しで何を記録すべきか
実際の疑問に答えるレコードは、おおよそ以下の形状をしています。
{
"trace_id": "run_01J8ZK3M2Q",
"span_id": "call_004",
"parent_span_id": "call_003",
"timestamp": "2026-08-26T14:03:11.482Z",
"agent": "billing",
"step": 4,
"tool_name": "refundOrder",
"tool_args": { "orderId": "ord_92", "amount": 1200, "reason": "duplicate" },
"tools_available": ["getOrder", "listOrders", "refundOrder", "voidInvoice"],
"http": {
"method": "POST",
"url": "/v1/orders/ord_92/refund",
"request_body_hash": "sha256:1f4c...",
"status": 200,
"duration_ms": 412,
"retry_count": 1,
"idempotency_key": "9f2b7c14-6d3a-4b18"
},
"outcome": "success",
"tokens": { "prompt": 8420, "completion": 96 },
"policy": { "approval_required": true, "approved_by": "user_31", "dry_run": false }
}
特に重要な5つのフィールドがあります。 `tool_args`は最もよく欠落しているフィールドであり、常に必要とされるものです。エクゼキュータが引数を正規化する前に、モデルが生成した引数をログに記録してください。エージェントが間違ったIDを送信した場合、ここでそれが明らかになります。 `tools_available`は選択を説明します。モデルが奇妙なツールを選択した場合、最初に問われるのは他にどのような選択肢があったかです。このフィールドは数バイトのコストで即座にその疑問に答えます。 `retry_count`は「APIが遅かった」と「APIが2回失敗してから成功した」を区別します。これがなければ、3回の試行も1回の呼び出しのように見えてしまいます。 `outcome`は、ステータスコードから推測されるものではなく、明示的な列挙型であるべきです。`success`(成功)、`failed`(失敗)、`timed_out`(タイムアウト)、`blocked_by_policy`(ポリシーによりブロック)、`rejected_by_human`(人間によって拒否)。最後の2つが重要なのは、ブロックされた呼び出しはエラーではなく機能しているガードレールであり、それらを混同すると失敗率が損なわれるからです。 `policy`はあなたの監査証跡です。誰かが破壊的なアクションが承認されたかどうかを尋ねたとき、これがその答えとなります。AIエージェントのガードレールに関する弊社の記事で説明されている実施と対をなします。
アクションだけでなく、決定もログに記録する
最も難しいエージェントのバグは選択に関するものであり、それらを再構築できるだけの情報を記録してください。 実行に使用されたツール定義、またはそのハッシュを保持してください。選択の精度が変化した場合、最初に疑われるのは誰かが編集した記述であり、ハッシュがあれば良好な実行と問題のある実行の間でツールセットが変更されたかどうかを即座に知ることができます。ツールスキーマ設計に関する弊社の記事では、なぜそのテキストが振る舞いに大きな影響を与えるのかについて説明しています。 モデルとその設定を記録してください。モデルID、温度、プロンプトバージョンは実行レコードに含めるべきです。モデルバージョン間で動作は変化するため、このフィールドがないと、自分のコードを調査するのに丸一日を費やすことになります。 モデルが見たもの、または少なくともそのサイズを記録してください。完全なプロンプトダンプはストレージコストが高く、しばしば機密情報を含みます。トークン数とハッシュがあれば、診断価値のほとんどが得られます。通常の2倍のサイズのプロンプトを持つ実行は、本来追加されるべきでなかった何かが追加された実行です。 トリミング前の生のツール結果を記録してください。もしエクゼキュータがモデルに渡す前にレスポンスを削減する場合(コンテキストウィンドウからツールレスポンスを外すに関する弊社の記事のように)、トレースにはペイロード全体を保存してください。そうしないと、データが欠落していたのか、あなたがそれを削除したのかを判断できません。
保存する前に編集(リダクト)する
エージェントのトレースは、リクエストとその周囲の推論の両方を含み、プロンプトが個人データを収集する傾向があるため、特に危険です。 これを管理するための4つのルールがあります。 認証情報を決して保存しないでください。`Authorization`、APIキー、クッキー、署名付きURLはすべて削除してください。認証情報の値ではなく、キーIDのような識別子をログに記録してください。エージェント向け最小特権APIキーに関する弊社の記事では、なぜその識別子が必要なのか(どのエージェントが行動したかを示すため)を説明しています。 クエリではなく、境界で編集(リダクト)してください。読み取り時にフィルタリングするということは、秘密がディスクに書き込まれ、複製され、バックアップされたことを意味します。レコードがプロセスを離れる前に、ロギングミドルウェアで編集してください。 保存できないボディはハッシュ化してください。リクエストボディのハッシュは、ペイロードを保持せずに、2つの呼び出しが同一であったことを証明するのに役立ちます。これは重複調査に必要なことのほとんどです。 保持期間を機密性に応じて設定してください。完全なトレースは1週間、編集済みのサマリーは1年間。ほとんどのデバッグは数日以内に行われますが、ほとんどの監査質問は数ヶ月以内に発生します。
トレースをテストに変える
優れたトレーシングの利点は、デバッグの高速化だけではありません。現実的なテストケースの供給源となります。 すべての失敗した実行はシナリオです。問題のあるトレースからツール呼び出しを取り出し、それをあなたのAPIに対してリプレイすれば、再現が得られます。修正が適用されたら、そのリプレイを回帰テストとして保持してください。Apidogでは、失敗したリクエストを保存されたケースとして再構築し、修正された動作をアサートしてCIで実行できます。これにより、一度限りのインシデントが恒久的なカバレッジに変わります。 トレースはまた、何をモックすべきかを教えてくれます。エージェントが最も頻繁に呼び出すエンドポイントや、実際に遭遇する失敗ステータスは、推測ではなくデータから直接得られます。それらに基づいてモックを作成し、本番ではなくモックに対してエージェントを実行するに関する弊社の記事に従ってください。 そして、見過ごしてしまうような緩やかな変化を表面化させます。週にいくつかの数値を追跡してください。ツール選択の分布、エンドポイントごとのリトライ率、完了したタスクごとの呼び出し数、ポリシーによってブロックされた実行の割合です。これらいずれかの変化は、インシデントになる前の信号です。API契約テストガイドにあるような契約レベルのチェックは、通常その原因となる上流の変化を捉えます。
トレースが乗り越えなければならない3つの調査
**「エージェントが間違った顧客に課金した。」** モデルが生成した引数、解決されたURL、そしてその前のステップが必要です。十中八九、IDは複数のマッチを返した以前のツール結果から来ており、モデルが最初の一つを選んだものです。トレースは以前の結果、曖昧さ、そして選択を示します。`tool_args`がなければ、`200`という結果と非常に不満な顧客がいるだけです。 **「火曜日に機能しなくなった。」** 良好な実行と問題のある実行をフィールドごとに比較してください。モデルID、ツールセットハッシュ、プロンプトバージョン、平均レスポンスサイズなど。何かが変更されており、通常はこれら4つのうちの1つが原因を示します。これが、実行レコードがイベントだけでなく設定も含む理由です。差分は、両側が同じフィールドを記録している場合にのみ可能です。 **「誰かがこれを承認したのか?」** ポリシーブロックがその問いへの完全な答えであり、それは後から再構築するのではなく、決定の瞬間に記録されるべきです。`approval_required`、`approved_by`、およびタイムスタンプがあれば、緊張した会話を単なる検索に変えることができます。 これらに共通している点に注目してください。いずれも「ツールが200を返した」では答えられません。3つすべてが、記録するのにほとんどコストがかからず、後から回復することが不可能なフィールドによって答えられます。
サンプリングと、決してサンプリングしてはならないもの
すべての実行で高精度のトレーシングを行うと、量が増えるにつれて高価になるため、チームはサンプリングを行います。エージェントのトラフィックは一様ではないため、慎重にサンプリングしてください。 常に、失敗したすべての実行、ポリシーブロックに当たったすべての実行、書き込みを含むすべての実行を保持してください。これらは誰かが尋ねる可能性のある実行です。成功した読み取り専用の実行は、ボリュームの大部分を占め、個々には最も関心が薄いため、サンプリングしてください。ただし、ベースラインを計算するのに十分な量は必要です。 GoogleのSREブックのモニタリングに関する章は、なぜボリュームではなくシグナルのためにサンプリングするのかを最も明確に述べており、その推論は直接的に当てはまります。 ペイロードを破棄する場合でも、実行レコードは保持してください。ツール名、結果、期間を含むスケルトントレースは小さく、上記の4つのメトリクスを依然としてサポートします。コストがかかるのはボディとプロンプトであり、これらが最初に破棄できる部分です。 テールサンプリングに関する注意点:実行が終了した後に何を保持するかを決定する場合、その決定が結果が判明した後に行われることを確認してください。ステップ3では問題なく見え、ステップ9で失敗する実行は完全に保持される必要があり、これは進行中に破棄するのではなくバッファリングすることを意味します。
トレースはどこに存在するべきか
上記すべては、あなたがストレージを所有していることを前提としています。エージェントがあなたのサービスで、あなたのAPIを呼び出している場合は、それは正しい仮定です。しかし、エージェントが開発者マシンのコーディングランタイムである場合、そのトレースは実行されたターミナルに残るため、この前提は適切ではありません。 Sharklyは別のアプローチを取ります。実行トレースはエージェントに割り当てられたタスクに紐付けられます。実行履歴、実行ログ、結果は、目標、ステータス、そして人間が作業をレビューしたコメントスレッドの隣に置かれます。実用的な違いは検索にあります。「なぜエージェントはそんなことをしたのか」という質問は、マシン、セッション、スクロールバックを探すのではなく、タスクを開くことで答える問題になります。

これはここで説明されているトレーシングを置き換えるものではなく、ランタイムを置き換えるものでもありません。Claude CodeやCodexは依然として作業を行います。これが変えるのは、エージェントがあなたがデプロイしたサービスではない場合、レコードがどこに保管されるかという点です。
4つの数値を監視する
トレースは、誰かが見て初めて役立ちます。これら4つの数値はダッシュボードに置かれるべきものです。 **完了したタスクあたりの呼び出し数。** 最も明確な効率性指標です。この数値が上昇した場合、エージェントがより多くの探索をしていることを示します。通常は、記述が悪化したか、エンドポイントが失敗し始めたためです。 **エンドポイントごとのリトライ率。** 最も信頼性の低い依存関係をランク付けし、いつ劣化が始まったかを示します。エージェントエラー回復に関する弊社の記事では、そのリストの上位にあるものにどう対処すべきかを説明しています。 **ポリシーによるブロック率。** 低く安定しているべきです。急上昇は、エージェントがすべきでないことを試みているか、ポリシーが厳しすぎてボトルネックになっているかのいずれかを意味します。 **最初のツール呼び出しまでの時間。** 開始が遅い場合、通常はプロンプトが肥大化していることを意味します。プロンプトサイズは、誰も意図せずとも大きくなるものです。
チェックリスト
- 実行ごとに1つのトレースID、ツール呼び出しごとに1つのスパンIDを、3つのすべてのレイヤーにスタンプする。
- モデルの引数は正規化前にログに記録する。
- すべての呼び出しで利用可能なツールリストを記録する。
- ポリシーブロックを含む結果を明示的な列挙型として記録する。
- リトライ回数は呼び出し回数とは別に記録する。
- 実行レコードに、モデル、温度、プロンプトバージョン、ツールセットのハッシュを含める。
- トリミングされたモデルに渡されたバージョンだけでなく、生のツール結果を保存する。
- ミドルウェアで認証情報を削除し、保存できないボディはハッシュ化する。
- 保持期間を機密性に応じて階層化する。
- 失敗したトレースをリプレイ可能なテストケースに変換できるようにする。
目標は単純です。誰かがなぜエージェントがそんなことをしたのかと尋ねたとき、推測ではなく記録から答えられるようにすることです。トレース内の呼び出しをリプレイし、再現をテストとして保持するためにApidogをダウンロードしてください。
よくある質問
OpenTelemetryと、専用のエージェントオブザーバビリティツールのどちらを使うべきですか? 相関関係をすでに処理し、あなたのインフラがOpenTelemetryに対応している可能性が高いため、トランスポートとトレースモデルにはOpenTelemetryを使用してください。エージェント固有のツールは、その上に役立つビューを追加しますが、根底にあるデータはポータブルであるべきです。
フルトレーシングのストレージコストはどのくらいですか? 階層化すれば、人々が予想するよりも少ないです。数日間は完全なペイロードを、それ以上はボディなしの構造化されたレコードを保持することで、ほとんどのボリュームを抑えることができます。プロンプトダンプは高価な部分なので、デフォルトで保存するのではなく、ハッシュ化してサイズを記録してください。
モデルの推論テキストをログに記録する必要がありますか? 通常は必要ありません。選択したツール、生成した引数、および利用可能なオプションがほとんどの決定を説明します。プロバイダーが推論コンテンツを公開している場合、失敗した実行の場合のみそれを保存し、機密情報として扱ってください。
複数のエージェント間でトレースする方法は? タスク全体に対して1つのトレースIDを保持し、各エージェントに独自のスパンを与え、引き渡し(handoff)をイベントとして記録します。マルチエージェントの引き渡しに関する弊社の記事では、その引き渡し記録に何を含めるべきかについて説明しています。
エージェントが顧客のマシンで実行される場合はどうなりますか? ユーザーがオプトインしない限り、ローカルにログを記録し、厳しく編集(リダクト)し、集計メトリクスのみを送信してください。ツール名、結果、期間は、デバイスからペイロードを送信することなく、フリートレベルのモニタリングには通常十分です。
リクエストボディのハッシュは本当に役立ちますか? はい、最も一般的な質問に対しては役立ちます。ペイロード自体を保持することなく、2つの呼び出しが同一であったことを証明し、ほとんどの重複書き込み調査を解決します。重複を防ぐはずだったべき等性キーと組み合わせてください。
