0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Microsoft Foundry Agent Tracing 検証

0
Posted at

Microsoft Foundry Agent Tracing 検証

1. 概要

Microsoft Foundry の Agent Tracing 機能を包括的に検証した。4つのトレーシングオプションを同一条件で実行し、セットアップの容易さ・取得データ・パフォーマンス・ユースケース適合性を比較分析した。

項目 内容
検証日 2026-04-27
リージョン East US
モデル gpt-4.1-nano (GlobalStandard, 50K TPM)
SDK バージョン azure-ai-projects 2.1.0, opentelemetry 1.40.0
IaC Bicep (API version 2025-06-01)

使用 Python パッケージ

パッケージ バージョン 用途
azure-ai-projects 2.1.0 Foundry Project クライアント
azure-ai-agents 1.1.0 Agent 操作
azure-identity 1.25.3 Azure 認証 (DefaultAzureCredential)
azure-core 1.39.0 Azure SDK 共通基盤
azure-core-tracing-opentelemetry 1.0.0b12 Azure SDK ↔ OTel ブリッジ
azure-monitor-opentelemetry 1.8.7 Azure Monitor エクスポーター (Option A)
azure-monitor-opentelemetry-exporter 1.0.0b51 App Insights テレメトリ送信
opentelemetry-api 1.40.0 OTel API
opentelemetry-sdk 1.40.0 OTel SDK (TracerProvider, SpanProcessor)
opentelemetry-semantic-conventions 0.61b0 GenAI セマンティック属性定義
opentelemetry-exporter-otlp-proto-http 1.40.0 OTLP HTTP エクスポーター (Option D)
opentelemetry-resource-detector-azure 0.1.5 Azure リソース検出
python-dotenv 1.2.2 .env ファイル読込

2. インフラストラクチャ構成

2.1 Bicep で作成したリソース

┌─────────────────────────────────────────────────┐
│  Resource Group: rg-foundry-tracing-verify       │
│                                                   │
│  ┌─────────────────────────────────────────────┐ │
│  │ AI Services (S0)                             │ │
│  │  └─ Project: proj-tracing-verify             │ │
│  │  └─ Model: gpt-4.1-nano (GlobalStandard)    │ │
│  ├─────────────────────────────────────────────┤ │
│  │ Log Analytics Workspace                      │ │
│  ├─────────────────────────────────────────────┤ │
│  │ Application Insights                         │ │
│  │  (linked to Log Analytics)                   │ │
│  └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘

2.2 IaC の留意点

課題 詳細
API バージョン 2025-06-01 が必須。2024-10-01 では accounts/projects リソースタイプが未対応
Project 作成 REST API 経由では "identity": {"type": "SystemAssigned"} が必須(省略すると InternalServerError)
allowProjectManagement AI Services アカウントに allowProjectManagement: true が必要

3. トレーシングオプション比較

3.1 検証した4オプション

Option エクスポーター 送信先 主なユースケース
A: Azure Monitor configure_azure_monitor() Application Insights 本番運用・長期モニタリング
B: Console ConsoleSpanExporter 標準出力 (stdout) 開発・デバッグ
C: Custom Attributes Console + SpanProcessor 標準出力 + カスタムメタデータ A/Bテスト・実験管理
D: OTLP OTLPSpanExporter OpenTelemetry Collector 既存OTelインフラ統合

3.2 セットアップ比較

 セットアップ難易度(低い = 簡単)
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Option A ██░░░░░░░░ 低  (configure_azure_monitor 1行)
 Option B ███░░░░░░░ 低  (TracerProvider + Exporter設定)
 Option C █████░░░░░ 中  (SpanProcessor自作が必要)
 Option D ████████░░ 高  (外部Collector構築が前提)
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

3.3 必要なパッケージ

Option 追加パッケージ
A azure-monitor-opentelemetry
B opentelemetry-sdk (azure-ai-projects に付属)
C opentelemetry-sdk (同上)
D opentelemetry-exporter-otlp + 外部 Collector

3.4 コア設定コード

共通(全オプション必須):

import os
os.environ["AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING"] = "true"
# ↑ GenAI セマンティック属性のキャプチャに必須

Option A – Azure Monitor:

from azure.monitor.opentelemetry import configure_azure_monitor
conn_str = project_client.telemetry.get_application_insights_connection_string()
configure_azure_monitor(connection_string=conn_str)

Option B – Console:

from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
from azure.ai.projects.telemetry import AIProjectInstrumentor
from azure.ai.inference.tracing import AIInferenceInstrumentor

provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)
AIProjectInstrumentor().instrument()
AIInferenceInstrumentor().instrument()

Option C – Custom Attributes:

