ag2-telemetry

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Telemetry — 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
LoggingMiddleware
instead (see
ag2-middleware
).
用户希望:
  • 查看每轮/每次调用的延迟细分
  • 在不同操作间归因令牌使用情况
  • 将追踪数据推送至Jaeger、Grafana Tempo、Datadog、Honeycomb、Langfuse等平台
  • 通过结构化跨度而非打印语句端到端调试性能缓慢的Agent
如果用户仅需要快速的标准输出调试,请引导他们使用
LoggingMiddleware
(详见
ag2-middleware
)。

Installation

安装

bash
pip install "ag2[openai,tracing]"
Required. Run this install before delivering the code. If you cannot run commands, state the exact
pip install
command.
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 TelemetryMiddleware
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 TelemetryMiddleware

1. 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
ask()
produces a root span with children:
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
ag2.span.type
attribute:
ag2.span.type
Operation nameHook
agent
invoke_agent
on_turn
— full turn
llm
chat
on_llm_call
— each LLM call
tool
execute_tool
on_tool_execution
— each tool
human_input
await_human_input
on_human_input
— HITL
每个跨度都带有
ag2.span.type
属性:
ag2.span.type
操作名称钩子函数
agent
invoke_agent
on_turn
— 完整交互轮次
llm
chat
on_llm_call
— 每个LLM调用
tool
execute_tool
on_tool_execution
— 每个工具执行
human_input
await_human_input
on_human_input
— 人机交互(HITL)

Semantic attributes (GenAI semconv)

语义属性(GenAI 语义规范)

Spans carry standard OpenTelemetry GenAI attributes:
AttributeSpansDescription
gen_ai.operation.name
All
invoke_agent
/
chat
/
execute_tool
/
await_human_input
gen_ai.agent.name
agent, human_inputAgent name
gen_ai.provider.name
agent, llmAuto-detected (
openai
,
anthropic
, …)
gen_ai.request.model
agent, llme.g.
gpt-4o-mini
gen_ai.response.model
llmResolved from response
gen_ai.response.finish_reasons
llme.g.
["stop"]
,
["tool_calls"]
gen_ai.usage.input_tokens
llmPrompt tokens
gen_ai.usage.output_tokens
llmCompletion tokens
gen_ai.usage.cache_creation_input_tokens
llmPrompt-cache writes (Anthropic)
gen_ai.usage.cache_read_input_tokens
llmPrompt-cache reads (Anthropic, OpenAI, Gemini)
gen_ai.tool.name
toolTool function name
gen_ai.tool.call.id
toolTool call ID
gen_ai.tool.type
toolAlways
function
跨度携带标准的OpenTelemetry GenAI属性:
属性适用跨度描述
gen_ai.operation.name
所有
invoke_agent
/
chat
/
execute_tool
/
await_human_input
gen_ai.agent.name
agent、human_inputAgent名称
gen_ai.provider.name
agent、llm自动检测(
openai
anthropic
等)
gen_ai.request.model
agent、llm例如
gpt-4o-mini
gen_ai.response.model
llm从响应中解析
gen_ai.response.finish_reasons
llm例如
["stop"]
["tool_calls"]
gen_ai.usage.input_tokens
llm提示词令牌数
gen_ai.usage.output_tokens
llm补全内容令牌数
gen_ai.usage.cache_creation_input_tokens
llm提示词缓存写入(Anthropic)
gen_ai.usage.cache_read_input_tokens
llm提示词缓存读取(Anthropic、OpenAI、Gemini)
gen_ai.tool.name
tool工具函数名称
gen_ai.tool.call.id
tool工具调用ID
gen_ai.tool.type
tool固定为
function

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:
AttributeSpanContent
gen_ai.input.messages
llmJSON request messages
gen_ai.output.messages
llmJSON response messages
gen_ai.tool.call.arguments
toolTool args (JSON)
gen_ai.tool.call.result
toolTool result
ag2.human_input.prompt
human_inputPrompt shown to human
ag2.human_input.response
human_inputHuman'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,   # 省略消息、工具参数和结果
)
开启时,会出现以下额外属性:
属性适用跨度内容
gen_ai.input.messages
llmJSON格式的请求消息
gen_ai.output.messages
llmJSON格式的响应消息
gen_ai.tool.call.arguments
toolJSON格式的工具参数
gen_ai.tool.call.result
tool工具执行结果
ag2.human_input.prompt
human_input展示给用户的提示词
ag2.human_input.response
human_input用户的回复
对于隐私敏感的后端(或遥测数据会离开您基础设施的场景),请设置
capture_content=False

