Every multi-agent framework eventually makes you answer the same question, and most of them bury it: who decides which agent runs next? Microsoft Agent Framework at least makes the answer explicit — it ships five orchestration patterns, and each one is just a different answer to that single question. Get the framing right and the choice stops being a menu and becomes a decision tree.
The one axis that matters: control vs. autonomy#
Line the five patterns up by who holds the routing decision and they sort themselves from most-controlled to most-autonomous:
- Sequential — you decide, at build time. A fixed order: agent A, then B, then C.
- Concurrent — nobody decides. Every agent runs in parallel on the same input; results are aggregated.
- Group Chat — a turn policy decides, rotating the floor among agents in one shared transcript.
- Handoff — the current agent decides, transferring control to another agent based on context.
- Magentic — a manager LLM decides, planning the round-by-round coordination dynamically.
That ordering is also, not coincidentally, the order of increasing token cost and decreasing debuggability. Every step you move toward autonomy, you hand the routing to the model — which is powerful exactly where a fixed graph can't express the path, and a liability exactly where it can.
The two you'll reach for first#
Concurrent is the workhorse and the one most teams under-use. When you want several independent perspectives on the same input — a researcher, a marketer, and a legal reviewer all reacting to one product brief — you don't need them talking to each other. You need them running at once and their outputs merged. The API is deliberately small:
import os
from agent_framework.foundry import FoundryChatClient
from agent_framework.orchestrations import ConcurrentBuilder
from agent_framework import Message
from azure.identity import AzureCliCredential
from typing import cast
chat_client = FoundryChatClient(
project_endpoint=os.environ["FOUNDRY_PROJECT_ENDPOINT"],
model=os.environ["FOUNDRY_MODEL"],
credential=AzureCliCredential(),
)
researcher = chat_client.as_agent(
instructions="Expert market and product researcher. Give concise insights, opportunities, and risks.",
name="researcher",
)
# ...marketer and legal defined the same way
workflow = ConcurrentBuilder(participants=[researcher, marketer, legal]).build()
output: list[Message] | None = None
async for event in workflow.run("We're launching a budget e-bike for urban commuters.", stream=True):
if event.type == "output":
output = event.data
for i, msg in enumerate(cast(list[Message], output or []), start=1):
name = msg.author_name or "user"
print(f"{i:02d} [{name}]:\n{msg.text}")
Note the shape: you build with ConcurrentBuilder(participants=[...]).build() and consume event.type == "output" off a streamed workflow.run(...). The other builders — SequentialBuilder, GroupChatBuilder, HandoffBuilder, MagenticBuilder — follow the same build-then-run rhythm, which is the point: swapping patterns is a one-line change, not a rewrite.
Sequential is the other default. If you already know the order — draft, then critique, then revise — encode it. You get a fully deterministic pipeline that's trivial to trace and cheap to run, because control flow never depends on model output. Most "agentic" workflows that ship to production are Sequential wearing a fancier name.
If you can draw the graph before you run it, you don't need a model to route it. Reserve the autonomous patterns for the cases where you genuinely can't.
The three that spend tokens for adaptivity#
Group Chat puts agents in one shared transcript and lets a turn policy rotate who speaks. Use it when the collaboration itself is the product — several agents refining a document together, each seeing the others' contributions. It costs more than Concurrent because the transcript grows every round.
Handoff lets the active agent transfer control based on context — the pattern behind triage and routing. A front-line agent inspects the request and hands off to billing, or tech support, or escalation. This is the same idea as agent handoffs in LangGraph and the OpenAI/Google SDKs: the routing is data-dependent, so you let the model make it. Powerful for support-style flows; non-deterministic by nature, so instrument every hop.
Magentic is the most autonomous, drawn from Microsoft's Magentic-One research. A manager agent owns the coordination: it plans, delegates to specialist workers, and tracks progress round by round, bounded by configurable max-round and stall/reset limits so it can't spin forever. Reach for it when the task is open-ended enough that you can't pre-plan the steps — but know you're paying for the manager's reasoning on top of every worker call. It's the pattern most likely to impress in a demo and most likely to surprise you on the invoice.
The rule of thumb#
Start with the most constrained pattern that expresses your problem, and escalate only when it can't route correctly. Concrete order of preference: Sequential or Concurrent → Group Chat → Handoff → Magentic. Because all five support streaming, checkpointing, and human-in-the-loop pause/resume, you can also mix — a deterministic Sequential spine with a Magentic step in the one place that needs open-ended planning. If you're still choosing a framework at all, this orchestration surface is a good part of the broader multi-agent comparison: the patterns are similar everywhere, but MAF is unusually explicit about naming them — and that clarity is worth something at 3 a.m. when a workflow won't route.



