【Azure AI Foundry:第6回】対話プロセスの品質監査:Tracing可視化と自動精度評価(本編完結)
【新連載:Azure AI Foundryとマルチエージェント】
※本連載は、Azure AI Foundry SDK (
azure-ai-projects) を用い、実務で安全・強力に動作する「エンタープライズ仕様の自律チームエージェント」を構築するステップバイステップのハンズオン連載です。
1. イントロダクション(今回の到達目標)
前回は、ConnectedAgentTool を用いて、ドキュメント検索(RAG)を行う子エージェントとコード実行を行う子エージェントをコーディネーターが裏で操る「マルチエージェント協調」を構築しました。
エージェントシステムが複雑化し、分業チームとしての挙動をとるようになると、最終的な結果が間違っていた際に「どのエージェントが、どのデータをもとに、どう推論を誤ったのか」の調査(デバッグ)が非常に困難になります。また、プロンプトの調整やモデル変更が、回答全体の品質に悪影響を及ぼしていないかを定量的に評価する必要があります。
本編最終回となる第6回は、エージェント間の呼び出しやLLMの思考プロセスをミリ秒単位で完全に可視化する「Application Insights(OpenTelemetry規格)の統合」と、回答の根拠崩れやハルシネーション(嘘)の度合いを評価用LLMが自動スコアリングする「azure-ai-evaluationライブラリ」の実装を学び、エージェント運用のための「品質監査防衛線」を構築することを目標とします。
前提条件(Prerequisites)
- 動作確認済みライブラリ:
azure-ai-projects>=2.0.0,azure-ai-evaluation>=1.0.0,azure-monitor-opentelemetry - Azure上のリソース:
- AIプロジェクトに関連付けられた Application Insights がプロビジョニングされており、その接続文字列(ConnectionString)が取得可能であること。
- ローカル環境の認証: Azure CLI によるサインイン(
az login)が完了していること。
2. 対話プロセスの「見える化」と「自動監査」の設計
本番運用における品質保証は、以下の2段階のフローで実行されます。
① 実行時トレースの可視化
エージェントの内部では、LLMの呼び出し、接続されたツールの実行、子エージェントへの処理委譲など、多くの非同期イベントが発生しています。これらをOpenTelemetry標準のスパンデータとして Application Insights にパブリッシュすることで、どの処理でどの程度時間がかかったのか、どのプロンプトが渡されたのかをブラウザ上で視覚的な滝グラフ(タイムライン)として確認できます。
② 品質メトリクスの自動評価(LLM-as-a-Judge)
人間が数千件の対話ログを目視でチェックするのは現実的ではありません。そこで、評価用に別の高性能なLLM(例: gpt-4o など)を「監査役(Judge)」として用意し、回答がソースデータにどれだけ裏付けられているか(Groundedness)、回答の論理的整合性があるか(Coherence)などを1〜5点満点で厳密にスコアリングさせます。これが azure-ai-evaluation ライブラリの役割です。
3. 【実践】トレースの設定とAI評価の自動実行
アプリケーション全体に自動トレースを仕込み、取得した回答に対して評価ライブラリを走らせて品質を自動スコアリングする、完全な Python スクリプトを実行してみましょう。
# 動作確認済みライブラリバージョン:
# azure-ai-projects==2.0.0, azure-ai-evaluation==1.0.0, azure-monitor-opentelemetry==1.6.0
import os
from azure.identity import DefaultAzureCredential
from azure.ai.projects import AIProjectClient
from azure.monitor.opentelemetry import configure_azure_monitor
from opentelemetry import trace
from azure.ai.evaluation import GroundednessEvaluator, CoherenceEvaluator
def main():
project_endpoint = os.environ.get("AZURE_AI_PROJECT_ENDPOINT")
app_insights_conn = os.environ.get("APPLICATIONINSIGHTS_CONNECTION_STRING") # App Insightsの接続文字列
if not all([project_endpoint, app_insights_conn]):
print("Error: 環境変数 AZURE_AI_PROJECT_ENDPOINT, APPLICATIONINSIGHTS_CONNECTION_STRING が設定されていません。")
return
# --- (A) OpenTelemetry を用いた自動トレースの有効化 ---
# この設定を呼び出すだけで、以降のSDKの処理スパンがApplication Insightsへ自動転送されます
print("🌐 OpenTelemetry 自動監視を有効化しています...")
configure_azure_monitor(connection_string=app_insights_conn)
# トレースインスタンスの取得
tracer = trace.get_tracer(__name__)
credential = DefaultAzureCredential()
# --- (B) トレーススコープ内でのエージェント接続と対話の実行 ---
# with span を使用することで、独自のカスタムスパンもタイムラインへ混入できます
with tracer.start_as_current_span("agent_execution_span"):
with AIProjectClient(endpoint=project_endpoint, credential=credential) as project_client:
print("🤖 AI Project Client を疎通実行中 (トレース送信中)...")
openai_client = project_client.get_openai_client(api_version="2024-10-21")
# テストデータと質問
query = "TrailBlaze ハイキングパンツの保証期間は?"
context = "製品仕様: TrailBlaze ハイキングパンツは、お買い上げ日から1年間の限定保証(初期不良対応)が適用されます。"
response = openai_client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "コンテキストのみを根拠にして回答してください。"},
{"role": "user", "content": f"【コンテキスト】: {context}\n【質問】: {query}"}
]
)
answer = response.choices[0].message.content
print(f"🤖 回答: {answer}")
# --- (C) azure-ai-evaluation を用いた自動精度評価 (LLM-as-a-Judge) ---
print("\n⚖️ 監査LLMによる自動評価を実行中...")
# 評価用の判定モデル(GPT-4o)の設定を定義します
eval_model_config = {
"azure_endpoint": os.environ.get("AZURE_OPENAI_ENDPOINT"), # Azure OpenAIのエンドポイント
"api_key": os.environ.get("AZURE_OPENAI_KEY"), # 認証キー
"azure_deployment": "gpt-4o",
"api_version": "2024-08-01-preview"
}
# グラウンデッドネス(回答がコンテキストに接地しているか)の評価
groundedness_eval = GroundednessEvaluator(model_config=eval_model_config)
groundedness_result = groundedness_eval(
query=query,
response=answer,
context=context
)
# コヒーレンス(回答の論理的な首尾一貫性)の評価
coherence_eval = CoherenceEvaluator(model_config=eval_model_config)
coherence_result = coherence_eval(
query=query,
response=answer
)
# 評価結果の表示
print("\n=== 自動監査結果 ===")
print(f"📉 Groundedness (根拠性): {groundedness_result.get('groundedness')} / 5")
print(f"👉 理由: {groundedness_result.get('gpt_groundedness_explanation')}\n")
print(f"📈 Coherence (一貫性): {coherence_result.get('coherence')} / 5")
print(f"👉 理由: {coherence_result.get('gpt_coherence_explanation')}")
print("====================")
if __name__ == "__main__":
main()
結果の見方とアクション
- Groundednessスコアが低い(1〜2点)場合: 回答がコンテキストに基づいておらず、LLM自身の知識から適当な嘘(ハルシネーション)を書き出している可能性があります。システムプロンプトに「提供されたコンテキストのみを根拠とすること」を強めるか、検索インデックスから渡す文書チャンクの精度を見直す必要があります。
- Coherenceスコアが低い場合: 回答の論理構成が崩れています。モデルをより大きなパラメータサイズのものへ切り替えるか、思考の道筋を示すFew-Shot(例示)をプロンプトにアタッチする必要があります。
4. まとめと本編完結にあたって
新連載『Azure AI Foundryとマルチエージェント』の基本編全6回は、今回でめでたく完結となります!
ローカル接続の最初の一歩からスタートし、クラウド上での永続記憶である Thread、強固なセキュリティ境界に囲まれたデータ検索 Azure AI Search、安全なコード実行サンドボックス Code Interpreter、それらを統合する ConnectedAgentTool によるチーム協調、そして最終回となるトレースと自動監査の実装まで、実務レベルで真に求められるエンタープライズ・エージェントの基本設計をすべて体験・構築することができました。
しかし、本連載にはまだ「おまけ」が残っています。
現実の企業実務で最も厄介なドキュメントの筆頭である「複雑な表(テーブル)やリストが入ったPDF」を、RAGやエージェントチームに対してどうやって正確に読み込ませて処理させるかという実戦的なテクニックです。
次回(第7回・補足編おまけ①)。
決算書や製品スペック表などのPDFからレイアウトを一切崩さずに高精度にマークダウンテキスト(Tableタグ含む)として抽出するAzureの最強文書解析エンジン、「Document Intelligence」の構築とPython実装のチュートリアルをお届けします。
知識を現実の荒波に適用する、実務特化編のスタートです。