B2BB2B LLM
ビジネスに関する洞察

OpenTelemetry を使用してプロバイダー中立の LLM 可観測性を構築する方法

スパン設計、GenAI 属性、プライバシー制御、テール サンプリング、ダッシュボード、コントラクト テストなど、マルチモデル API ゲートウェイ層で LLM 可観測性を計測するための実践的な実装ガイド。

すべてのアプリケーション チームがプロバイダーの応答を独自の形式でログに記録すると、LLM の可観測性が損なわれます。インシデントが発生した際、プラットフォーム チームは具体的な質問に答える必要があります。つまり、どのチームがリクエストを行ったのか、どの API キー スコープが使用されたのか、どのモデルがリクエストされたのか、どのプロバイダが実際にサービスを提供したのか、再試行またはフォールバックが発生したかどうか、消費されたトークンの数、どのレイテンシ バケットが変更されたのか、失敗の原因となったエラー クラスは何かなどです。また、生のプロンプト、入力完了、プロバイダー キー、または顧客 ID を汎用ログ ストアにコピーすることなく、これらの回答が必要です。

実際的な解決策は、マルチモデル API ゲートウェイを可観測性コントロール ポイントとして計測することです。アプリケーション レベルのトレースは依然として重要ですが、ゲートウェイは、テレメトリがダウンストリーム ツールに到達する前に、プロバイダーの選択、再試行、フォールバック、使用状況のアカウンティング、リクエストの所有権、およびプライバシーの適用を正規化できる場所です。 エンタープライズ LLM API を運用しているチームの場合、これが散在するデバッグ データとプロバイダ中立の運用モデルの違いになります。

最初にオブザーバビリティ コントラクトを定義します

ダッシュボードのスクリーンショットではなく、書面による属性コントラクトから始めます。コントラクトでは、すべての LLM リクエストが発行する必要がある最小限のメタデータ、どのフィールドがゲートウェイからの送信を許可されるか、どのフィールドが制限されるか、どのフィールドがエクスポートされないかを定義する必要があります。

有用なベースライン コントラクトには、所有権、ルーティング、モデル、使用状況、レイテンシ、結果のメタデータが含まれます。所有権属性は、組織、チーム、環境、ワークロード、アプリケーション、および API キーのスコープを識別します。ルーティング属性は、ゲートウェイ ルート、ポリシー バージョン、要求されたプロバイダー、要求されたモデル、選択されたプロバイダー、選択されたモデル、再試行回数、フォールバック数、およびストリーミングが使用されたかどうかを識別します。使用状況属性は、入力トークン、出力トークン、キャッシュされた入力トークン、利用可能な場合の推論トークン、リクエスト数、および推定コスト クラスをキャプチャします。結果属性は、ステータス、安全な場合のプロバイダ エラー コード、正規化されたエラー クラス、検証結果、タイムアウト状態、最終応答モデルをキャプチャします。

コントラクトをプロバイダ中立に保ちます。レート制限応答、オーバーロードされたモデル応答、スキーマ検証の失敗、安全性の拒否、タイムアウト、またはコンテキスト ウィンドウ エラーなどのプロバイダー固有のエラーは、ダッシュボードがプロバイダー間でグループ化できる正規化されたエラー クラスにマップする必要があります。元のプロバイダーのエラー コードは役立つ可能性がありますが、ダッシュボードのプライマリ ディメンションではなく、制限された診断データとして扱う必要があります。

ゲートウェイ中心のスパン モデルを使用する

明確なトレース構造により、LLM テレメトリが平らなスパンの山になるのを防ぎます。ゲートウェイが実行する作業には、1 つの受信アプリケーション リクエスト スパン、1 つの論理 LLM 操作スパン、および子スパンを使用します。

一般的な階層は次のようになります。

inbound.http_request
  llm.operation
    llm.provider_attempt
    llm.provider_attempt.retry
    llm.provider_attempt.fallback
    retrieval.query
    tool.call
    output.validation

