1. See What A Multi-Agent Prototype Lacks In Production

Suppose a researcher gathers evidence, a writer drafts the report, and a reviewer approves it. A prototype already looks convincing when the researcher can hand results to the writer and the writer can send a draft to the reviewer. AutoGen is valuable because it makes this question explicit: who sends which message to whom, and what should the recipient do next?

Production introduces a different set of failures. The service restarts before approval; a user returns the next day and the system cannot find the paused task; Web, Teams, and API endpoints duplicate integration code; or a reviewer supplies feedback and the whole report starts again. The missing piece is no longer another agent. It is a runtime that records progress, pauses, resumes, and connects channels consistently.

2. Learn The Six Concepts Used Throughout This Chapter

Put the two generations on one map before reading class names. Every source detail later in the chapter implements one of these six ideas:

  • AutoGen focuses on how multiple agents collaborate through messages, making it useful for research and conversational prototypes.
  • Message runtime is the team's internal post office: it accepts messages, queues them, finds recipients, and invokes their handlers.
  • Team conversation organizes researcher, writer, and reviewer by deciding who speaks, who takes over, and when the task ends.
  • MAF is Microsoft's newer framework for production agents and multi-agent workflows.
  • Workflow and checkpoint make steps, branches, and pauses explicit; a checkpoint is a saved point from which work can resume.
  • Hosting connects the same agent or workflow to different channels while managing sessions, recovery, and runtime state.

AutoGen's README sets the boundary clearly: AutoGen is now in maintenance mode. It will not receive new features, new users should start with Microsoft Agent Framework, and existing users are encouraged to migrate. The same notice calls MAF the enterprise-ready successor, with stable APIs, long-term support, multi-agent orchestration, multi-provider model support, and interoperability through A2A and MCP. Source: AutoGen README maintenance notice.

MAF's own README is not written like a simple AutoGen rename. It describes Microsoft Agent Framework as an open, multi-language framework for production-grade AI agents and multi-agent workflows in Python and .NET. It fits teams that need production operation, orchestration beyond a single prompt or stateless chat loop, graph patterns, durability, restartability, observability, governance, human-in-the-loop control, and provider flexibility. Source: MAF README overview.

3. Run The Same Report Once In Each Implementation

This is one logical task implemented and run twice, not a live run that starts in AutoGen and migrates midway into MAF. The AutoGen prototype exposes team messages and role rules. The MAF production version reimplements the same goal with approval, checkpoint, and publication receipt inside an explicit Workflow.

3.1 AutoGen Prototype Run

  1. The user asks for research on three competitors. The example chooses a specific AgentChat Team pattern and calls team.run(...).
  2. The researcher publishes findings, and the team rule hands them to a writer.
  3. The writer produces a draft, the lead receives a review message, and the Team reaches its termination condition.
  4. If later recovery is required, the application calls save_state, persists the result, and calls load_state before resuming in a new process.

3.2 MAF Production Run

  1. A new request enters MAF Hosting. The host target is explicitly a Workflow, not a runtime choice between Agent and Workflow.
  2. The Workflow records research, writing, review, and publishing, then emits request-info and a checkpoint before review.
  3. The lead responds later; the caller resumes the same Workflow through responses or checkpoint id.
  4. A publisher executor performs the external publication after approval and stores its receipt. Only that receipt advances approved to published.

Restart recovery has prerequisites: Hosting needs durable checkpoint storage, such as the applicable state_dir/checkpoint_location, plus a stable isolation key. State left only in memory disappears with the process. The presence of a checkpoint parameter alone is not proof of cross-process recovery.

Reading contract. Keep AutoGen's historical value in view: it makes the multi-agent message runtime unusually legible. Then read MAF through its newer production boundary: Agent.run, Workflow.run, orchestration builders, checkpoints, HITL, and host channels. The important change is not the project name; it is where runtime responsibility and recoverable state live.

Evidence boundary. AutoGen links are pinned to public snapshot 027ecf0a379bcc1d09956d46d12d44a3ad9cee14. Microsoft Agent Framework links are pinned to public snapshot a9e5f6d7985a555d042ff807995da7ca908f86d2. Production orchestration surface is my engineering reading of the public positioning and visible source ownership.