class CustomAttributeSpanProcessor(SpanProcessor):
    def __init__(self, attributes: dict):
        self.attributes = attributes
    def on_start(self, span, parent_context=None):
        for k, v in self.attributes.items():
            span.set_attribute(k, v)

provider.add_span_processor(CustomAttributeSpanProcessor({
    "custom.experiment_name": "tracing-comparison",
    "custom.option": "C",
    "custom.environment": "verification",
}))

4. パフォーマンス比較

4.1 レイテンシ測定結果

同一の3プロンプトを各オプションで実行(gpt-4.1-nano, 同一 Agent 設定):

プロンプト Option A (Azure Monitor) Option B (Console) Option C (Custom Attrs) Option D (OTLP)*
日本の首都は? 2.86s 1.78s 2.82s 9.61s
Pythonソート方法 1.92s 1.60s 1.58s 10.59s
吾輩は猫である著者 1.90s 1.42s 1.44s 9.36s
平均 2.23s 1.60s 1.95s 9.85s

*Option D はローカルに OTLP Collector が不在のためエクスポートリトライが発生し、大幅に遅延。Collector が正常稼働していれば Option B と同等のレイテンシが期待される。

 平均レイテンシ (秒) — 低いほど高速
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 Option A ██████░░░░░░░░░░░░░░░░░░ 2.23s
 Option B ████░░░░░░░░░░░░░░░░░░░░ 1.60s  ← 最速
 Option C █████░░░░░░░░░░░░░░░░░░░ 1.95s
 Option D ████████████████████████ 9.85s  ← Collector不在による遅延
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

注意: 初回リクエストはコールドスタートの影響で遅い傾向(全オプション共通)。2回目以降はほぼ同等。Azure Monitor の若干のオーバーヘッドは、テレメトリのバッファリング・エクスポート処理に起因する。Option D の遅延はエクスポーターのリトライタイムアウトに起因し、Collector 正常稼働時には発生しない。

4.2 コンテンツ記録の影響

OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT 環境変数の ON/OFF での比較:

設定 Prompt 1 Prompt 2 Prompt 3 平均
OFF (デフォルト) 1.78s 1.60s 1.42s 1.60s
ON 2.83s 1.62s 1.48s 1.98s

→ コンテンツ記録 ON でもレイテンシへの影響は軽微(初回のみやや遅い)。


5. 取得データ比較

5.1 キャプチャされるスパン

全オプション共通で 11スパン が生成された(3プロンプト実行時):

スパン名 種別 説明
option_X_tracing Root 実行全体の親スパン
AIProjectClient.get_openai_client Internal OpenAI クライアント取得
create_agent TracingTestAgent-X Internal Agent 作成
create_conversation Internal 会話作成
invoke_agent TracingTestAgent-X (×3) Internal Agent 呼出(プロンプトごと)
AgentsOperations.delete_version Internal Agent 削除
GET / POST / DELETE HTTP 実際の HTTP リクエスト

5.2 GenAI セマンティック属性

invoke_agent スパンにキャプチャされる OTel GenAI 属性:

属性 説明 Content OFF Content ON
gen_ai.operation.name 操作名
gen_ai.agent.id Agent ID
gen_ai.agent.name Agent 名
gen_ai.agent.type Agent タイプ (prompt)
gen_ai.agent.version Agent バージョン
gen_ai.conversation.id 会話 ID
gen_ai.provider.name プロバイダー名
gen_ai.request.model リクエストモデル
gen_ai.response.model レスポンスモデル
gen_ai.response.id レスポンス ID
gen_ai.usage.input_tokens 入力トークン数
gen_ai.usage.output_tokens 出力トークン数
gen_ai.system_instructions システム指示内容
gen_ai.input.messages 入力メッセージ内容 構造のみ* ✅ 全文
gen_ai.output.messages 出力メッセージ内容 構造のみ* ✅ 全文
server.address サーバーアドレス
az.namespace Azure namespace
az.client_request_id クライアントリクエストID

*「構造のみ」= {"role": "user", "parts": [{"type": "text"}]} のようにロール・タイプのみ、内容テキストは空

5.3 コンテンツ記録 ON/OFF の出力差異

Content OFF (デフォルト — プライバシー保護):

{
  "gen_ai.input.messages": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\"}]}]",
  "gen_ai.output.messages": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\"}], \"finish_reason\": \"completed\"}]"
}

Content ON (OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true):

{
  "gen_ai.system_instructions": "[{\"type\": \"text\", \"content\": \"あなたは日本語で簡潔に答えるアシスタントです。\"}]",
  "gen_ai.input.messages": "[{\"role\": \"user\", \"parts\": [{\"type\": \"text\", \"content\": \"日本の首都はどこですか?\"}]}]",
  "gen_ai.output.messages": "[{\"role\": \"assistant\", \"parts\": [{\"type\": \"text\", \"content\": \"東京です。\"}], \"finish_reason\": \"completed\"}]"
}