受信リクエスト スパンは、ゲートウェイに対する呼び出し側のリクエストを表します。論理 LLM 操作スパンは、ゲートウェイがプロバイダーを複数回試行した場合でも、ユーザーに表示される LLM タスクを表します。プロバイダーの試行スパンは、上流モデル API への実際の呼び出しをそれぞれキャプチャします。取得、ツール、検証スパンは、最終応答生成の一部である場合、論理操作の子である必要があります。

インシデント時には、この分離が重要です。リクエストがあるモデルから別のモデルにフォールバックする場合、最初のプロバイダーの試行は失敗しても、論理操作は成功する可能性があります。最終出力がスキーマ検証に失敗した場合、プロバイダーの試行は技術的には成功する可能性がありますが、論理操作は失敗します。個別のスパンを使用しない場合、ダッシュボードは、成功したエンドユーザーの応答の背後にプロバイダーの障害を隠したり、正常に回復した障害を誇張したりすることになります。

内部マッパーの背後で OpenTelemetry GenAI 属性をマップする

OpenTelemetry のセマンティック規則が存在するため、テレメトリ プロデューサーはコードベース、ライブラリ、プラットフォーム全体で共通の名前と属性を使用します。OpenTelemetry プロジェクトでは、Generative AI 規約が別の GenAI リポジトリを指すようになり、これらの規約は、プロバイダー名、リクエストされたモデル、レスポンス モデル、入力トークン、出力トークン、推論トークン、キャッシュされた入力トークンなどのモデルのリクエスト属性とレスポンス属性を定義します。

これらの GenAI 属性は適切な場所で使用しますが、生の属性名をゲートウェイ コード全体に分散させないでください。それらを小さなテレメトリ マッパーの後ろにラップします。このマッパーは、内部リクエスト レコードを受け入れ、標準化されたスパン属性を生成する必要があります。

record LlmTelemetryContext {
  organization_id
  team_id
  environment
  api_key_scope
  route_name
  route_policy_version
  workload_class
  provider_requested
  model_requested
  provider_selected
  model_response
  input_tokens
  output_tokens
  cached_input_tokens
  reasoning_tokens
  retry_count
  fallback_count
  normalized_error_class
}

マッパーは、標準フィールドの OpenTelemetry GenAI 属性と、ビジネス コンテキストのプライベート ゲートウェイ属性を出力できます。 llm_gateway.organization_id、llm_gateway.team_id、llm_gateway.key_scope、llm_gateway.route_policy、llm_gateway.workload_class などのプライベート属性を制御された名前空間に保持します。

この設計により、コードベースをチャーンから保護しながら、ベンダー中立のテレメトリが得られます。 GenAI の規約はまだ進化しているため、マッパーでは、すべてのハンドラー、再試行モジュール、ストリーミング アダプター、および検証コンポーネントを編集せずに名前を変更できます。

機密コンテンツからメタデータを分離

最も有用なデバッグ データは、プロンプト、取得したドキュメント、ツール パラメーター、完了、ユーザー ID、顧客など、広く保持すべきではないデータと同じである可能性があるため、LLM トレースは非常に機密です。識別子、および生のプロバイダー資格情報。デフォルトの姿勢は、メタデータ優先の可観測性である必要があります。

推奨されるデフォルト フィールドには、プロンプト ハッシュ、プロンプト テンプレート ID、プロンプト バージョン、スキーマ ID、ツール名、取得コレクション、ルート名、トークン カウント、レイテンシ、正規化されたエラー クラス、および検証ステータスが含まれます。これらのフィールドは、生のコンテンツをエクスポートせずに、多くの運用上の疑問に答えます。

生のプロンプトと完了のキャプチャは、エクスポート前にオプトイン、時間制限、アクセス制御、および編集する必要があります。便利な機能としてグローバルに有効にしないでください。本番環境のインシデントでコンテンツ キャプチャが必要な場合は、限られたリクエストのセットにデバッグ フラグを付加し、それらのトレースを制限されたバックエンドにルーティングし、短い保存期間を設定します。

