
Ag2 Telemetry
- 33 installs
- 8 repo stars
- Updated July 27, 2026
- ag2ai/ag2-skills
ag2-telemetry is a Claude Code skill that instruments an AG2 beta Agent with OpenTelemetry traces via TelemetryMiddleware for latency and token-usage observability.
About
This skill adds OpenTelemetry tracing to an AG2 beta Agent using TelemetryMiddleware. It emits spans for the full turn, each LLM call, each tool execution, and each human-input request following OpenTelemetry GenAI semantic conventions. A developer uses it to get per-turn latency breakdowns, attribute token usage, and push traces into an existing observability backend such as Jaeger, Grafana Tempo, Datadog, Honeycomb, or Langfuse.
- Adds OpenTelemetry traces to an AG2 beta Agent via TelemetryMiddleware
- Emits spans for the full turn, each LLM call, tool execution, and human-input request using GenAI semantic conventions
- Works with any OTLP backend including Jaeger, Grafana Tempo, Datadog, Honeycomb, and Langfuse
Ag2 Telemetry by the numbers
- 33 all-time installs (skills.sh)
- Ranked #8,968 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 1, 2026 (Skillselion catalog sync)
ag2-telemetry capabilities & compatibility
Free skill; requires pip install ag2[openai,tracing], an LLM API key, and an OTLP backend.
- Capabilities
- agent observability · distributed tracing · latency analysis · token attribution
- Works with
- datadog · grafana
- Use cases
- orchestration
- Pricing
- Bring your own API key
What ag2-telemetry says it does
Add OpenTelemetry traces to an AG2 beta `Agent` via `TelemetryMiddleware`
Compatible with any OTLP backend — Jaeger, Grafana Tempo, Datadog, Honeycomb, Langfuse.
npx skills add https://github.com/ag2ai/ag2-skills --skill ag2-telemetryAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 33 |
|---|---|
| repo stars | ★ 8 |
| Last updated | July 27, 2026 |
| Repository | ag2ai/ag2-skills ↗ |
What it does
Instrument an AG2 beta agent with OpenTelemetry spans and ship latency and token-usage traces to an OTLP observability backend.
Who is it for?
Developers who want production traces, latency analysis, and token attribution for AG2 agents in an existing observability stack.
Skip if: Quick stdout debugging (the skill points to LoggingMiddleware for that).
When should I use this skill?
The user wants production-grade traces, latency analysis, token-usage attribution, or to ship telemetry into an observability stack.
What you get
The agent emits OpenTelemetry spans for turns, LLM calls, tools, and human input to any OTLP backend.
- AG2 Agent wired with TelemetryMiddleware
- OpenTelemetry spans exported to an OTLP backend
By the numbers
- 4 span types documented (agent, llm, tool, human_input)
Files
Telemetry — OpenTelemetry instrumentation
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).
Installation
pip install "ag2[openai,tracing]"Required. Run this install before delivering the code. If you cannot run commands, state the exact pip install command.60-second recipe
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 autogen.beta import Agent
from autogen.beta.config import OpenAIConfig
from autogen.beta.middleware.builtin import TelemetryMiddleware
# 1. Configure OpenTelemetry
resource = Resource.create({"service.name": "ag2-beta-quickstart"})
tracer_provider = TracerProvider(resource=resource)
tracer_provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(tracer_provider)
# 2. Wire the middleware
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
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.
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-loopSpan types
Every span has an ag2.span.type attribute:
ag2.span.type | Operation name | Hook |
|---|---|---|
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 |
Semantic attributes (GenAI semconv)
Spans carry standard OpenTelemetry GenAI attributes:
| Attribute | Spans | Description |
|---|---|---|
gen_ai.operation.name | All | invoke_agent / chat / execute_tool / await_human_input |
gen_ai.agent.name | agent, human_input | Agent name |
gen_ai.provider.name | agent, llm | Auto-detected (openai, anthropic, …) |
gen_ai.request.model | agent, llm | e.g. gpt-4o-mini |
gen_ai.response.model | llm | Resolved from response |
gen_ai.response.finish_reasons | llm | e.g. ["stop"], ["tool_calls"] |
gen_ai.usage.input_tokens | llm | Prompt tokens |
gen_ai.usage.output_tokens | llm | Completion tokens |
gen_ai.usage.cache_creation_input_tokens | llm | Prompt-cache writes (Anthropic) |
gen_ai.usage.cache_read_input_tokens | llm | Prompt-cache reads (Anthropic, OpenAI, Gemini) |
gen_ai.tool.name | tool | Tool function name |
gen_ai.tool.call.id | tool | Tool call ID |
gen_ai.tool.type | tool | Always 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:
TelemetryMiddleware(
tracer_provider=tracer_provider,
agent_name="assistant",
capture_content=False, # omit messages, tool args, results
)When enabled, additional attributes appear:
| Attribute | Span | Content |
|---|---|---|
gen_ai.input.messages | llm | JSON request messages |
gen_ai.output.messages | llm | JSON response messages |
gen_ai.tool.call.arguments | tool | Tool args (JSON) |
gen_ai.tool.call.result | tool | Tool result |
ag2.human_input.prompt | human_input | Prompt shown to human |
ag2.human_input.response | human_input | Human's response |
For privacy-sensitive backends (or anywhere telemetry leaves your infra), set capture_content=False.
Constructor reference
| Parameter | Type | Default | Description |
|---|---|---|---|
tracer_provider | `TracerProvider \ | None` | Global provider |
capture_content | bool | True | Include message/tool content in spans |
agent_name | `str \ | None` | "unknown" |
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.
Going deeper
website/docs/beta/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.
Common pitfalls
- `SimpleSpanProcessor` + `ConsoleSpanExporter` in production — synchronous, blocks every span emit. Use
BatchSpanProcessorand a real exporter (OTLP / Jaeger / vendor) outside of dev. - Leaking content into telemetry —
capture_content=Trueis the default. For privacy-sensitive prompts (PII, credentials), setcapture_content=Falseand audit what your backend retains. - Forgetting `trace.set_tracer_provider(...)` — without it,
tracer_provideryou 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 V1 tracing docs — the semantic-attribute format is the same; only the agent instrumentation method differs (V1 uses
instrument_agent()/instrument_llm_wrapper()/instrument_pattern(); beta usesTelemetryMiddleware).
Related skills
FAQ
Which backends does ag2-telemetry support?
It uses standard OpenTelemetry, so any OTLP-compatible backend works, including Jaeger, Grafana Tempo, Langfuse, Honeycomb, and Datadog.
Does it capture message content?
By default message content, tool args, and results are included on spans; set capture_content=False to omit them for privacy-sensitive backends.