基于 OpenTelemetry 的 Microsoft Agent Framework 可观测性
Microsoft Agent Framework 内置了 OpenTelemetry 探针。每一次 Agent 运行、模型调用、工具执行和工作流步骤都会生成一个 span,并遵循 OpenTelemetry GenAI 语义约定,因此无需额外安装探针包。
本指南演示如何启用该探针并将其导出到 SigNoz,使 Agent 追踪数据与应用的其他遥测数据并列呈现。
什么是 Microsoft Agent Framework 可观测性?
Microsoft Agent Framework 可观测性是指从 Agent 应用中收集追踪数据,以便了解每次运行的具体行为:哪些 Agent 被调用、使用了哪些模型、消耗了多少 token、调用了哪些工具、工作流如何在 Agent 间传递任务,以及失败点在哪里。
在 SigNoz 中实现完整的 Microsoft Agent Framework 可观测性后,您可以追踪请求从工作流到单次工具调用的全过程,将 token 消耗归因到特定 Agent 或模型,发现那些静默恢复的失败工具,并将 Agent 故障与应用其他部分的异常进行关联。
先决条件
- SigNoz Cloud 账号和摄入密钥
- Python 3.10 或更高版本
- OpenAI API 密钥,或框架支持的其他聊天客户端凭证
- 基于 Python 版 Microsoft Agent Framework 构建的应用程序
使用 OpenTelemetry 监控 Microsoft Agent Framework
框架的 agent_framework.observability 模块会为您创建 tracer、meter 和 logger 提供者以及 OTLP 导出器。启动时只需调用一次 configure_otel_providers(),该函数会读取标准的 OTEL_* 环境变量并开始导出数据。
步骤 1: 安装框架、您使用的聊天客户端以及 OTLP/HTTP 导出器。
Copypip install \
agent-framework-core \
agent-framework-openai \
opentelemetry-exporter-otlp-proto-http
agent-framework 元包也能工作,但它会引入框架提供的所有集成。对于基于 OpenAI 的 Agent 来说,上述两个包已足够。
步骤 2: 通过环境变量配置导出器。
Copyexport OTEL_SERVICE_NAME="<service_name>"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OPENAI_API_KEY="<your-openai-api-key>"
请核对以下各项值:
<service_name>:应用在 SigNoz 中显示的名称,例如travel-agent。<region>:你的 SigNoz Cloud 区域。<your-ingestion-key>:你的 SigNoz ingestion key。<your-openai-api-key>:在 OpenAI 控制台获取的 OpenAI API key。
当 OTEL_EXPORTER_OTLP_PROTOCOL 未设置时,框架默认使用 gRPC,但第 1 步并没有安装 gRPC exporter。如果不设置 http/protobuf,configure_otel_providers() 会抛出 ImportError,提示需要安装 opentelemetry-exporter-otlp-proto-grpc。
第 3 步:在启动时、第一次运行 agent 之前,调用一次 configure_otel_providers()。
import asyncio
import random
from typing import Annotated
from agent_framework import Agent, tool
from agent_framework.observability import configure_otel_providers
from agent_framework.openai import OpenAIChatClient
configure_otel_providers()
@tool
def get_weather(city: Annotated[str, "City name"]) -> str:
"""Get the current weather for a city."""
return f"{random.choice(['sunny', 'cloudy', 'rainy'])}, {random.randint(8, 30)}C in {city}"
@tool
def get_flight_price(
origin: Annotated[str, "Origin city"], destination: Annotated[str, "Destination city"]
) -> str:
"""Get the cheapest round-trip flight price between two cities."""
return f"${random.randint(180, 900)} round trip from {origin} to {destination}"
async def main() -> None:
agent = Agent(
client=OpenAIChatClient(model="gpt-4o-mini"),
name="TravelAgent",
instructions="You are a travel assistant. Use the tools, then give a one-line recommendation.",
tools=[get_weather, get_flight_price],
)
result = await agent.run("Seattle or Denver this weekend? Check weather and flights from San Francisco.")
print(result.text)
asyncio.run(main())
从 .env 文件加载配置?请在调用 configure_otel_providers() 之前先执行 load_dotenv()。Provider 只在创建时读取一次环境变量,之后加载的变量会被忽略。
第 4 步:运行应用。
Copypython main.py
使用自托管 SigNoz?大部分步骤相同。若要调整本指南,请修改端点并移除 ingestion key 请求头,具体参考云到自托管文档。
每次运行都会发出携带 gen_ai.operation.name、gen_ai.agent.name、gen_ai.request.model、gen_ai.usage.input_tokens 和 gen_ai.usage.output_tokens 的 span。等待几秒,这些 span 便会出现在 SigNoz 中。
在 SigNoz 中查看 Microsoft Agent Framework 追踪数据
打开Traces 探索器,并根据你的 service.name 进行过滤。每次 agent 运行都会显示为一个 invoke_agent <agent> span,旁边伴有其 chat 和 execute_tool span。

