Overview
Side-by-side translations of the canonical multi-agent orchestration patterns from classic (non-beta) AG2 (autogen.agentchat.group) onto the beta WorkflowAdapter. Each pattern lists the classic primitives it used, a beta translation, the full runnable source, and any gaps that don't yet have a clean equivalent.
For the classic (non-beta) versions and their conceptual background, see the Pattern Cookbook in the user guide.
Status Legend#
| Status | Meaning |
|---|---|
| Clean | Maps one-to-one onto existing beta primitives. Code below works as written. |
| Partial | Translates with one or more named gaps. Workaround included; gap tracked on roadmap. |
Quick Reference#
| # | Pattern | Status | Beta primitives | Notable gap |
|---|---|---|---|---|
| 1 | Pipeline | Clean | TransitionGraph.sequence or FromSpeaker → AgentTarget chain | — |
| 2 | Hierarchical | Partial | Handoff returns from delegate tools + ContextEquals for terminate | No NestedChatTarget; sub-flows via separate channels |
| 3 | Star | Clean | ToolCalled graph rule for spoke selection + WAL-reading synthesis tool | — |
| 4 | Coordinator | Clean | One generic handoff(to) tool returning Handoff + finish tool returning Finish; empty transitions list + RevertToInitiatorTarget default | — |
| 5 | Escalation | Clean | Handoff returns from escalate tools + ToolCalled("resolve") for terminate | — |
| 6 | Redundant | Partial | Sequential fan-out via TransitionGraph.sequence | No parallel dispatch; one specialist at a time |
| 7 | Feedback Loop | Clean | ContextEquals on a done flag with max_turns cap | — |
| 8 | Context-Aware Routing | Partial | Router agent's tool sets category → ContextEquals per branch | No LLMCondition; routing reasoning lives inside the coordinator's LLM, not the framework |
| 9 | Triage with Tasks | Clean | TransitionGraph.sequence over a triage-produced plan; knobs["context_vars"] seeds the queue | — |
The "Organic" pattern from classic AG2 (LLM-driven AutoPattern group-manager auto-selection) translates to the Coordinator pattern: one generic parameterised handoff tool on the coordinator, plus a Finish tool to terminate. No graph rewrite when specialists are added or removed. See Roadmap for the remaining gaps.
Routing idioms#
Every cookbook page below uses one of three composable routing idioms. Picking the right one is the most common decision when porting a classic pattern.
1. Static routing, graph-centralised. Plain @tool returning a string; the graph holds the routing edge.
When to use: many routing edges across multiple agents and you want one place (the graph) to read the topology. Used by 03_star.py.
2. Static routing, tool-local. @tool returning a fixed-target Handoff. No graph rule needed — the framework reads Handoff.target from the agent's local ToolResultEvent stream and stamps it onto the packet's routing field directly.
When to use: simple workflows where the routing target is obvious from the tool's name and you'd rather not maintain a parallel graph rule. Used by 02_hierarchical.py and 04_escalation.py.
3. Dynamic routing. @tool returning a computed-target Handoff. The case that wasn't cleanly expressible before the typed return shape.
When to use: target depends on runtime state, load balancing, or any condition the graph can't express declaratively.
State updates#
State mutations are independent of routing and use the workflow-scoped helpers set_context(channel, key, value) and delete_context(channel, key). They live in autogen.beta.network.workflow_helpers rather than the top-level autogen.beta.network namespace — they only operate on WorkflowState.context_vars and raise RuntimeError on a non-workflow channel, so the import path itself signals the adapter scope.
Knowing when the workflow is finished#
Every cookbook page below uses the same close-detection primitive in its demo main:
AgentClient.wait_for_channel_event blocks on the per-channel inbox until an envelope matching the predicate arrives — here, the EV_CHANNEL_CLOSED envelope every termination route emits. The reason string distinguishes the close (e.g. 'sequence_complete', 'approved', 'resolved', 'fall_through', 'max_iterations', 'ttl_expired').
To print the transcript, dump the WAL once after close — no polling helper needed (this is the pattern used in each cookbook page below).
For the full picture of the five close routes (application close, agent-side tool, adapter sentinel, workflow TerminateTarget, TTL / expectations), see Closing Channels → Watching for Close.
Roadmap#
The gaps surfaced in each pattern page are tracked. None block the patterns; each either has a working workaround or is currently deferred:
LLMCondition— declarative routing where the framework asks an LLM whether a transition fires. Unblocks the cleanest version of Context-Aware Routing.NestedChatTarget— first-class sub-flow target. Unblocks Hierarchical and Redundant fully.- Parallel dispatch — fan out to multiple speakers within a single workflow turn, gather their replies, advance once all are in. Unblocks parallel Redundant.
- Auto-merge of tool-return fields into context — the
ReplyResult.context_variablesanalogue. Cuts the boilerplate for Escalation and Triage-with-Tasks. AllOf/AnyOfcondition composers — useful sugar across most patterns; today the conjunction is encoded via transition order.
For the broader scope of what the workflow adapter does and doesn't yet ship versus classic, see Migrating from Group Chat.
See Also#
- Workflow Adapter — the underlying graph machinery and built-in conditions.
- Context Variables —
set_context/delete_context,ContextEquals, custom conditions. - Closing Channels — termination patterns; many cookbook entries lean on
TerminateTargetwith informative reasons. - Migrating from Group Chat — concept-level translation table.