Pipeline
The Pipeline pattern organises agents into a strict linear sequence: each agent processes the previous agent's output, then hands off to the next. Information flows in one direction; the run ends after the last stage replies.
Classic primitives: DefaultPattern with explicit AgentTarget handoffs, optionally ReplyResult to bundle a context update with each reply.
Key Characteristics#
- Specialised stages. Each agent focuses on one transformation — validate, enrich, fulfil — and ignores the rest.
- Unidirectional flow. Each stage hands off forward only. There is no return path for revisions inside the pipeline.
- Progressive refinement. The conversation accumulates through the WAL: every agent sees the full prior context via the windowed view, so no explicit state passing is needed.
- Well-defined interfaces. Each agent's prompt shapes its single reply line so the next stage can pick it up unambiguously.
Information Flow#
The graph's TransitionGraph.sequence([...]) shorthand wires FromSpeaker(a) → AgentTarget(b), FromSpeaker(b) → AgentTarget(c), and so on, with TerminateTarget("sequence_complete") as the default and max_turns=len(steps) matching the pipeline length. Each step terminates only by reaching the end — a stage that wants to abort early can return a typed Handoff(target="terminate") or emit any other routing intent the framework recognises.
Agent Flow#
sequenceDiagram
participant User
participant Intake as intake
participant Validator as validator
participant Enricher as enricher
participant Fulfilment as fulfilment
User->>Intake: Order line + customer ref
Intake->>Validator: FromSpeaker(intake) → AgentTarget(validator)
Validator->>Enricher: VALID — ... (FromSpeaker → AgentTarget)
Enricher->>Fulfilment: ENRICHED — tier=..., notes=...
Fulfilment->>User: SHIPPED — tracking=#..., ETA=...
Note over User,Fulfilment: TerminateTarget("sequence_complete") fires after fulfilment's reply Migrating from Classic to AG2?#
| Classic | AG2 |
|---|---|
DefaultPattern + per-agent handoff registration | TransitionGraph.sequence([...]) |
ReplyResult(message, target=AgentTarget(next)) from a tool | Either bake the handoff into the graph (preferred), return a typed Handoff(target=...) from a tool, or wire a ToolCalled rule to a plain @tool |
ContextVariables carrying intermediate state | set_context(channel, key, value) from inside a tool; reads via ChannelStateInject |
Code#
Tip
Each agent uses AnthropicConfig(model="claude-sonnet-4-6") so the validator / enricher / fulfilment stages produce real domain output. Set ANTHROPIC_API_KEY before running.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | |
Output#
channel: 3a1f...
intake: Order: 2x widget (SKU W-100), customer ACME-7, ship-to: London EC1.
validator: VALID — order has customer ref ACME-7 and one line item (2x SKU W-100).
enricher: ENRICHED — tier=Gold, notes=expedite for London EC1, signature on delivery.
fulfilment: SHIPPED — tracking=#GB-2026-09-AC7-W100, ETA=next-day before 12:00 GMT.
closed: reason='sequence_complete'