点击 invoke_agent span 即可查看完整运行过程。瀑布图会显示第一次请求工具的模型调用、并行执行的工具,以及写入回答的模型调用,右侧则列出了 gen_ai.* 属性。

Agent 单次运行生成的 span 树结构如下:
Copyinvoke_agent 每个 agent.run() 对应一个,携带 Agent 名称
├─ chat 每次模型调用对应一个,携带 token 数量
├─ execute_tool 每次工具调用对应一个
└─ chat
使用 SequentialBuilder、ConcurrentBuilder 或 HandoffBuilder 构建的工作流会在上述结构之上增加一层:
workflow.run 每个 workflow 运行对应一个,携带 workflow.name
├─ executor.process 每个步骤对应一个(包括内置步骤)
│ └─ invoke_agent
├─ edge_group.process
└─ message.send
编写自定义查询时,需注意两个关键细节:
- Token 数据重复出现。每个
invoke_agentspan 会重复其下属chatspan 的汇总 token 数,因此若对gen_ai.usage.*进行全量求和,实际数值会被翻倍计算。统计总量时应仅针对chatspan 求和,invoke_agentspan 仅用于按 Agent 维度拆分。 - 工具错误只停留在工具的 span 上。抛出异常的工具会把自己的
execute_toolspan 标记为错误,但 agent 会自行恢复,其invoke_agentspan 保持正常。模型调用失败则会向上传播:传播到invoke_agentspan,在 workflow 中还会一直传播到workflow.run。
捕获 prompt 和 completion
Prompt、completion 以及工具参数内容默认不会记录。如需开启:
Copyexport ENABLE_SENSITIVE_DATA="true"
开启后,内容会记录在 gen_ai.input.messages、gen_ai.output.messages 和 gen_ai.tool.call.* 属性中,每条消息还会作为日志记录导出并关联到对应 span。Prompt 中常常包含用户数据,所以请谨慎开启,并先确认你的数据保留策略是否允许。
Microsoft Agent Framework Observability 仪表盘
SigNoz 提供了预置的 Microsoft Agent Framework 仪表盘,覆盖 agent 运行、按模型和 agent 统计的 token 用量、延迟分位数、工具活动、workflow 和错误等指标。面板说明和导入链接参见 Microsoft Agent Framework 仪表盘文档。

Microsoft Agent Framework Observability 故障排查
opentelemetry-exporter-otlp-proto-grpc 出现 ImportError
这是因为 OTEL_EXPORTER_OTLP_PROTOCOL 未设置,框架回退到了 gRPC。把它设为 http/protobuf,即可使用第 1 步中安装的 HTTP exporter。
SigNoz 中没有收到任何 span
检查 configure_otel_providers() 是否在首次 agent 运行之前执行,且位于所有 load_dotenv() 调用之后。同时确认 endpoint 末尾没有 /v1/traces 后缀,因为 exporter 会自行拼接信号路径。
Span 出现在 agent_framework 这个服务名下
创建 Provider 时未设置 OTEL_SERVICE_NAME。请在运行 configure_otel_providers() 之前设置该变量,或者直接通过 configure_otel_providers(service_name="<service_name>") 传入。
Token 总量看起来比 Provider 账单高出一倍
查询汇总了 invoke_agent 和 chat 两类 span 的 usage。请过滤 gen_ai.operation.name = 'chat' 以获取准确总量。
工具执行失败但 Agent 未显示错误
这是正常现象。Agent 会接收工具错误并进行恢复,因此只有 execute_tool span 会被标记为错误。请直接监控 execute_tool span 来追踪工具故障。
Token 指标读数接近零
框架还会导出具有累积性(cumulative temporality)的 gen_ai.client.token.usage 和 gen_ai.client.operation.duration 指标。短生命周期的脚本每次运行都会创建新的时间序列,导致 rate 和 increase 查询结果偏低。请改为聚合 span 属性,这也是仪表板模板采用的方法。
Handoff 工作流在构建时抛出 ValueError
Hand