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

SpanFuture AGI typeNotes
invoke_agent <name>agentWhole run, agent name, run input and output
chat <model>llmModel, provider, input/output tokens, request parameters, messages
execute_tool <name>toolTool name, arguments, result
workflow / executor / edge-group spanschainInput/output bubbled up from child spans
  • Token usage is counted on each chat span. The agent span keeps the framework’s run totals as agent_framework.usage.*, so the same tokens are not counted twice.
  • Every span of one run carries the same session.id. It comes from using_session(...) when you set it, otherwise from the run’s gen_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_data is 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 a TraceConfig to enable_fi_attribute_mapping(config=...).
  • With FI_HIDE_INPUTS and FI_HIDE_OUTPUTS set, 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_data off (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 no FI_HIDE_* variable is set. If your environment sets OTEL_SEMCONV_STABILITY_OPT_IN, include gen_ai_latest_experimental in 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-openai under 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).
  • AutoGen is a different framework with its own package.
  • Provider instrumentors such as traceAI-openai patch the provider SDK. Agent Framework uses its own native spans, so only this package is needed.
Was this page helpful?

Questions & Discussion