ag2-telemetry
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTelemetry — OpenTelemetry instrumentation
遥测——OpenTelemetry 埋点
When to use
适用场景
The user wants to:
- See per-turn / per-call latency breakdowns
- Attribute token usage across operations
- Push traces to Jaeger, Grafana Tempo, Datadog, Honeycomb, Langfuse, etc.
- Debug a slow agent end-to-end with structured spans rather than print statements
If they just want quick stdout debugging, point them at instead (see ).
LoggingMiddlewareag2-middleware用户希望:
- 查看每轮/每次调用的延迟细分
- 在不同操作间归因令牌使用情况
- 将追踪数据推送至Jaeger、Grafana Tempo、Datadog、Honeycomb、Langfuse等平台
- 通过结构化跨度而非打印语句端到端调试性能缓慢的Agent
如果用户仅需要快速的标准输出调试,请引导他们使用(详见)。
LoggingMiddlewareag2-middlewareInstallation
安装
bash
pip install "ag2[openai,tracing]"Required. Run this install before delivering the code. If you cannot run commands, state the exactcommand.pip install
bash
pip install "ag2[openai,tracing]"必须执行。在交付代码前运行此安装命令。若无法执行命令,请明确告知该命令。pip install
60-second recipe
60秒快速上手
python
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
from ag2 import Agent
from ag2.config import OpenAIConfig
from ag2.middleware.builtin import TelemetryMiddlewarepython
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor, ConsoleSpanExporter
from ag2 import Agent
from ag2.config import OpenAIConfig
from ag2.middleware.builtin import TelemetryMiddleware1. Configure OpenTelemetry
1. 配置OpenTelemetry
resource = Resource.create({"service.name": "ag2-quickstart"})
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(tracer_provider)
resource = Resource.create({"service.name": "ag2-quickstart"})
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(tracer_provider)
2. Wire the middleware
2. 接入中间件
agent = Agent(
"assistant",
prompt="You are a helpful assistant.",
config=OpenAIConfig(model="gpt-4o-mini"),
middleware=[
TelemetryMiddleware(
tracer_provider=tracer_provider,
agent_name="assistant",
),
],
)
agent = Agent(
"assistant",
prompt="You are a helpful assistant.",
config=OpenAIConfig(model="gpt-4o-mini"),
middleware=[
TelemetryMiddleware(
tracer_provider=tracer_provider,
agent_name="assistant",
),
],
)
3. Run — spans emit automatically
3. 运行——自动生成跨度
import asyncio
asyncio.run(agent.ask("What is the capital of France?"))
For production, swap `ConsoleSpanExporter` for `OTLPSpanExporter` (or your backend's exporter) and `SimpleSpanProcessor` for `BatchSpanProcessor`.import asyncio
asyncio.run(agent.ask("What is the capital of France?"))
生产环境中,请将`ConsoleSpanExporter`替换为`OTLPSpanExporter`(或对应后端的导出器),并将`SimpleSpanProcessor`替换为`BatchSpanProcessor`。Span hierarchy
跨度层级结构
Each produces a root span with children:
ask()invoke_agent assistant
├── chat gpt-4o-mini # LLM API call
├── execute_tool get_weather # tool execution
├── chat gpt-4o-mini # LLM call after tool result
└── await_human_input assistant # human-in-the-loop每次调用都会生成一个根跨度,包含以下子跨度:
ask()invoke_agent assistant
├── chat gpt-4o-mini # LLM API调用
├── execute_tool get_weather # 工具执行
├── chat gpt-4o-mini # 工具返回结果后的LLM调用
└── await_human_input assistant # 人机交互环节Span types
跨度类型
Every span has an attribute:
ag2.span.type | Operation name | Hook |
|---|---|---|
| | |
| | |
| | |
| | |
每个跨度都带有属性:
ag2.span.type | 操作名称 | 钩子函数 |
|---|---|---|
| | |
| | |
| | |
| | |
Semantic attributes (GenAI semconv)
语义属性(GenAI 语义规范)
Spans carry standard OpenTelemetry GenAI attributes:
| Attribute | Spans | Description |
|---|---|---|
| All | |
| agent, human_input | Agent name |
| agent, llm | Auto-detected ( |
| agent, llm | e.g. |
| llm | Resolved from response |
| llm | e.g. |
| llm | Prompt tokens |
| llm | Completion tokens |
| llm | Prompt-cache writes (Anthropic) |
| llm | Prompt-cache reads (Anthropic, OpenAI, Gemini) |
| tool | Tool function name |
| tool | Tool call ID |
| tool | Always |
跨度携带标准的OpenTelemetry GenAI属性:
| 属性 | 适用跨度 | 描述 |
|---|---|---|
| 所有 | |
| agent、human_input | Agent名称 |
| agent、llm | 自动检测( |
| agent、llm | 例如 |
| llm | 从响应中解析 |
| llm | 例如 |
| llm | 提示词令牌数 |
| llm | 补全内容令牌数 |
| llm | 提示词缓存写入(Anthropic) |
| llm | 提示词缓存读取(Anthropic、OpenAI、Gemini) |
| tool | 工具函数名称 |
| tool | 工具调用ID |
| tool | 固定为 |
Content capture (default ON)
内容捕获(默认开启)
By default, message content, tool args, and results are included on spans. Useful for debugging but can leak sensitive data:
python
TelemetryMiddleware(
tracer_provider=tracer_provider,
agent_name="assistant",
capture_content=False, # omit messages, tool args, results
)When enabled, additional attributes appear:
| Attribute | Span | Content |
|---|---|---|
| llm | JSON request messages |
| llm | JSON response messages |
| tool | Tool args (JSON) |
| tool | Tool result |
| human_input | Prompt shown to human |
| human_input | Human's response |
For privacy-sensitive backends (or anywhere telemetry leaves your infra), set .
capture_content=False默认情况下,消息内容、工具参数和结果会被包含在跨度中。这对调试很有用,但可能泄露敏感数据:
python
TelemetryMiddleware(
tracer_provider=tracer_provider,
agent_name="assistant",
capture_content=False, # 省略消息、工具参数和结果
)开启时,会出现以下额外属性:
| 属性 | 适用跨度 | 内容 |
|---|---|---|
| llm | JSON格式的请求消息 |
| llm | JSON格式的响应消息 |
| tool | JSON格式的工具参数 |
| tool | 工具执行结果 |
| human_input | 展示给用户的提示词 |
| human_input | 用户的回复 |
对于隐私敏感的后端(或遥测数据会离开您基础设施的场景),请设置。
capture_content=FalseConstructor reference
构造函数参考
| Parameter | Type | Default | Description |
|---|---|---|---|
| | Global provider | OpenTelemetry TracerProvider |
| | | Include message/tool content in spans |
| | | Agent name for span attributes |
| | | Provider override (auto-detected if unset) |
| | | Model override (auto-detected if unset) |
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
| | 全局提供者 | OpenTelemetry TracerProvider |
| | | 在跨度中包含消息/工具内容 |
| | | 跨度属性中的Agent名称 |
| | | 提供者覆盖值(未设置时自动检测) |
| | | 模型覆盖值(未设置时自动检测) |
Backend integration
后端集成
TelemetryMiddleware- Jaeger —
OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces") - Grafana Tempo — same OTLP exporter, point at the Tempo gateway
- Langfuse, Honeycomb, Datadog — vendor-specific exporters; the agent-side setup is identical
For container-orchestrated stacks, this repo includes a directory with Docker-Compose for otel-collector + Grafana Tempo.
tracing/TelemetryMiddleware- Jaeger —
OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces") - Grafana Tempo — 使用相同的OTLP导出器,指向Tempo网关
- Langfuse、Honeycomb、Datadog — 使用厂商特定的导出器;Agent端设置保持一致
对于容器编排栈,本仓库包含目录,其中有用于otel-collector + Grafana Tempo的Docker-Compose配置。
tracing/Going deeper
深入了解
- — full attribute table, configuration, example.
website/docs/user-guide/telemetry.mdx - — Docker setup for local otel-collector + Tempo + Grafana.
tracing/ - For sibling middleware (logging, retry, history limits), see .
ag2-middleware
- — 完整属性表、配置说明及示例。
website/docs/user-guide/telemetry.mdx - — 本地otel-collector + Tempo + Grafana的Docker配置。
tracing/ - 关于其他中间件(日志、重试、历史记录限制),请查看。
ag2-middleware
Common pitfalls
常见陷阱
- +
SimpleSpanProcessorin production — synchronous, blocks every span emit. UseConsoleSpanExporterand a real exporter (OTLP / Jaeger / vendor) outside of dev.BatchSpanProcessor - Leaking content into telemetry — is the default. For privacy-sensitive prompts (PII, credentials), set
capture_content=Trueand audit what your backend retains.capture_content=False - Forgetting — without it,
trace.set_tracer_provider(...)you pass to the middleware is fine, but third-party libraries that auto-instrument may use a different provider.tracer_provider - Token usage missing — requires the provider client to surface usage in the response. Streaming providers may emit usage only at the end; if you don't see them, check the provider's response shape.
gen_ai.usage.* - Span hierarchy doesn't show parent-child — your exporter or backend may need the OTLP/HTTP path enabled, not just OTLP/gRPC. Check both.
- Comparing to AG2 Classic tracing docs — the semantic-attribute format is the same; only the agent instrumentation method differs (AG2 Classic uses /
instrument_agent()/instrument_llm_wrapper(); AG2 usesinstrument_pattern()).TelemetryMiddleware
- 生产环境使用+
SimpleSpanProcessor— 同步模式,会阻塞每次跨度生成。开发环境外请使用ConsoleSpanExporter和真实导出器(OTLP / Jaeger / 厂商专属)。BatchSpanProcessor - 遥测数据中泄露内容 — 是默认设置。对于包含隐私信息的提示词(个人身份信息、凭据),请设置
capture_content=True并审核后端保留的数据。capture_content=False - 遗漏— 即使您向中间件传递了
trace.set_tracer_provider(...),没有此设置的话,自动埋点的第三方库可能会使用不同的提供者。tracer_provider - 令牌使用信息缺失 — 需要提供者客户端在响应中返回使用数据。流式提供者可能仅在结束时返回使用数据;若未看到,请检查提供者的响应格式。
gen_ai.usage.* - 跨度层级未显示父子关系 — 您的导出器或后端可能需要启用OTLP/HTTP路径,而不仅仅是OTLP/gRPC。请同时检查两者。
- 与AG2 Classic追踪文档混淆 — 语义属性格式相同;仅Agent埋点方法不同(AG2 Classic使用/
instrument_agent()/instrument_llm_wrapper();AG2使用instrument_pattern())。TelemetryMiddleware