Use the same researcher-writer-reviewer task and the migration line becomes a change in state ownership, not just a change in class names:

AutoGen prototype
  User message
    -> SendMessageEnvelope(message, recipient, future)
    -> runtime queue
    -> MessageContext(is_rpc=True)
    -> RoutedAgent handler
    -> ResponseMessageEnvelope

  Team chat
    -> group topic / manager topic / participant topics
    -> embedded runtime publishes messages
    -> team save_state / load_state

MAF production route (a separate implementation)
  channel request
    -> AgentFrameworkHost
    -> ChannelContext.run_stream(...)
    -> Workflow.run(message=...) or Workflow.run(checkpoint_id/responses=...)
    -> status / request_info / checkpoint events
    -> channel response and durable recovery point

On the AutoGen side, the important shape is envelope, topic, and handler. On the MAF side, the important shape becomes hosted channel, session, workflow checkpoint, and HITL continuation. Keeping that difference in view prevents "multi-agent chat" and "production orchestration" from collapsing into the same idea.

4. Set The Migration Boundary

AutoGen's "Why AutoGen?" section still matters because it captures the design that made the project influential. Core API implements message passing, event-driven agents, local and distributed runtime, and .NET/Python support. AgentChat is the simpler opinionated API on top of Core, familiar to v0.2 users and supporting two-agent chats and group chats. Extensions provide LLM clients, AzureOpenAI, OpenAI, code execution, and other integrations. Source: AutoGen layered design.

The same README also cautions that AutoGen Studio is for rapid prototyping and demos, not a production-ready app; deployed applications must implement authentication, security, and related features themselves. Source: AutoGen Studio caution. That keeps the comparison honest: AutoGen Studio is not the same kind of surface as MAF Hosting.

Read AutoGen Runtime First

  • Core: send / publish / topic
  • AgentChat: ChatAgent / Team
  • Extensions: LLM clients / tools

Read MAF Production Surface First

  • Agent: client / tools / session
  • Workflow: graph / checkpoint / HITL
  • Hosting: channels / state / checkpoint

5. AutoGen Core Owns The Message Runtime

AutoGen Core is easiest to understand as an agent message center. It has to distinguish a direct request to one agent from an event sent to every subscriber of a topic. It also has to know how an agent type is created and how hosted agent state is saved and restored.

Operation Mental model What the runtime owns
send_message A point-to-point request, similar to RPC. Locate the target agent, await its response, and return that response to the caller.
publish_message An event sent to a topic. Resolve subscribers through the subscription manager and deliver the event to each of them.
registration / state Hand an agent to the runtime for hosting. Create agent instances and save or restore runtime-owned agent state.

Those responsibilities are visible in the AgentRuntime protocol: send_message and publish_message, agent registration, and runtime state.

SingleThreadedAgentRuntime is the reference implementation. It processes PublishMessageEnvelope, SendMessageEnvelope, and ResponseMessageEnvelope through one asyncio queue while tracking agent factories, instantiated agents, intervention handlers, a subscription manager, serialization registry, and tracing helper. Its docstring says it is suitable for development and standalone applications, not high-throughput or high-concurrency scenarios. Sources: runtime notes and runtime fields.

The send and publish paths are sharply different. send_message creates a future, queues a direct envelope, and waits for a response. publish_message queues a topic envelope and expects no response. Direct processing builds MessageContext(is_rpc=True) and wraps the handler output as a ResponseMessageEnvelope. Publish processing asks the subscription manager for recipients, builds MessageContext(is_rpc=False), and invokes subscribed agents concurrently. Sources: send / publish queueing, direct processing, and publish processing.

6. RoutedAgent Turns Handlers Into Typed Routes

AutoGen Core is not just string dispatch. The @message_handler decorator reads function type hints, records target message types and return types, and checks both input and output types at runtime. @event is the publish-event variant: it requires None return values and gates on ctx.is_rpc so RPC messages do not hit event handlers. Sources: @message_handler contract and @event contract.

That is the core AutoGen flavor. An agent is not just a single LLM call. It is an actor-like object scheduled by message type, topic, and RPC/event semantics. This explains why AutoGen remains useful for understanding multi-agent conversation and research-oriented collaboration patterns, and why authentication, channels, and durable service ownership were not the Core runtime's center.

