重要
Microsoft Agent 365 への早期アクセスを得るには、Frontier プレビュー プログラムのメンバーである必要があります。 フロンティアは、Microsoftの最新の AI イノベーションと直接接続します。 Frontier のプレビューは、お客様の契約書に記載されている既存のプレビュー利用規約に従います。 これらの機能は現在開発中であるため、提供状況や機能は今後変更される可能性があります。
Agent 365エコシステムに参加するには、エージェントにAgent 365のObservability機能を追加してください。 Agent 365 Observabilityは OpenTelemetry(OTel) を基盤とし、すべてのエージェントプラットフォームで一貫して安全にテレメトリをキャプチャするための統一フレームワークを提供します。 この必須コンポーネントを実装することで、IT 管理者は、Microsoft管理センターでエージェントのアクティビティを監視し、セキュリティ チームがコンプライアンスと脅威の検出にDefenderと Purview を使用できるようにします。
主な利点
-
エンドツーエンドの可視性:セッション、ツールコール、例外を含むすべてのエージェント呼び出しの包括的なテレメトリをキャプチャし、プラットフォーム間での完全なトレーサビリティを実現します。
-
セキュリティとコンプライアンスの有効化: 統合監査ログをDefenderと Purview にフィードし、エージェントの高度なセキュリティ シナリオとコンプライアンス レポートを有効にします。
-
クロス プラットフォームの柔軟性: OTel 標準を基に構築し、Copilot Studio、Foundry、将来のエージェント フレームワークなどの多様なランタイムとプラットフォームをサポートします。
-
管理者の操作効率: エージェントを管理する IT チームのロールベースのアクセス制御を使用して、Microsoft 365 admin centerの一元的な監視機能を提供し、トラブルシューティング時間を短縮し、ガバナンスを向上させます。
サポートされているエージェント
次の種類のエージェントでは、エージェント 365 の可観測性がサポートされています。
インストール
次のコマンドを使用して、Agent 365 でサポートされている言語の監視モジュールをインストールします。
コアの可観測性とランタイム パッケージをインストールします。 Agent 365 Observability を使用するすべてのエージェントには、これらのパッケージが必要です。
pip install microsoft-agents-a365-observability-core
pip install microsoft-agents-a365-runtime
エージェントが Microsoft Agents Hosting パッケージを使用している場合は、ホスティング統合パッケージをインストールします。
TurnContextから手荷物とスコープを自動的に埋め込むとともに、監視エクスポーター用のトークンキャッシュを含むミドルウェアを提供します。
pip install microsoft-agents-a365-observability-hosting
エージェントでサポートされている AI フレームワークのいずれかを使用している場合は、対応する自動インストルメンテーション拡張機能をインストールして、手動インストルメンテーション コードなしでテレメトリを自動的にキャプチャします。 構成の詳細については、「 自動インストルメンテーション」を参照してください。
# For Semantic Kernel
pip install microsoft-agents-a365-observability-extensions-semantic-kernel
# For OpenAI Agents SDK
pip install microsoft-agents-a365-observability-extensions-openai
# For Microsoft Agent Framework
pip install microsoft-agents-a365-observability-extensions-agent-framework
# For LangChain
pip install microsoft-agents-a365-observability-extensions-langchain
コアの可観測性とランタイム パッケージをインストールします。 Agent 365 Observability を使用するすべてのエージェントには、これらのパッケージが必要です。
npm install @microsoft/agents-a365-observability
npm install @microsoft/agents-a365-runtime
エージェントが @microsoft/agents-hosting パッケージを使用している場合は、ホスティング統合パッケージをインストールします。
TurnContextから手荷物とスコープを自動的に埋め込むとともに、監視エクスポーター用のトークンキャッシュを含むミドルウェアを提供します。
npm install @microsoft/agents-a365-observability-hosting
エージェントでサポートされている AI フレームワークのいずれかを使用している場合は、対応する自動インストルメンテーション拡張機能をインストールして、手動インストルメンテーション コードなしでテレメトリを自動的にキャプチャします。 構成の詳細については、「 自動インストルメンテーション」を参照してください。
// For OpenAI Agents SDK
npm install @microsoft/agents-a365-observability-extensions-openai
// For LangChain
npm install @microsoft/agents-a365-observability-extensions-langchain
コアの可観測性とランタイム パッケージをインストールします。 Agent 365 Observability を使用するすべてのエージェントには、このパッケージが必要です。
dotnet add package Microsoft.Agents.A365.Observability.Runtime
エージェントが Microsoft。Agents.A365.Observability.Hosting NuGet パッケージ、ホスティング統合パッケージをインストールします。
TurnContext から手荷物を自動的に取り込むミドルウェアを提供し、監視エクスポーターのトークン キャッシュを含みます。
dotnet add package Microsoft.Agents.A365.Observability.Hosting
エージェントでサポートされている AI フレームワークのいずれかを使用している場合は、対応する自動インストルメンテーション拡張機能をインストールして、手動インストルメンテーション コードなしでテレメトリを自動的にキャプチャします。 構成の詳細については、「 自動インストルメンテーション」を参照してください。
// For Semantic Kernel
dotnet add package Microsoft.Agents.A365.Observability.Extensions.SemanticKernel
// For OpenAI
dotnet add package Microsoft.Agents.A365.Observability.Extensions.OpenAI
// For Agent Framework
dotnet add package Microsoft.Agents.A365.Observability.Extensions.AgentFramework
構成
以下の設定を使って、エージェントのAgent 365 Observabilityを有効にしてカスタマイズしてください。
ENABLE_A365_OBSERVABILITY_EXPORTER環境変数をtrueに設定して観察しやすくしてください。 この設定では、ログがサービスにエクスポートされ、 token_resolver を指定する必要があります。 それ以外はコンソールのエクスポーターを使用します。
from microsoft_agents_a365.observability.core import configure
def token_resolver(agent_id: str, tenant_id: str) -> str | None:
# Implement secure token retrieval here
return "Bearer <token>"
configure(
service_name="my-agent-service",
service_namespace="my.namespace",
token_resolver=token_resolver,
)
トークンリゾルバはコンソールへのログログから除外されます。
Agent365ExporterOptions インスタンスをexporter_optionsに渡すことで、エクスポーターの動作をカスタマイズできます。
exporter_optionsを指定すると、token_resolverパラメーターとcluster_categoryパラメーターよりも優先されます。
from microsoft_agents_a365.observability.core import configure, Agent365ExporterOptions
configure(
service_name="my-agent-service",
service_namespace="my.namespace",
exporter_options=Agent365ExporterOptions(
cluster_category="prod",
token_resolver=token_resolver,
),
suppress_invoke_agent_input=True,
)
次の表では、 configure()の省略可能なパラメーターについて説明します。
| パラメーター |
説明 |
デフォルト |
logger_name |
デバッグとコンソール ログ出力に使用されるPython ロガーの名前。 |
microsoft_agents_a365.observability.core |
exporter_options |
トークン リゾルバーとクラスター カテゴリを一緒に構成する Agent365ExporterOptions インスタンス。 |
None |
suppress_invoke_agent_input |
Trueすると、InvokeAgentスパンでの入力メッセージが抑制されます。 |
False |
次の表では、 Agent365ExporterOptionsの省略可能なプロパティについて説明します。
| 財産 |
説明 |
デフォルト |
use_s2s_endpoint |
True場合は、サービス間エンドポイント パスを使用します。 |
False |
max_queue_size |
バッチ プロセッサの最大キュー サイズ。 |
2048 |
scheduled_delay_ms |
エクスポート バッチ間の遅延 (ミリ秒単位)。 |
5000 |
exporter_timeout_ms |
エクスポート操作のタイムアウト (ミリ秒単位)。 |
30000 |
max_export_batch_size |
エクスポート操作の最大バッチ サイズ。 |
512 |
ENABLE_A365_OBSERVABILITY_EXPORTER環境変数をtrueに設定して観察しやすくしてください。 この設定では、ログがサービスにエクスポートされ、トークン リゾルバーを指定する必要があります。 それ以外はコンソールのエクスポーターを使用します。
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
// Define a token resolver to authenticate with the observability service for exporting logs
const tokenResolver = (agentId, tenantId) => {
// Your token resolution logic here
return "your-token";
};
// Advanced configuration with builder pattern
const builder = ObservabilityManager.configure(builder =>
builder
.withService('my-agent-service', '1.0.0')
.withTokenResolver((agentId, tenantId) => {
return tokenResolver(agentId, tenantId);
})
);
builder.start();
環境変数の代わりに、 withConfigurationProvider メソッドを使用して構成プロバイダーを使用して、プログラムで可観測性を構成できます。 個々のビルダー メソッド ( withExporterOptions や withClusterCategoryなど) も使用する場合は、構成プロバイダーの値よりも個々のビルダー メソッドが優先されます。
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
import { ObservabilityConfiguration } from '@microsoft/agents-a365-observability';
const configProvider = new ObservabilityConfiguration({
isObservabilityExporterEnabled: () => true,
// Set log levels as pipe-separated values (for example, 'info|warn|error')
observabilityLogLevel: () => 'info|warn|error',
});
const builder = ObservabilityManager.configure(builder =>
builder
.withService('my-agent-service', '1.0.0')
.withConfigurationProvider(configProvider)
.withTokenResolver((agentId, tenantId) => {
return tokenResolver(agentId, tenantId);
})
);
builder.start();
Agent365ExporterOptions インスタンスをwithExporterOptionsに渡すことで、エクスポーターの動作をカスタマイズできます。 このオプションを使用すると、バッチ処理、タイムアウト、ルート モードを制御できます。
import {
ObservabilityManager,
Agent365ExporterOptions,
} from '@microsoft/agents-a365-observability';
import { ClusterCategory } from '@microsoft/agents-a365-runtime';
const exporterOptions = new Agent365ExporterOptions();
exporterOptions.maxQueueSize = 10;
const builder = ObservabilityManager.configure(builder =>
builder
.withService('my-agent-service', '1.0.0')
.withClusterCategory(ClusterCategory.prod)
.withExporterOptions(exporterOptions)
.withTokenResolver(tokenResolver)
);
builder.start();
次の表では、 Agent365ExporterOptionsの省略可能なプロパティについて説明します。
| 財産 |
説明 |
デフォルト |
useS2SEndpoint |
true場合は、サービス間エンドポイント パスを使用します。 |
false |
maxQueueSize |
バッチ プロセッサの最大キュー サイズ。 |
2048 |
scheduledDelayMilliseconds |
エクスポート バッチ間の遅延 (ミリ秒単位)。 |
5000 |
exporterTimeoutMilliseconds |
エクスポート操作全体のタイムアウト (ミリ秒単位)。 |
90000 |
httpRequestTimeoutMilliseconds |
バックエンドへの個々の HTTP 要求のタイムアウト (ミリ秒)。 |
30000 |
maxExportBatchSize |
エクスポート操作の最大バッチ サイズ。 |
512 |
また、 ILogger インターフェース(info、 warn、 error、 event)を実装したカスタムロガーを提供することも可能です。
withCustomLoggerを使ってビルダーに渡します。
const builder = ObservabilityManager.configure(builder =>
builder
.withService('my-agent-service', '1.0.0')
.withCustomLogger({
info: (message, ...args) => { /* your logging logic */ },
warn: (message, ...args) => { /* your logging logic */ },
error: (message, ...args) => { /* your logging logic */ },
event: (eventName, success, durationMs, message, details) => { /* your logging logic */ }
})
.withTokenResolver((agentId, tenantId) => {
return tokenResolver(agentId, tenantId);
})
);
builder.start();
EnableAgent365Exporter で true を appsettings.json に設定します。
Program.cs で、サービス コレクションに Agent365ExporterOptions を追加します。 この変更により、トレース エクスポーターがトークンの取得に使用する代理人が構成されます。
AddA365Tracing()を使って可観測性に関連する依存関係を追加してください。
using Microsoft.Agents.A365.Observability.Runtime;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Exporters;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(sp =>
{
return new Agent365ExporterOptions
{
TokenResolver = async (agentId, tenantId) =>
{
// It's recommended to implement caching in your token provider for performance.
var token = await tokenProvider.GetObservabilityTokenAsync(agentId, tenantId);
return token;
}
};
});
builder.AddA365Tracing();
構成デリゲートとエクスポーターの種類を AddA365Tracing()に渡すことで、エクスポーターの動作をカスタマイズできます。
builder.AddA365Tracing(
configure: tracingBuilder =>
{
// Use the builder to add extensions (e.g., WithSemanticKernel(), WithOpenAI())
},
agent365ExporterType: Agent365ExporterType.Agent365ExporterAsync
);
次の表では、 Agent365ExporterOptionsの省略可能なプロパティについて説明します。
| 財産 |
説明 |
デフォルト |
UseS2SEndpoint |
true場合は、サービス間エンドポイント パスを使用します。 |
false |
MaxQueueSize |
バッチ プロセッサの最大キュー サイズ。 |
2048 |
ScheduledDelayMilliseconds |
エクスポート バッチ間の遅延 (ミリ秒単位)。 |
5000 |
ExporterTimeoutMilliseconds |
エクスポート操作のタイムアウト (ミリ秒単位)。 |
30000 |
MaxExportBatchSize |
エクスポート操作の最大バッチ サイズ。 |
512 |
バゲッジ属性
BaggageBuilder を使用して、要求のすべてのスパンを流れるコンテキスト情報を設定します。
SDKは、空でないすべての手荷物エントリを既存の属性を上書きせずに新たに開始したスパンにコピーする SpanProcessor を実装しています。
from microsoft_agents_a365.observability.core import BaggageBuilder
with (
BaggageBuilder()
.tenant_id("tenant-123")
.agent_id("agent-456")
.conversation_id("conv-789")
.build()
):
# Any spans started in this context will receive these as attributes
pass
BaggageBuilderからTurnContextを自動的に設定するには、populate パッケージのmicrosoft-agents-a365-observability-hosting ヘルパーを使用します。 このヘルパーは、アクティビティから呼び出し元、エージェント、テナント、チャネル、会話の詳細を自動的に抽出します。
from microsoft_agents.hosting.core.turn_context import TurnContext
from microsoft_agents_a365.observability.core import BaggageBuilder
from microsoft_agents_a365.observability.hosting.scope_helpers.populate_baggage import populate
builder = BaggageBuilder()
populate(builder, turn_context)
with builder.build():
# Baggage is auto-populated from the TurnContext activity
pass
import { BaggageBuilder } from '@microsoft/agents-a365-observability';
// Create and apply baggage context
const baggageScope = new BaggageBuilder()
// Core identifiers
.tenantId('tenant-123')
.agentId('agent-456')
.conversationId('conv-789')
.build();
// Execute operations within the baggage context
baggageScope.run(() => {
// All spans created within this context will inherit the baggage values
// Invoke another agent
const agentScope = InvokeAgentScope.start(request, scopeDetails, agentDetails);
// ... agent logic
// Execute tools
const toolScope = ExecuteToolScope.start(request, toolDetails, agentDetails);
// ... tool logic
});
BaggageBuilderからTurnContextを自動的に設定するには、fromTurnContext パッケージの@microsoft/agents-a365-observability-hosting ヘルパーを使用します。 このヘルパーは、アクティビティから呼び出し元、エージェント、テナント、チャネル、会話の詳細を自動的に抽出します。
import { BaggageBuilder } from '@microsoft/agents-a365-observability';
import { BaggageBuilderUtils } from '@microsoft/agents-a365-observability-hosting';
const baggageScope = BaggageBuilderUtils.fromTurnContext(new BaggageBuilder(), context)
.invokeAgentServer(context.activity.serviceUrl, 3978)
.build();
await baggageScope.run(async () => {
// Baggage is auto-populated from the TurnContext activity
});
using Microsoft.Agents.A365.Observability.Runtime.Common;
using var baggageScope = new BaggageBuilder()
.TenantId("tenant-123")
.AgentId("agent-456")
.ConversationId("conv-789")
.Build();
// Any spans started in this context will receive them as attributes.
BaggageBuilder から ITurnContext を自動設定するには、FromTurnContext パッケージの Microsoft.Agents.A365.Observability.Hosting 拡張メソッドを使用します。 このメソッドは、アクティビティから呼び出し元、エージェント、テナント、チャネル、および会話の詳細を自動的に抽出します。
using Microsoft.Agents.A365.Observability.Runtime.Common;
using Microsoft.Agents.A365.Observability.Hosting.Extensions;
using var baggageScope = new BaggageBuilder()
.FromTurnContext(turnContext)
.Build();
手荷物ミドルウェア
エージェントがホスティング統合パッケージを使用している場合は、手荷物ミドルウェアを登録して、すべての着信要求に対して自動的に手荷物を設定します。 この手順により、各アクティビティ ハンドラーで BaggageBuilder を手動で呼び出す必要がなくなります。
アダプター ミドルウェア セットに BaggageMiddleware を登録します。 すべての着信 TurnContext から呼び出し元、エージェント、テナント、チャネル、および会話の詳細が自動的に抽出され、要求が手荷物スコープにラップされます。
from microsoft_agents_a365.observability.hosting import BaggageMiddleware
adapter.use(BaggageMiddleware())
または、 ObservabilityHostingManager を使用して、手荷物ミドルウェアとその他のホスティング機能を構成します。
from microsoft_agents_a365.observability.hosting import ObservabilityHostingManager, ObservabilityHostingOptions
options = ObservabilityHostingOptions(enable_baggage=True)
ObservabilityHostingManager.configure(adapter.middleware_set, options)
ミドルウェアは、非同期応答 (ContinueConversation イベント) の手荷物設定をスキップして、元の要求が既に設定した手荷物を上書きしないようにします。
アダプターに BaggageMiddleware を登録します。 すべての着信 TurnContext から呼び出し元、エージェント、テナント、チャネル、および会話の詳細が自動的に抽出され、要求が手荷物スコープにラップされます。
import { BaggageMiddleware } from '@microsoft/agents-a365-observability-hosting';
// Option 1: Register middleware directly on the adapter
adapter.use(new BaggageMiddleware());
または、 ObservabilityHostingManager を使用して、手荷物ミドルウェアとその他のホスティング機能を構成します。
import { ObservabilityHostingManager } from '@microsoft/agents-a365-observability-hosting';
const manager = new ObservabilityHostingManager();
manager.configure(adapter, { enableBaggage: true });
ミドルウェアは、非同期応答 (ContinueConversation イベント) の手荷物設定をスキップして、元の要求が既に設定した手荷物を上書きしないようにします。
アダプターに BaggageTurnMiddleware を登録します。 すべての着信 ITurnContext から呼び出し元、エージェント、テナント、チャネル、および会話の詳細が自動的に抽出され、要求が手荷物スコープにラップされます。
using Microsoft.Agents.A365.Observability.Hosting.Middleware;
adapter.Use(new BaggageTurnMiddleware());
ミドルウェアは、非同期応答 (ContinueConversation イベント) の手荷物設定をスキップして、元の要求が既に設定した手荷物を上書きしないようにします。
HTTP レベルの手荷物 (たとえば、Bot Framework パイプラインの実行前にテナント ID とエージェント ID を設定する) が必要な場合は、ObservabilityBaggageMiddleware 拡張メソッドを使用して、ASP.NET Core パイプラインに UseObservabilityRequestContext を登録します。 HTTP コンテキストからテナント ID とエージェント ID を抽出するリゾルバー関数を指定する必要があります。
using Microsoft.Agents.A365.Observability.Hosting.Middleware;
app.UseObservabilityRequestContext((httpContext) =>
{
// Extract tenant and agent IDs from your request context
var tenantId = GetTenantIdFromContext(httpContext);
var agentId = GetAgentIdFromContext(httpContext);
return (tenantId, agentId);
});
トークン リゾルバー
Agent 365 エクスポーターを使用する場合は、認証トークンを返すトークン リゾルバー関数を指定する必要があります。
エージェント ホスティング フレームワークで Agent 365 Observability SDK を使用する場合は、エージェント アクティビティの TurnContext を使用してトークンを生成できます。
次のスニペットは、 microsoft_agents.hosting.core SDK を使用してトークンを生成する方法を示しています。 ここで生成された認証トークンは、スパンを A365 インジェスト サービスにエクスポートするために使用されます。 エージェントは、 Microsoft Authentication Library (MSAL) を使用するなどしてトークン自体を自由に生成できますが、トークンが監視スコープを持っていることを確認する必要があります。
from microsoft_agents.activity import load_configuration_from_env
from microsoft_agents.authentication.msal import MsalConnectionManager
from microsoft_agents.hosting.aiohttp import CloudAdapter
from microsoft_agents.hosting.core import (
AgentApplication,
Authorization,
MemoryStorage,
TurnContext,
TurnState,
)
from microsoft_agents_a365.runtime import (
get_observability_authentication_scope,
)
agents_sdk_config = load_configuration_from_env(environ)
STORAGE = MemoryStorage()
CONNECTION_MANAGER = MsalConnectionManager(**agents_sdk_config)
ADAPTER = CloudAdapter(connection_manager=CONNECTION_MANAGER)
ADAPTER.use(TranscriptLoggerMiddleware(ConsoleTranscriptLogger()))
AUTHORIZATION = Authorization(STORAGE, CONNECTION_MANAGER, **agents_sdk_config)
AGENT_APP = AgentApplication[TurnState](
storage=STORAGE, adapter=ADAPTER, authorization=AUTHORIZATION, **agents_sdk_config
)
@AGENT_APP.activity("message", auth_handlers=["AGENTIC"])
async def on_message(context: TurnContext, _state: TurnState):
aau_auth_token = await AGENT_APP.auth.exchange_token(
context,
scopes=get_observability_authentication_scope(),
auth_handler_id="AGENTIC",
)
# cache this auth token and return via token resolver
AI チームメイトと Microsoft Agent 365 Observability Hosting Library パッケージを使用する A365 CLI を使用して構築されたエージェントの場合は、 AgenticTokenCache を使用してトークン キャッシュを自動的に処理します。 アクティビティ ハンドラー中にエージェントとテナントごとに 1 回トークンを登録し、監視構成のcache.get_observability_tokenとしてtoken_resolver渡します。
from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.hosting.token_cache_helpers import (
AgenticTokenCache,
AgenticTokenStruct,
)
from microsoft_agents_a365.runtime import get_observability_authentication_scope
# Create a shared cache instance
token_cache = AgenticTokenCache()
# Use the cache as your token resolver in configure()
configure(
service_name="my-agent-service",
service_namespace="my.namespace",
token_resolver=token_cache.get_observability_token,
)
@AGENT_APP.activity("message", auth_handlers=["AGENTIC"])
async def on_message(context: TurnContext, _state: TurnState):
token_cache.register_observability(
agent_id="agent-456",
tenant_id="tenant-123",
token_generator=AgenticTokenStruct(
authorization=AGENT_APP.auth,
turn_context=context,
),
observability_scopes=get_observability_authentication_scope(),
)
次のスニペットは、 @microsoft/agents-hosting SDK を使用してトークンを生成する方法を示しています。 ここで生成された認証トークンは、スパンを A365 インジェスト サービスにエクスポートするために使用されます。 エージェントは、 Microsoft Authentication Library (MSAL) を使用するなどしてトークン自体を自由に生成できますが、トークンが監視スコープを持っていることを確認する必要があります。
import {
TurnState,
AgentApplication,
MemoryStorage,
TurnContext,
} from '@microsoft/agents-hosting';
import { ActivityTypes } from '@microsoft/agents-activity';
import { getObservabilityAuthenticationScope } from '@microsoft/agents-a365-runtime';
interface ConversationState {
count: number;
}
type ApplicationTurnState = TurnState<ConversationState>;
const storage = new MemoryStorage();
export const agentApplication = new AgentApplication<ApplicationTurnState>({
authorization: {
agentic: {}, // We have the type and scopes set in the .env file
},
storage,
});
agentApplication.onActivity(
ActivityTypes.Message,
async (context: TurnContext, state: ApplicationTurnState) => {
const aauAuthToken = await agentApplication.authorization.exchangeToken(context, 'agentic', {
scopes: getObservabilityAuthenticationScope()
});
// cache this auth token and return via token resolver
}
);
AI チームメイトと @microsoft/agents-a365-observability-hosting パッケージを使用する A365 CLI で構築されたエージェントの場合は、 AgenticTokenCacheInstance を使用してトークン キャッシュを自動的に処理します。 アクティビティ ハンドラー中にエージェントとテナントごとに 1 回RefreshObservabilityToken呼び出し、監視構成のAgenticTokenCacheInstance.getObservabilityTokenとしてtokenResolverを渡します。
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
import { AgenticTokenCacheInstance } from '@microsoft/agents-a365-observability-hosting';
import { getObservabilityAuthenticationScope } from '@microsoft/agents-a365-runtime';
// Use the cache as your token resolver in configure()
const builder = ObservabilityManager.configure(builder =>
builder
.withService('my-agent-service', '1.0.0')
.withTokenResolver((agentId, tenantId) =>
AgenticTokenCacheInstance.getObservabilityToken(agentId, tenantId)
)
);
builder.start();
agentApplication.onActivity(
ActivityTypes.Message,
async (context: TurnContext, state: ApplicationTurnState) => {
const agentId = context.activity.recipient?.agenticAppId || '';
const tenantId = context.activity.recipient?.tenantId || '';
await AgenticTokenCacheInstance.RefreshObservabilityToken(
agentId,
tenantId,
context,
agentApplication.authorization,
getObservabilityAuthenticationScope()
);
}
);
次のスニペットは、 Microsoft.Agents ホスティング SDK を使用してトークンを生成する方法を示しています。 生成する認証トークンは、スパンを A365 インジェスト サービスにエクスポートするために使用されます。 エージェントは、 たとえば Microsoft Authentication Library (MSAL) を使用してトークン自体を生成できますが、トークンに監視スコープがあることを確認する必要があります。
Agent365ExporterOptionsに登録することで、TokenResolverトークンリゾルバーを提供します。 デリゲートは、 agentId と tenantId を受け取り、認証トークンを返します。
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Exporters;
builder.Services.AddSingleton(sp =>
{
return new Agent365ExporterOptions
{
TokenResolver = async (agentId, tenantId) =>
{
// Implement your token retrieval logic here
return await GetTokenAsync(agentId, tenantId);
}
};
});
AI チームメイトと Microsoft.Agents.A365.Observability.Hosting NuGet パッケージを使用する A365 CLI を使用して構築されたエージェントの場合は、 AddAgenticTracingExporter() メソッドを使用して、依存関係の挿入によってトークン キャッシュを自動的に処理します。
using Microsoft.Agents.A365.Observability.Hosting;
builder.Services.AddAgenticTracingExporter();
エージェント アプリケーションで、トークンを登録します。
using Microsoft.Agents.Builder;
using Microsoft.Agents.Builder.App.UserAuth;
using Microsoft.Extensions.Logging;
using Microsoft.Agents.A365.Observability.Hosting.Caching;
using Microsoft.Agents.A365.Observability.Runtime.Common;
using System;
using System.Threading.Tasks;
public class MyAgent : AgentApplication
{
private readonly IExporterTokenCache<AgenticTokenStruct> _agentTokenCache;
private readonly ILogger<MyAgent> _logger;
public MyAgent(AgentApplicationOptions options, IExporterTokenCache<AgenticTokenStruct> agentTokenCache, ILogger<MyAgent> logger)
: base(options)
{
_agentTokenCache = agentTokenCache ?? throw new ArgumentNullException(nameof(agentTokenCache));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
using var baggageScope = new BaggageBuilder()
.TenantId(turnContext.Activity.Recipient.TenantId)
.AgentId(turnContext.Activity.Recipient.AgenticAppId)
.Build();
try
{
_agentTokenCache.RegisterObservability(
turnContext.Activity.Recipient.AgenticAppId,
turnContext.Activity.Recipient.TenantId,
new AgenticTokenStruct(
userAuthorization: UserAuthorization,
turnContext: turnContext,
authHandlerName: "AGENTIC"
),
EnvironmentUtils.GetObservabilityAuthenticationScope()
);
}
catch (Exception ex)
{
_logger.LogWarning($"Error registering for observability: {ex.Message}");
}
}
}
自動インストルメンテーション
自動インストルメンテーションは、エージェンティック フレームワーク (SDK) の既存のテレメトリ信号をトレース用に自動的にリッスンし、それらを Agent 365 監視サービスに転送します。 この機能により、開発者が手動でモニタリングコードを書く必要がなくなり、設定が簡素化され、パフォーマンスの一貫性が保証されます。
複数のSDKおよびプラットフォームが自動計測をサポートしています:
注意
自動インストルメンテーションのサポートは、プラットフォームと SDK の実装によって異なります。
セマンティックカーネル
自動インストルメンテーションにはバゲッジ ビルダーの使用が必要です。 エージェントIDとテナントIDは BaggageBuilderで設定できます。
パッケージをインストールします。
pip install microsoft-agents-a365-observability-extensions-semantic-kernel
可観測性を構成します。
from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.semantickernel.trace_instrumentor import SemanticKernelInstrumentor
# Configure observability
configure(
service_name="my-semantic-kernel-agent",
service_namespace="ai.agents"
)
# Enable auto-instrumentation
instrumentor = SemanticKernelInstrumentor()
instrumentor.instrument()
# Your Semantic Kernel code is now automatically traced
Semantic Kernelは JavaScript ではサポートされていません。
依存関係をサービス コレクションに追加します。
using Microsoft.Agents.A365.Observability.Extensions.SemanticKernel;
builder.AddA365Tracing(configure: config => config.WithSemanticKernel());
AgentIdとTenantIdはBaggageBuilderを使って設定してください。
ChatCompletionAgentを作成する際に使うIDが、BaggageBuilderに渡すエージェントIDと一致していることを確認してください。
using Microsoft.Agents.A365.Observability.Extensions.SemanticKernel;
using Microsoft.Agents.A365.Observability.Runtime.Common;
public class MyAgent
{
public async Task<AgentResponse> ProcessUserRequest(string userInput)
{
using var baggageScope = new BaggageBuilder()
.AgentId(<your-agent-id>) // NOTE: This will be the agent ID with which the TokenResolver delegate is invoked.
.TenantId(<your-tenant-id>) // NOTE: This will be the tenant ID with which the TokenResolver delegate is invoked.
.Build();
var chatCompletionAgent = new ChatCompletionAgent
{
// NOTE: This will be the agent ID with which the TokenResolver delegate is invoked. Should match above.
Id = <your-agent-id>,
...
};
}
}
OpenAI
自動インストルメンテーションにはバゲッジ ビルダーの使用が必要です。 エージェントIDとテナントIDは BaggageBuilderで設定できます。
パッケージをインストールします。
pip install microsoft-agents-a365-observability-extensions-openai
可観測性を構成します。
from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.openai import OpenAIAgentsTraceInstrumentor
# Configure observability
configure(
service_name="my-openai-agent",
service_namespace="ai.agents"
)
# Enable auto-instrumentation
instrumentor = OpenAIAgentsTraceInstrumentor()
instrumentor.instrument()
# Your OpenAI Agents code is now automatically traced
パッケージをインストールします。
npm install @microsoft/agents-a365-observability-extensions-openai
可観測性を構成します。
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
import { OpenAIAgentsTraceInstrumentor } from '@microsoft/agents-a365-observability-extensions-openai';
// Configure observability first
const sdk = ObservabilityManager.configure((builder) =>
builder
.withService('My Agent Service', '1.0.0')
);
// Create and enable the instrumentor
const instrumentor = new OpenAIAgentsTraceInstrumentor({
enabled: true,
tracerName: 'openai-agents-tracer',
tracerVersion: '1.0.0'
});
sdk.start();
instrumentor.enable();
依存関係をサービス コレクションに追加します。
using Microsoft.Agents.A365.Observability.Extensions.OpenAI;
builder.AddA365Tracing(configure: config => config.WithOpenAI());
AgentIdとTenantIdはBaggageBuilderを使って設定してください。 ツール呼び出しの場合は、Trace()インスタンスでChatToolCallを使ってトレースを開始します。
using Microsoft.Agents.A365.Observability.Extensions.OpenAI;
using Microsoft.Agents.A365.Observability.Runtime.Common;
public class MyAgent
{
public async Task<AgentResponse> ProcessUserRequest(string userInput)
{
using var baggageScope = new BaggageBuilder()
.AgentId(<your-agent-id>) // NOTE: This will be the agent ID with which the TokenResolver delegate is invoked.
.TenantId(<your-tenant-id>) // NOTE: This will be the tenant ID with which the TokenResolver delegate is invoked.
.Build();
// NOTE: This will be the agent and tenant ID with which the TokenResolver delegate will be invoked.
using var scope = chatToolCall.Trace(agentId: <your-agent-id>, <your-tenant-id>);
}
}
エージェント フレームワーク
自動インストルメンテーションにはバゲッジ ビルダーの使用が必要です。 エージェントIDとテナントIDは BaggageBuilderで設定できます。
パッケージをインストールします。
pip install microsoft-agents-a365-observability-extensions-agent-framework
可観測性を構成します。
from microsoft_agents_a365.observability.core import configure
from microsoft_agents_a365.observability.extensions.agentframework import (
AgentFrameworkInstrumentor,
)
# Configure observability
configure(
service_name="AgentFrameworkTracingWithAzureOpenAI",
service_namespace="AgentFrameworkTesting",
)
# Enable auto-instrumentation
AgentFrameworkInstrumentor().instrument()
Agent Framework は JavaScript ではサポートされていません。
依存関係をサービス コレクションに追加します。
using Microsoft.Agents.A365.Observability.Extensions.AgentFramework;
builder.AddA365Tracing(configure: config => config.WithAgentFramework());
AgentIdとTenantIdはBaggageBuilderを使って設定してください。
using Microsoft.Agents.A365.Observability.Runtime.Common;
public class MyAgent : AgentApplication
{
protected async Task MessageActivityAsync(ITurnContext turnContext, ITurnState turnState, CancellationToken cancellationToken)
{
using var baggageScope = new BaggageBuilder()
.AgentId(<your-agent-id>) // NOTE: This will be the agent ID with which the TokenResolver delegate is invoked.
.TenantId(<your-tenant-id>) // NOTE: This will be the tenant ID with which the TokenResolver delegate is invoked.
.Build();
}
}
LangChain フレームワーク
自動インストルメンテーションにはバゲッジ ビルダーの使用が必要です。 エージェントIDとテナントIDは BaggageBuilderで設定できます。
パッケージをインストールします。
pip install microsoft-agents-a365-observability-extensions-langchain
可観測性を構成します。
from microsoft_agents_a365.observability.core.config import configure
from microsoft_agents_a365.observability.extensions.langchain import CustomLangChainInstrumentor
# Configure observability
configure(
service_name="my-langchain-agent",
service_namespace="ai.agents"
)
# Enable auto-instrumentation
CustomLangChainInstrumentor()
# Your LangChain code is now automatically traced
パッケージをインストールします。
npm install @microsoft/agents-a365-observability-extensions-langchain
可観測性を構成します。
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
import { LangChainTraceInstrumentor } from '@microsoft/agents-a365-observability-extensions-langchain';
import * as LangChainCallbacks from '@langchain/core/callbacks/manager';
// Configure observability first
const sdk = ObservabilityManager.configure((builder) =>
builder
.withService('My Agent Service', '1.0.0')
);
sdk.start();
// Enable LangChain auto-instrumentation
LangChainTraceInstrumentor.instrument(LangChainCallbacks);
// Your LangChain code is now automatically traced
LangChain は、.NETではサポートされていません。
手動インストルメンテーション
エージェントの内部動作を理解するには、Agent 365の観測可能性SDKを使用してください。
SDK には、開始できるスコープ ( InvokeAgentScope、 ExecuteToolScope、 InferenceScope、 OutputScope) が用意されています。
エージェント呼び出し
エージェントプロセスを開始する際に、この範囲を使用してください。 インヴォークエージェントスコープを使うことで、現在呼び出されているエージェントやエージェントのユーザーデータなどのプロパティをキャプチャできます。
from microsoft_agents_a365.observability.core import (
InvokeAgentScope,
InvokeAgentScopeDetails,
AgentDetails,
CallerDetails,
UserDetails,
Channel,
Request,
ServiceEndpoint,
)
agent_details = AgentDetails(
agent_id="agent-456",
agent_name="My Agent",
agent_description="An AI agent powered by Azure OpenAI",
agentic_user_id="auid-123",
agentic_user_email="agent@contoso.com",
agent_blueprint_id="blueprint-789",
tenant_id="tenant-123",
)
scope_details = InvokeAgentScopeDetails(
endpoint=ServiceEndpoint(hostname="myagent.contoso.com", port=443),
)
request = Request(
content="User asks a question",
session_id="session-42",
conversation_id="conv-xyz",
channel=Channel(name="msteams"),
)
caller_details = CallerDetails(
user_details=UserDetails(
user_id="user-123",
user_email="jane.doe@contoso.com",
user_name="Jane Doe",
),
)
with InvokeAgentScope.start(request, scope_details, agent_details, caller_details):
# Perform agent invocation logic
response = call_agent(...)
import {
InvokeAgentScope,
InvokeAgentScopeDetails,
AgentDetails,
CallerDetails,
UserDetails,
Channel,
Request,
ServiceEndpoint,
} from '@microsoft/agents-a365-observability';
// Use the same agentDetails instance across all scopes in a request
const agentDetails: AgentDetails = {
agentId: 'agent-456',
agentName: 'Email Assistant',
agentDescription: 'An AI agent powered by Azure OpenAI',
agentAuid: 'auid-123',
agentEmail: 'agent@contoso.com',
agentBlueprintId: 'blueprint-789',
tenantId: 'tenant-123',
};
const scopeDetails: InvokeAgentScopeDetails = {
endpoint: { host: 'myagent.contoso.com', port: 443 } as ServiceEndpoint,
};
// Use the same request instance across all scopes in a request
const request: Request = {
content: 'Please help me organize my emails',
sessionId: 'session-42',
conversationId: 'conv-xyz',
channel: { name: 'msteams' } as Channel,
};
// Optional: Caller details (human user, or agent-to-agent)
const callerDetails: CallerDetails = {
userDetails: {
userId: 'user-123',
userEmail: 'jane.doe@contoso.com',
userName: 'Jane Doe',
} as UserDetails,
};
const scope = InvokeAgentScope.start(request, scopeDetails, agentDetails, callerDetails);
try {
await scope.withActiveSpanAsync(async () => {
// Record input messages
scope.recordInputMessages(['Please help me organize my emails', 'Focus on urgent items']);
// Your agent invocation logic here
const response = await invokeAgent(request.content);
// Record output messages
scope.recordOutputMessages(['I found 15 urgent emails', 'Here is your organized inbox']);
});
} catch (error) {
scope.recordError(error as Error);
throw error;
} finally {
scope.dispose();
}
エージェントが @microsoft/agents-a365-observability-hosting パッケージを使用している場合は、 ScopeUtils.populateInvokeAgentScopeFromTurnContext を使用して、 TurnContextから自動的に派生するエージェントの詳細、呼び出し元の詳細、チャネル情報を含むスコープを作成できます。
import { InvokeAgentScopeDetails, AgentDetails, ServiceEndpoint } from '@microsoft/agents-a365-observability';
import { ScopeUtils } from '@microsoft/agents-a365-observability-hosting';
const agentDetails: AgentDetails = { agentId: 'agent-456' };
const scopeDetails: InvokeAgentScopeDetails = {
endpoint: { host: 'myagent.contoso.com', port: 443 } as ServiceEndpoint,
};
const scope = ScopeUtils.populateInvokeAgentScopeFromTurnContext(
agentDetails,
scopeDetails,
context, // TurnContext
authToken // authentication token string
);
try {
await scope.withActiveSpanAsync(async () => {
// Agent details, caller details, and channel are auto-populated from context
const response = await invokeAgent(context.activity.text);
scope.recordOutputMessages([response]);
});
} finally {
scope.dispose();
}
using System;
using System.Threading.Tasks;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
public class MyAgent
{
public async Task<AgentResponse> ProcessUserRequest(string userInput)
{
var agentDetails = new AgentDetails(
agentId: "agent-456",
agentName: "MyAgent",
agentDescription: "Handles user requests.",
agenticUserId: "auid-123",
agenticUserEmail: "agent@contoso.com",
agentBlueprintId: "blueprint-789",
tenantId: "tenant-123"
);
var scopeDetails = new InvokeAgentScopeDetails(
endpoint: new Uri("https://myagent.contoso.com")
);
var request = new Request(
content: userInput,
sessionId: "session-abc",
channel: new Channel("msteams"),
conversationId: "conv-xyz"
);
var callerDetails = new CallerDetails(
userDetails: new UserDetails(
userId: "user-123",
userEmail: "jane.doe@contoso.com",
userName: "Jane Doe"
)
);
// Start the scope
using var scope = InvokeAgentScope.Start(
request: request,
scopeDetails: scopeDetails,
agentDetails: agentDetails,
callerDetails: callerDetails
);
// Record input messages
scope.RecordInputMessages(new[] { userInput });
// ... your agent logic here ...
var output = $"Processed: {userInput}";
scope.RecordOutputMessages(new[] { output });
return new AgentResponse { Content = output };
}
}
public class AgentResponse
{
public string Content { get; set; }
}
以下の例は、エージェントのツール実行に観測可能性トラッキングを追加する方法を示しています。 この追跡は監視および監査目的でテレメトリーを記録します。
from microsoft_agents_a365.observability.core import (
ExecuteToolScope,
ToolCallDetails,
Request,
ServiceEndpoint,
)
# Use the same agent_details and request instances from the InvokeAgentScope example above
tool_details = ToolCallDetails(
tool_name="summarize",
tool_type="function",
tool_call_id="tc-001",
arguments="{'text': '...'}",
description="Summarize provided text",
endpoint=ServiceEndpoint(hostname="tools.contoso.com", port=8080),
)
with ExecuteToolScope.start(request, tool_details, agent_details) as scope:
result = run_tool(tool_details)
scope.record_response(result)
import { ExecuteToolScope, ToolCallDetails } from '@microsoft/agents-a365-observability';
// Use the same agentDetails and request instances from the InvokeAgentScope example above
const toolDetails: ToolCallDetails = {
toolName: 'email-search',
arguments: JSON.stringify({ query: 'from:boss@company.com', limit: 10 }),
toolCallId: 'tool-call-456',
description: 'Search emails by criteria',
toolType: 'function',
endpoint: {
host: 'tools.contoso.com',
port: 8080, // Will be recorded since not 443
protocol: 'https'
},
};
const scope = ExecuteToolScope.start(request, toolDetails, agentDetails);
try {
return await scope.withActiveSpanAsync(async () => {
// Execute the tool
const result = await searchEmails(toolDetails.arguments);
// Record the tool execution result
scope.recordResponse(result);
return result;
});
} catch (error) {
scope.recordError(error as Error);
throw error;
} finally {
scope.dispose();
}
エージェントが @microsoft/agents-a365-observability-hosting パッケージを使用している場合は、 ScopeUtils.populateExecuteToolScopeFromTurnContext を使用して、 TurnContextから自動的に派生したエージェントの詳細を含むスコープを作成します。
import { ToolCallDetails } from '@microsoft/agents-a365-observability';
import { ScopeUtils } from '@microsoft/agents-a365-observability-hosting';
const toolDetails: ToolCallDetails = {
toolName: 'email-search',
arguments: JSON.stringify({ query: 'from:boss@company.com' }),
toolCallId: 'tool-call-456',
toolType: 'function',
};
const scope = ScopeUtils.populateExecuteToolScopeFromTurnContext(
toolDetails,
context, // TurnContext
authToken // authentication token string
);
try {
await scope.withActiveSpanAsync(async () => {
const result = await searchEmails(toolDetails.arguments);
scope.recordResponse(JSON.stringify(result));
});
} finally {
scope.dispose();
}
using System;
using System.Threading.Tasks;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
// Use the same agentDetails and request instances from the InvokeAgentScope example above
var toolCallDetails = new ToolCallDetails(
toolName: "summarize",
arguments: "{\"text\": \"...\"}",
toolCallId: "tc-001",
description: "Summarize provided text",
toolType: "function",
endpoint: new Uri("https://tools.contoso.com:8080")
);
using var scope = ExecuteToolScope.Start(
request: request,
details: toolCallDetails,
agentDetails: agentDetails
);
// ... your tool logic here ...
scope.RecordResponse("{\"summary\": \"The text was summarized.\"}");
推論
次の例では、監視追跡を使用して AI モデル推論呼び出しをインストルメント化して、トークンの使用状況、モデルの詳細、応答メタデータをキャプチャする方法を示します。
from microsoft_agents_a365.observability.core import (
InferenceScope,
InferenceCallDetails,
InferenceOperationType,
)
# Use the same agent_details and request instances from the InvokeAgentScope example above
inference_details = InferenceCallDetails(
operationName=InferenceOperationType.CHAT,
model="gpt-4o-mini",
providerName="azure-openai",
inputTokens=123,
outputTokens=456,
finishReasons=["stop"],
)
with InferenceScope.start(request, inference_details, agent_details) as scope:
completion = call_llm(...)
scope.record_output_messages([completion.text])
scope.record_input_tokens(completion.usage.input_tokens)
scope.record_output_tokens(completion.usage.output_tokens)
import { InferenceScope, InferenceDetails, InferenceOperationType } from '@microsoft/agents-a365-observability';
// Use the same agentDetails and request instances from the InvokeAgentScope example above
const inferenceDetails: InferenceDetails = {
operationName: InferenceOperationType.CHAT,
model: 'gpt-4o-mini',
providerName: 'azure-openai',
};
const scope = InferenceScope.start(request, inferenceDetails, agentDetails);
try {
return await scope.withActiveSpanAsync(async () => {
// Record input messages
scope.recordInputMessages(['Summarize the following emails for me...']);
// Call the LLM
const response = await callLLM();
// Record detailed telemetry with granular methods
scope.recordOutputMessages(['Here is your email summary...']);
scope.recordInputTokens(145);
scope.recordOutputTokens(82);
scope.recordFinishReasons(['stop']);
return response.text;
});
} catch (error) {
scope.recordError(error as Error);
throw error;
} finally {
scope.dispose();
}
エージェントが @microsoft/agents-a365-observability-hosting パッケージを使用している場合は、 ScopeUtils.populateInferenceScopeFromTurnContext を使用して、 TurnContextから自動的に派生したエージェントの詳細を含むスコープを作成できます。
import { InferenceDetails, InferenceOperationType } from '@microsoft/agents-a365-observability';
import { ScopeUtils } from '@microsoft/agents-a365-observability-hosting';
const inferenceDetails: InferenceDetails = {
operationName: InferenceOperationType.CHAT,
model: 'gpt-4o-mini',
providerName: 'azure-openai',
};
const scope = ScopeUtils.populateInferenceScopeFromTurnContext(
inferenceDetails,
context, // TurnContext
authToken // authentication token string
);
try {
await scope.withActiveSpanAsync(async () => {
const response = await callLLM();
scope.recordOutputMessages([response.text]);
scope.recordInputTokens(response.usage.inputTokens);
scope.recordOutputTokens(response.usage.outputTokens);
});
} finally {
scope.dispose();
}
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
// Use the same agentDetails and request instances from the InvokeAgentScope example above
var inferenceDetails = new InferenceCallDetails(
operationName: InferenceOperationType.Chat,
model: "gpt-4o-mini",
providerName: "Azure OpenAI",
inputTokens: 123,
outputTokens: 456,
finishReasons: new[] { "stop" }
);
using var scope = InferenceScope.Start(
request: request,
details: inferenceDetails,
agentDetails: agentDetails
);
// ... your inference logic here ...
scope.RecordOutputMessages(new[] { "AI response message" });
scope.RecordInputTokens(123);
scope.RecordOutputTokens(456);
アウトプット
このスコープは、 InvokeAgentScope、 ExecuteToolScope、または InferenceScope が出力データを同期的にキャプチャできない非同期シナリオに使用します。 子スパンとして OutputScope を開始し、親スコープの終了後に最終的な出力メッセージを記録します。
from microsoft_agents_a365.observability.core import (
OutputScope,
Response,
SpanDetails,
)
# Use the same agent_details and request instances from the InvokeAgentScope example above
# Get the parent context from the originating scope
parent_context = invoke_scope.get_context()
response = Response(messages=["Here is your organized inbox with 15 urgent emails."])
with OutputScope.start(
request,
response,
agent_details,
span_details=SpanDetails(parent_context=parent_context),
):
# Output messages are recorded automatically from the response
pass
import { OutputScope, OutputResponse, SpanDetails } from '@microsoft/agents-a365-observability';
// Use the same agentDetails and request instances from the InvokeAgentScope example above
// Get the parent context from the originating scope
const parentContext = invokeScope.getSpanContext();
const response: OutputResponse = {
messages: ['Here is your organized inbox with 15 urgent emails.'],
};
const scope = OutputScope.start(
request,
response,
agentDetails,
undefined, // userDetails
{ parentContext } as SpanDetails
);
// Output messages are recorded automatically from the response
scope.dispose();
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
// Use the same agentDetails and request instances from the InvokeAgentScope example above
// Get the parent context from the originating scope
var parentContext = invokeScope.GetActivityContext();
var response = new Response(new[] { "Here is your organized inbox with 15 urgent emails." });
using var scope = OutputScope.Start(
request: request,
response: response,
agentDetails: agentDetails,
spanDetails: new SpanDetails(parentContext: parentContext)
);
// Output messages are recorded automatically from the response
ローカルでの検証
監視 SDK と正常に統合されたことを確認するには、エージェントによって生成されたコンソール ログと、observability SDK のログを調べます。
ENABLE_A365_OBSERVABILITY_EXPORTER 環境変数を false に設定します。 この設定はスパン(トレース)をコンソールにエクスポートします。
エクスポートエラーを調査するには、 ENABLE_A365_OBSERVABILITY_EXPORTER を true に設定し、アプリケーションの起動時にデバッグ ログを構成することで、詳細ログを有効にします。
import logging
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("microsoft_agents_a365.observability.core").setLevel(logging.DEBUG)
# Or target only the exporter:
logging.getLogger(
"microsoft_agents_a365.observability.core.exporters.agent365_exporter"
).setLevel(logging.DEBUG)
キー ログ メッセージ:
DEBUG Token resolved for agent {agentId} tenant {tenantId}
DEBUG Exporting {n} spans to {url}
DEBUG HTTP 200 - correlation ID: abc-123
ERROR Token resolution failed: {error}
ERROR HTTP 401 exporting spans - correlation ID: abc-123
INFO No spans with tenant/agent identity found; nothing exported.
ENABLE_A365_OBSERVABILITY_EXPORTER 環境変数を false に設定します。 この設定はスパン(トレース)をコンソールにエクスポートします。
エクスポートエラーを調査するには、 .env またはシェルで環境変数を設定します。
# Enable the Agent365 exporter
ENABLE_A365_OBSERVABILITY_EXPORTER=true
# Enable verbose logging
A365_OBSERVABILITY_LOG_LEVEL=info|warn|error
次のようなメッセージのコンソール出力を確認します。
[INFO] [Agent365Exporter] Exporting 245 spans
[INFO] [Agent365Exporter] Partitioned into 3 identity groups (2 spans skipped)
[INFO] [Agent365Exporter] Token resolved successfully via tokenResolver
[EVENT] export-group succeeded in 98ms {"tenantId":"...","agentId":"...","correlationId":"abc-123"}
[ERROR] [Agent365Exporter] Failed with status 401, correlation ID: abc-123
[WARN] export-partition-span-missing-identity: 5 spans skipped due to missing tenant or agent ID
必要に応じて、カスタム ロガーを使用して、エクスポート イベントをファイルにキャプチャします。
import { setLogger, ExporterEventNames } from '@microsoft/agents-a365-observability';
setLogger({
info: (msg, ...args) => myLogger.info(msg, ...args),
warn: (msg, ...args) => myLogger.warn(msg, ...args),
error: (msg, ...args) => myLogger.error(msg, ...args),
event: (eventType: ExporterEventNames, isSuccess: boolean, durationMs: number,
message?: string, details?: Record<string, string>) => {
myLogger.info({ eventType, isSuccess, durationMs, message, ...details });
}
});
EnableAgent365Exporter で false を appsettings.json に設定します。 この設定はスパン(トレース)をコンソールにエクスポートします。
エクスポートの失敗を調査するには、appsettings.jsonで詳細なログを設定します。
{
"EnableAgent365Exporter": "True",
"Logging": {
"LogLevel": {
"Microsoft.Agents.A365.Observability": "Debug"
}
}
}
または、環境変数を設定します。
EnableAgent365Exporter=True
A365_OBSERVABILITY_DOMAIN_OVERRIDE=https://your-test-endpoint.example.com
A365_OBSERVABILITY_SCOPE_OVERRIDE=https://api.powerplatform.com/.default
キー ログ メッセージ:
info: Agent365ExporterCore: Obtained token for agent {agentId} tenant {tenantId}.
info: Agent365ExporterCore: Sending {count} spans to {requestUri} for agent {agentId} tenant {tenantId}.
info: Agent365ExporterCore: HTTP {statusCode} exporting spans. 'x-ms-correlation-id': '{correlationId}'.
error: Agent365Exporter: Exception exporting spans: {exception}
warn: Agent365ExporterCore: No token obtained for agent {agentId} tenant {tenantId}. Skipping export.
注意
DI に ILoggerFactory を登録しない場合、エクスポーターは自動的にコンソール ロガーにフォールバックします。
エクスポートされたログの表示
Microsoft PurviewまたはMicrosoft Defenderでエージェント テレメトリを表示するには、次の要件が満たされていることを確認します。
ストアパブリッシングのための検証
重要
ストアの検証を成功させるには、エージェントで、InvokeAgentScope、およびInferenceScopeスコープを実装するExecuteToolScope。 公開には、これら 3 つのスコープが必要です。
発行する前に、コンソール ログを使用して、必要な invoke agent、 execute tool、 inference、および output スコープを実装して、エージェントの可観測性の統合を検証します。 次に、エージェントのログを以下の属性リストと比較し、必要な属性がすべて揃っているか確認します。 各スコープや手荷物ビルダーで属性を取得でき、オプションの属性も自由に加えてください。
ストア公開要件の詳細については、 ストア検証ガイドラインをご覧ください。
InvokeAgentScope 属性
以下のリストは、 InvokeAgentScope開始時に記録される必要およびオプションのテレメトリ属性をまとめたものです。
"attributes": {
"error.type": "Optional",
"microsoft.a365.agent.blueprint.id": "Required",
"gen_ai.agent.description": "Optional",
"gen_ai.agent.id": "Required",
"gen_ai.agent.name": "Required",
"microsoft.a365.agent.platform.id": "Optional",
"microsoft.agent.user.email": "Required",
"microsoft.agent.user.id": "Required",
"gen_ai.agent.version": "Optional",
"microsoft.a365.caller.agent.blueprint.id": "Optional",
"microsoft.a365.caller.agent.id": "Optional",
"microsoft.a365.caller.agent.name": "Optional",
"microsoft.a365.caller.agent.platform.id": "Optional",
"microsoft.a365.caller.agent.user.email": "Optional",
"microsoft.a365.caller.agent.user.id": "Optional",
"microsoft.a365.caller.agent.version": "Optional",
"client.address": "Required",
"user.id": "Required",
"user.name": "Optional",
"user.email": "Required",
"microsoft.channel.link": "Optional",
"microsoft.channel.name": "Required",
"gen_ai.conversation.id": "Required",
"microsoft.conversation.item.link": "Optional",
"gen_ai.input.messages": "Required",
"gen_ai.operation.name": "Required",
"gen_ai.output.messages": "Required",
"server.address": "Required",
"server.port": "Required",
"microsoft.session.id": "Optional",
"microsoft.session.description": "Optional",
"microsoft.tenant.id": "Required"
}
以下のリストは、 ExecuteToolScope開始時に記録される必要およびオプションのテレメトリ属性をまとめたものです。
"attributes": {
"error.type": "Optional",
"microsoft.a365.agent.blueprint.id": "Required",
"gen_ai.agent.description": "Optional",
"gen_ai.agent.id": "Required",
"gen_ai.agent.name": "Required",
"microsoft.a365.agent.platform.id": "Optional",
"microsoft.agent.user.email": "Required",
"microsoft.agent.user.id": "Required",
"gen_ai.agent.version": "Optional",
"client.address": "Required",
"user.id": "Required",
"user.name": "Optional",
"user.email": "Required",
"microsoft.channel.link": "Optional",
"microsoft.channel.name": "Required",
"gen_ai.conversation.id": "Required",
"microsoft.conversation.item.link": "Optional",
"gen_ai.operation.name": "Required",
"gen_ai.tool.call.arguments": "Required",
"gen_ai.tool.call.id": "Required",
"gen_ai.tool.call.result": "Required",
"gen_ai.tool.description": "Optional",
"gen_ai.tool.name": "Required",
"gen_ai.tool.type": "Required",
"server.address": "Optional",
"server.port": "Optional",
"microsoft.session.id": "Optional",
"microsoft.session.description": "Optional",
"microsoft.tenant.id": "Required"
}
InferenceScope 属性
以下のリストは、 InferenceScope開始時に記録される必要およびオプションのテレメトリ属性をまとめたものです。
"attributes": {
"error.type": "Optional",
"microsoft.a365.agent.blueprint.id": "Required",
"gen_ai.agent.description": "Optional",
"gen_ai.agent.id": "Required",
"gen_ai.agent.name": "Required",
"microsoft.a365.agent.platform.id": "Optional",
"microsoft.a365.agent.thought.process": "Optional",
"microsoft.agent.user.email": "Required",
"microsoft.agent.user.id": "Required",
"gen_ai.agent.version": "Optional",
"client.address": "Required",
"user.id": "Required",
"user.name": "Optional",
"user.email": "Required",
"microsoft.channel.link": "Optional",
"microsoft.channel.name": "Required",
"gen_ai.conversation.id": "Required",
"microsoft.conversation.item.link": "Optional",
"gen_ai.input.messages": "Required",
"gen_ai.operation.name": "Required",
"gen_ai.output.messages": "Required",
"gen_ai.provider.name": "Required",
"gen_ai.request.model": "Required",
"gen_ai.response.finish_reasons": "Optional",
"gen_ai.usage.input_tokens": "Optional",
"gen_ai.usage.output_tokens": "Optional",
"server.address": "Optional",
"server.port": "Optional",
"microsoft.session.description": "Optional",
"microsoft.session.id": "Optional",
"microsoft.tenant.id": "Required"
}
OutputScope 属性
以下のリストは、 OutputScope開始時に記録される必要およびオプションのテレメトリ属性をまとめたものです。 このスコープは、親スコープが出力データを同期的にキャプチャできない非同期シナリオに使用します。
"attributes": {
"microsoft.a365.agent.blueprint.id": "Required",
"gen_ai.agent.description": "Optional",
"gen_ai.agent.id": "Required",
"gen_ai.agent.name": "Required",
"microsoft.a365.agent.platform.id": "Optional",
"microsoft.agent.user.email": "Required",
"microsoft.agent.user.id": "Required",
"gen_ai.agent.version": "Optional",
"client.address": "Required",
"user.id": "Required",
"user.name": "Optional",
"user.email": "Required",
"microsoft.channel.link": "Optional",
"microsoft.channel.name": "Required",
"gen_ai.conversation.id": "Required",
"microsoft.conversation.item.link": "Optional",
"gen_ai.operation.name": "Required",
"gen_ai.output.messages": "Required",
"microsoft.session.id": "Optional",
"microsoft.session.description": "Optional",
"microsoft.tenant.id": "Required"
}
可観測性でエージェントをテストする
エージェントに可観測性を実装したら、それをテストして、テレメトリが正しくキャプチャされていることを確認します。
テストガイドに従って環境を整えましょう。 次に、監視機能の実装が期待どおりに動作していることを検証するために、主に [監視ログの 表示 ] セクションに焦点を当てます。
検証:
- 以下に移動します:
https://admin.cloud.microsoft/#/agents/all
- エージェント > アクティビティを選択してください
- セッションとツール呼び出しが表示される
トラブルシューティング
このセクションでは、可観測性の実装および使用における一般的な問題について説明します。
観測データが表示されません
症状:
- エージェントが走っている
- 管理センターにテレメトリはありません
- エージェントの活動が見えません
根本原因:
- 観測可能性は有効になっていません
- 構成エラー
- トークンリゾルバの問題
解決策: 問題解決のために以下の手順を試してみてください。
可観測性エクスポーターが有効になっていることを確認する
エージェント 365 エクスポーターを明示的に有効にする必要があります。 無効にすると、SDK はコンソール エクスポーターにフォールバックし、テレメトリはサービスに送信されません。 構成の詳細については、「 構成」を参照してください。
トークンリゾルバの設定を確認する
エクスポーターには、エクスポート要求ごとにベアラー トークンを返す有効なトークン リゾルバーが必要です。 トークン リゾルバーが見つからないか、 nullを返した場合、エクスポートは自動的にスキップされます。 コードがトークンリゾルバを正しく実装しているか確認してください。 詳細については、「 トークン リゾルバー」を参照してください。
ログの誤りをチェックしてください
詳細ログを有効にし、 az webapp log tail コマンド を使用して、監視に関連するエラーのログを検索します。 プラットフォームごとにログ記録を有効にする方法の詳細については、「 ローカルで検証する」を参照してください。
# Look for observability-related errors
az webapp log tail --name <your-app-name> --resource-group <your-resource-group> | Select-String "observability"
テレメトリのエクスポートを検証してください
テレメトリが正常に生成・エクスポートされているか確認してください。
- コンソール エクスポーターを追加し、テレメトリがローカルで生成されているかどうかを確認します。 コンソール エクスポーターを使用して出力を検証する方法の詳細については、「 ローカルで検証する」を参照してください。
テナント ID またはエージェント ID が見つからない - 範囲がスキップされました
症状: システムは自動的にスパンをドロップし、エクスポートしません。 一部の SDK では、スキップされたスパンの数や、"テナント/エージェント ID が見つかったスパンがありません" などのメッセージが記録されます。他のユーザーは、ログを記録せずに削除します。
解決方法:
- エクスポートする前に、SDK パーティションはテナント ID とエージェント ID ごとにまたがっています。 システムは、テナント ID またはエージェント ID を持たないスパンを削除し、サービスに送信することはありません。
- スパンを作成する前に、
BaggageBuilder がテナント ID とエージェント ID で設定されていることを確認します。 これらの値は OpenTelemetry コンテキストを通じて伝達され、手荷物スコープ内で作成されたすべてのスパンにアタッチされます。 プラットフォーム固有の API については、「 Baggage 属性」を参照してください。
- ホスティング統合パッケージの手荷物ミドルウェアまたはターンコンテキストヘルパーを使用してIDを設定する場合、
TurnContext アクティビティにエージェントIDを持つ有効な受信者がいることを確認してください。
トークン解決失敗 - エクスポートがスキップされるか未承認
症状: トークン リゾルバーは null を返すか、エラーをスローします。 SDK によっては、エクスポートが完全にスキップされるか、要求が承認ヘッダーなしで送信され、HTTP 401 で失敗します。
解決方法:
- トークン リゾルバーは初期化時に必要です。 見つからない場合、エクスポーターは起動時にエラーをスローします。 トークン リゾルバーが提供され、有効なベアラー トークンが返されることを確認します。
- これらの値はトークン リゾルバーに渡されるため、
BaggageBuilderに正しいテナント ID とエージェント ID が使用されていることを確認します。
- Azureホステッド エージェントの場合は、マネージド ID に監視スコープに必要な API アクセス許可があることを確認します。
HTTP 401 認証されていません
症状: HTTP 401 でエクスポートが失敗する。 エクスポーターはこのエラーを再試行しません。
解決方法:
- トークン対象ユーザーが可観測性エンドポイントスコープと一致するかどうかを確認します。 既定のスコープは、能動的エージェントに対して
https://api.powerplatform.com/.defaultである。
- ID (マネージド ID またはアプリの登録) に Agent 365 監視アクセス許可があることを確認します。
- トークン リゾルバーが、委任されたユーザー トークン、正しくない対象ユーザーのトークン、または期限切れのトークンを返していないことを確認します。
重要
これらのパッケージ バージョンにアップグレードする既存のエージェントには、追加の手順が必要です
この手順は、既存のエージェントをアップグレードする場合にのみ適用されます。 新しいエージェントのインストールでは、この手順は必要ありません。 次のパッケージ バージョン以降にアップグレードする場合は、ID (マネージド ID またはアプリの登録) に新しい Agent365.Observability.OtelWrite アクセス許可を付与する必要があります。 このアクセス許可がない場合、テレメトリのエクスポートは HTTP 401 で失敗します。
| プラットフォーム |
この手順を必要とする最小バージョン |
| .NET |
0.3-beta |
| Node.js |
0.2.0-preview.1 |
| Python |
0.3.0 |
必要な手順については、アップグレードするパッケージの変更ログを参照してください。
HTTP 403 Forbidden(アクセス禁止)
症状: HTTP 403 でエクスポートが失敗する。 エクスポーターはこのエラーを再試行しません。
解決方法:
- テナント ID が、トレース インジェストのためにエージェント 365 の許可されるテナントの一覧に追加されているかどうかを確認します。
- エージェント ID に、ターゲット テナントに必要なロールまたはアクセス許可があることを確認します。
HTTP 429 / 5xx — 一時的なエラー
症状: エクスポートは、429 や 5xx などの一時的な HTTP 状態コードで失敗します。
解決方法:
- 通常、これらのエラーは一時的なものであり、単独で解決されます。 Pythonおよび JavaScript SDK は、指数バックオフを使用して HTTP 408、429、および 5xx 状態コードで最大 3 回自動的に再試行します。 .NET SDK は自動的に再試行されません。
- エラーが解決しない場合は、サービス正常性ダッシュボードを確認します。
- バッチ間のスケジュールされた遅延を増やすか、最大エクスポート バッチ サイズを増やすことで、エクスポート頻度を減らすことを検討してください。 プラットフォームごとの構成オプションについては、「
Agent365ExporterOptions」の表を参照してください。
エクスポートのタイムアウト
症状: エクスポートの試行がタイムアウトしました。
解決方法:
- 監視エンドポイントへのネットワーク接続を確認します。
- タイムアウトの既定値はプラットフォームによって異なります。 既定の HTTP 要求タイムアウトは 30 秒です。 一部の SDK には、再試行を含むエクスポート サイクル全体をカバーする個別の全体的なエクスポーター タイムアウトもあります。 プラットフォームごとの正確なプロパティと既定値については、「
Agent365ExporterOptions」のの表を参照してください。
- タイムアウトが頻繁に発生する場合は、エクスポーター オプションで関連するタイムアウト値を増やします。
エクスポートは成功しますが、テレメトリは Defender または Purview に表示されません
Symptoms: ログにはエクスポートが成功したことが示されますが、テレメトリはMicrosoft DefenderまたはMicrosoft Purviewに表示されません。
解決方法:
- エクスポートされたログを表示するための前提条件を満たしていることを確認します。 Purview の場合、監査を有効にする必要があります。 Defenderの場合は、高度なハンティングを構成する必要があります。 詳細については、 エクスポートされたログの表示を参照してください。
- エクスポートが成功した後、テレメトリの設定には数分かかる場合があります。 さらに調査する前に、データが表示されるまで待ちます。
可観測性のテストの詳細については、以下を参照してください。