Contents
Figure 1: A team is a conversation with rules — who speaks next, and when it stops
You want two AI agents to argue, one to draft and one to critique, until the answer improves. AutoGen made that pattern easy, and it still works. Before you invest, though, you should know one fact up front: AutoGen is now in maintenance mode.
This tutorial teaches the current AutoGen AgentChat API, since plenty of teams still run it and its ideas carry over to other frameworks. It also tells you where Microsoft points new projects. You'll build a writer-and-critic pair, then a three-agent team with a smart speaker selector.
The Status Check You Need
AutoGen's repository says the project is in maintenance mode: no new features or enhancements, and community-managed from here. It directs new users to Microsoft Agent Framework, a .NET and Python framework for agents and multi-agent workflows, and links a migration guide for existing AutoGen users.
So why learn AutoGen at all? Three reasons:
- Existing code: Plenty of teams run AutoGen today and need to read and maintain it.
- Transferable ideas: Teams, termination conditions, and speaker selection show up in every multi-agent framework, including the CrewAI crews you may meet next.
- Migration prep: You can't move a codebase you don't understand.
If you start a brand-new production project, evaluate Agent Framework first. Note that a community fork called AG2 also continues the older AutoGen 0.2 line, so check which package a tutorial targets before you copy code. The wider framework comparison in this series covers how these options stack up.
What AutoGen Does
AutoGen lets you create agents that talk to each other in a shared conversation. Each agent wraps an LLM with a system message and optional tools. A team coordinates who speaks next and decides when the conversation ends.
The current AgentChat API is async. You write async def functions and run them with asyncio.run. That surprises people coming from simpler frameworks, so get comfortable with it early.
Setup
AutoGen needs Python 3.10 or later. Install the agent layer and the OpenAI client extension:
pip install -U "autogen-agentchat" "autogen-ext[openai]"
Export your key as OPENAI_API_KEY, since the examples call the OpenAI API. Other model providers have their own client classes in the extension package, so check the docs for yours.
Step 1: Run One Agent
Start with the smallest possible program. This hello-world comes from the project's README:
import asyncio
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
async def main() -> None:
model_client = OpenAIChatCompletionClient(model="gpt-4.1")
agent = AssistantAgent("assistant", model_client=model_client)
print(await agent.run(task="Say 'Hello World!'"))
await model_client.close()
asyncio.run(main())
Three details matter here. The model client holds the connection to the LLM, the agent adds a name and behavior, and await model_client.close() releases the connection. Forget that last line and you leak resources.
Step 2: Build a Writer-Critic Team
One agent talking to itself isn't a conversation. A team lets agents take turns. The simplest team, RoundRobinGroupChat, rotates through its members in order:
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_agentchat.teams import RoundRobinGroupChat
from autogen_agentchat.ui import Console
writer = AssistantAgent(
"writer",
model_client=model_client,
system_message="You write a short, clear paragraph on the topic you are given. Revise it when the critic gives feedback.",
)
critic = AssistantAgent(
"critic",
model_client=model_client,
system_message="Give one concrete piece of feedback at a time. Reply with 'APPROVE' once your feedback is addressed.",
)
stop = TextMentionTermination("APPROVE") | MaxMessageTermination(max_messages=8)
team = RoundRobinGroupChat([writer, critic], termination_condition=stop)
await Console(team.run_stream(task="Explain what a vector database does."))
The writer drafts, the critic responds, and the loop continues until someone says the magic word. Why do two mediocre prompts beat one good one? The critic sees the draft cold, with no investment in defending it.
Step 3: Control When It Stops
Termination conditions are the most important safety feature in a team. Without one, two agents can politely thank each other forever, and you pay for every message.
The docs show two ways to stop:
- Text mention:
TextMentionTermination("APPROVE")ends the run when a message contains that word. - Combination: Join conditions with the
|operator to stop on whichever fires first.
The docs' own example pairs a text trigger with an external termination object you can fire from your app. This example adds MaxMessageTermination as a hard cap, imported from the same conditions module — confirm the max_messages argument name in your installed version.
Always set a hard cap. A text trigger alone is wishful thinking, because an LLM sometimes never says the word.
Step 4: Watch the Conversation
You have two ways to run a team. await team.run(task=...) returns a result once the team stops. team.run_stream(task=...) yields each message as it arrives, and wrapping it in Console prints them nicely.
Use the stream while you build. Reading the live exchange tells you why the team drifts, which a final result can't. If you stream manually, the final item is a TaskResult with a stop reason, so you can see which condition ended the run.
Teams keep state between runs. Call await team.reset() before you reuse a team on an unrelated task, or old context leaks into the new one.
Step 5: Add a Tool
Agents get more useful with tools. This one counts words, so the writer can check its own length:
async def word_count(text: str) -> str:
"""Count the words in a piece of text."""
return f"{len(text.split())} words"
writer = AssistantAgent(
"writer",
model_client=model_client,
tools=[word_count],
reflect_on_tool_use=True,
system_message="Write a 150-word brief from the notes. Check the length with your tool.",
)
The agent reads the function's name, type hints, and docstring to decide when to call it, so write them carefully. Test the tool pattern against your installed version before you rely on it — extension APIs move quickly.
Step 6: Let a Model Choose Who Speaks
Round-robin is rigid. SelectorGroupChat lets a model pick the next speaker based on the conversation so far. By default, it reads each agent's name and description, so write good descriptions:
from autogen_agentchat.teams import SelectorGroupChat
planner = AssistantAgent("planner", model_client=model_client,
description="Breaks the topic into steps.")
researcher = AssistantAgent("researcher", model_client=model_client,
description="Gathers facts and sources.")
writer = AssistantAgent("writer", model_client=model_client,
description="Writes the final draft from the notes.")
team = SelectorGroupChat(
[planner, researcher, writer],
model_client=model_client,
termination_condition=TextMentionTermination("DONE") | MaxMessageTermination(max_messages=12),
allow_repeated_speaker=False,
)
By default, the same agent doesn't speak twice in a row unless it's the only one available. The allow_repeated_speaker=True option lifts that rule. You can also supply your own selector_prompt with {participants}, {roles}, and {history} placeholders to steer the choice.
Step 7: Override the Selector With Code
Sometimes you know the right order better than an LLM does. A selector_func takes over:
def selector_func(messages):
if messages[-1].source != planner.name:
return planner.name
return None
This function sends the floor back to the planner after anyone else speaks. Returning None hands the decision back to the model. Per the docs, candidate_func is a softer option that narrows the choices and lets the model pick among them, and you can't set both.
Hard-code the predictable parts, and let the model decide the rest. Mixing the two modes is usually the pragmatic answer.
Where Microsoft Agent Framework Fits
Agent Framework is the successor the AutoGen repository points to. It supports Python and C#/.NET and describes itself as a framework for production-grade agents and multi-agent workflows. Its README highlights graph-based workflows with sequential, concurrent, handoff, and group collaboration patterns, plus checkpointing, streaming, and human-in-the-loop control — features that will look familiar if you've read the LangGraph tutorial in this series.
Its Python install is pip install agent-framework, and the README's hello-world uses a different client and agent class from AutoGen's. That means migration isn't a rename. Read Microsoft's AutoGen migration guide before you move anything.
Design Tips That Hold Up
- Keep teams small. Two to four agents handle most jobs, and each extra agent adds cost and noise.
- Write sharp descriptions. The selector relies on them.
- Cap every run. Pair a text trigger with a message limit.
- Reset between tasks. Stale context causes strange behavior.
- Log the conversation. You'll need the transcript when something breaks.
Common Pitfalls
- Forgetting to close the model client. It leaks connections.
- Relying on a text trigger alone. The word may never appear.
- Giving agents vague roles. Overlapping roles produce loops.
- Skipping a single-agent baseline. A team that doesn't beat one good prompt isn't worth its cost.
- Copying code across versions. AutoGen 0.2 examples, AG2 examples, and the current AgentChat API differ, so match the package to the tutorial.
Recommended Books
| Cover | Book | Description | Get it |
|---|---|---|---|
![]() |
AI Agents in Action | - hands-on coverage of agent conversations, tools, and team patterns. | View on Amazon |
![]() |
Designing Agentic AI Systems | - architecture decisions for roles, handoffs, and multi-agent design. | View on Amazon |
![]() |
AI Engineering | - production context for when a team of agents is worth the cost. | View on Amazon |
Unlock AI That Actually Works
Get lifetime access to GPT-6 Astra, Claude Fable 5.1, Gemini 3.5, Grok 4.5, and more — all in one platform. Build websites, apps, videos, content, and digital products from a single command. No monthly fees. No tool-hopping.
Click here to get GPTAstra Max now — one-time payment, lifetime access.
Frequently Asked Questions
Is AutoGen dead? Should I still learn it?
It's in maintenance mode, not dead. No new features, community-managed, and Microsoft points new projects at Microsoft Agent Framework. Learn it if you maintain existing AutoGen code, if your team uses it today, or because its ideas — teams, termination conditions, speaker selection — transfer to every multi-agent framework. For brand-new production work, evaluate Agent Framework first.
What's the difference between AutoGen 0.2, AG2, and the current AgentChat API?
AutoGen 0.2 is the older API that many tutorials still show. AG2 is a community fork that continues that 0.2 line. The current AutoGen package (autogen-agentchat) is the AgentChat API this tutorial uses — async-first, different imports, different team classes. Always check which package a tutorial targets before copying code; the APIs are not interchangeable.
Why do termination conditions matter so much?
Without one, two polite agents can thank each other forever and you pay for every message. Pair a text trigger like TextMentionTermination("APPROVE") with a hard MaxMessageTermination cap joined by the | operator. The text trigger alone is wishful thinking — an LLM sometimes never says the word.
Round-robin or SelectorGroupChat — which should I use?
Round-robin when the order is fixed and known (a writer-critic loop). SelectorGroupChat when the next speaker should depend on the conversation — it reads each agent's name and description to choose. You can also override the choice entirely with a selector_func, or narrow the options with candidate_func; you can't set both.
Wrapping This Up
AutoGen's lasting lessons are simple: agents are LLMs with roles, teams manage the turns, and termination conditions keep the bill sane. Learn those, and you can move between frameworks without starting over — the same anatomy the from-scratch agent guide makes you write by hand. For new production work, look at Microsoft Agent Framework first, and use AutoGen when you maintain existing code.
Build the writer-critic pair this week, then compare its paragraph against a single-prompt version. If the pair doesn't win, simplify before you add a third agent. New to multi-agent ideas? The beginners guide covers the fundamentals these teams sit on.

