トレーシング
トレーシングはループのどこに位置するか
従来のソフトウェアの多くは決定論的で、実行は事前に定義された形式に従います。 LLM アプリケーションではそうはいきません。 エージェントの実行は整然とは進まず、予期しない入出力や実行順序を伴う創発的な挙動を扱うことになります。 エージェントの挙動を追うには別の手段が必要です。 それが トレース です。
トレースとは、ある 1 つのリクエストに対してアプリケーションが何をしたかを構造化して記録したものです。 どのステップを踏んだか、どんなデータを参照したか、何を生成したかが残ります。
トレーシングは改善ループ全体の中心にあります。 レビュー、データセット構築、実験の実行、評価という他のすべてのステップは、トレースを基盤として動きます。
従来のオブザーバビリティの概念に既に慣れている方は、以下の内容が繰り返しに感じられるかもしれません。 読み飛ばしたり、先のセクションに進んだりしても問題ありません。
トレースの構造
トレースは、アプリケーションの要求に応じて複雑にも単純にもなりますが、基本構造はすべて共通です。 エージェントが辿った経路を表す オブザベーション の集合で構成されます。
オブザベーションとは、プロセスの中の 1 ステップです。 入力、出力、開始・終了時刻、そしてそのステップで何が起きたかを示すメタデータを持ちます。
階層構造
トレースは階層的な木構造を持ちます。 内部にはオブザベーションが入れ子になっており、別のオブザベーションを子に持つこともできます。 親子構造は AI アプリケーションの実際の実行をそのまま反映します。
何がどの順番で起きたか、どのステップがどの上位ステップの一部だったかを確認できます。
オブザベーションのデータ
入力と出力。 各オブザベーションは入力と出力を持てます。 ほとんどの場合は両方を持ちますが、特定のケースではどちらか一方だけのこともあります。 解釈しやすさのため、そのステップで起きている処理に対して意味のある入力・出力を設定することが重要です。
オブザベーションの種別。 操作の種類を区別しやすくするため、複数の オブザベーション種別 が用意されています。 それぞれの種別は、エージェントの異なる種類の相互作用を記録するために使います。
| エージェントの動作 | オブザベーション種別 | 典型的なオブザベーションの入出力 |
|---|---|---|
| 言語モデルの呼び出し | generation | プロンプト全体やメッセージ履歴を入力、補完を出力、加えてモデル名やトークン数などのメタデータ |
| 外部ソースから情報を取得するステップ | retriever | クエリと取得されたドキュメント |
| エージェントによるツール・関数の呼び出し | tool | どのツールが呼ばれたか、引数、戻り値 |
| 汎用的な処理 | span | ユースケースに大きく依存 |
オブザベーション種別があると、トレースが読みやすくなりフィルタリングも容易になります。 20 個のオブザベーションを含むトレースで LLM 呼び出しを一瞬で見分けられると、時間の節約になります。
コスト、レイテンシー、トークン使用量
入力と出力以外にも、LLM アプリケーションでは必須となる属性がいくつかあります。 コスト、レイテンシー、そして トークン使用量 です。 これらはオブザベーション単位で記録され、トレースレベルで集計されます。
トレースとセッション
エージェントのライフサイクル全体を 1 つのトレースとして見ることは、通常はありません。 トレースは セッション でグループ化できます。 ではトレースとセッションの境界はどこで引くべきでしょうか?
一般的な目安は次のとおりです。 1 トレースは、システムの 1 回の呼び出しに対応します。 通常は 1 回の API 呼び出し、または 1 回のエージェント実行です。 そしてセッションは複数のトレースをまとめます。 たとえばマルチターン会話の全ターンをまとめる、といった具合です。
具体例として、トレースとセッションの分割をどう設計したかの 2 つのアプリケーション例を示します。
SaaS 企業のヘルプページに埋め込まれたカスタマーサポートチャットボット。 ユーザーはアカウント・請求・製品の使い方について質問するために開きます。 典型的なセッションは、課題が解決するか、人間のエージェントに引き継がれるまでの数往復のやり取りです。
トレースとセッションの分割は次のようになります。
Session: conversation_8f2a
├── Trace: "Why was I charged twice this month?"
├── Trace: "Can you refund the duplicate?"
└── Trace: "Thanks, when will I see it?"こうすることで、ある入力に対するチャットボットの実行を 1 つのトレース単独で評価できます。 会話全体を確認したいときはセッション全体を見ます。
オープン中のプルリクエストにコミットがプッシュされるたびに動く、自動コードレビューエージェント。 実行のたびに diff と周辺ファイルを読み、静的チェックを実行し、インラインレビューコメントを投稿します。 1 つの PR のライフサイクル全体で、著者の修正に応じて複数回のレビュー実行が行われるのが普通です。
トレースとセッションの分割は次のようになります。
Session: PR #1234
├── Trace: review run on commit a3f9b
├── Trace: review run on commit c7d2e
└── Trace: review run on commit 8b1f0ここでは 1 トレース = 1 回のレビュー実行です。 コメントの質は、何を読んだかに依存します。 1 回のレビュー実行のステップを個別のトレースに分割すると、コンテキストが散らばってレビューを追いにくくなります。
共通のトレードオフは次のとおりです。 分割を細かくしすぎるとトレースの文脈が読めなくなります。 大きくしすぎると、個別の失敗が読めないトレースの中に埋もれます。
どこから始めるか
これから始める方は、すべての経路をカバーしようとするのではなく、1 つの実際のワークフローを端から端まで計装することに集中してください。
- アプリケーションの重要なリクエスト経路を 1 つ選び、トレーシングを設定する
- 各オブザベーションが、そのステップに有用な入力・出力・メタデータを記録していることを確認する
- 実トレースをいくつか手動でレビューし、構造がデバッグに使えるほど追いやすいかを確認する
次のステップ
トレースが見えるようになったら、次は モニタリング に進めます。 モニタリングは、トレースをエージェントの改善・反復ループに接続するものです。
Last edited