7. AgentChat Wraps The Runtime Into Team Conversations

AgentChat's ChatAgent protocol narrows the lower-level runtime into a developer-facing interface: an agent has name, description, produced_message_types, processes chat messages through on_messages or on_messages_stream, and supports reset, pause, resume, save_state, load_state, and close. Source: ChatAgent.

The group chat base class shows how AgentChat sits on Core. BaseGroupChat says participants share context by publishing messages. It maps AgentChat agents to the Core agent runtime and handles run, pause, resume, and reset. Each team gets unique topic types for the group, manager, participants, and output, then runs on an embedded SingleThreadedAgentRuntime. Sources: BaseGroupChat overview, topics and embedded runtime, and runtime registration and subscriptions.

So AutoGen's higher-level experience is not a separate DSL floating above Core. It builds round-robin, selector, swarm, and Magentic-One style team patterns out of topics, subscriptions, and routed agents. The README's multi-agent orchestration sample also shows AgentTool: wrap specialist agents as tools, then give them to a general assistant. Source: AutoGen AgentTool example.

7.1 The Application Still Owns AutoGen Recovery

pause/resume changes the current Team's running state, while save_state/load_state exports and imports state. The application still decides when to save, where to persist, and which record to load after restart. MAF Hosting can own Workflow checkpoints, but cross-process recovery exists only after durable storage and isolation identity are configured. Similar state APIs do not imply the same durability owner.

8. MAF Agent Combines Client, Tools, And Session

The MAF Python README starts with Agent(client=OpenAIChatClient(), instructions=...) and agent.run(...). It also shows direct chat client use through get_response without constructing an agent. That separation is important: the chat client adapts a model service; the agent adds tools, context, session, middleware, and telemetry. Source: Python quickstart and direct chat client.

Layer What it owns Why the split matters
Chat client Connect to a model provider and return a response or streaming updates. The same agent abstraction can change providers without binding application logic to one SDK.
Agent Manage instructions, tools, context providers, session, middleware, and telemetry. A model call is one step; the run also prepares context, invokes tools, and preserves session state.
as_tool Wrap one agent as a tool another agent can call. Multi-agent work can reuse ordinary tool semantics instead of always opening a group chat.

In source, the SupportsChatGetResponse protocol only requires get_response. It supports streaming and non-streaming calls with messages, options, compaction strategy, tokenizer, function invocation kwargs, and client kwargs. Agent.run prepares a run context, calls the downstream client's get_response, then parses ChatResponse or streaming updates into AgentResponse. Sources: SupportsChatGetResponse, Agent.run and client call, and response parsing.

BaseAgent owns id, name, description, context providers, middleware, session creation, and service session retrieval. RawAgent takes the client, instructions, tools, default options, context providers, middleware, compaction strategy, and tokenizer. It normalizes tools, separates MCP tools, and merges agent-level defaults into chat options. Sources: BaseAgent session and context and RawAgent setup.

MAF also makes agent delegation a first-class tool path. BaseAgent.as_tool wraps an agent as a FunctionTool, with approval mode, streaming callback, and optional parent-session propagation. Multi-agent collaboration does not have to start as group chat; it can also use ordinary tool invocation semantics. Source: BaseAgent.as_tool.

9. MAF Workflow Is A Graph Engine, Not A Chat Transcript

Workflow has a heavy docstring for a reason. It is a graph-based execution engine that connects executors with edge groups and uses a Pregel-like superstep model until the graph becomes idle. Executors run when they receive messages, send downstream messages with ctx.send_message(), yield workflow-level outputs with ctx.yield_output(), and add custom events with ctx.add_event(). Source: Workflow overview.

Its run API looks like a recoverable job interface rather than a normal chat loop. run supports an initial message, streaming, responses, checkpoint_id, checkpoint_storage, status event inclusion, and kwargs passed to subagent tools or clients. Validation forbids message together with responses or checkpoint_id, and requires at least one of message, responses, or checkpoint_id. Sources: Workflow.run and run parameter rules.