識別子のハッシュ化は、自動的には匿名化されません。入力スペースが小さいか予測可能な場合、推測によってハッシュ値を逆にすることができます。機密性の高い顧客またはユーザー ID の場合は、削除、サロゲート ID、バケット化、切り捨て、または厳格なキー制御によるキー付きハッシュを検討してください。ハッシュは、包括的なプライバシーの答えとしてではなく、主にリスクが理解されている場合の安定した相関関係のために使用します。

コレクターでのプライバシーの強制

OpenTelemetry のガイダンスでは、機密データはエクスポート前に処理する必要があると記載されています。コレクターは、属性、フィルター、編集、変換などのプロセッサーを使用して、テレメトリ属性を削除、ハッシュ、フィルター、編集、または変換できます。これにより、コレクタはゲートウェイ インストルメンテーション自体に続く 2 番目の防御線になります。

実際のコレクタ パイプラインでは、低リスク属性のホワイトリストを使用し、デフォルトで生のプロンプトおよび応答フィールドを削除し、ブロックされたパターンに一致する値をマスクし、コンテンツ キャプチャが明示的に有効になっている場合は高機密のトレースを個別にルーティングする必要があります。 OpenTelemetry Collector 属性プロセッサは、削除やハッシュなどのアクションをサポートします。リダクション プロセッサは、ホワイトリストにない属性を削除し、ブロックされたパターンに一致する値をマスクするように設計されています。

たとえば、ゲートウェイはデフォルトで未加工のコンテンツの出力を回避できますが、コレクターは llm.prompt.raw、llm.completion.raw、provider.api_key、authorization、cookie などの属性がバグまたはライブラリの統合により表示された場合は削除します。これを、安全でないデータを気軽に送信する理由としてではなく、多層防御の制御として扱ってください。

再試行、フォールバック、および検証を個別に計測する

再試行とフォールバックは、多くの場合、集計 API 指標には表示されません。この不可視性により、運用上 2 つの問題が発生します。まず、成功した応答によって複数の失敗した試行が隠蔽される可能性があるため、遅延が悪化する可能性があります。第 2 に、単一のユーザー リクエストで複数のアップストリーム モデル呼び出しが作成される可能性があるため、コストが増加する可能性があります。

各プロバイダの試行範囲には、試行回数、再試行の理由、選択したプロバイダ、選択したモデル、タイムアウト予算、レイテンシ、トークンの使用状況(使用可能な場合)、および結果を含める必要があります。フォールバックが発生した場合、フォールバック スパンは、元のルート ポリシー、フォールバックの理由、および最終応答に実際に使用されるモデルを識別する必要があります。

構造化された出力検証は、独自のスパンまたはイベントである必要があります。スキーマ ID、スキーマ バージョン、検証結果、修復試行回数、および最終ステータスをキャプチャします。デフォルトでは、無効な出力全体を保存しないでください。検証の失敗はプロバイダのトランスポート エラーとは運用上異なり、ダッシュボードではこれらを一緒に混同すべきではありません。

プロバイダではなく質問に基づいてダッシュボードを構築する

プロバイダに依存しない可観測性は、運用上の質問に直接答える必要があります。便利なダッシュボードには、モデル、プロバイダー、チーム、環境、ワークロード クラスごとの p95 および p99 レイテンシーが含まれます。チームおよびルートごとのトークンの使用。正規化されたエラークラス別の故障率。ルートポリシーによる増幅の再試行。要求されたモデルによるフォールバック頻度。プロンプト テンプレートによるコンテキスト ウィンドウ エラー。スキーマによる構造化出力検証の失敗。

