ガイドと洞察

マルチモデル API ゲートウェイの LLM 可観測性: トレース、トークン台帳、テナント分析、安全なプロンプト ロギング

マルチモデル AI ゲートウェイ向けの実用的な可観測性アーキテクチャ: すべての LLM 呼び出しを 1 回トレースし、テレメトリをトークン台帳とコスト台帳に結合し、プロバイダーの請求書を調整し、デフォルトで生のプロンプトを保存せずに安全にデバッグします。

お客様から、昨日あるワークフローがなぜ遅くなったのか、より高価になったのか、または信頼性が低くなったのかを尋ねられた場合、リクエスト数や毎月の費用を集計するだけでは十分ではありません。マルチモデル API ゲートウェイは、可観測性をコントロール プレーンの一部として扱う場合、その質問に答えることができます。つまり、すべてのリクエストがトレースを取得し、すべてのモデル呼び出しで使用状況台帳が更新され、すべてのテナントとワークフローが帰属可能であり、機密コンテンツはデフォルトで保護されます。

この記事では、OpenAI 互換 API を通じて複数のプロバイダーに対応するゲートウェイでの AI 使用状況分析と LLM 可観測性の実用的な設計について説明します。このパターンは、特定のベンダーを使用しない場合でも役立ちます。つまり、ゲートウェイで一度計測し、モデル テレメトリを正規化し、請求の帰属を保持し、明示的なポリシーに基づいてのみプロンプト コンテンツをキャプチャします。

リーダーの問題: 「変更の原因となったテナント、モデル、プロンプト、または取得パスはどれですか?」

ほとんどのチームは最終的に同じデバッグ ギャップに直面します。アプリケーション ログには、機能が失敗したことが示されています。プロバイダーのダッシュボードには、トークンの使用量が増加していることが示されています。財務部門は請求書を確認します。これらのビューはいずれも、それ自体では、テナント リクエストからモデル呼び出し、取得コンテキストへの完全なパスを説明して請求コストを再試行するものではありません。

目標は、合計トークンを含む別のダッシュボードではありません。目標は、次のような運用に関する質問に答えることです:

  • どのテナントまたは API キーが支出の急増を引き起こしましたか?
  • モデルのエイリアスが変更された後、レイテンシは増加しましたか?
  • 再試行またはフォールバックはコストを二重にカウントしますか?
  • 最も多くのエラー バジェットを消費するプロンプト バージョンはどれですか?
  • 取得によって追加されたコンテキスト トークンが多すぎるため、RAG ワークフローのコストが高くなりましたか?
  • プライベート ユーザー プロンプトを読まずにインシデントのデバッグをサポートできますか?

事実、推奨事項、予測

事実: OpenTelemetry は、チャット、generate_content、text_completion などの操作名を含む、モデル操作の生成 AI セマンティック規則と属性を文書化します。同じドキュメントでは、GenAI の入力および出力メッセージ属性には機密情報または PII が含まれる可能性があり、フィルタリングまたは切り捨てが必要になる可能性があると警告しています。主要なモデルプロバイダーも、プロバイダー側の調整をサポートできる使用状況ダッシュボード、API、またはエクスポートを公開していますが、詳細はプロバイダーによって異なります。

推奨事項: プロバイダーに依存しないトレースには OpenTelemetry を使用しますが、ゲートウェイ所有のビジネス ディメンションは独自の属性と台帳に保持してください。デフォルトでは、生のプロンプトまたは出力を保存しません。メタデータ、ハッシュ、トークン数、プロンプト テンプレート ID、スキーマ名、エラー クラス、および安全ラベルを最初に保存します。コンテンツ キャプチャは、オプトインでアクセス制御された短期間のデバッグ機能としてのみ追加してください。

予測: LLM の可観測性は、分離されたプロバイダーのダッシュボードではなく、クロスプロバイダーのコントロール プレーンに依存するようになるでしょう。チームは、レイテンシ、コスト、品質、ポリシー イベント、テナントの動作、モデル間の請求の差分を 1 か所で調査できることを期待します。

リファレンス アーキテクチャ: リクエスト パス全体を観察します

