subagentic.ai
How to migrate AutoGen agents to Microsoft Agent Framework

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

autogenmicrosoft-agent-frameworkmigrationpythonmulti-agent

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:

  1. Orchestration. AutoGen pairs an event-driven core with a high-level Team. Agent Framework centers on a typed, graph-based Workflow that routes data along edges and activates executors when inputs are ready.
  2. 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.
  3. Agent behavior. AssistantAgent is single-turn unless you increase max_tool_iterations. Agent is multi-turn by default and keeps invoking tools until it can return a final answer (with built-in safety against infinite loops).
  4. 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.

Sources