Observability

可观测性是构建可靠且可维护的系统的关键方面。 代理框架为可观测性提供内置支持,使你能够监视代理的行为。

本指南将指导你完成使用 Agent Framework 启用可观测性的步骤,以帮助你了解代理的执行方式和诊断可能出现的任何问题。

OpenTelemetry 集成

Agent Framework 与 OpenTelemetry 集成,更具体地说,Agent Framework 会根据 OpenTelemetry GenAI 语义约定发出跟踪、日志和指标。

启用可观测性 (C#)

若要为聊天客户端启用可观测性,需要按如下所示构建聊天客户端:

// Using the AIProjectClient as an example
var instrumentedChatClient = new AIProjectClient(new Uri(endpoint), new DefaultAzureCredential())
    .GetProjectOpenAIClient()
    .GetProjectResponsesClient()
    .AsIChatClient(deploymentName) // Converts into a Microsoft.Extensions.AI.IChatClient
    .AsBuilder()
    .UseOpenTelemetry(sourceName: SourceName, configure: (cfg) => cfg.EnableSensitiveData = true)    // Enable OpenTelemetry instrumentation with sensitive data
    .Build();

Warning

DefaultAzureCredential 对于开发来说很方便,但在生产中需要仔细考虑。 在生产环境中,请考虑使用特定凭据(例如), ManagedIdentityCredential以避免延迟问题、意外凭据探测以及回退机制的潜在安全风险。

若要为代理启用可观测性,需要按如下所示生成代理:

var agent = new ChatClientAgent(
    instrumentedChatClient,
    name: "OpenTelemetryDemoAgent",
    instructions: "You are a helpful assistant that provides concise and informative responses.",
    tools: [AIFunctionFactory.Create(GetWeatherAsync)]
)
    .AsBuilder()
    .UseOpenTelemetry(sourceName: SourceName, configure: (cfg) => cfg.EnableSensitiveData = true) // Enable OpenTelemetry instrumentation with sensitive data
    .Build();

重要

为聊天客户端和代理启用可观测性时,可能会看到重复的信息,尤其是在启用敏感数据时。 聊天上下文(包括聊天客户端和代理捕获的提示和响应)将同时包含在这两个范围中。 根据需求,可以选择仅在聊天客户端上启用可观测性,或仅启用代理来避免重复。 有关为 LLM 和代理捕获的属性的更多详细信息,请参阅 GenAI 语义约定

Warning

仅在开发或测试环境中启用敏感数据,因为它可能会在生产日志和跟踪中公开用户信息。 敏感数据包括提示、响应、函数调用参数和结果。

Configuration

现在已检测聊天客户端和代理,可以配置 OpenTelemetry 导出程序以将遥测数据发送到所需的后端。

Traces

若要将跟踪导出到所需的后端,可以在应用程序启动代码中配置 OpenTelemetry SDK。 例如,若要将跟踪导出到Azure Monitor资源:

using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Trace;
using OpenTelemetry.Resources;
using System;

// The source name under which all activities, metrics, and logs will be emitted.
const string SourceName = "MyApplication";
const string ServiceName = "AgentOpenTelemetry";

var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
    ?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService(ServiceName);

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource(SourceName)
    .AddAzureMonitorTraceExporter(options => options.ConnectionString = applicationInsightsConnectionString)
    .Build();

Tip

该方法 AddSource 用于指定提供程序将侦听的源名称。 请确保它与检测代码中使用的源名称(例如) UseOpenTelemetry(sourceName: SourceName)匹配。 如果未在检测代码中指定源名称,则默认为 Experimental.Microsoft.Agents.AI,在这种情况下,应在跟踪提供程序和计量提供程序配置中使用 AddSource("Experimental.Microsoft.Agents.AI")

Tip

根据后端的不同,可以使用不同的导出程序。 有关详细信息,请参阅 OpenTelemetry .NET 文档。 对于本地开发,请考虑使用 Aspire 仪表板

Metrics

同样,若要将指标导出到所需的后端,可以在应用程序启动代码中配置 OpenTelemetry SDK。 例如,若要将指标导出到Azure Monitor资源:

using Azure.Monitor.OpenTelemetry.Exporter;
using OpenTelemetry;
using OpenTelemetry.Metrics;
using OpenTelemetry.Resources;
using System;

var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
    ?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");

var resourceBuilder = ResourceBuilder
    .CreateDefault()
    .AddService(ServiceName);

using var meterProvider = Sdk.CreateMeterProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource(SourceName)
    .AddAzureMonitorMetricExporter(options => options.ConnectionString = applicationInsightsConnectionString)
    .Build();

Logs

日志是通过所使用的日志记录框架捕获的,例如Microsoft.Extensions.Logging。 若要将日志导出到Azure Monitor资源,可以在应用程序启动代码中配置日志记录提供程序:

using Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Extensions.Logging;

var applicationInsightsConnectionString = Environment.GetEnvironmentVariable("APPLICATION_INSIGHTS_CONNECTION_STRING")
    ?? throw new InvalidOperationException("APPLICATION_INSIGHTS_CONNECTION_STRING is not set.");

using var loggerFactory = LoggerFactory.Create(builder =>
{
    // Add OpenTelemetry as a logging provider
    builder.AddOpenTelemetry(options =>
    {
        options.SetResourceBuilder(resourceBuilder);
        options.AddAzureMonitorLogExporter(options => options.ConnectionString = applicationInsightsConnectionString);
        // Format log messages. This is default to false.
        options.IncludeFormattedMessage = true;
        options.IncludeScopes = true;
    })
    .SetMinimumLevel(LogLevel.Debug);
});

// Create a logger instance for your application
var logger = loggerFactory.CreateLogger<Program>();

Aspire 仪表板

请考虑将 Aspire 仪表板用作在开发过程中可视化跟踪和指标的快速方法。 若要了解详细信息,请参阅 Aspire 仪表板文档。 Aspire 仪表板通过 OpenTelemetry 收集器接收数据,可按如下所示添加到跟踪提供程序:

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .SetResourceBuilder(resourceBuilder)
    .AddSource(SourceName)
    .AddOtlpExporter(options => options.Endpoint = new Uri("http://localhost:4317"))
    .Build();

入门指南

请参阅 在 Agent Framework 存储库中启用了 OpenTelemetry 的代理的完整示例。

Tip

有关完整的可运行示例,请参阅 .NET 示例

Dependencies

包含的包

若要在 Python 应用程序中启用可观测性,默认情况下会安装以下 OpenTelemetry 包:

出口商

默认情况下 我们不会安装导出程序,以防止不必要的依赖项和自动检测的潜在问题。 有多种导出程序可用于不同的后端,因此可以选择最符合需求的导出程序。

你可能希望根据需求安装一些常见的导出程序:

  • 对于 gRPC 协议支持:安装 opentelemetry-exporter-otlp-proto-grpc
  • 对于 HTTP 协议支持:安装 opentelemetry-exporter-otlp-proto-http
  • 对于 Azure 应用程序 Insights:安装 azure-monitor-opentelemetry

使用 OpenTelemetry 注册表 查找更多导出者和检测包。

启用可观测性(Python)

MCP 跟踪传播

每当有活动的 OpenTelemetry 范围上下文时,Agent Framework 都会通过 params._meta 请求字段 tools/call 自动将跟踪上下文传播到 MCP 服务器。 它默认使用全局配置的 OpenTelemetry 传播器(s)(W3C 跟踪上下文,生成 traceparenttracestate),因此也支持自定义传播器(B3、Jaeger 等)。 这样就可以跨代理到 MCP 服务器边界进行分布式跟踪,并符合 MCP _meta 规范

范围:自动_meta注入仅适用于代理进程本身打开的 MCP 会话,MCPStreamableHTTPToolMCPStdioTool以及MCPWebsocketTool(或任何其他客户端打开的MCPTool子类)。 它不适用于托管/提供程序管理的 MCP 工具配置,例如FoundryChatClient.get_mcp_tool(...),、OpenAIChatClient.get_mcp_tool(...)AnthropicClient.get_mcp_tool(...)GeminiChatClient.get_mcp_tool(...)或 Foundry 托管代理工具箱,因为在这些情况下,tools/call消息由提供程序服务运行时而不是代理进程发出。 因此,框架没有机会将这些请求注入跟踪上下文,并且跨该托管服务边界传播 traceparent/tracestate 是服务运行时的责任,而不是代理框架。 如果需要端到端分布式跟踪到下游 MCP 服务器,请使用客户端打开的 MCP 传输而不是托管连接器。

配置可观测性的五种模式

我们确定了在应用程序中配置可观测性的多种方式,具体取决于你的需求:

最简单的方法 - 通过环境变量配置所有内容:

from agent_framework.observability import configure_otel_providers

# Reads OTEL_EXPORTER_OTLP_* environment variables automatically
configure_otel_providers()

或者,如果只需要控制台导出程序,请设置 ENABLE_CONSOLE_EXPORTERS 环境变量:

ENABLE_CONSOLE_EXPORTERS=true
from agent_framework.observability import configure_otel_providers

# Console exporters are enabled via the ENABLE_CONSOLE_EXPORTERS env var
configure_otel_providers()

还可以在代码中替代通用服务、资源和 OTLP 导出程序设置:

from agent_framework.observability import configure_otel_providers

configure_otel_providers(
    service_name="customer-support-agent",
    resource_attributes={
        "deployment.environment.name": "production",
        "service.namespace": "customer-support",
    },
    otlp_endpoint="https://otel.example.com",
    otlp_protocol="http/protobuf",
)

参数otlp_protocol接受grpchttp/protobufhttp。 还可以设置service_version、秒 otlp_timeoutotlp_headersotlp_compressiongzipdeflatenone。 显式服务名称和版本值优先于其环境变量,同时resource_attributes合并 。OTEL_RESOURCE_ATTRIBUTES 以编程方式 OTLP 设置会覆盖其基本环境变量。 特定于信号的终结点和标头变量保持更具体,并在 otlp_headers 合并特定于信号的标头之前替换基标头。 对于 HTTP,基本终结点会自动接收/v1/traces/v1/metrics/v1/logs路径。

2. 自定义导出程序

若要更好地控制出口商,请自己创建它们并将其传递给 configure_otel_providers()

from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.exporter.otlp.proto.grpc._log_exporter import OTLPLogExporter
from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
from agent_framework.observability import configure_otel_providers

# Create custom exporters with specific configuration
exporters = [
    OTLPSpanExporter(endpoint="http://localhost:4317", compression=Compression.Gzip),
    OTLPLogExporter(endpoint="http://localhost:4317"),
    OTLPMetricExporter(endpoint="http://localhost:4317"),
]

# These will be added alongside any exporters from environment variables
configure_otel_providers(exporters=exporters, enable_sensitive_data=True)

3. 第三方设置

许多第三方 OpenTelemetry 包都有自己的设置方法。 可以先使用这些方法,然后调用 enable_instrumentation() 激活 Agent Framework 检测代码路径:

from azure.monitor.opentelemetry import configure_azure_monitor
from agent_framework.observability import create_resource, enable_instrumentation

# Configure Azure Monitor first
configure_azure_monitor(
    connection_string="InstrumentationKey=...",
    resource=create_resource(),  # Uses OTEL_SERVICE_NAME, etc.
    enable_live_metrics=True,
)

# Then activate Agent Framework's telemetry code paths
# This is optional if ENABLE_INSTRUMENTATION and/or ENABLE_SENSITIVE_DATA are set in env vars
enable_instrumentation(enable_sensitive_data=False)

对于 Langfuse

from agent_framework.observability import enable_instrumentation
from langfuse import get_client

langfuse = get_client()

# Verify connection
if langfuse.auth_check():
    print("Langfuse client is authenticated and ready!")

# Then activate Agent Framework's telemetry code paths
enable_instrumentation(enable_sensitive_data=False)

4.手动设置

若要完全控制,可以手动设置导出程序、提供程序和检测。 使用帮助程序函数 create_resource() 创建具有相应服务名称和版本的资源。 有关手动检测的详细指南,请参阅 OpenTelemetry Python 文档

5. 自动检测 (零代码)

使用 OpenTelemetry CLI 工具 自动检测应用程序,而无需更改代码:

opentelemetry-instrument \
    --traces_exporter console,otlp \
    --metrics_exporter console \
    --service_name your-service-name \
    --exporter_otlp_endpoint 0.0.0.0:4317 \
    python agent_framework_app.py

有关详细信息,请参阅 OpenTelemetry Zero-code Python 文档

使用跟踪器和计量

配置可观测性后,可以创建自定义范围或指标:

from agent_framework.observability import get_tracer, get_meter

tracer = get_tracer()
meter = get_meter()
with tracer.start_as_current_span("my_custom_span"):
    # do something
    pass
counter = meter.create_counter("my_custom_counter")
counter.add(1, {"key": "value"})

这些是 OpenTelemetry API 的包装器,该 API 从全局提供程序返回跟踪器或计量, agent_framework 默认情况下设置为检测库名称。

环境变量

以下环境变量控制 Agent Framework 可观测性:

  • ENABLE_INSTRUMENTATION - 默认值为 true;设置为 false 禁用 OpenTelemetry 检测。
  • ENABLE_SENSITIVE_DATA- 默认值设置为falsetrue启用敏感数据的日志记录(提示、响应、函数调用参数和结果)。 请谨慎使用此设置,因为它可能会公开敏感数据。
  • ENABLE_MESSAGE_EVENTS- 默认值为 true;值true1yeson启用 v1.36 消息和选择日志事件,不区分大小写。 任何其他设置值都禁用它们。 仅当启用检测和敏感数据时才会发出这些事件。
  • ENABLE_CONSOLE_EXPORTERS- 默认值设置为falsetrue启用遥测的控制台输出。
  • VS_CODE_EXTENSION_PORT - 用于 AI 工具包的端口或 Microsoft Foundry VS Code 扩展集成。
  • OTEL_SEMCONV_STABILITY_OPT_IN - 取消设置时,Agent Framework 使用最新的实验性 GenAI 约定。 如果已设置,请在逗号分隔值中包含区分 gen_ai_latest_experimental 大小写的标记以使用最新约定。 一个省略此令牌(包括空值)的设置值会选择 v1.36 约定。

最新模式范围属性发出 gen_ai.provider.name;v1.36 范围属性和消息事件发出 gen_ai.system。 消息事件选择与语义约定选择无关。 选择 v1.36 会禁止显示最新的消息范围属性,但不禁用 v1.36 消息事件。 启用敏感数据后,默认的最新模式将发出这两种表示形式。

Agent Framework 还会将其包和版本添加到支持的客户端请求 User-Agent。 批准的Microsoft Foundry 和 Azure OpenAI 请求路径可以包括一个进程范围的功能使用令牌,用于对框架功能类别进行编码,而不是提示或响应内容。 在开始该过程之前设置这些变量:

  • AGENT_FRAMEWORK_FEATURE_MASK_DISABLED=true - 仅禁用功能使用令牌并保留包/版本 User-Agent。
  • AGENT_FRAMEWORK_USER_AGENT_DISABLED=true - 禁用整个代理框架 User-Agent 贡献,包括功能令牌。

Warning

敏感信息包括提示、响应等,仅应在开发或测试环境中启用。 不建议在生产环境中启用此功能,因为它可能会公开敏感数据。

标准 OpenTelemetry 环境变量

configure_otel_providers() 函数自动读取标准 OpenTelemetry 环境变量:

OTLP 配置 (适用于 Aspire 仪表板、Jaeger 等):

  • OTEL_EXPORTER_OTLP_ENDPOINT - 所有信号的基本终结点(例如 http://localhost:4317
  • OTEL_EXPORTER_OTLP_TRACES_ENDPOINT - 特定于跟踪的终结点(替代基终结点)
  • OTEL_EXPORTER_OTLP_METRICS_ENDPOINT - 特定于指标的终结点(重写基数)
  • OTEL_EXPORTER_OTLP_LOGS_ENDPOINT - 特定于日志的终结点(重写基数)
  • OTEL_EXPORTER_OTLP_PROTOCOL - 要使用的协议(grpchttp,默认值: grpc
  • OTEL_EXPORTER_OTLP_HEADERS - 所有信号的标头(例如 key1=value1,key2=value2

服务标识

  • OTEL_SERVICE_NAME - 服务名称(默认值: agent_framework
  • OTEL_SERVICE_VERSION - 服务版本(默认:包版本)
  • OTEL_RESOURCE_ATTRIBUTES - 其他资源属性

有关更多详细信息,请参阅 OpenTelemetry 规范

Microsoft Foundry 设置

Microsoft Foundry 内置支持使用跨度可视化进行跟踪。

请确保已使用 Azure Monitor 实例配置 Foundry,请参阅 details

安装 azure-monitor-opentelemetry 包:

pip install azure-monitor-opentelemetry

直接从 配置可观测性

对于 Foundry 项目,可以直接从以下项 FoundryChatClient配置可观测性:

import os

from agent_framework.foundry import FoundryChatClient
from azure.identity.aio import AzureCliCredential

async def main():
    async with AzureCliCredential() as credential:
        client = FoundryChatClient(
            project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
            model=os.environ["FOUNDRY_MODEL"],
            credential=credential,
        )

        # Automatically configures Azure Monitor with the connection string from the Foundry project
        await client.configure_azure_monitor(enable_live_metrics=True)

Tip

client.configure_azure_monitor() 的参数通过 configure_azure_monitor() 包传递到基础 azure-monitor-opentelemetry 函数,有关详细信息,请参阅 documentation,我们负责设置连接字符串和资源。

配置 Azure Monitor 并选择性地启用检测

对于 Application Insights 的非 Foundry 项目,请确保在 Foundry 中设置自定义代理,请参阅 详细信息

然后,使用与 Foundry 中注册相同的 OpenTelemetry 代理 ID 运行代理,并按如下所示配置 Azure Monitor:

from azure.monitor.opentelemetry import configure_azure_monitor
from agent_framework.observability import create_resource, enable_instrumentation

configure_azure_monitor(
    connection_string="InstrumentationKey=...",
    resource=create_resource(),
    enable_live_metrics=True,
)
# optional if you do not have ENABLE_INSTRUMENTATION in env vars
enable_instrumentation()

# Create your agent with the same OpenTelemetry agent ID as registered in Foundry
agent = Agent(
    client=...,
    name="My Agent",
    instructions="You are a helpful assistant.",
    id="<OpenTelemetry agent ID>"
)
# use the agent as normal

Aspire 仪表板

对于没有Azure设置的本地开发,可以使用 Aspire Dashboard,该仪表板通过 Docker 在本地运行,并提供出色的遥测查看体验。

使用 Docker 设置 Aspire 仪表板

# Pull and run the Aspire Dashboard container
docker run --rm -it -d \
    -p 18888:18888 \
    -p 4317:18889 \
    --name aspire-dashboard \
    mcr.microsoft.com/dotnet/aspire-dashboard:latest

此命令将使用以下命令启动仪表板:

  • Web UI:在以下位置提供 http://localhost:18888
  • OTLP 终结点:可用于 http://localhost:4317 应用程序发送遥测数据

配置应用程序

设置以下环境变量:

ENABLE_INSTRUMENTATION=true
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317

或将它们包含在 .env 文件中,并确保在应用程序开始时调用 load_dotenv() (代理框架不会自动加载 .env 文件)。

示例运行完成后,在 Web 浏览器中导航到 http://localhost:18888 以查看遥测数据。 按照 Aspire 仪表板探索指南 向仪表板进行身份验证,并开始浏览跟踪、日志和指标。

跨度和指标

设置所有内容后,你将开始看到自动创建的跨度和指标,范围是:

  • invoke_agent <agent_name>:这是每个代理调用的顶级范围,它将包含所有其他范围作为子级。
  • chat <model_name>:当代理调用基础聊天模型时,会创建此范围,如果 enable_sensitive_data 设置为 True,它将包含提示和响应作为属性。
  • execute_tool <function_name>:当代理调用函数工具时,将创建此范围,如果设置为 enable_sensitive_dataTrue它将包含函数参数和结果作为属性。

创建的指标包括:

  • 对于聊天客户端和 chat 作:

    • gen_ai.client.operation.duration (直方图):此指标以秒为单位测量每个作的持续时间。
    • gen_ai.client.token.usage (直方图):此指标以令牌数度量令牌使用情况。
  • 对于作过程中 execute_tool 的函数调用:

    • agent_framework.function.invocation.duration (直方图):此指标度量每个函数执行的持续时间(以秒为单位)。

跟踪输出示例

运行启用了可观测性的代理时,会看到类似于以下控制台输出的跟踪数据:

{
    "name": "invoke_agent Joker",
    "context": {
        "trace_id": "0xf2258b51421fe9cf4c0bd428c87b1ae4",
        "span_id": "0x2cad6fc139dcf01d",
        "trace_state": "[]"
    },
    "kind": "SpanKind.CLIENT",
    "parent_id": null,
    "start_time": "2025-09-25T11:00:48.663688Z",
    "end_time": "2025-09-25T11:00:57.271389Z",
    "status": {
        "status_code": "UNSET"
    },
    "attributes": {
        "gen_ai.operation.name": "invoke_agent",
        "gen_ai.provider.name": "openai",
        "gen_ai.agent.id": "Joker",
        "gen_ai.agent.name": "Joker",
        "gen_ai.request.instructions": "You are good at telling jokes.",
        "gen_ai.response.id": "chatcmpl-CH6fgKwMRGDtGNO3H88gA3AG2o7c5",
        "gen_ai.usage.input_tokens": 26,
        "gen_ai.usage.output_tokens": 29
    }
}

此跟踪显示:

  • 跟踪和跨度标识符:用于关联相关作
  • 计时信息:作启动和结束时间
  • 代理元数据:代理 ID、名称和说明
  • 模型信息:AI 提供程序使用的 (OpenAI) 和响应 ID
  • 令牌使用情况:用于成本跟踪的输入和输出令牌计数

Samples

存储库中有 microsoft/agent-framework 一些示例演示了这些功能。 有关详细信息,请参阅 可观测性示例文件夹。 该文件夹还包含使用零代码遥测的示例。

完整示例

# Copyright (c) Microsoft. All rights reserved.

import asyncio
from random import randint
from typing import Annotated

from agent_framework import Agent, tool
from agent_framework.observability import configure_otel_providers, get_tracer
from agent_framework.openai import OpenAIChatClient
from opentelemetry.trace import SpanKind
from opentelemetry.trace.span import format_trace_id
from pydantic import Field

"""
This sample shows how you can observe an agent in Agent Framework by using the
same observability setup function.
"""


# NOTE: approval_mode="never_require" is for sample brevity. Use "always_require" in production; see samples/02-agents/tools/function_tool_with_approval.py and samples/02-agents/tools/function_tool_with_approval_and_sessions.py.
@tool(approval_mode="never_require")
async def get_weather(
    location: Annotated[str, Field(description="The location to get the weather for.")],
) -> str:
    """Get the weather for a given location."""
    await asyncio.sleep(randint(0, 10) / 10.0)  # Simulate a network call
    conditions = ["sunny", "cloudy", "rainy", "stormy"]
    return f"The weather in {location} is {conditions[randint(0, 3)]} with a high of {randint(10, 30)}°C."


async def main():
    # calling `configure_otel_providers` will *enable* tracing and create the necessary tracing, logging
    # and metrics providers based on environment variables.
    # See the .env.example file for the available configuration options.
    configure_otel_providers()

    questions = ["What's the weather in Amsterdam?", "and in Paris, and which is better?", "Why is the sky blue?"]

    with get_tracer().start_as_current_span("Scenario: Agent Chat", kind=SpanKind.CLIENT) as current_span:
        print(f"Trace ID: {format_trace_id(current_span.get_span_context().trace_id)}")

        agent = Agent(
            client=OpenAIChatClient(),
            tools=get_weather,
            name="WeatherAgent",
            instructions="You are a weather assistant.",
            id="weather-agent",
        )
        thread = agent.create_session()
        for question in questions:
            print(f"\nUser: {question}")
            print(f"{agent.name}: ", end="")
            async for update in agent.run(
                question,
                session=thread,
                stream=True,
            ):
                if update.text:
                    print(update.text, end="")


if __name__ == "__main__":
    asyncio.run(main())

使用 OpenTelemetry 的可观测性

Go 代理框架包括一个 OpenTelemetry 中间件,用于自动跟踪代理调用。

Setup

import (
    "github.com/microsoft/agent-framework-go/provider/otelprovider"

    "go.opentelemetry.io/otel/exporters/stdout/stdouttrace"
    sdktrace "go.opentelemetry.io/otel/sdk/trace"
    otellib "go.opentelemetry.io/otel"
)

// Create a tracer provider with a console exporter
exporter, _ := stdouttrace.New(stdouttrace.WithPrettyPrint())
tp := sdktrace.NewTracerProvider(sdktrace.WithBatcher(exporter))
defer tp.Shutdown(context.Background())
otellib.SetTracerProvider(tp)

将中间件添加到代理

a := foundryprovider.NewAgent(endpoint, token, foundryprovider.ModelDeployment(model), foundryprovider.AgentConfig{
    Instructions: "You are a helpful assistant.",
    Config: agent.Config{
        Middlewares: []agent.Middleware{
            otelprovider.NewMiddleware(otelprovider.MiddlewareConfig{}), // OpenTelemetry tracing
        },
    },
})

中间件使用属性发出范围,包括:

  • gen_ai.provider.name — 提供程序名称(例如“openai”)
  • gen_ai.agent.id — 代理的唯一 ID
  • gen_ai.agent.name — 代理的显示名称
  • gen_ai.agent.description — 代理的说明

Tip

有关完整的可运行示例,请参阅 完整示例

将可观测性与 Harness 代理配合使用

对于纯代理,请使用或之前所示,将 UseOpenTelemetryWithOpenTelemetryOpenTelemetry 添加到聊天客户端或代理管道。 默认情况下,添加 HarnessAgent 聊天客户端和代理 OpenTelemetry 检测:

using Microsoft.Agents.AI;
using OpenTelemetry;
using OpenTelemetry.Trace;

const string SourceName = "MyApplication.Harness";

using var tracerProvider = Sdk.CreateTracerProviderBuilder()
    .AddSource(SourceName)
    .AddOtlpExporter()
    .Build();

AIAgent agent = chatClient.AsHarnessAgent(new HarnessAgentOptions
{
    OpenTelemetrySourceName = SourceName,
});

OpenTelemetrySourceName 默认为 Experimental.Microsoft.Agents.AI。 传递给 AddSource 它的名称必须与它匹配。 设置为 DisableOpenTelemetry = true 省略两个已添加的 Harness 检测层。

Harness 配置检测,但仍拥有 TracerProvider、导出程序、凭据、刷新和关闭。 请勿预检测同一聊天客户端,除非有意想要重复跨度,否则将 Harness 检测保持启用状态。

默认情况下,遥测包含元数据。 设置 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true 还会记录提示、响应、工具参数和工具结果;仅在导出者和保留策略适合该数据时启用它。

HarnessAgent 可从包获取 Microsoft.Agents.AI.Harness

Agent 实例已包含遥测层;使用 configure_otel_providers() 或你自己的 OpenTelemetry SDK 设置配置 OpenTelemetry 提供程序和导出程序。 create_harness_agent 使用相同的全局配置并分配特定于 Harness 的提供程序名称:

from agent_framework import create_harness_agent
from agent_framework.observability import configure_otel_providers

configure_otel_providers()

agent = create_harness_agent(
    client=client,
    otel_provider_name="my.application.harness",
)

otel_provider_name 控制在 Harness 遥测上记录的提供程序名称。 它默认为 microsoft.agent_framework.harness;它不会配置导出程序或遥测目标。 默认情况下启用检测,默认情况下禁用敏感数据捕获,并且不会自动安装或配置导出程序。

OpenTelemetry 提供程序是进程范围的资源。 配置一次,保护导出程序凭据和终结点,并根据所选的 OpenTelemetry SDK 和导出程序刷新或关闭它们。 在必须禁用遥测时设置 ENABLE_INSTRUMENTATION=false 或调用 disable_instrumentation() 。 启用 ENABLE_SENSITIVE_DATA 添加原始消息、工具参数和工具结果。

create_harness_agent 在 .. 中 agent-framework-core发布。

打包的 Go Harness 当前不可用。 直接在普通 Go 代理上配置 OpenTelemetry 中间件,如前所述。

后续步骤