ゲートウェイは、すべてのアプリケーション チームがカスタム テレメトリを構築する必要がなく、リクエストのライフサイクル全体を確認できます。有用なトレース モデルは、受信顧客リクエストの 1 つの親スパンと、コスト、レイテンシ、品質に影響を与えるステップの子スパンから始まります。

推奨されるスパン構造

  • ゲートウェイ リクエスト スパン: リクエストは受け入れられ、認証され、許可され、レート制限され、ルーティングされました。
  • モデル呼び出しスパン: プロバイダー、モデル、オペレーション、トークンの使用状況、応答ステータス、レイテンシ。
  • 取得スパン: クエリされたインデックス、ドキュメント ID またはハッシュ ID、チャンク カウント、取得レイテンシ、およびコンテキスト トークン シェア。
  • ツール呼び出しスパン: ツール名、ステータス、レイテンシ、エラー クラス、および副作用の分類。
  • 再試行範囲: 再試行理由、試行回数、プロバイダーのステータス、および増分コスト。
  • フォールバック スパン: 元のモデル、フォールバック モデル、トリガー、互換性ポリシー、および最終結果。
  • ガードレールまたはモデレーション スパン: ポリシーの呼び出し、決定、ラベル、出力がブロックされたか変換されたかどうか。
  • 後処理スパン: JSON 検証、スキーマ修復、引用チェック、または最終的な書式設定。

親スパンには安定した相関識別子が含まれている必要があります。子スパンには、正規化された技術属性が含まれている必要があります。使用状況台帳には、永続的な請求および分析記録が含まれている必要があります。すべての情報をメトリクス ラベルに強制的に組み込むことは避けてください。テナント ID、プロンプト ハッシュ、ドキュメント ID などのカーディナリティの高い値は、トレース、ログ、台帳テーブルに保存し、ダッシュボードに集約する方が適切です。

すべての LLM 呼び出しでキャプチャされたメタデータを正規化します

プロバイダーに関係なく、すべてのモデル リクエストで一貫したレコードが生成される必要があります。正確なスキーマは異なりますが、実用的な最小値は次のようになります:

{
  "request_id": "req_01J...",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "tenant_id": "tenant_123",
  "team_id": "team_456",
  "app_id": "support_bot",
  "gateway_key_id": "key_789",
  "operation": "chat",
  "provider": "provider_name",
  "model": "provider-model-id",
  "model_alias": "fast-support-chat",
  "prompt_template_id": "refund_policy_v5",
  "prompt_hash": "sha256:...",
  "response_schema": "support_answer_v2",
  "status": "completed",
  "error_class": null,
  "latency_ms": 1842,
  "input_tokens": 2110,
  "output_tokens": 384,
  "cached_input_tokens": 1200,
  "estimated_cost_usd": "0.00492",
  "final_billed_cost_usd": null,
  "finish_reason": "stop",
  "retry_count": 0,
  "fallback_used": false,
  "content_capture_policy": "metadata_only"
}

2 つのアイデアを分けてください。telemetry は何が起こったのかを説明し、使用状況台帳 は請求、調整、報告する必要があるものを記録します。これらはリクエスト ID とトレース ID で相互に参照しますが、同じストレージ システムに存在する必要はありません。

カウンターだけでなく、トークンとコスト台帳を作成する

トークン カウンターはグラフには便利ですが、請求やインシデントの調査には十分ではありません。台帳は状態の遷移を表す必要があります。ゲートウェイがリクエストを受け入れるときに行を作成し、リクエストの進行に応じて行を更新します。

便利な台帳の状態

  • accepted: 認証とポリシー チェックに合格しました。
  • forwarded: リクエストはプロバイダに送信されました。
  • ストリーミング: プロバイダはトークンを返し始めました。
  • 完了: 応答は正常に終了しました。
  • user_aborted: クライアントは完了前に切断されました。
  • 再試行: 追加のプロバイダ試行が行われました。
  • fallback_used: 失敗またはポリシー一致の後に、別のモデルまたはプロバイダが選択されました。
  • 失敗しました: リクエストは使用可能な応答なしで終了しました。
  • 調整済み: プロバイダー側の使用量またはコスト データが比較され、適用されました。