Constructor reference

构造函数参考

ParameterTypeDefaultDescription
tracer_provider
TracerProvider | None
Global providerOpenTelemetry TracerProvider
capture_content
bool
True
Include message/tool content in spans
agent_name
str | None
"unknown"
Agent name for span attributes
provider_name
str | None
None
Provider override (auto-detected if unset)
model_name
str | None
None
Model override (auto-detected if unset)
参数类型默认值描述
tracer_provider
TracerProvider | None
全局提供者OpenTelemetry TracerProvider
capture_content
bool
True
在跨度中包含消息/工具内容
agent_name
str | None
"unknown"
跨度属性中的Agent名称
provider_name
str | None
None
提供者覆盖值(未设置时自动检测)
model_name
str | None
None
模型覆盖值(未设置时自动检测)

Backend integration

后端集成

TelemetryMiddleware
uses standard OpenTelemetry, so any OTLP-compatible backend works:
  • 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
tracing/
directory with Docker-Compose for otel-collector + Grafana Tempo.
TelemetryMiddleware
使用标准OpenTelemetry,因此所有兼容OTLP的后端均可使用:
  • Jaeger
    OTLPSpanExporter(endpoint="http://localhost:4318/v1/traces")
  • Grafana Tempo — 使用相同的OTLP导出器,指向Tempo网关
  • Langfuse、Honeycomb、Datadog — 使用厂商特定的导出器;Agent端设置保持一致
对于容器编排栈,本仓库包含
tracing/
目录,其中有用于otel-collector + Grafana Tempo的Docker-Compose配置。

Going deeper

深入了解

  • website/docs/user-guide/telemetry.mdx
    — full attribute table, configuration, example.
  • tracing/
    — Docker setup for local otel-collector + Tempo + Grafana.
  • For sibling middleware (logging, retry, history limits), see
    ag2-middleware
    .
  • website/docs/user-guide/telemetry.mdx
    — 完整属性表、配置说明及示例。
  • tracing/
    — 本地otel-collector + Tempo + Grafana的Docker配置。
  • 关于其他中间件(日志、重试、历史记录限制),请查看
    ag2-middleware

Common pitfalls

常见陷阱

  • SimpleSpanProcessor
    +
    ConsoleSpanExporter
    in production
    — synchronous, blocks every span emit. Use
    BatchSpanProcessor
    and a real exporter (OTLP / Jaeger / vendor) outside of dev.
  • Leaking content into telemetry
    capture_content=True
    is the default. For privacy-sensitive prompts (PII, credentials), set
    capture_content=False
    and audit what your backend retains.
  • Forgetting
    trace.set_tracer_provider(...)
    — without it,
    tracer_provider
    you pass to the middleware is fine, but third-party libraries that auto-instrument may use a different provider.
  • Token usage missing
    gen_ai.usage.*
    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.
  • 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()
    /
    instrument_pattern()
    ; AG2 uses
    TelemetryMiddleware
    ).
  • 生产环境使用
    SimpleSpanProcessor
    +
    ConsoleSpanExporter
    — 同步模式,会阻塞每次跨度生成。开发环境外请使用
    BatchSpanProcessor
    和真实导出器(OTLP / Jaeger / 厂商专属)。
  • 遥测数据中泄露内容
    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()
    /
    instrument_pattern()
    ;AG2使用
    TelemetryMiddleware
    )。