サンプリングされたトレースから請求や合計使用量のレポートを作成しないでください。テール サンプリングはデバッグには便利ですが、合計が歪む可能性があります。トークンの合計、リクエスト数、およびコスト台帳は、非サンプリング カウンター、リクエスト台帳、または請求調整システムから取得する必要があります。トレースは、高価なリクエストまたは遅いリクエストが発生した理由を説明する必要があります。財務上の真実の唯一の情報源であってはなりません。

高価値のトレースにはテール サンプリングを使用する

OpenTelemetry Collector のテール サンプリング プロセッサは、スパンの完了後に、属性や数値に基づくポリシーなどのサンプリングの決定を行うことができます。これは、応答が終了した後でのみトレースが価値があるかどうかを知ることができることが多いため、LLM トラフィックにとって役立ちます。

プロバイダー エラー、検証の失敗、非常に長いレイテンシ、異常に高価なトークンの使用量、コンテキスト ウィンドウの失敗、フォールバックの試行、および手動でデバッグタグを付けたリクエストのトレースを保持します。ルーチンの正常なトラフィックを低レートでサンプリングします。これにより、ストレージ ボリュームを制御しながら、インシデントを説明する可能性が最も高いトレースが保持されます。

合理的なポリシー モデルは単純です。エラーを常に保持し、リクエストをレイテンシまたはトークンのしきい値を常に超えて保持し、デバッグ タグ付きトレースを常に保持し、通常の成功したリクエストを確率的にサンプリングします。トラフィックの変化に応じてしきい値を再検討します。初期導入時に便利なしきい値は、運用トラフィックが増大すると低すぎる可能性があります。

テレメトリの契約テストを追加する

テレメトリは、ダウンストリーム ダッシュボード、アラート、コスト管理、インシデント ワークフローに依存するため、API 契約のようにテストする必要があります。代表的なゲートウェイ リクエストを実行し、必要なスパンと属性が出力されることをアサートするテストを追加します。

テストでは、成功したリクエストが論理 LLM 操作スパン、プロバイダ試行スパン、リクエストされたモデル、応答モデル、プロバイダ名、トークン数 (利用可能な場合)、チームまたはキー スコープのメタデータ、ルート ポリシー バージョン、および最終ステータスを出力することを検証する必要があります。再試行テストでは、試行回数と再試行理由をアサートする必要があります。フォールバック テストでは、失敗した試行と最終的に成功したプロバイダー試行の両方をアサートする必要があります。検証テストでは、スキーマ ID、検証ステータス、修復試行回数をアサートする必要があります。

セキュリティ テストも同様に重要です。未加工のプロバイダー キー、認証ヘッダー、Cookie、未加工のプロンプト、未加工のコンプリーション、および未承認の顧客 ID がエクスポートされたテレメトリに存在しないことをアサートします。開発者が分類せずに新しいスパン属性を追加した場合、これらのテストは失敗して終了する必要があります。

実装チェックリスト

  • 属性契約: 必須、オプション、制限付き、および禁止された属性を定義します。
  • スパン階層: 個別の受信リクエスト、論理 LLM 操作、プロバイダー試行、再試行、フォールバック、取得
  • セマンティック マッピング: 適合する場合は OpenTelemetry GenAI 属性を使用し、所有権とルーティング コンテキストにはプライベート ゲートウェイ属性を使用します。
  • プライバシー ポリシー: デフォルトはハッシュ、テンプレート ID、スキーマ ID、ツール名、トークン数、レイテンシー、およびエラーです
  • コレクター プロセッサ: 禁止されたフィールドを削除し、ブロックされたパターンを編集し、低リスクの属性を許可リストに登録し、機密性の高いトレースを個別にルーティングします。
  • サンプリング ポリシー: 高価値のトレースをテールサンプリングし、集計メトリクスを保持します。未サンプリング。
  • ダッシュボード: レイテンシ、使用状況、失敗、再試行、フォールバック、検証、コスト要因に関するビューを構築します。
  • アラート: 正規化されたエラー クラス、p99 レイテンシ シフト、再試行増幅、フォールバック スパイク、検証失敗、トークンに関するアラート異常。
  • 契約テスト: 必要なテレメトリが存在し、機密テレメトリが存在しないことを確認します。

