Microsoft Agent Framework Integration with Future AGI for Agent Tracing
Trace Microsoft Agent Framework (Python) agents, model calls, tools and workflows in Future AGI with traceAI-agent-framework.
About
Trace Microsoft Agent Framework agent runs, model calls, tool calls and workflows in Future AGI. This page covers the Python package (PyPI agent-framework), not the .NET SDK. It is a different framework from AutoGen, Semantic Kernel and AG2.
Agent Framework already emits OpenTelemetry spans that follow the GenAI semantic conventions. traceAI-agent-framework does not wrap the framework. It adds one span processor that gives those native spans the Future AGI span kind, input and output, session ID and token totals, so they appear as agent, LLM, tool and chain spans.
1. Installation
Use Python 3.10 to 3.13 and Agent Framework 1.0.0 or later.
pip install "traceAI-agent-framework==0.1.0" agent-framework
2. Set environment variables
Set credentials in your shell, not in source code:
export FI_API_KEY="your-futureagi-api-key"
export FI_SECRET_KEY="your-futureagi-secret-key"
export OPENAI_API_KEY="your-openai-api-key"
3. Register the tracer provider
Agent Framework emits spans on the global tracer provider only, so register with set_global_tracer_provider=True.
from fi_instrumentation import register
from fi_instrumentation.fi_types import ProjectType
trace_provider = register(
project_type=ProjectType.OBSERVE,
project_name="agent_framework_app",
set_global_tracer_provider=True,
)
4. Turn on the mapping
from agent_framework.observability import enable_instrumentation
from traceai_agent_framework import enable_fi_attribute_mapping
enable_instrumentation(enable_sensitive_data=True)
enable_fi_attribute_mapping()
enable_sensitive_data=True is the framework’s own switch for recording prompts, completions and tool arguments on its spans. Without it, the framework does not record that content, so traces show no prompts or answers. enable_fi_attribute_mapping() is idempotent.
5. Run an agent
import asyncio
from agent_framework import Agent
from agent_framework.openai import OpenAIChatCompletionClient
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
return f"Sunny, 21C in {city}"
agent = Agent(
OpenAIChatCompletionClient(model="gpt-4o-mini"),
name="weather_agent",
instructions="You are a concise weather assistant. Always call get_weather.",
tools=[get_weather],
)
async def main():
print(await agent.run("What's the weather in Paris?"))
asyncio.run(main())
trace_provider.force_flush()
force_flush() sends the last spans before a short script exits.
6. View the trace
Open Observe, select agent_framework_app, and open the latest trace. The invoke_agent weather_agent span contains the chat model spans and the execute_tool get_weather tool span.
What is captured
| Span | Future AGI type | Notes |
|---|---|---|
invoke_agent <name> | agent | Whole run, agent name, run input and output |
chat <model> | llm | Model, provider, input/output tokens, request parameters, messages |
execute_tool <name> | tool | Tool name, arguments, result |
| workflow / executor / edge-group spans | chain | Input/output bubbled up from child spans |
- Token usage is counted on each
chatspan. The agent span keeps the framework’s run totals asagent_framework.usage.*, so the same tokens are not counted twice. - Every span of one run carries the same
session.id. It comes fromusing_session(...)when you set it, otherwise from the run’sgen_ai.conversation.id. - A failing tool or model call is recorded with ERROR status and the exception class name.
- The framework does not emit retrieval spans.
Privacy
- Content is captured by default (like every traceAI integration) once the framework’s
enable_sensitive_datais on. Hide it with the standard traceAI switches:FI_HIDE_INPUTS=true,FI_HIDE_OUTPUTS=true,FI_HIDE_INPUT_MESSAGES,FI_HIDE_OUTPUT_MESSAGES,FI_HIDE_INPUT_TEXT,FI_HIDE_OUTPUT_TEXT, or pass aTraceConfigtoenable_fi_attribute_mapping(config=...). - With
FI_HIDE_INPUTSandFI_HIDE_OUTPUTSset, prompts, responses, system instructions, tool arguments and tool results are removed or redacted. Model, token counts, timings, span structure and tool names stay. - To keep content out entirely, leave
enable_sensitive_dataoff (the framework then never records it). - Raw exception text and stack traces are never exported. A failed span keeps ERROR status with only the exception class name.
Troubleshooting
- No spans.
register(..., set_global_tracer_provider=True)is required.enable_fi_attribute_mapping()logs a warning if the provider is not the global one. - No prompts or answers in the trace. Call
enable_instrumentation(enable_sensitive_data=True)and check that noFI_HIDE_*variable is set. If your environment setsOTEL_SEMCONV_STABILITY_OPT_IN, includegen_ai_latest_experimentalin it; otherwise current Agent Framework releases do not put messages and tool arguments on spans. - One session per turn on the Responses API. Wrap the turns in
with using_session("my-session"):(from fi_instrumentation import using_session). - Duplicate LLM spans. Do not also enable
traceAI-openaiunder Agent Framework; the framework already emits the model span. - Spans missing in a short script. Call
trace_provider.force_flush()before exit.
Limitations
- Python only. No .NET.
- Do not call
configure_otel_providers(); it can install a second exporter. - Traces only (no metrics or logs).
Difference from related integrations
- AutoGen is a different framework with its own package.
- Provider instrumentors such as
traceAI-openaipatch the provider SDK. Agent Framework uses its own native spans, so only this package is needed.
Questions & Discussion