この状態モデルは、一般的な請求エラーや分析エラーを捕捉するのに役立ちます。たとえば、クライアントが切断された場合のストリーミング応答、プロバイダによって請求されたがユーザーには隠された再試行、間違ったモデルをカウントしたフォールバック パス、プロバイダ間のキャッシュ アカウンティングの違いなどです。

OpenTelemetry GenAI 規則を使用し、慎重に拡張します

OpenTelemetry GenAI のセマンティック規則は、モデル操作のための移植可能な語彙を提供します。オペレーション名、プロバイダー、モデル、リクエスト パラメーター、応答終了理由、トークンの使用法、エラー ステータスなどの一般的な属性には、適用される場合はこれらの規則を使用します。

ただし、プロバイダー中立の規約は、ゲートウェイのすべてのビジネス側面をカバーするわけではありません。次のゲートウェイ所有の属性または台帳列を追加します:

  • テナント ID、チーム ID、販売代理店の顧客 ID、アプリ ID;
  • ゲートウェイ API キー ID とキー スコープ;
  • 料金プラン、支出制限、予算ポリシー;
  • モデルのエイリアスとルーティング ポリシーのバージョン;
  • プロンプト テンプレート ID とプロンプト バージョン;
  • ワークフロー名とワークフローステップ;
  • 推定費用、最終請求費用、調整ステータス。

トレードオフはカーディナリティです。これらのフィールドは調査には価値がありますが、あらゆる場所でメトリック ラベルとして使用すると、メトリックが高価になり、ノイズが多くなる可能性があります。実際的なルールは次のとおりです。カーディナリティの低い集計はメトリクスに送られます。カーディナリティの高い識別子は、トレース、ログ、台帳に保存されます。

安全なプロンプトと出力ログを設計する

完全なプロンプト ログによりデバッグが容易になりますが、プライバシー、コンプライアンス、ストレージ、内部関係者のリスクが増大します。より安全なデフォルトは、メタデータ優先の可観測性です。

デフォルト: メタデータのみ

ほとんどの実運用トラフィックの場合、次の場所に保存します:

  • プロンプト テンプレート ID とバージョン;
  • 正規化されたプロンプトと出力のハッシュ;
  • 入力、出力、キャッシュされたトークン、およびコンテキスト トークンの数;
  • 応答スキーマ名と検証結果;
  • 安全ラベルとポリシーの決定;
  • エラーの概要とプロバイダーのエラー クラス;
  • 生のドキュメントではなく、メタデータを取得します。

オプトイン: 制御されたコンテンツのキャプチャ

詳細なデバッグのために生のコンテンツまたは編集されたコンテンツが必要な場合は、明示的なポリシーが必要です。優れた管理には、環境ホワイトリスト、テナントの同意、サンプリング、最大ペイロード長、自動編集、短い保存期間、暗号化、ロールベースのアクセス、監査ログ、機密インシデントの非常に厳格な承認パスが含まれます。

編集を完璧なものとして扱わないでください。それはリスクを軽減します。それを排除するものではありません。規制されているワークロードまたは機密性の高いワークロードの場合は、ハッシュのみを保存し、承認されたテスト データを使用して合成ハーネスに問題を再生することを検討してください。

RAG オブザーバビリティを別のレイヤーとして追加します

検索拡張生成により、品質とコストの両方が変化する可能性があります。最終的なモデル呼び出しのみをログに記録すると、取得者が多すぎるチャンク、古いドキュメント、または無関係なコンテキストを返した場合に、根本原因が隠蔽されます。

取得ステップごとに、次をキャプチャします:

  • インデックスまたはコレクション名;
  • 取得戦略と埋め込みモデル;
  • ドキュメント ID またはハッシュ ID;
  • チャンク数と合計コンテキスト トークン;
  • 取得待ち時間;
  • 上位スコアの分布 (利用可能な場合);
  • 引用範囲;
  • 取得されたコンテキストが最終的な回答で使用されたかどうか。