Workflow state is user-visible. The run stream emits started, status, request_info, and failed control events. If an executor requests outside input, the workflow can enter IDLE_WITH_PENDING_REQUESTS; the caller can later continue with run(responses=...), or restore from a checkpoint and provide responses. Checkpointing captures executor states, in-transit messages, and shared state for restart. Sources: request info and checkpointing, workflow status events, and core run continuation.

10. Orchestrations Are Prebuilt Graphs, Not A Second Runtime

The MAF README lists sequential, concurrent, handoff, and group collaboration as graph-based workflow patterns, with checkpointing, streaming, human-in-the-loop, and time-travel. The Python README lists advanced orchestration patterns as Sequential, Concurrent, Group Chat, Handoff, and Magentic. Sources: MAF key features and Python orchestration overview.

In source, SequentialBuilder resolves participants into executors. Agent-like participants become AgentExecutor; with request info enabled, they become AgentApprovalExecutor. It then uses WorkflowBuilder to add edges from input conversation through each participant. Sequential orchestration is therefore a workflow graph template. Sources: SequentialBuilder setup, participant resolution, and workflow build.

Human-in-the-loop also lands on workflow mechanics. AgentRequestInfoExecutor receives an agent response and calls ctx.request_info(...). If the user provides extra messages, execution returns to the agent executor; if not, it approves the original response. AgentApprovalExecutor wraps an internal workflow containing the agent executor and request-info executor loop. Sources: AgentRequestInfoExecutor and AgentApprovalExecutor.

For the report, that decision approves a draft; it does not publish it. A separate publisher executor consumes an approved draft. Requested changes return to the writer, rejection terminates publication, and approval permits the external publication call. Only a returned publication_id advances the Workflow to published. The draft being produced, the lead validating it, and the publication system adopting it are distinct states.

Group chat likewise does not return to AutoGen's topic runtime. It is expressed as orchestrator plus workflow graph. GroupChatOrchestrator uses a selection function to choose the next participant, broadcasts context, receives responses, saves conversation, checks termination or round limits, then continues. AgentBasedGroupChatOrchestrator asks an agent to produce the structured selection decision. Sources: group chat module overview, selection-function orchestrator, and group chat loop.

11. Hosting Connects Channels, Sessions, And Checkpoints

The MAF hosting package pushes the production story outward. The file-level docs describe AgentFrameworkHost as a Starlette wrapper. It accepts a hostable target, either a SupportsAgentRun agent or a Workflow, and a set of channels. Each channel contributes routes; the host gives channels a ChannelContext with run and run_stream. Sources: host module overview and ChannelContext.

The host constructor shows its workflow responsibilities: target can be agent or workflow; channels mount under channel paths; workflow targets can receive checkpoint_location or state_dir for cross-request checkpoint persistence; the host also manages session aliases and refuses double ownership when a workflow already has checkpoint storage. Sources: AgentFrameworkHost.__init__ and checkpoint ownership.

“Can receive” is the important qualifier. Hosting dispatches according to target type; this report selects Workflow. With state_dir=None and no external checkpoint storage, relevant host-managed state remains in memory and cannot survive process exit. A production-ready claim therefore needs storage, isolation identity, restart tests, and idempotent external publication together.

That is the practical shift from AutoGen to MAF. AutoGen centers multi-agent message runtime. MAF centers deployable agent and workflow surfaces, then connects similar collaboration capabilities to provider flexibility, HITL, checkpointing, channel hosting, and observability.

12. Place It Beside The Earlier Chapters

Framework Owner To Read First Best Question
AgentScope Agent turn ledger and OpenAI API adapters. How do message, tool, event, and context unify inside one turn?
ADK Python Code-first Agent + Workflow + Runner. How do autonomous agents and deterministic graphs share a service boundary?
Agno AgentOS platform control plane. Who owns APIs, storage, approval, RBAC, and interfaces?
AutoGen Core message runtime and AgentChat team. How do multi-agent conversations, topics, subscriptions, and group chats work?
Microsoft Agent Framework Agent, Workflow, Orchestrations, Hosting. How should new projects move agent systems toward production orchestration?

The next chapter moves to CrewAI. Its keywords are not runtime bus first, but role, task, crew, process, flow, knowledge, and memory: it models team collaboration directly as an agent application.

Sources