AutoGen’s sequential chat and group chat solve different coordination problems. Sequential chat enforces a fixed speaking order — useful for pipelines where each agent transforms the artifact before passing it forward. Group chat lets agents bid for the floor dynamically, which fits open-ended collaboration but introduces nondeterminism. Understanding the trade-offs saves you from fighting the framework.
What sequential chat does
Sequential chat implements a deterministic pipeline. You define an ordered list of agents, and the framework cycles through them until a termination condition fires. Each agent sees the full conversation history but speaks only when its turn arrives.
from autogen import Agent, UserProxyAgent, register_function
coder = Agent(
name="coder",
system_message="Write Python code. Return only the code block.",
llm_config={"model": "gpt-4o-mini"},
)
reviewer = Agent(
name="reviewer",
system_message="Review code for bugs and style. Return fixes only.",
llm_config={"model": "gpt-4o-mini"},
)
tester = Agent(
name="tester",
system_message="Write pytest tests for the code. Return only tests.",
llm_config={"model": "gpt-4o-mini"},
)
user_proxy = UserProxyAgent(
name="user",
human_input_mode="NEVER",
code_execution_config={"use_docker": False},
)
chat = user_proxy.initiate_chat(
recipient=coder,
message="Implement a LRU cache with O(1) get/put",
max_turns=2,
)
# Manual sequencing for more control
from autogen import ConversableAgent
def run_pipeline(task: str):
agents = [coder, reviewer, tester]
history = [{"role": "user", "content": task}]
for agent in agents:
response = agent.generate_reply(messages=history)
history.append({"role": "assistant", "content": response, "name": agent.name})
return history
The key constraint: agent N cannot react to agent N+1’s output in the same round. If the reviewer catches a bug, the coder won’t see that feedback until the next full cycle. This makes sequential chat predictable but rigid.
What group chat does
Group chat introduces a speaker selection mechanism. After each turn, a selector function decides who speaks next based on the conversation state. The default auto selector uses an LLM to pick the most relevant agent; you can also use round_robin, random, or a custom callable.
from autogen import GroupChat, GroupChatManager
architect = Agent(
name="architect",
system_message="Design system architecture. Output Mermaid diagrams.",
llm_config={"model": "gpt-4o"},
)
backend = Agent(
name="backend",
system_message="Implement REST APIs and database schemas.",
llm_config={"model": "gpt-4o-mini"},
)
frontend = Agent(
name="frontend",
system_message="Build React components and TypeScript types.",
llm_config={"model": "gpt-4o-mini"},
)
devops = Agent(
name="devops",
system_message="Write Dockerfiles, CI/CD, and Terraform.",
llm_config={"model": "gpt-4o-mini"},
)
group = GroupChat(
agents=[architect, backend, frontend, devops],
messages=[],
max_round=15,
speaker_selection_method="auto", # LLM picks next speaker
)
manager = GroupChatManager(groupchat=group, llm_config={"model": "gpt-4o"})
user_proxy.initiate_chat(manager, message="Build a real-time collaborative editor")
With speaker_selection_method="auto", the manager LLM evaluates the last few messages and chooses the agent whose expertise matches the current need. The architect speaks first, then backend and frontend may interleave, then devops wraps up. The sequence emerges from the task, not from a hardcoded list.
You can inject a custom selector for deterministic control:
def custom_selector(last_speaker: str, agents: list[Agent]) -> Agent:
# Simple state machine: architect -> backend -> frontend -> devops -> done
order = ["architect", "backend", "frontend", "devops"]
idx = order.index(last_speaker) if last_speaker in order else -1
next_idx = (idx + 1) % len(order)
return next(a for a in agents if a.name == order[next_idx])
group = GroupChat(
agents=[architect, backend, frontend, devops],
messages=[],
max_round=12,
speaker_selection_method=custom_selector,
)
This hybrid gives you dynamic branching (an agent can speak twice if the selector returns it again) while keeping the overall flow auditable.
Comparison across dimensions
Capabilities
Sequential chat excels at linear transformations: code → review → test → document. Each stage refines a single artifact. Group chat handles divergent-convergent workflows: multiple agents explore different facets (API design, data model, UI components) before converging on a shared spec. The manager LLM can also synthesize conflicting proposals — something sequential chat cannot do without an explicit synthesis agent.
Group chat’s allow_repeat_speaker parameter (default True) lets an agent hold the floor across turns. This matters when a complex task needs sustained focus. Sequential chat forces a context switch every turn, which fragments reasoning for multi-step subtasks.
Price and cost model
Both patterns consume tokens per turn. The difference is in turn count variance.
| Pattern | Typical turns | Variance | Cost predictability |
|---|---|---|---|
| Sequential | Fixed (agents × cycles) | Low | High |
| Group (auto) | 8–25+ | High | Low |
With speaker_selection_method="auto", the manager LLM adds one completion per turn to select the next speaker. At 15 rounds with 4 agents, that’s ~15 extra manager calls. A custom selector eliminates this overhead but requires you to encode the routing logic.
Sequential chat’s cost is turns × (agent_tokens + overhead). Group chat’s cost is turns × (agent_tokens + manager_tokens). If you run thousands of pipelines, sequential chat’s predictability wins for budgeting.
Latency and throughput
Sequential chat is inherently serial. Agent N+1 waits for agent N to finish. Total latency = sum of all agent latencies × cycles. No parallelization within a single conversation.
Group chat with auto selection is also serial — only one agent speaks at a time. But you can run multiple independent group chats in parallel across different tasks. The framework doesn’t support intra-chat parallelism (e.g., backend and frontend working simultaneously on the same conversation). For that, you’d need a custom orchestrator that fans out to multiple group chats and merges results.
If latency matters, sequential chat with fewer, more capable agents often beats group chat with many lightweight agents. Each turn adds network round-trips and model inference time.
Ergonomics
Sequential chat is simpler to debug. The conversation flow is visible in the agent list. You can print the history after each agent and see exactly what transformed the artifact. Group chat’s dynamic selection produces surprising sequences — the architect might speak three times in a row, or devops might jump in before frontend. Logging the selector’s reasoning helps:
def logging_selector(last_speaker: str, agents: list[Agent]) -> Agent:
choice = custom_selector(last_speaker, agents)
print(f"[selector] {last_speaker} -> {choice.name}")
return choice
Group chat also requires tuning max_round. Too low and the task truncates mid-thought; too high and agents loop. Sequential chat’s max_turns maps directly to pipeline depth.
Ecosystem and tooling
Both patterns use the same Agent and UserProxyAgent base classes. Tools (function calling, code execution, RAG) attach to individual agents identically. The difference appears in conversation-level tooling:
- Sequential chat: easy to insert a validation step between agents (e.g., run tests after coder, block reviewer if tests fail)
- Group chat: the manager can invoke tools to inspect state before selecting the next speaker, but this adds latency
AutoGen’s register_function works per-agent. For cross-agent tools (shared memory, vector store), you attach the same function to multiple agents or use a global context variable.
Limits
Sequential chat breaks when the task needs backtracking. If the tester discovers a design flaw, the pipeline must restart from the architect. Group chat handles this naturally — the selector routes back to the architect.
Group chat breaks when agent count grows. Beyond 5–6 agents, the auto selector struggles to distinguish roles, and the context window fills with irrelevant history. Sequential chat scales linearly — add a documentation agent at the end without affecting earlier stages.
Both patterns hit the context window. Group chat accumulates more history per turn because agents speak in varied order. Sequential chat’s predictable structure makes truncation strategies easier (drop intermediate reviews, keep final artifact).
Comparison table
| Dimension | Sequential chat | Group chat (auto) | Group chat (custom selector) |
|---|---|---|---|
| Flow control | Fixed order, deterministic | LLM-driven, dynamic | Programmable, auditable |
| Backtracking | Requires full restart | Natural (selector routes back) | Explicit in selector logic |
| Turn predictability | Exact (agents × cycles) | High variance | Medium (depends on selector) |
| Manager overhead | None | 1 LLM call/turn | None (pure Python) |
| Parallelization | None (serial) | None (serial) | None (serial) |
| Debugging | Trivial (print history) | Hard (log selector reasoning) | Medium (selector is visible) |
| Context efficiency | High (linear history) | Lower (branching history) | Medium |
| Best for | Pipelines, ETL, code gen → test → doc | Design exploration, open-ended tasks | Controlled collaboration, state machines |
| Agent count scaling | Linear, no degradation | Degrades >5 agents | Scales with selector complexity |
| Cost predictability | High | Low | Medium |
Which to choose
Choose sequential chat when
You have a known, repeatable pipeline. Code generation → lint → test → package. Documentation extraction → summarize → translate → publish. The stages are fixed, the artifact flows one direction, and you want zero surprises.
Cost predictability matters. Running 10,000 pipelines a day? Sequential chat’s fixed turn count lets you forecast spend within 5%. Group chat’s variance can swing 3–5× depending on how chatty the manager gets.
Debugging speed matters. When the output is wrong, you know exactly which agent produced it. Add print(history[-1]) after each step and you have a full trace.
The task is linear transformation. No branching, no “let’s reconsider the architecture.” If the reviewer finds a bug, you’re fine restarting the pipeline — the cost of a re-run is lower than the complexity of dynamic routing.
Choose group chat with auto selection when
The task is exploratory. “Design a system for real-time collaboration” — you don’t know upfront whether the backend or frontend agent needs to speak next. The manager LLM figures it out.
Agents have overlapping expertise. Architect and backend both understand databases. The selector routes to whoever is most relevant right now, not whoever is next in a list.
You accept variance for flexibility. Some runs take 8 turns, others 22. The quality ceiling is higher because the conversation adapts, but the floor is less predictable.
Prototyping. You’re discovering the workflow. Start with auto, observe the emergent sequences, then codify them into a custom selector or sequential pipeline once the pattern stabilizes.
Choose group chat with custom selector when
You need a state machine. The workflow has phases (design → implement → test → deploy) but agents may revisit phases conditionally. Encode the transitions in Python, not in an LLM prompt.
Determinism is required. CI/CD pipelines, compliance workflows, any scenario where “the LLM decided to loop” is a bug. The selector is pure logic — testable, versionable, auditable.
You want manager overhead eliminated. At scale, the manager LLM call per turn adds up. A custom selector is a function call.
Hybrid workflows. Sequential within phases, dynamic across phases. Example: architect speaks once, then backend+frontend run a sequential sub-pipeline, then devops wraps up. The selector implements this macro-structure while sub-pipelines handle micro-structure.
Bottom line: Start with sequential chat. It’s simpler, cheaper to run, and easier to debug. Graduate to group chat only when the task genuinely demands dynamic coordination — and when you do, write a custom selector first. The auto selector is a prototype tool, not a production primitive.