5.4 Option C: カスタム属性

Option C では、全スパンに以下のカスタム属性が自動付与された:

{
  "custom.experiment_name": "tracing-comparison",
  "custom.option": "C",
  "custom.environment": "verification"
}

これにより、A/Bテスト・実験管理・マルチ環境でのトレース分類が可能。


6. Option D: OTLP エクスポーター

6.1 構成

from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
exporter = OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")

6.2 検証結果

Agent 呼出自体は成功(3プロンプトとも正常応答)。ただし、ローカルに OTLP Collector が稼働していないため、エクスポーターがリトライを繰り返し、以下の影響が確認された:

項目 結果
Agent 呼出 ✅ 成功(3/3 プロンプト正常応答)
トレースエクスポート ❌ 失敗(Connection refused on localhost:4318)
平均レイテンシ 9.85s(Collector 不在によるリトライタイムアウト込み)
エラーメッセージ Failed to export span batch due to timeout, max retries or shutdown

重要な発見: OTLP エクスポーターの接続失敗はアプリケーション全体をブロックしない(Agent 呼出は正常完了)。ただし、リトライ処理がバックグラウンドで走り続けるため、レイテンシに大きな影響を与える。本番環境では Collector のヘルスチェックが重要。

6.3 OTLP が適するケース

  • Jaeger / Zipkin / Grafana Tempo など既存の分散トレーシング基盤がある場合
  • マルチクラウド・マルチサービスで統一的にトレースを収集する場合
  • Azure Monitor 以外のバックエンドにトレースを送信したい場合

6.4 OTLP 構築時の推奨

# OpenTelemetry Collector を Docker で起動する例
docker run -p 4318:4318 otel/opentelemetry-collector-contrib:latest

7. Application Insights でのトレース確認

7.1 収集されたデータ概要

Option A (Azure Monitor) で送信されたトレースを App Insights から KQL で確認した:

テレメトリタイプ 件数
dependency 29

7.2 invoke_agent スパンの詳細(App Insights customDimensions)

App Insights の dependencies テーブルには GenAI 属性が customDimensions として格納される:

┌───────────────────────────────────────────────────────────────────────┐
│ invoke_agent TracingTestAgent-A (duration: 2861ms)                   │
├───────────────────────────────────────────────────────────────────────┤
│ az.namespace              : Microsoft.CognitiveServices              │
│ gen_ai.operation.name     : invoke_agent                             │
│ gen_ai.agent.id           : TracingTestAgent-A:1                     │
│ gen_ai.agent.name         : TracingTestAgent-A                       │
│ gen_ai.conversation.id    : conv_dadec4c95b0c760a00dCmappe...        │
│ gen_ai.provider.name      : microsoft.foundry                        │
│ gen_ai.response.model     : gpt-41-nano                              │
│ gen_ai.usage.input_tokens : 44                                       │
│ gen_ai.usage.output_tokens: 4                                        │
│ gen_ai.input.messages     : [{"role":"user","parts":[{"type":"text"}]}]│
│ gen_ai.output.messages    : [{"role":"assistant",...}]                │
│ gen_ai.response.id        : resp_dadec4c95b0c760a...                 │
└───────────────────────────────────────────────────────────────────────┘

7.3 App Insights での分析用 KQL サンプル

// Agent 呼出のレイテンシ分布
dependencies
| where name startswith "invoke_agent"
| summarize avg(duration), percentile(duration, 50), percentile(duration, 95) by name

// トークン使用量の集計
dependencies
| where name startswith "invoke_agent"
| extend input_tokens = toint(customDimensions["gen_ai.usage.input_tokens"]),
         output_tokens = toint(customDimensions["gen_ai.usage.output_tokens"])
| summarize sum(input_tokens), sum(output_tokens), count() by bin(timestamp, 1h)

// エラー率の監視
dependencies
| where customDimensions["az.namespace"] == "Microsoft.CognitiveServices"
| summarize total = count(), failures = countif(success == false) by bin(timestamp, 1h)
| extend error_rate = round(100.0 * failures / total, 2)

// Agent 別のパフォーマンス比較
dependencies
| where name startswith "invoke_agent"
| extend agent_name = tostring(customDimensions["gen_ai.agent.name"])
| summarize avg(duration), count() by agent_name

8. 総合比較表