これにより、「モデルが悪化した」ことと「レトリバーが低品質または過剰なコンテキストを送信し始めた」ことを区別できます。また、コンテキスト トークンが総コストの大半を占めるワークフローを特定するのにも役立ちます。

ゲートウェイの使用状況とプロバイダーの請求を調整する

ゲートウェイの見積もりはすぐに利用できます。プロバイダー側​​の請求データは通常は遅くなりますが、より信頼性が高くなります。両方を使用してください。

毎日の調整ジョブでは、ゲートウェイ台帳の行をプロバイダー使用状況 API、コスト API、ダッシュボード エクスポート、または請求書のエクスポートと比較する必要があります。プロバイダー、モデル、プロジェクト、および時間枠ごとにデルタをグループ化します。入力トークン、出力トークン、キャッシュされたトークン、リクエスト数、コストの違いを個別に追跡します。

一般的な調整の相違点

  • ストリーミングの切断: プロバイダーが生成されたトークンの請求を継続している間に、ゲートウェイはクライアントが中止されたことを認識する可能性があります。
  • 再試行: 最終応答が 1 つだけ返された場合でも、複数の試行に対して料金が発生する場合があります。
  • プロンプト キャッシュ: プロバイダーは、キャッシュされたトークン アカウンティングを別の方法で公開する場合があります。
  • 丸め: リクエストごとの小さな違いは、大規模に表示される可能性があります。
  • バッチ割引または階層割引: プロバイダーの請求書には、リアルタイム見積もりではまだ認識されていない価格が適用される場合があります。
  • プロバイダ側の変更: モデルの価格設定、トークン化の動作、または請求のエクスポートは時間の経過とともに変更される可能性があります。

調整でデルタが見つかった場合は、台帳を黙って上書きすることは避けてください。元の見積もり、プロバイダーが調整した値、調整ソース、および理由コード (わかっている場合) を保存します。

運用に関する質問に答えるダッシュボード

バニティ指標ではなく、読者の問題からダッシュボードを開始します。便利なビューは次のとおりです:

  • テナント、チーム、アプリ、ワークフローごとのコスト;
  • リクエストあたりのコストではなく、成功したタスクあたりのコスト;
  • プロバイダー、モデル、モデル エイリアス別の p50、p95、および p99 レイテンシー;
  • ルート別のフォールバック率と再試行率;
  • タイムアウト率とプロバイダー エラー クラスの傾向;
  • キャッシュ ヒット率とキャッシュされたトークンの節約の見積もり;
  • 構造化出力検証失敗率;
  • エラー バジェット消費による上位のプロンプト バージョン;
  • ワークフローごとの RAG コンテキスト トークンの共有;
  • ガードレール ブロックとプロンプト インジェクション分類子のヒット。

アラートの場合は、技術的なシグナルとビジネス シグナルを組み合わせます。テナント支出の突然の急増は、世界的な遅延のわずかな増加よりも緊急である可能性があります。モデルのエイリアス変更後のフォールバック率の上昇は、互換性の問題を示している可能性があります。 401、429、または 5xx 応答が繰り返される場合は、重要な問題、割り当ての枯渇、プロバイダの不安定性を示している可能性があります。

OpenAI 互換プロキシの最小限の実装フロー

/chat/completions プロキシの場合、フローは単純になります:

  1. リクエストを受信し、request_id を割り当ててコンテキストをトレースします。
  2. ゲートウェイ キーを認証し、テナント、チーム、アプリ、ポリシーのスコープを解決します。
  3. 親ゲートウェイ スパンを作成します。
  4. 状態 accepted のレジャー行を作成します。
  5. モデルのエイリアスをプロバイダー モデルとルーティング ポリシーのバージョンに解決します。
  6. メタデータを記録します: 操作、プロンプト テンプレート ID、スキーマ名、プロンプト ハッシュ、およびコンテンツ キャプチャ ポリシー。
  7. 該当する場合、GenAI セマンティック属性を使用してモデル呼び出しスパンを開始します。
  8. 選択したプロバイダーにリクエストを転送します。
  9. ストリーミングの場合、最初のチャンクが到着したときに状態を更新し、プロバイダーの応答で許可される限り正確に使用量をカウントします。
  10. 完了すると、プロバイダーの使用状況を解析し、理由、ステータス、エラー クラスを終了します。
  11. トークン、推定コスト、再試行/フォールバックの詳細、最終リクエストの状態を含む台帳を更新します。
  12. 台帳とスパン データからメトリクスを出力します。
  13. 毎日調整を実行し、プロバイダーが確認したコストを元の見積もりとは別に保存します。

