トレースを使用すると、各実行ステップで詳細なテレメトリをキャプチャすることで、アプリケーションの実行を詳細に把握できます。 このような方法は、不正確なツール呼び出し、誤解を招くプロンプト、待機時間の長い、低品質の評価スコアなどの問題を特定することで、問題の診断とパフォーマンスの向上に役立ちます。
この記事では、Azure AI Foundry で OpenAI SDK と OpenTelemetry を使用して AI アプリケーションのトレースを実装する方法について説明します。
[前提条件]
このチュートリアルを完了するには、次のものが必要です。
Azure AI Foundry プロジェクトが作成されました。
OpenAI SDK を使用して Azure AI Foundry でホストされているモデルを呼び出す AI アプリケーション。
プロジェクトでトレースを有効にする
Azure AI Foundry は、OpenTelemetry を使用して Azure Application Insight リソースにトレースを格納します。 既定では、新しい Azure AI Foundry リソースではこれらのリソースはプロビジョニングされません。 プロジェクトを既存の Azure Application Insights リソースに接続することも、プロジェクト内から新しいリソースを作成することもできます。 このような構成は、Azure AI Foundry リソースごとに 1 回行います。
次の手順では、リソースを構成する方法を示します。
Azure AI Foundry ポータルに移動し、プロジェクトに移動します。
サイド ナビゲーション バーで、[トレース] を選択 します。
Azure Application Insights リソースが Azure AI Foundry リソースに関連付けられていない場合は、関連付けます。
既存の Azure Application Insights を再利用するには、ドロップダウン の Application Insights リソース名 を使用してリソースを検索し、[ 接続] を選択します。
ヒント
既存の Azure Application Insights に接続するには、Azure AI Foundry リソース (またはハブ) への少なくとも共同作成者アクセス権が必要です。
新しい Azure Application Insights リソースに接続するには、[ 新規作成] オプションを選択します。
構成ウィザードを使用して、新しいリソースの名前を構成します。
既定では、新しいリソースは、Azure AI Foundry リソースが作成されたのと同じリソース グループに作成されます。 [詳細設定] オプションを使用して、別のリソース グループまたはサブスクリプションを構成します。
ヒント
新しい Azure Application Insight リソースを作成するには、選択したリソース グループ (または既定のリソース グループ) に対する共同作成者ロールも必要です。
[ 作成] を選択してリソースを作成し、Azure AI Foundry リソースに接続します。
接続が構成されたら、リソース内の任意のプロジェクトでトレースを使用する準備が整います。
プロジェクトのランディング ページに移動し、プロジェクトのエンドポイント URI をコピーします。 このチュートリアルの後半で必要になります。
Von Bedeutung
プロジェクトのエンドポイントを使用するには、アプリケーションで Microsoft Entra ID を構成する必要があります。 Entra ID が構成されていない場合は、チュートリアルの手順 3 で示されているように、Azure Application Insights 接続文字列を使用します。
OpenAI SDK をインストルメント化する
OpenAI SDK を使用して開発する場合は、コードをインストルメント化して、トレースが Azure AI Foundry に送信されるようにすることができます。 コードをインストルメント化するには、次の手順に従います。
環境に
azure-ai-projects
、azure-monitor-opentelemetry
、およびopentelemetry-instrumentation-openai-v2
をインストールします。pip
の使用例を次に示します。pip install azure-ai-projects azure-monitor-opentelemetry opentelemetry-instrumentation-openai-v2
OpenAIInstrumentor()
を使用して OpenAI SDK をインストルメント化します。from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor OpenAIInstrumentor().instrument()
プロジェクトに関連付けられている Azure Application Insights リソースへの接続文字列を取得します。 次の行では、認証に Microsoft Entra ID を使用する必要がある Azure AI Project クライアントを使用します。
from azure.ai.projects import AIProjectClient from azure.identity import DefaultAzureCredential project_client = AIProjectClient( credential=DefaultAzureCredential(), endpoint="https://<your-resource>.services.ai.azure.com/api/projects/<your-project>", ) connection_string = project_client.telemetry.get_connection_string()
Azure Application Insights にトレースを送信するように OpenTelemetry を構成します。
from azure.monitor.opentelemetry import configure_azure_monitor configure_azure_monitor(connection_string=connection_string)
既定では、OpenTelemetry は入力と出力をキャプチャしません。 環境変数
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
を使用してキャプチャします。 この環境変数が、コードが実行されている環境レベルで構成されていることを確認します。通常どおり OpenAI SDK を使用します。
client = project_client.get_azure_openai_client() response = client.chat.completions.create( model="deepseek-v3-0324", messages=[ {"role": "user", "content": "Write a short poem on open telemetry."}, ], )
Azure AI Foundry ポータルに戻ると、トレースが表示されます。
複雑なアプリケーションを開発するときに、ビジネス ロジックとモデルを組み合わせたコードのセクションをキャプチャすると便利な場合があります。 OpenTelemetry では、スパンの概念を使用して、関心のあるセクションをキャプチャします。 独自のスパンの生成を開始するには、現在の トレーサー オブジェクトのインスタンスを取得します。
from opentelemetry import trace tracer = trace.get_tracer(__name__)
次に、メソッドでデコレーターを使用して、関心のあるコード内の特定のシナリオをキャプチャします。 このようなデコレーターはスパンを自動的に生成します。 次のコード例では、要求の一覧を反復処理して
assess_claims_with_context
と呼ばれるメソッドをインストルメント化し、LLM を使用してコンテキストで要求がサポートされているかどうかを確認します。 このメソッドで行われたすべての呼び出しは、同じスパン内でキャプチャされます。def build_prompt_with_context(claim: str, context: str) -> str: return [{'role': 'system', 'content': "I will ask you to assess whether a particular scientific claim, based on evidence provided. Output only the text 'True' if the claim is true, 'False' if the claim is false, or 'NEE' if there's not enough evidence."}, {'role': 'user', 'content': f""" The evidence is the following: {context} Assess the following claim on the basis of the evidence. Output only the text 'True' if the claim is true, 'False' if the claim is false, or 'NEE' if there's not enough evidence. Do not output any other text. Claim: {claim} Assessment: """}] @tracer.start_as_current_span("assess_claims_with_context") def assess_claims_with_context(claims, contexts): responses = [] for claim, context in zip(claims, contexts): response = client.chat.completions.create( model="gpt-4.5-preview", messages=build_prompt_with_context(claim=claim, context=context), ) responses.append(response.choices[0].message.content.strip('., ')) return responses
トレースは次のようになります。
現在のスパンに追加情報を追加することもできます。 OpenTelemetry では、そのための 属性 の概念が使用されます。
trace
オブジェクトを使用してそれらにアクセスし、追加情報を含めます。 属性を含むようにassess_claims_with_context
メソッドがどのように変更されたかを確認します。@tracer.start_as_current_span("assess_claims_with_context") def assess_claims_with_context(claims, contexts): responses = [] current_span = trace.get_current_span() current_span.set_attribute("operation.claims_count", len(claims)) for claim, context in zip(claims, contexts): response = client.chat.completions.create( model="gpt-4.5-preview", messages=build_prompt_with_context(claim=claim, context=context), ) responses.append(response.choices[0].message.content.strip('., ')) return responses
トレースをコンソールへ
また、アプリケーションをトレースし、トレースをローカル実行コンソールに送信すると便利な場合があります。 このようなアプローチは、自動化された CI/CD パイプラインを使用してアプリケーションで単体テストまたは統合テストを実行する場合に役立つ場合があります。 トレースをコンソールに送信し、CI/CD ツールでキャプチャしてさらに分析できます。
トレースを次のように構成します。
通常どおり OpenAI SDK をインストルメント化します。
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor OpenAIInstrumentor().instrument()
トレースをコンソールに送信するように OpenTelemetry を構成します。
from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter span_exporter = ConsoleSpanExporter() tracer_provider = TracerProvider() tracer_provider.add_span_processor(SimpleSpanProcessor(span_exporter)) trace.set_tracer_provider(tracer_provider)
通常どおり OpenAI SDK を使用します。
response = client.chat.completions.create( model="deepseek-v3-0324", messages=[ {"role": "user", "content": "Write a short poem on open telemetry."}, ], )
{ "name": "chat deepseek-v3-0324", "context": { "trace_id": "0xaaaa0a0abb1bcc2cdd3d", "span_id": "0xaaaa0a0abb1bcc2cdd3d", "trace_state": "[]" }, "kind": "SpanKind.CLIENT", "parent_id": null, "start_time": "2025-06-13T00:02:04.271337Z", "end_time": "2025-06-13T00:02:06.537220Z", "status": { "status_code": "UNSET" }, "attributes": { "gen_ai.operation.name": "chat", "gen_ai.system": "openai", "gen_ai.request.model": "deepseek-v3-0324", "server.address": "my-project.services.ai.azure.com", "gen_ai.response.model": "DeepSeek-V3-0324", "gen_ai.response.finish_reasons": [ "stop" ], "gen_ai.response.id": "aaaa0a0abb1bcc2cdd3d", "gen_ai.usage.input_tokens": 14, "gen_ai.usage.output_tokens": 91 }, "events": [], "links": [], "resource": { "attributes": { "telemetry.sdk.language": "python", "telemetry.sdk.name": "opentelemetry", "telemetry.sdk.version": "1.31.1", "service.name": "unknown_service" }, "schema_url": "" } }