評価項目 Option A (Azure Monitor) Option B (Console) Option C (Custom Attrs) Option D (OTLP)
セットアップ難易度 ⭐ 最も簡単 ⭐⭐ 簡単 ⭐⭐⭐ やや複雑 ⭐⭐⭐⭐ 複雑
外部依存 App Insights なし なし OTel Collector
追加パッケージ azure-monitor-opentelemetry なし (組込み) なし (組込み) opentelemetry-exporter-otlp
平均レイテンシ 2.23s 1.60s 1.95s 9.85s*
オーバーヘッド 軽微(バッチ送信) 最小 最小 Collector依存*
データ永続化 ✅ App Insights ❌ 揮発性 ❌ 揮発性 ✅ 外部バックエンド
KQL クエリ ✅ 対応 バックエンド依存
カスタムメタデータ SpanProcessor追加で可 SpanProcessor追加で可 ✅ 標準対応 SpanProcessor追加で可
GenAI 属性数 18 18 18 + カスタム 18
本番適合性 ⭐⭐⭐⭐⭐ ⭐⭐ ⭐⭐⭐⭐

*Option D のレイテンシは Collector 不在時の値。Collector 正常稼働時は Option B と同等が期待される。


9. 環境変数リファレンス

環境変数 必須 説明
AZURE_EXPERIMENTAL_ENABLE_GENAI_TRACING true に設定すると GenAI セマンティック属性がキャプチャされる
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT true でメッセージ内容を完全記録(プライバシー注意)
AZURE_IDENTITY_DISABLE_MANAGED_IDENTITY WSL 等 IMDS なし環境で true に設定(タイムアウト回避)

10. 推奨ガイドライン

用途別の推奨オプション

 ユースケース → 推奨オプション
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 本番運用・長期モニタリング        → Option A (Azure Monitor)
 ローカル開発・デバッグ            → Option B (Console)
 A/Bテスト・実験管理              → Option C (Custom Attributes)
 既存OTelインフラ統合             → Option D (OTLP)
 本番 + カスタムメタデータ         → Option A + C (組合せ)
 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

10.1 本番環境

推奨: Option A (Azure Monitor) + Option C のカスタム属性

# 本番推奨構成
configure_azure_monitor(connection_string=conn_str)
# カスタム属性も追加
provider = trace.get_tracer_provider()
provider.add_span_processor(CustomAttributeSpanProcessor({
    "custom.environment": "production",
    "custom.version": "1.0.0",
}))
  • App Insights でのダッシュボード・アラート設定が可能
  • KQL でトレースを詳細分析
  • カスタム属性でデプロイメント・バージョン追跡

10.2 開発環境

推奨: Option B (Console)

  • 追加インフラ不要、即座にスパン情報を確認
  • OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true を設定して入出力内容もデバッグ

10.3 コンテンツ記録の判断

環境 推奨設定 理由
開発・検証 CAPTURE_MESSAGE_CONTENT=true デバッグに入出力内容が必要
本番(社内データ) 要件に応じて判断 トレースに機密データが含まれる可能性
本番(顧客データ) CAPTURE_MESSAGE_CONTENT=false PII/プライバシー保護が最優先

11. IaC コード

Bicep テンプレート: iac/main.bicep

デプロイコマンド:

az group create --name rg-foundry-tracing-verify --location eastus \
  --tags SecurityControl=Ignore

az deployment group create \
  --resource-group rg-foundry-tracing-verify \
  --template-file iac/main.bicep

12. 検証で発見した課題と対策

課題 影響 対策
Bicep Project 作成の制限 accounts/projects が InternalServerError REST API で identity.type=SystemAssigned 指定で回避
OTLP Collector 必須 ローカル環境で Option D 実行不可 Docker で Collector を事前構築、または Azure Monitor に統一
コンテンツ記録のデフォルト OFF 開発時にメッセージ内容が見えない 開発環境で明示的に CAPTURE_MESSAGE_CONTENT=true 設定

13. 結論

Microsoft Foundry の Agent Tracing は、OpenTelemetry 標準に準拠した柔軟なトレーシング基盤を提供する。

  1. 最小構成でも18のGenAI属性が自動キャプチャされ、トークン使用量・レイテンシ・Agent メタデータの可視化が可能
  2. Azure Monitor (Option A) は本番環境に最適。1行の設定で App Insights への永続化・KQL 分析・アラートが実現
  3. Console (Option B) は開発時の即座のフィードバックに最適。追加インフラ不要
  4. Custom Attributes (Option C) は実験管理・A/Bテストに有効。SpanProcessor の自作は容易
  5. コンテンツ記録オプションは強力だが、本番ではプライバシーポリシーに従って慎重に設定すべき
  6. オプションは組合せ可能 — 例えば Azure Monitor + Custom Attributes で本番運用しつつ実験メタデータも記録できる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?