明示的に決定するトレードオフ

ゲートウェイ レベルのインストルメンテーションは一貫したメタデータを迅速に提供しますが、チームがテナントなどの構造化されたリクエスト メタデータを渡さない限り、アプリケーション固有のコンテキストを見逃す可能性があります。ワークフロー、プロンプト テンプレート、および機能名。自由形式のログに依存するのではなく、そのメタデータをゲートウェイ リクエスト コントラクトの一部にします。

完全なコンテンツ キャプチャによりデバッグと評価が向上しますが、プライバシー、セキュリティ、保持、アクセス制御の負担が増加します。多くのチームは、ハッシュ、テンプレート ID、スキーマ ID、編集された抜粋のみから始める必要があります。

プロバイダーに依存しないエラー クラスにより、ダッシュボードは複数のモデル API 間で使用可能になりますが、プロバイダー固有の詳細が圧縮されます。生のプロバイダー エラー コードは安全な場合にのみ保持し、それらへのアクセスを制限します。

OpenTelemetry GenAI 規則によりロックインが軽減されますが、規則は進化し続けます。内部マッパーにより、不安定な属性名がコードベースに漏洩することなく、標準化のメリットが得られます。

結論

プロバイダー中立の LLM オブザーバビリティは、モデル呼び出しにトレースが追加されるだけではありません。これは、ゲートウェイ層での運用契約です。一貫したスパン、正規化されたモデルとプロバイダのメタデータ、所有権コンテキスト、トークンの使用状況、再試行とフォールバックの可視性、プライバシー制御、サンプリング ルール、機密データの漏洩を防ぐテストです。

ゲートウェイから始めましょう。最も重要な決定がゲートウェイですでに確認されているためです。つまり、誰がリクエストを行ったか、どのポリシーがリクエストをルーティングしたか、どのプロバイダがサービスを提供したか、トークンのコスト、所要時間、回復ロジックが実行されたかどうか、何が失敗したかなどです。基盤が安定すると、アプリケーション チームは、各チームが独自の LLM 可観測性システムを発明しなくても、より豊富なワークフロー コンテキストを追加できます。

関連資料

FAQ

よくある質問

LLM 可観測性はアプリケーション コードで開始する必要がありますか、それとも API ゲートウェイで開始する必要がありますか?
共有コントラクトのゲートウェイから開始します: プロバイダー、モデル、ルート ポリシー、キー スコープ、トークンの使用法、再試行、フォールバック、遅延、正規化されたエラー。アプリケーション チームは、機能名、テナント、プロンプト テンプレート、ビジネス プロセスなどのワークフロー固有のコンテキストを追加できます。
プロンプトと完了はトレースに保存する必要がありますか?
デフォルトではありません。プロンプト ハッシュ、テンプレート ID、スキーマ ID、ツール名、トークン数、レイテンシ、エラー クラスを最初に保存します。生のコンテンツのキャプチャはオプトイン、時間制限、アクセス制御が必要で、エクスポート前に編集する必要があります。
サンプリングされたトレースは LLM コストのレポートに使用できますか?
サンプリングされたトレースは、高価なリクエストや失敗したリクエストのデバッグに役立ちますが、合計の唯一のソースにするべきではありません。トークンの使用量と請求メトリクスは、サンプリングされていないカウンター、リクエスト台帳、またはプロバイダーの請求調整から得られる必要があります。
OpenTelemetry GenAI のセマンティック規則を使用する理由は何ですか?
これらは、プロバイダー、要求されたモデル、応答モデル、トークン数など、モデルの要求と応答に共通の属性名を提供します。内部マッパーを通じてこれらを使用するため、規約の変更にゲートウェイ全体にわたる編集が必要なくなります。