Microsoft Agent Framework
Zero-config tracing for Microsoft Agent Framework (MAF) agents and workflows.
Microsoft Agent Framework already emits OpenTelemetry spans for agents, model calls, tools, and multi-agent workflows. Rhesis turns those spans into first-class traces with a single call: enable MAF’s instrumentation, translate its GenAI spans into the Rhesis semantic conventions, and synthesize agent handoff events for the Graph View. Your agent code does not change.
Installation
Install the SDK with the agent-framework extra:
Install the agent-framework extra of rhesis-sdk, not the bare agent-framework meta-package. The meta-package pulls in optional stubs that can shadow the real agent_framework module and break instrumentation detection.
Quick Start
Create the RhesisClient first (it installs the OpenTelemetry tracer provider and Rhesis exporter), then call auto_instrument. After that, use MAF exactly as you normally would.
Order matters. auto_instrument() must run after RhesisClient is created. If no Rhesis tracer provider is active, the call returns an empty list and MAF spans are not translated.
auto_instrument() with no arguments auto-detects every installed framework (including MAF). Pass "agent_framework" (or "maf") to enable it explicitly. The call returns the list of frameworks that were instrumented:
What Gets Traced
Once enabled, MAF operations are captured automatically and mapped onto the Rhesis schema:
- Agents - each agent activation becomes an
ai.agent.invokespan - Model calls - chat completions become
ai.llm.invokespans with token counts - Tools - tool executions become
ai.tool.invokespans withai.tool.input/ai.tool.outputevents - Handoffs - control passing between agents is recorded as
ai.agent.handoffspans - Embeddings - embedding calls become
ai.embedding.generatespans - Workflows -
HandoffBuilder/ workflow orchestration becomesfunction.workflow.*spans
Operation Mapping
MAF operation (gen_ai.operation.name) | Rhesis span name |
|---|---|
chat | ai.llm.invoke |
invoke_agent | ai.agent.invoke |
create_agent | ai.agent.invoke |
execute_tool | ai.tool.invoke |
embeddings | ai.embedding.generate |
workflow.*, executor.* | function.workflow.* |
Spans that don’t match a known operation fall back to function.maf.<name> so they always pass backend validation, with the original name preserved on the gen_ai.original_span_name attribute.
Multi-Agent Handoffs
MAF’s HandoffBuilder workflows route work between agents. With current MAF builds, a handoff is expressed as a tool call inside the chat span rather than a separate tool span, so Rhesis reads the model output and synthesizes an ai.agent.handoff span for each transition. These render as edges in the Graph View.
Each handoff span carries ai.agent.handoff.to and, when it can be resolved, ai.agent.handoff.from. See the Multi-Agent Tracing page for the full span reference.
Content Capture and Privacy
By default, the integration captures message content (prompts, completions, tool arguments and results) so traces show what each agent actually sent and received.
To omit message content - for example in production or regulated environments - set RHESIS_DISABLE_CONTENT_CAPTURE before initializing:
Accepted truthy values: 1, true, yes, on (case-insensitive). When disabled, spans are still exported with structural metadata (model, provider, token counts, agent names, operation types), but no prompt, completion, or tool input/output payloads are recorded.
Workflow Span Verbosity
To keep traces readable, the integration trims low-value workflow infrastructure spans (edge_group.*, message.send and workflow.build) by default while keeping the structural executor.* spans that parent agent activations.
To keep every workflow span (useful when debugging the orchestration layer itself), set:
Combining with Decorators
Auto-instrumentation composes with @endpoint and @observe. Wrap your entry point with @endpoint so Rhesis can run tests against it; MAF spans created inside are nested under the endpoint span automatically:
Do not call agent_framework.observability.configure_otel_providers() (or setup_observability()) after creating the RhesisClient. Doing so replaces the Rhesis tracer provider and spans will no longer reach Rhesis. auto_instrument("agent_framework") already enables MAF instrumentation against the Rhesis provider for you.
Multi-Turn Conversations
MAF opens its own root span per turn, so OpenTelemetry mints a fresh trace id every time you run an agent or a workflow. Bind a conversation id and the integration puts all of that conversation’s turns on one trace, with the run root of each turn carrying the turn’s message and reply:
The first turn keeps the trace id it was born with and later turns join it, so a link to the first turn still resolves. Bind the id before the run starts: the target trace has to be known when the run root is created, and MAF assigns no span attributes before then.
Two cases stand this down, because there the trace id is already owned and published elsewhere: a run inside an @endpoint or @observe span, and a platform-driven turn. Both join the turns themselves, so the integration leaves their spans where they are.
The join is per-integration. It groups turns that MAF itself served, and it does not coordinate with conversation_turn or with another framework’s integration. So a conversation whose turns alternate between a bare agent.run() and some other mechanism, under the same conversation id, arrives as more than one trace. Wrap every turn of such a conversation in conversation_turn to keep them together. What each integration can join differs too, so check its own page rather than assuming this page’s behaviour applies everywhere.
Worked Example: Travel Agent
The repository ships a runnable multi-agent MAF demo - a HandoffBuilder workflow with a coordinator and seven specialists - built specifically to produce agent, LLM, tool, and handoff traces in Rhesis. See agents/travel-agent and its architecture notes .
Migrating from AutoGen
AutoGen 0.2 has been folded into the unified Microsoft Agent Framework. The legacy auto_instrument("autogen") path is now a no-op placeholder - use auto_instrument("agent_framework") instead, which covers the full Agent / tool / workflow surface.
Disabling
Turn instrumentation off (restores the original exporter) with:
Related:
- Auto-Instrumentation - zero-config tracing for LangChain, LangGraph, Microsoft Agent Framework, Pydantic AI, Google ADK and Haystack
- Multi-Agent Tracing - agent and handoff spans
- Setup - initial configuration
- Connector - register functions as endpoints