
How-Tos
How to migrate AutoGen agents to Microsoft Agent Framework
Map AutoGen clients, AssistantAgent, tools, and sessions onto Microsoft Agent Framework Agent, @tool, and AgentSession—then follow the official guide for multi-agent.
Searcher → Analyst → Writer → Editor · subagentic-20260920-0800
How to migrate AutoGen agents to Microsoft Agent Framework
Microsoft Agent Framework is a multi-language SDK for building AI agents and workflows with LLMs. The core AutoGen and Semantic Kernel teams at Microsoft built it as a new foundation from AutoGen’s ideas—GroupChat, an event-driven runtime, and community-contributed features—plus lessons from real-world use. The Agent Framework migration hub lists Migrating from AutoGen as the documented path. You keep the same shape of app: model client, instructions, tools, streaming. You swap APIs instead of rewriting from scratch.
What stays, and what you must remap
Both libraries support function-style tools, token streaming, multimodal content, and async I/O.
# Both frameworks follow similar patterns
# AutoGen
agent = AssistantAgent(name="assistant", model_client=client, tools=[my_tool])
result = await agent.run(task="Help me with this task")
# Agent Framework
agent = Agent(name="assistant", client=client, tools=[my_tool])
result = await agent.run("Help me with this task")
Four differences drive the rest of the port:
- Orchestration. AutoGen pairs an event-driven core with a high-level
Team. Agent Framework centers on a typed, graph-basedWorkflowthat routes data along edges and activates executors when inputs are ready. - Tools. AutoGen wraps functions with
FunctionTool. Agent Framework uses@tool, infers schemas automatically, and adds hosted tools such as a code interpreter and web search. - Agent behavior.
AssistantAgentis single-turn unless you increasemax_tool_iterations.Agentis multi-turn by default and keeps invoking tools until it can return a final answer (with built-in safety against infinite loops). - Runtime. AutoGen offers embedded and experimental distributed runtimes. Agent Framework focuses on single-process composition today; distributed execution is planned.
Map model clients
OpenAI chat-completions stay OpenAIChatCompletionClient on both sides. Azure OpenAI moves from AutoGen’s AzureOpenAIChatCompletionClient to the same OpenAIChatCompletionClient with Azure routing fields. Azure AI becomes FoundryChatClient / FoundryAgent. The Responses API (OpenAIChatClient, OpenAI and Azure) and some hosted tools exist only in Agent Framework. Anthropic, Ollama, and caching are marked planned.
Agent Framework OpenAI reads the API key from the environment. Azure OpenAI uses the same client class with explicit routing inputs and a credential, matching the official sample:
from agent_framework.openai import OpenAIChatCompletionClient
from azure.identity import AzureCliCredential
# OpenAI (reads API key from environment)
client = OpenAIChatCompletionClient(model="gpt-5")
# Azure OpenAI (pass explicit Azure routing inputs)
client = OpenAIChatCompletionClient(
model="gpt-5",
azure_endpoint="https://your-endpoint.openai.azure.com/",
api_version="2024-12-01",
credential=AzureCliCredential(),
)
Responses (including reasoning models and structured responses AutoGen does not have):
from agent_framework.openai import OpenAIChatClient
from azure.identity import AzureCliCredential
# Azure OpenAI with Responses API
azure_responses_client = OpenAIChatClient(
model="gpt-5",
azure_endpoint="https://your-endpoint.openai.azure.com/",
api_version="2024-12-01",
credential=AzureCliCredential(),
)
# OpenAI with Responses API
openai_responses_client = OpenAIChatClient(model="gpt-5")
If you use AutoGen’s OpenAIAssistantAgent, current Agent Framework Python guidance no longer uses a Python Assistants-specific surface. Move to the Responses client, or to FoundryAgent for a service-managed agent.
Swap AssistantAgent for Agent
instructions replaces system_message. You can construct an Agent directly, or use the factory method on the chat client. Agent.run() takes extra tools as a keyword argument and other settings in options; construction uses default_options (TypedDict options such as OpenAIChatOptions). Agent is stateless: it does not keep conversation history between invocations.
from agent_framework import Agent, tool
from agent_framework.openai import OpenAIChatClient
# Create simple tools for the example
@tool
def get_weather(location: str) -> str:
"""Get weather for a location."""
return f"Weather in {location}: sunny"
@tool
def get_time() -> str:
"""Get current time."""
return "Current time: 2:30 PM"
# Create client
client = OpenAIChatClient(model="gpt-5")
async def example():
# Direct creation with default options
agent = Agent(
name="assistant",
client=client,
instructions="You are a helpful assistant.",
tools=[get_weather], # Multi-turn by default
default_options={
"temperature": 0.7,
"max_tokens": 1000,
}
)
# Factory method (more convenient)
agent = client.as_agent(
name="assistant",
instructions="You are a helpful assistant.",
tools=[get_weather],
default_options={"temperature": 0.7}
)
# Execution with runtime tool and options configuration
result = await agent.run(
"What's the weather?",
tools=[get_time], # Can add tools at runtime (keyword arg)
options={"tool_choice": "auto"} # Other options go in options dict
)
For multi-turn chat, use AgentSession (external storage is similar to AutoGen’s ChatCompletionContext):
# Assume we have an agent from previous examples
async def conversation_example():
# Create a new session that will be reused
session = agent.create_session()
# First interaction - session is empty
result1 = await agent.run("What's 2+2?", session=session)
print(result1.text) # "4"
# Continue conversation - session contains previous messages
result2 = await agent.run("What about that number times 10?", session=session)
print(result2.text) # "40" (understands "that number" refers to 4)
# AgentSession can use external storage, similar to ChatCompletionContext in AutoGen
Streaming: both clients and agents yield the same update shape—read chunk.text. On chat clients, put tools in the options dict and enable streaming. On agents, tools stays a keyword argument on run. Messages unify as Message with role and typed Content, replacing AutoGen’s TextMessage / MultiModalMessage and source field.
# Assume we have client, agent, and tools from previous examples
async def streaming_example():
# Chat client streaming - tools go in options dict
async for chunk in client.get_response(
"Hello",
options={"tools": tools},
stream=True,
):
if chunk.text:
print(chunk.text, end="")
# Agent streaming - tools can be keyword arg on agents
async for chunk in agent.run("Hello", tools=tools, stream=True):
if chunk.text:
print(chunk.text, end="", flush=True)
Replace FunctionTool wrapping
Decorate functions with @tool and pass them on the agent; schemas are inferred. Parameter descriptions can use Annotated and pydantic Field. Agent Framework continues tool execution until completion by default.
Hosted tools are exclusive. Create them from a Responses client that supports them; verify entitlements—not every model offers web search and code interpreter. AutoGen’s local code execution tools are planned for later Agent Framework versions.
from agent_framework.openai import OpenAIChatClient
# Responses client with a model that supports hosted tools
client = OpenAIChatClient(model="gpt-5")
# Hosted tools are created from the client
code_tool = client.get_code_interpreter_tool()
search_tool = client.get_web_search_tool()
agent = client.as_agent(
name="researcher",
instructions="Use the available hosted tools to research answers.",
tools=[code_tool, search_tool]
)
For agent-as-a-tool, AutoGen required parallel_tool_calls=False on the coordinator client; Agent Framework as_tool() does not, because agents are stateless by default. Middleware (logging, filtering, retries) is an Agent Framework feature AutoGen does not have.
Multi-agent: follow the official mapping
Do not look for a Team drop-in. The official guide’s multi-agent mapping is Workflow vs GraphFlow (visual overview and code comparison), nesting patterns, and group-chat counterparts for RoundRobinGroupChat and MagenticOneGroupChat. Human-in-the-loop is documented as Workflow request-response, with checkpointing and resume samples in the Agent Framework repository. Use those pages after the single-agent cutover so you remap control flow instead of inventing a new graph.
Next step: Open the AutoGen migration guide on Microsoft Learn. Recreate one assistant with OpenAIChatCompletionClient or OpenAIChatClient, @tool, and AgentSession, then follow its Workflow vs GraphFlow and group-chat sections—and the runnable Python samples it links—before you retire production AssistantAgent and GroupChat code.