AutoGen to Microsoft Agent Framework: Step-by-Step Migration
Microsoft Agent Framework (MAF) reached general availability on April 3, 2026, and it is the direct successor to both AutoGen and Semantic Kernel, built by the same core teams (Source: Microsoft Agent Framework blog). AutoGen v0.4 is now in maintenance mode: Microsoft ships security fixes but no new features, so new multi-agent projects should start on MAF. If you are running AutoGen agents in production today, migrating to MAF 1.0 is now the supported path: the API is stable with a long-term-support commitment, and Build 2026 (June 3, 2026) added an Agent Harness for production context management, Foundry Hosted Agents with scale-to-zero deployment, and a CodeAct execution mode that had multi-step benchmarks running 52.4% faster (Source: Microsoft Agent Framework Build 2026 recap). This guide walks you through three phases of refactoring - agent instantiation, tool definition, and multi-agent coordination - with concrete before/after Python code verified against the official agent_framework package and Microsoft's own AutoGen migration guide.
Before You Start: Inventory and Validation
Understand what you are migrating. AutoGen deployments typically use AssistantAgent and UserProxyAgent classes paired with a dictionary-based llm_config for model and API settings. Semantic Kernel codebases organize logic into Plugin classes decorated with @kernel_function. Both patterns worked, but they diverge significantly from MAF's unified client model.
Start by auditing:
- How many agents run across your system? (MAF tracks agent identity; you will assign each one on creation.)
- How many share a single
llm_configor API key? (This shared-credential pattern is exactly what MAF eliminates via per-agent authentication.) - What tool framework do you use? (AutoGen's
FunctionToolobjects, Semantic Kernel's decorated plugin methods, or raw Python functions?) - Do you have test coverage for agent behavior, tool invocation, and multi-turn conversations? (You will want it when validating the migration.)
Watch for a naming trap first: pip install autogen on PyPI now resolves to the community AG2 fork, not Microsoft's own AutoGen, with no error or warning (Source: Alex Bevi migration analysis). If your requirements.txt pins bare autogen, confirm which package actually installed before you start mapping APIs.
Plan 2-3 days per agent for refactoring plus testing. Operator note (first-hand): migrate one agent end-to-end in a staging environment before rolling out to your fleet. Code that passes in AutoGen's loose llm_config dicts may fail in MAF's stricter client instantiation - particularly around credential passing, system message format, and tool schema validation. Test context persistence explicitly: create a session, send two messages, and confirm the agent recalls the first message in its response to the second.
Phase 1: Agent Instantiation and Client Setup
The biggest single change is authentication and client initialization. AutoGen relied on passing API keys and model metadata in dictionaries; MAF uses a client object that you create once and reuse across all agents.
From AutoGen to MAF
In AutoGen, you set up agents like this:
from autogen import AssistantAgent, UserProxyAgent
llm_config = {
"model": "gpt-4",
"api_type": "azure",
"api_base": os.getenv("AZURE_OPENAI_ENDPOINT"),
"api_key": os.getenv("AZURE_OPENAI_KEY"),
"api_version": "2024-08-01-preview"
}
assistant = AssistantAgent(
name="Assistant",
llm_config=llm_config,
system_message="You are a helpful assistant."
)
user_proxy = UserProxyAgent(
name="User",
human_input_mode="ALWAYS",
code_execution_config=False
)
In MAF, the pattern is a chat client plus an Agent object, confirmed against the agent_framework package on PyPI and Microsoft's own AutoGen migration guide (Source: Microsoft Learn migration guide):
from agent_framework.openai import OpenAIChatClient
from azure.identity import AzureCliCredential
client = OpenAIChatClient(
model="gpt-5",
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_version="2024-12-01",
credential=AzureCliCredential(),
)
agent = client.as_agent(
name="Assistant",
instructions="You are a helpful assistant."
)
# For multi-turn context, create a session and reuse it
session = agent.create_session()
Key differences:
- Credentials: AutoGen passed API keys as strings; MAF's Azure routing takes an explicit credential object such as
AzureCliCredential()fromazure-identity(orDefaultAzureCredential()in service environments with Managed Identity). Locally,az loginauthenticates via your default browser. - Agent vs. User: AutoGen's
UserProxyAgentwas a proxy for human input or code execution. MAF treats agents uniformly; if you need human-in-the-loop, you pause the orchestrator and prompt the user explicitly. - System message: AutoGen's
system_messageparameter becomesinstructionsin MAF. Same content, different name. - State is opt-in, not automatic: an
Agentis stateless by default (eachrun()call is independent); callagent.create_session()once and passsession=sessionon every subsequentrun()to persist conversation history, replacing AutoGen's manualChatHistorymanagement.
From Semantic Kernel to MAF
If you are using Semantic Kernel, the shift is similar in spirit but different in practice:
AutoGen (before):
from semantic_kernel import Kernel
from semantic_kernel.services import AzureOpenAIChatCompletion
kernel = Kernel()
service = AzureOpenAIChatCompletion(
api_key=os.getenv("AZURE_OPENAI_KEY"),
endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
deployment_id="gpt-4"
)
kernel.add_service(service)
chat_history = ChatHistory()
chat_history.add_user_message("Summarize the main themes...")
result = await kernel.invoke_prompt("{{$input}}", input="...")
MAF (after):
from agent_framework.openai import OpenAIChatClient
from azure.identity import AzureCliCredential
client = OpenAIChatClient(
model="gpt-5",
azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
api_version="2024-12-01",
credential=AzureCliCredential(),
)
agent = client.as_agent(
name="Summarizer",
instructions="You are a concise summarizer."
)
response = await agent.run("Summarize the main themes...")
The Kernel object disappears; you work directly with the client and agent. The invoke_prompt call becomes a simple agent.run() call. Semantic Kernel's service registration abstraction is gone - the client handles it (Source: Nithin Mohan TK, dataa.dev migration series).
Phase 2: Tools and Function Definition
Tools changed most visibly. AutoGen required you to wrap Python functions in FunctionTool objects with explicit schema dictionaries. Semantic Kernel used class-based Plugin decorators. MAF unified both under a single @tool decorator and Pydantic-based parameter documentation.
AutoGen FunctionTool to MAF @tool
In AutoGen:
from autogen import FunctionTool
def get_weather(city: str) -> str:
"""Get the current weather for a city."""
import requests
response = requests.get(f"https://api.weather.example.com/current?q={city}")
return response.json().get("description", "Unknown")
weather_tool = FunctionTool(
func=get_weather,
description="Fetch the current weather for a given city",
schema={
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "Name of the city (e.g., San Francisco)"
}
},
"required": ["city"]
}
)
# Pass to agent when you create it
assistant = AssistantAgent(name="Assistant", llm_config=..., tools=[weather_tool])
In MAF:
from agent_framework import tool
from typing import Annotated
from pydantic import Field
@tool
def get_weather(city: Annotated[str, Field(description="Name of the city (e.g., San Francisco)")]) -> str:
"""Get the current weather for a city."""
import requests
response = requests.get(f"https://api.weather.example.com/current?q={city}")
return response.json().get("description", "Unknown")
# Pass function reference directly
agent = client.as_agent(name="Assistant", tools=[get_weather])
The advantages are clear:
- No schema dict: Type hints and Pydantic's
Field()replace the verbose JSON schema. - No wrapper object: The
@tooldecorator sits on the function itself, not a separate class. - Automatic registration: Pass the function straight into the
toolslist; MAF inspects the signature. - Cleaner type-checking: Type hints are Python-native and IDE-discoverable.
The migration path is straightforward: unwrap each FunctionTool, move the description from the schema dict to Field(description="..."), and apply the @tool decorator (Source: Microsoft Learn migration guide).
Semantic Kernel Plugins to MAF Tools
Semantic Kernel plugins were class-based:
from semantic_kernel.functions import kernel_function
from semantic_kernel.functions.kernel_function_decorator import kernel_function
class WeatherPlugin:
@kernel_function(description="Get weather for a city")
def get_weather(self, city: str) -> str:
"""Fetch the current weather."""
...
kernel.add_plugin(WeatherPlugin(), "weather")
In MAF, you move the method out of the class:
from agent_framework import tool
from typing import Annotated
from pydantic import Field
@tool
def get_weather(city: Annotated[str, Field(description="Name of the city")]) -> str:
"""Fetch the current weather."""
...
agent = client.as_agent(name="...", tools=[get_weather])
The [Description] attributes in C# or docstrings in Python become Field(description="...") in the annotation. That is the essence of the change (Source: Microsoft Learn migration guide).
Phase 3: Multi-Agent Orchestration and Workflows
The third and most consequential shift is how agents coordinate. AutoGen's GroupChat was a messaging loop with heuristics (round-robin, max rounds, speaker selection). MAF replaces it with explicit orchestrator classes and workflow definitions.
In AutoGen:
from autogen import GroupChat, GroupChatManager
group_chat = GroupChat(
agents=[researcher, writer, editor],
messages=[],
max_round=5,
speaker_selection_method="round_robin"
)
manager = GroupChatManager(groupchat=group_chat, llm_config=llm_config)
# Kick off the chat
user_proxy.initiate_chat(
manager,
message="Write a blog post about AI agents. When done, announce FINAL ANSWER."
)
# Extract final output
last_msg = assistant.last_message() # or similar
In MAF:
from agent_framework.orchestrations import SequentialBuilder
workflow = SequentialBuilder(participants=[researcher, writer, editor]).build()
async for event in workflow.run(
"Write a blog post about AI agents. When done, announce FINAL ANSWER.",
stream=True,
):
if event.type == "output":
final_messages = event.data # list[Message]
The difference is declarative vs. imperative. AutoGen's GroupChat was a live message loop with heuristic speaker selection. MAF's orchestrations module is explicit and confirmed live in the official migration guide (Source: Microsoft Learn migration guide):
- Sequential (
SequentialBuilder): each agent runs in order; output from one becomes input to the next. - Concurrent (
ConcurrentBuilder): all agents run in parallel, then results are combined (useful for independent research tasks). - Magentic (
MagenticBuilder): a manager agent dynamically plans and delegates across specialist agents, with round/stall/reset limits and optional human-in-the-loop plan review, roughly comparable to LangGraph-style state management. - Custom
WorkflowBuildergraphs: connect executors with typed edges for bespoke topologies, with built-in checkpointing viaFileCheckpointStorage.
Handoff-style, condition-based delegation (AutoGen's Swarm-equivalent) is on the roadmap: Microsoft's Build 2026 recap names a Handoff pattern reaching 1.0, but the AutoGen migration guide itself still lists Swarm-based handoff under "future patterns" as of its June 26, 2026 update (Inference: treat Handoff as rolling out rather than universally available; verify against your installed agent-framework version before depending on it).
For a blog-writing pipeline (research -> draft -> edit), SequentialBuilder is the right choice. For parallel research across multiple sources, use ConcurrentBuilder and feed the combined results to a synthesis step.
Testing and Validation Checklist
Validate the migration systematically:
- Imports resolved: No remaining
from autogen importstatements. Check thatagent-frameworkandazure-identitypackages are installed (pip install agent-framework azure-identity). - Credentials work: Run
AzureCliCredential()(orDefaultAzureCredential()on Azure compute) and confirm it finds credentials. If using local development, runaz login. - Agent creation succeeds: Call
client.as_agent(...)and verify the returned object hasname,instructions, andtoolsset as expected. - Tool invocation: Call each
@tool-decorated function directly in Python to confirm it works, then pass it to an agent and check the agent can invoke it. - Context persistence: Create a session with
agent.create_session(), send message A ("My favorite color is blue"), send message B ("What is my favorite color?") with the samesession=, confirm the agent answers correctly. - Workflow execution: Run the orchestrator with a 3-agent pipeline and confirm each agent runs in order and passes output forward.
- Error messages: Test failure paths: missing credentials, invalid model name, tool that raises an exception. Confirm errors are clear, not silent hangs.
Common Pitfalls and Fixes
- "ModuleNotFoundError: No module named 'agent_framework'": Install via
pip install agent-framework azure-identity(PyPI package isagent-framework; the import isagent_framework, underscore not hyphen). - "Agent refuses to invoke tools": Ensure tool function names and signatures match exactly. MAF is strict about type hints; if a tool expects
strand the agent passesint, it will fail. - "Agent forgets the previous message":
Agentis stateless by default. Create onesession = agent.create_session()and passsession=sessionon everyrun()call; a fresh session per message discards history. - "Magentic workflow hangs waiting for human input": pass
.with_human_input_on_stall()explicitly and handle therequest_infoevent; the default is fully autonomous with no pause points. - "Cannot find my system message in the response": MAF calls it
instructions, notsystem_message. Update youras_agent()orAgent()call. - "Tool returns a complex object and the agent chokes": MAF requires tools to return JSON-serializable types. If you return a Pandas DataFrame or custom class, serialize it first (to dict or JSON string).
AutoGen vs Microsoft Agent Framework
AutoGen is not gone, but it is no longer where Microsoft ships new agent features. AutoGen v0.4 sits in maintenance mode: the GitHub repo still takes security patches, but Agent Harness, Foundry Hosted Agents, CodeAct, and every other capability announced at Build 2026 land in Microsoft Agent Framework only (Source: Microsoft Agent Framework blog).
Microsoft's own migration guide at learn.microsoft.com is comprehensive on API mechanics: it walks through model clients, single-agent features, and multi-agent workflows side by side, autogen next to agent_framework (Source: Microsoft Learn migration guide). What it does not do is tell you whether to migrate yet, or flag the rough edges you will hit mid-project. Three gaps this guide fills that the official one does not:
- The PyPI naming collision (
pip install autogeninstalls AG2, a different project) is a support-ticket-generating trap the official guide never mentions. - Provider parity gaps: Agent Framework's direct chat-client classes cover OpenAI and Azure OpenAI today; Anthropic and Ollama are marked planned in the same migration guide's own comparison table, even though the broader MAF 1.0 announcement lists both as supported through Microsoft Foundry's model routing. If you call Anthropic or Ollama directly rather than through Foundry, budget time to verify client support before you commit a team to the migration.
- Handoff-based delegation status: Build 2026's recap names Handoff as reaching 1.0, but the AutoGen migration guide (updated June 26, 2026) still lists Swarm-style handoff under "future patterns." Treat it as rolling out, not universally shipped, until you confirm it against your installed
agent-frameworkversion.
If you are choosing between staying on AutoGen or moving to MAF: stay only if you have no near-term feature roadmap and cannot spare 2-3 days per agent; migrate if you plan to keep building, since AutoGen will not receive Agent Harness, Hosted Agents, or CodeAct.
FAQ
Q: Is AutoGen deprecated?
Not deprecated, but in maintenance mode. Microsoft's core AutoGen and Semantic Kernel teams now build Microsoft Agent Framework instead; AutoGen v0.4 gets security fixes, not new features (Source: Microsoft Agent Framework blog).
Q: What does AutoGen maintenance mode mean for existing projects?
Existing AutoGen deployments keep running and keep receiving security patches, but new capabilities (Agent Harness, Foundry Hosted Agents, CodeAct, Handoff orchestration) ship in MAF only. Plan new multi-agent work on MAF; migrate existing AutoGen systems on your own timeline once you have staging validation in place.
Q: Does MAF run my existing AutoGen code unchanged?
No. The agent and tool APIs diverged enough that you need to refactor. Expect 2-3 days per agent, plus testing.
Q: Can I use MAF with my existing Azure OpenAI setup?
Yes, but authentication changes from explicit API keys to a credential object: AzureCliCredential() for local development or DefaultAzureCredential() on Azure compute (VMs, containers, App Service), which resolves Managed Identity automatically.
Q: What if my multi-agent logic is more complex than Sequential or Concurrent?
Use MagenticBuilder for manager-led dynamic delegation with round/stall/reset limits, or build a custom topology with WorkflowBuilder and typed executor edges. Both support checkpointing via FileCheckpointStorage for resumable long-running workflows.
Q: Is migration reversible?
No. Once you refactor to MAF, reverting to AutoGen is impractical. Test thoroughly in staging before production rollout.
Q: Does this guide cover C#?
The steps are identical in C#, but syntax differs. The patterns - client creation, agent instantiation, tool definition, orchestrator setup - are language-agnostic. Check the Microsoft Foundry docs for C# examples.
Q: What about support for non-Azure models?
MAF's broader platform integrates OpenAI, Anthropic Claude, Amazon Bedrock, Google Gemini, and Ollama through Microsoft Foundry model routing (Source: Microsoft Agent Framework blog). Direct, non-Foundry chat-client classes are confirmed for OpenAI and Azure OpenAI today; verify current client support for other providers against your installed agent-framework version before committing.
Related coverage
- AI Agent Framework Status 2026: Maintained, Deprecated, Archived - Where AutoGen, AG2, LangGraph, and Mastra each stand today.
- Pydantic AI vs Microsoft Agent Framework: Which in 2026 - A typed, model-agnostic alternative to MAF for teams not locked into the Microsoft stack.
- Pydantic AI vs AutoGen: Which Agent Framework Wins in 2026 - If you are leaving AutoGen, how it compares against a non-Microsoft typed framework.
References
- Alex Bevi - Two Lineages, One Framework: How AutoGen and Semantic Kernel Became the Microsoft Agent Framework (alexbevi.com, June 2026)
- Microsoft Agent Framework - Microsoft Agent Framework Version 1.0 general availability announcement (devblogs.microsoft.com, April 2026)
- Microsoft Agent Framework - Build 2026 announcement recap: Agent Harness, Hosted Agents, CodeAct (devblogs.microsoft.com, June 2026)
- Microsoft Learn - AutoGen to Microsoft Agent Framework Migration Guide (learn.microsoft.com, updated June 2026)
- Nithin Mohan TK - Migration Guide: From Semantic Kernel & AutoGen to Microsoft Agent Framework, Part 10 (dataa.dev, November 2025)