ロールアウトチェックリスト

  • 正規リクエスト ID とトレース ID を定義します。
  • 共通モデル テレメトリに OpenTelemetry GenAI 属性を採用します。
  • リクエストの状態遷移を含むゲートウェイ使用状況台帳を作成します。
  • プロバイダー、モデル、モデル エイリアス、テナント、アプリ、ワークフローのディメンションを正規化します。
  • カーディナリティの高い調査データを指標ラベルに含めないでください。
  • 生のプロンプトと出力キャプチャをデフォルトで無効にします。
  • サンプリング、編集、保持、アクセス制御のための明示的なポリシーを追加します。
  • RAG ワークフローの取得メタデータをキャプチャします。
  • コスト、レイテンシ、信頼性、検証、テナントの動作に関するダッシュボードを構築します。
  • ゲートウェイの見積もりとプロバイダーの使用量およびコストのエクスポートを調整します。
  • 支出の急増、遅延の回帰、フォールバックのジャンプ、検証の失敗、セキュリティ関連のイベントに関するアラート。

結論

マルチモデル ゲートウェイは、プロバイダーに到達する前にリクエストを確認し、プロバイダーが知らないビジネス コンテキストを付加できるため、LLM オブザーバビリティを実装するのに最適な場所です。最強の設計は「すべてを記録する」ことではありません。これは階層化されたモデルです。実行のためのプロバイダー中立のトレース、請求のための耐久性のあるトークンとコスト台帳、ガバナンスのためのテナント分析、取得品質のための RAG メタデータ、安全なデバッグのためのプライバシー最優先のプロンプト ロギングです。

メタデータ、状態遷移、調整から始めます。ポリシー、保持、およびアクセス制御の準備ができている場合にのみ、コンテンツ キャプチャを追加します。このシーケンスにより、開発者は可観測性を新たなデータ漏洩リスクに変えることなく、遅延、品質、費用をデバッグするために必要な証拠を得ることができます。

関連資料

FAQ

よくある質問

LLM ゲートウェイは可観測性のために生のプロンプトと出力を保存する必要がありますか?
デフォルトではありません。まず、メタデータ、プロンプト テンプレート ID、ハッシュ、トークン数、スキーマ名、安全性ラベル、エラー概要を保存します。未加工または編集されたコンテンツのキャプチャは、オプトイン、サンプリング、短期保存、アクセス制御、および監査が必要です。
なぜトレースと使用状況台帳の両方を使用するのでしょうか?
トレースは、リクエストがゲートウェイ、プロバイダー呼び出し、取得、ツール、再試行、ガードレールをどのように通過したかを説明します。使用状況台帳には、リクエストの状態、トークンの使用状況、推定コスト、調整されたコスト、テナント、モデルの属性などの永続的な請求と分析の事実が記録されます。
ゲートウェイの使用状況とプロバイダーの請求データをどのくらいの頻度で調整する必要がありますか?
毎日の和解が実際的な出発点です。リアルタイムのゲートウェイ見積もりはダッシュボードと制限に役立ちますが、プロバイダーの使用状況 API またはエクスポートは、ストリーミングの切断、再試行、キャッシュされたトークンのアカウンティング、割引、丸め、または請求の変更によって生じる差異を修正するのに役立ちます。
テナント ID やプロンプト ハッシュなどのカーディナリティの高いフィールドはどこに保存する必要がありますか?
トレース、ログ、または台帳テーブルにカーディナリティの高いフィールドを保持します。高価なまたはノイズの多いメトリック シリーズを避けるために、メトリック ダッシュボードにはカーディナリティの低い集計を使用します。