중요
Microsoft 에이전트 365에 대한 초기 액세스를 얻으려면 프론티어 미리 보기 프로그램의 일부여야 합니다. 프론티어는 Microsoft의 최신 AI 혁신과 직접 연결합니다. 프론티어 미리 보기에는 고객 계약의 기존 미리 보기 조건이 적용됩니다. 이러한 기능은 아직 개발 중이므로 가용성 및 기능은 시간이 지남에 따라 변경 될 수 있습니다.
에이전트 365 에코시스템에 참여하려면 에이전트 365 관찰 기능 기능을 에이전트에 추가해야 합니다. 에이전트 365 관찰성은 OTel(OpenTelemetry)을 기반으로 하며 모든 에이전트 플랫폼에서 일관되고 안전하게 원격 분석을 캡처하기 위한 통합 프레임워크를 제공합니다. 이 필수 구성 요소를 구현하면 IT 관리자가 MAC(Microsoft Admin Center)에서 에이전트의 활동을 모니터링하고 보안 팀이 준수 및 위협 탐지를 위해 Defender 및 Purview를 사용할 수 있습니다.
주요 혜택
-
엔드 투 엔드 가시성: 세션, 도구 호출 및 예외를 포함하여 모든 에이전트 호출에 대한 포괄적인 원격 분석을 캡처하여 플랫폼 전체에서 완전한 추적 기능을 제공합니다.
-
보안 및 규정 준수 사용: 통합 감사 로그를 Defender 및 Purview에 공급하여 에이전트에 대한 고급 보안 시나리오 및 규정 준수 보고를 사용하도록 설정합니다.
-
플랫폼 간 유연성: OTel 표준을 기반으로 하며 Copilot Studio, Foundry 및 향후 에이전트 프레임워크와 같은 다양한 런타임 및 플랫폼을 지원합니다.
-
관리자를 위한 운영 효율성: MAC에서 중앙 집중식 관찰 기능을 제공하여 문제 해결 시간을 단축하고 에이전트를 관리하는 IT 팀의 역할 기반 액세스 제어를 통해 거버넌스를 개선합니다.
설치
이러한 명령을 사용하여 에이전트 365에서 지원하는 언어에 대한 관찰 모듈을 설치합니다.
pip install microsoft-agents-a365-observability-core
pip install microsoft-agents-a365-runtime
npm install @microsoft/agents-a365-observability
npm install @microsoft/agents-a365-runtime
dotnet add package Microsoft.Agents.A365.Observability
dotnet add package Microsoft.Agents.A365.Observability.Runtime
구성
관찰에 필요한 환경 변수는 다음과 같습니다.
| 환경 변수 |
설명 |
ENABLE_OBSERVABILITY=true |
추적을 사용하거나 사용하지 않도록 설정하는 플래그입니다. 기본적으로: false |
ENABLE_A365_OBSERVABILITY_EXPORTER=true |
True 로그를 서비스로 내보냅니다. 그렇지 않으면 콘솔 내보내기로 돌아갑니다. |
from microsoft_agents_a365.observability.core import config
def token_resolver(agent_id: str, tenant_id: str) -> str | None:
# Implement secure token retrieval here
return "Bearer <token>"
config.configure(
service_name="my-agent-service",
service_namespace="my.namespace",
token_resolver=token_resolver,
)
콘솔에 로그할 토큰 확인자를 제외합니다.
관찰에 필요한 환경 변수는 다음과 같습니다.
| 환경 변수 |
설명 |
ENABLE_OBSERVABILITY=true |
추적을 사용하거나 사용하지 않도록 설정하는 플래그입니다. 기본적으로: false |
ENABLE_A365_OBSERVABILITY_EXPORTER=true |
True 로그를 서비스로 내보냅니다. 그렇지 않으면 콘솔 내보내기로 돌아갑니다. |
import { ObservabilityManager } from '@microsoft/agents-a365-observability';
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();
에 EnableAgent365Exporter 설정
에서 Program.cs서비스 컬렉션에 추가 Agent365ExporterOptions 합니다. 이 변경은 추적 내보내기가 토큰을 검색하는 데 사용하는 대리자를 구성합니다.
를 사용하여 AddA365Tracing()관찰 가능성 관련 종속성을 추가합니다.
using Microsoft.Agents.A365.Observability.Runtime;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(sp =>
{
return new Agent365ExporterOptions
{
ClusterCategory = "prod",
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();
이미지 특성
요청의 모든 범위를 통과하는 컨텍스트 정보를 설정하는 데 사용합니다 BaggageBuilder .
SDK SpanProcessor 는 기존 특성을 덮어쓰지 않고 새로 시작된 범위에 모든 수하물 항목을 복사합니다.
from microsoft_agents_a365.observability.core.middleware.baggage_builder import BaggageBuilder
with (
BaggageBuilder()
.tenant_id("tenant-123")
.agent_id("agent-456")
.correlation_id("corr-789")
.build()
):
# Any spans started in this context will receive these as attributes
pass
import { BaggageBuilder } from '@microsoft/agents-a365-observability';
// Create and apply baggage context
using baggageScope = new BaggageBuilder()
// Core identifiers
.tenantId('tenant-123')
.agentId('agent-456')
.correlationId('correlation-789')
.build();
// Execute operations within the baggage context
baggageScope.run(() => {
// All spans created within this context will inherit the baggage values
// Invoke another agent
using agentScope = InvokeAgentScope.start(invokeDetails, agentDetails, tenantDetails);
// ... agent logic
// Execute tools
using toolScope = ExecuteToolScope.start(toolDetails, agentDetails, tenantDetails);
// ... tool logic
});
using var baggageScope = new BaggageBuilder()
.TenantId('tenant-123')
.AgentId('agent-456')
.CorrelationId('correlation-789')
.Build();
// Any spans started in this context will receive them as attributes.
토큰 확인자
에이전트 365 내보내기를 사용하는 경우 인증 토큰을 반환하는 토큰 확인자 함수를 제공해야 합니다.
에이전트 호스팅 프레임워크에서 에이전트 365 Observability SDK를 사용하는 경우 에이전트 활동에서 토큰을 TurnContext 생성할 수 있습니다.
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.environment_utils 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
import {
TurnState,
AgentApplication,
MemoryStorage,
TurnContext,
} from '@microsoft/agents-hosting';
import { Activity, ActivityTypes } from '@microsoft/agents-activity';
import { getObservabilityAuthenticationScope } from '@microsoft/agents-a365-runtime';
interface ConversationState {
count: number;
}
type ApplicationTurnState = TurnState<ConversationState>;
const downloader = new AttachmentDownloader();
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
};
에이전트 토큰 확인자를 서비스 컬렉션에 추가합니다.
using Microsoft.Agents.A365.Observability;
builder.Services.AddAgenticTracingExporter();
에이전트 애플리케이션에서 토큰을 등록합니다.
using Microsoft.Agents.Builder;
using Microsoft.Agents.Core.Models;
using Microsoft.Extensions.Logging;
using Microsoft.Agents.A365.Observability.Caching;
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
},
EnvironmentUtils.GetObservabilityAuthenticationScope()
);
}
catch (Exception ex)
{
_logger.LogWarning($"Error registering for observability: {ex.Message}");
}
}
}
자동 계측
자동 계측은 추적에 대한 기존 원격 분석 신호인 SDK(에이전트 프레임워크)를 자동으로 수신 대기하고 에이전트 365 관찰 서비스로 전달합니다. 이렇게 하면 개발자가 모니터링 코드를 수동으로 작성하여 설정을 간소화하고 일관된 성능 추적을 보장할 필요가 없습니다.
자동 계측은 여러 SDK 및 플랫폼에서 지원됩니다.
참고
자동 계측에 대한 지원은 플랫폼 및 SDK 구현에 따라 다릅니다.
의미 체계 커널
자동 계측을 사용하려면 수하물 작성기를 사용해야 합니다. 를 사용하여 에이전트 ID 및 테넌트 ID를 BaggageBuilder설정합니다.
패키지 설치
pip install microsoft-agents-a365-observability-extensions-semantic-kernel
가시성 구성
from microsoft_agents_a365.observability.core.config import configure
from microsoft_agents_a365.observability.extensions.semantic_kernel 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
의미 체계 커널은 JavaScript에서 지원되지 않습니다.
서비스 컬렉션에 종속성을 추가합니다.
using Microsoft.Agents.A365.Observability.Extensions.SemanticKernel;
builder.Services.AddTracing(config => config.WithSemanticKernel());
설정 AgentId 및 TenantId 사용 BaggageBuilder. 만들 ChatCompletionAgent 때 사용되는 ID가 전달된 에이전트 ID와 일치하는지 확인합니다 BaggageBuilder.
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.config import configure
from microsoft_agents_a365.observability.extensions.openai_agents 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')
.withConsoleExporter(true)
);
// 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.Services.AddTracing(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>);
}
}
에이전트를 프레임워크
자동 계측을 사용하려면 수하물 작성기를 사용해야 합니다. BaggageBuilder를 사용하여 에이전트 ID 및 테넌트 ID를 설정합니다.
패키지 설치
pip install microsoft-agents-a365-observability-extensions-agent-framework
가시성 구성
from microsoft_agents_a365.observability.core.config import configure
from microsoft_agents_a365.observability.extensions.agentframework.trace_instrumentor import (
AgentFrameworkInstrumentor,
)
# Configure observability
configure(
service_name="AgentFrameworkTracingWithAzureOpenAI",
service_namespace="AgentFrameworkTesting",
)
# Enable auto-instrumentation
AgentFrameworkInstrumentor().instrument()
JavaScript에서 에이전트 프레임워크는 지원되지 않습니다.
서비스 컬렉션에 종속성을 추가합니다.
using Microsoft.Agents.A365.Observability.Extensions.AgentFramework;
builder.Services.AddTracing(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
수동 계측
에이전트 365 관찰성 SDK를 사용하여 에이전트의 내부 작업을 이해할 수 있습니다.
SDK는 시작할 InvokeAgentScope수 있는 세 가지 범위( , ExecuteToolScope및 InferenceScope)를 제공합니다.
에이전트 호출
이 범위는 에이전트 프로세스를 시작할 때 사용해야 합니다. 호출 에이전트 범위를 사용하면 호출되는 현재 에이전트, 에이전트 사용자 데이터 등과 같은 속성을 캡처합니다.
from microsoft_agents_a365.observability.core.invoke_agent_scope import InvokeAgentScope
from microsoft_agents_a365.observability.core.invoke_agent_details import InvokeAgentDetails
from microsoft_agents_a365.observability.core.tenant_details import TenantDetails
from microsoft_agents_a365.observability.core.request import Request
invoke_details = InvokeAgentDetails(
details=agent_details, # AgentDetails instance
endpoint=my_endpoint, # Optional endpoint (with hostname/port)
session_id="session-42"
)
tenant_details = TenantDetails(tenant_id="tenant-123")
req = Request(content="User asks a question")
with InvokeAgentScope.start(invoke_details, tenant_details, req):
# Perform agent invocation logic
response = call_agent(...)
import {
InvokeAgentScope,
ExecutionType,
CallerDetails,
EnhancedAgentDetails
} from '@microsoft/agents-a365-observability';
// Basic agent invocation details
const invokeDetails = {
agentId: 'email-agent-123',
agentName: 'Email Assistant',
...
}
};
const tenantDetails = {
tenantId: 'tenant-789'
};
// Optional: Caller details (human user)
const callerDetails: CallerDetails = {};
// Optional: Caller agent details (for agent-to-agent calls)
const callerAgentDetails: EnhancedAgentDetails = {};
// Enhanced invocation with caller context
using scope = InvokeAgentScope.start(
invokeDetails,
tenantDetails,
callerAgentDetails,
callerDetails
);
try {
// Record input messages
scope.recordInputMessages(['Please help me organize my emails', 'Focus on urgent items']);
// Your agent invocation logic here
const response = await invokeAgent(invokeDetails.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;
}
// Scope automatically disposed at end of using block
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: Guid.NewGuid().ToString(),
agentName: "MyAgent",
agentDescription: "Handles user requests.",
tenantId: "tenant-789"
);
var tenantDetails = new TenantDetails(Guid.Parse("11111111-2222-3333-4444-555555555555"));
var request = new Request(
content: userInput,
executionType: ExecutionType.HumanToAgent,
sessionId: "session-abc",
channelMetadata: new ChannelMetadata("webchat", "https://webchat.contoso.com")
);
var callerDetails = new CallerDetails(
callerId: "user-123",
callerName: "Jane Doe",
callerUpn: "jane.doe@contoso.com",
callerUserId: "user-uuid-456",
tenantId: "tenant-789"
);
var endpoint = new Uri("https://myagent.contoso.com");
var invokeAgentDetails = new InvokeAgentDetails(endpoint, agentDetails, sessionId: "session-abc");
var conversationId = "conv-xyz";
// Start the scope
using var scope = InvokeAgentScope.Start(
invokeAgentDetails: invokeAgentDetails,
tenantDetails: tenantDetails,
request: request,
callerAgentDetails: null,
callerDetails: callerDetails,
conversationId: conversationId
);
// Record input messages
scope.RecordInputMessages(new[] { userInput });
// ... your agent logic here ...
// Simulate agent processing and output
var output = $"Processed: {userInput}";
scope.RecordOutputMessages(new[] { output });
// Optionally record a single response
scope.RecordResponse(output);
return new AgentResponse { Content = output };
}
}
public class AgentResponse
{
public string Content { get; set; }
}
다음 예제에서는 모니터링 및 감사 목적으로 원격 분석을 캡처하기 위해 관찰성 추적을 사용하여 에이전트의 도구 실행을 계측하는 방법을 보여 줍니다.
from microsoft_agents_a365.observability.core.execute_tool_scope import ExecuteToolScope
from microsoft_agents_a365.observability.core.tool_call_details import ToolCallDetails
tool_details = ToolCallDetails(
tool_name="summarize",
tool_type="function",
tool_call_id="tc-001",
arguments="{'text': '...'}",
description="Summarize provided text",
endpoint=None # or endpoint object with hostname/port
)
with ExecuteToolScope.start(tool_details, agent_details, tenant_details):
result = run_tool(tool_details)
import { ExecuteToolScope } from '@microsoft/agents-a365-observability';
const toolDetails = {
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'
}
};
using scope = ExecuteToolScope.start(toolDetails, agentDetails, tenantDetails);
try {
// Execute the tool
const result = await searchEmails(toolDetails.arguments);
// Record the tool execution result
scope.recordResponse(JSON.stringify(result));
return result;
} catch (error) {
scope.recordError(error as Error);
throw error;
}
using System;
using System.Threading.Tasks;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
public class MyToolAgent
{
public async Task<ToolResult> ExecuteTool(string toolName, object parameters)
{
var agentDetails = new AgentDetails(
agentId: Guid.NewGuid().ToString(),
agentName: "ToolAgent",
agentDescription: "Executes tools for users.",
agentAUID: "tool-auid-123",
agentUPN: "toolagent@contoso.com",
agentBlueprintId: "tool-blueprint-456",
agentType: AgentType.EntraEmbodied,
tenantId: "tenant-789"
);
var tenantDetails = new TenantDetails(Guid.Parse("11111111-2222-3333-4444-555555555555"));
var endpoint = new Uri("https://toolagent.contoso.com:8443");
var toolCallDetails = new ToolCallDetails(
toolName: toolName,
arguments: System.Text.Json.JsonSerializer.Serialize(parameters),
toolCallId: Guid.NewGuid().ToString(),
description: "Runs a tool operation.",
toolType: "custom-type",
endpoint: endpoint
);
// Start the scope
using var scope = ExecuteToolScope.Start(
toolCallDetails: toolCallDetails,
agentDetails: agentDetails,
tenantDetails: tenantDetails
);
// ... your tool logic here ...
// Record response
var toolOutput = $"Tool '{toolName}' processed with parameters: {System.Text.Json.JsonSerializer.Serialize(parameters)}";
scope.RecordResponse(toolOutput);
return new ToolResult { Output = toolOutput };
}
}
public class ToolResult
{
public string Output { get; set; }
}
추론
다음 예제에서는 관찰성 추적을 사용하여 AI 모델 유추 호출을 계측하여 토큰 사용량, 모델 세부 정보 및 응답 메타데이터를 캡처하는 방법을 보여 줍니다.
from microsoft_agents_a365.observability.core.inference_scope import InferenceScope
from microsoft_agents_a365.observability.core.inference_call_details import InferenceCallDetails
from microsoft_agents_a365.observability.core.request import Request
inference_details = InferenceCallDetails(
operationName=SomeEnumOrValue("chat"),
model="gpt-4o-mini",
providerName="azure-openai",
inputTokens=123,
outputTokens=456,
finishReasons=["stop"],
responseId="resp-987"
)
req = Request(content="Explain quantum computing simply.")
with InferenceScope.start(inference_details, agent_details, tenant_details, req):
completion = call_llm(...)
import { InferenceScope, InferenceOperationType } from '@microsoft/agents-a365-observability';
const inferenceDetails = {
operationName: InferenceOperationType.CHAT,
model: 'gpt-4',
providerName: 'openai',
inputTokens: 150,
outputTokens: 75,
finishReasons: ['stop'],
responseId: 'resp-123456'
};
using scope = InferenceScope.start(inferenceDetails, agentDetails, tenantDetails);
try {
// 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); // Update if different from constructor
scope.recordOutputTokens(82); // Update if different from constructor
scope.recordResponseId('resp-789123');
scope.recordFinishReasons(['stop', 'max_tokens']);
return response.text;
} catch (error) {
scope.recordError(error as Error);
throw error;
}
using System;
using System.Threading.Tasks;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Contracts;
using Microsoft.Agents.A365.Observability.Runtime.Tracing.Scopes;
public class MyInferenceAgent
{
public async Task<InferenceResult> RunInference(string input)
{
var agentDetails = new AgentDetails(
agentId: Guid.NewGuid().ToString(),
agentName: "InferenceAgent",
agentDescription: "Performs generative AI inference.",
agentAUID: "inference-auid-123",
agentUPN: "inferenceagent@contoso.com",
agentBlueprintId: "inference-blueprint-456",
agentType: AgentType.EntraEmbodied,
tenantId: "tenant-789"
);
var tenantDetails = new TenantDetails(Guid.Parse("11111111-2222-3333-4444-555555555555"));
var inferenceDetails = new InferenceCallDetails(
operationName: InferenceOperationType.Chat,
model: "gpt-4",
providerName: "OpenAI",
inputTokens: 42,
outputTokens: 84,
finishReasons: new[] { "stop", "length" },
responseId: "response-xyz"
);
// Start the scope
using var scope = InferenceScope.Start(
details: inferenceDetails,
agentDetails: agentDetails,
tenantDetails: tenantDetails
);
// ... your inference logic here ...
// Record input/output messages and other telemetry
scope.RecordInputMessages(new[] { input, "additional context" });
scope.RecordOutputMessages(new[] { "AI response message" });
scope.RecordInputTokens(42);
scope.RecordOutputTokens(84);
scope.RecordResponseId("response-xyz");
scope.RecordFinishReasons(new[] { "stop", "length" });
scope.RecordThoughtProcess("Reasoning step 1; step 2");
return new InferenceResult { Output = "AI response message" };
}
}
public class InferenceResult
{
public string Output { get; set; }
}
로컬 유효성 검사
ENABLE_A365_OBSERVABILITY_EXPORTER 환경 변수를 false로 설정합니다. 그러면 범위(추적)가 콘솔로 내보내집니다.
ENABLE_A365_OBSERVABILITY_EXPORTER 환경 변수를 false로 설정합니다. 그러면 범위(추적)가 콘솔로 내보내집니다.
에 EnableAgent365Exporter 설정 그러면 범위(추적)가 콘솔로 내보내집니다.
관찰 가능성으로 에이전트 테스트
에이전트에서 관찰 가능성을 구현한 후 원격 분석이 올바르게 캡처되는지 테스트합니다. 테스트 가이드에 따라 환경을 설정한 다음, 주로 관찰 가능성 로그 보기 섹션에 집중하여 관찰 가능성 구현이 예상대로 작동하는지 확인합니다.