5 Agent Chain Patterns Every Developer Should Know
Mentiko Team
Every complex agent system is built from a handful of recurring patterns. Once you recognize them, designing chains goes from "staring at a blank JSON file" to "snapping together known pieces." These five patterns cover the vast majority of real-world agent orchestration use cases.
We'll show each pattern as a Mentiko chain definition -- the same portable JSON format you'd commit to your repo.
1. Sequential Pipeline
One agent finishes, the next one starts. A straight line from input to output.
This is the simplest pattern and the one most people build first. Agent A triggers Agent B triggers Agent C. Each agent has exactly one upstream and one downstream. Data flows in a single direction.
When to use it: Content pipelines (research, write, edit), data processing (extract, transform, load), any workflow where each step depends entirely on the previous step's output.
{
"name": "content-pipeline",
"agents": [
{
"name": "researcher",
"prompt": "Research {TOPIC} and compile findings.",
"triggers": ["chain:start"],
"emits": ["research:complete"]
},
{
"name": "writer",
"prompt": "Write a blog post from the research findings.",
"triggers": ["research:complete"],
"emits": ["draft:complete"]
},
{
"name": "editor",
"prompt": "Edit the draft for clarity, grammar, and tone.",
"triggers": ["draft:complete"],
"emits": ["chain:complete"]
}
]
}
Pro tip: Sequential pipelines are easy to debug because you can inspect each agent's output in order. If the final output is wrong, walk backward through the event files until you find where the quality dropped. Keep your chains linear until you have a reason not to.
2. Fan-Out / Fan-In
One agent triggers multiple agents in parallel. A collector waits for all of them to finish before proceeding.
This is the pattern you reach for when you need the same input processed in multiple ways simultaneously. One event fans out to several agents, they all run at the same time, and a final agent aggregates their results.
When to use it: Multi-source research (query three different APIs in parallel), A/B testing content (generate three versions, pick the best), any workflow where parallel execution saves time and the results need to be combined.
{
"name": "multi-source-research",
"agents": [
{
"name": "dispatcher",
"prompt": "Parse the research query and prepare context for downstream agents.",
"triggers": ["chain:start"],
"emits": ["query:ready"]
},
{
"name": "source-academic",
"prompt": "Search academic papers and extract relevant findings.",
"triggers": ["query:ready"],
"emits": ["source:complete"]
},
{
"name": "source-news",
"prompt": "Search recent news articles for relevant coverage.",
"triggers": ["query:ready"],
"emits": ["source:complete"]
},
{
"name": "source-forums",
"prompt": "Search developer forums and discussions for practical insights.",
"triggers": ["query:ready"],
"emits": ["source:complete"]
},
{
"name": "synthesizer",
"prompt": "Combine all source findings into a unified research brief.",
"triggers": ["source:complete"],
"collect": 3,
"emits": ["chain:complete"]
}
]
}
The key detail is "collect": 3 on the synthesizer. It won't fire after the first source:complete event -- it waits until it has received three of them. All three source agents emit the same event type, and the collector counts them.
Pro tip: Always set an explicit collect count rather than relying on "wait for all." If one of your source agents fails silently, an unbounded wait hangs forever. A fixed count with a timeout lets you detect missing results and handle the gap.
3. Conditional Branching
One agent classifies the input and emits different events based on the result. Downstream agents only trigger on their specific event.
Not every input should follow the same path. A classifier agent examines the input, makes a decision, and routes work to the appropriate handler. This is how you build triage systems, quality gates, and priority routing.
When to use it: Support ticket triage (urgent vs. normal), content moderation (approve, flag, reject), quality gates where only some inputs need additional processing.
{
"name": "support-triage",
"agents": [
{
"name": "classifier",
"prompt": "Analyze this support ticket. If it mentions data loss, outage, or security, emit urgent. Otherwise emit normal.",
"triggers": ["chain:start"],
"emits": ["ticket:urgent", "ticket:normal"]
},
{
"name": "urgent-handler",
"prompt": "Draft an immediate response acknowledging the critical issue. Escalate to on-call.",
"triggers": ["ticket:urgent"],
"emits": ["chain:complete"]
},
{
"name": "normal-handler",
"prompt": "Draft a helpful response with relevant docs links. Queue for next business day.",
"triggers": ["ticket:normal"],
"emits": ["chain:complete"]
}
]
}
The classifier only emits one of its declared events per run. The emits array lists all possible events it can produce, but at runtime it chooses based on the input. The handler that doesn't get triggered simply never starts.
Pro tip: Make your classifier's decision criteria explicit in the prompt, not implicit. "If the ticket mentions data loss, outage, or security" is testable and debuggable. "If the ticket seems urgent" is a judgment call that will drift over time. When you need more than two branches, just add more event types and handlers -- the pattern scales linearly.
4. Error Recovery with Fallback Agents
A primary agent does the work. If it fails, a recovery agent catches the failure event and handles it gracefully.
Agents fail. API rate limits, context length overflows, malformed inputs, model refusals -- production pipelines hit all of these. Instead of letting the whole chain crash, you can wire up fallback agents that trigger specifically on failure events.
When to use it: API calls where you want to retry with a different provider, content generation where you need a degraded-but-functional fallback, any workflow where partial results are better than no results.
{
"name": "resilient-summarizer",
"agents": [
{
"name": "primary-summarizer",
"prompt": "Summarize this document using {MODEL}. Max 500 words.",
"triggers": ["chain:start"],
"emits": ["summary:complete"],
"on_error": "summary:failed"
},
{
"name": "fallback-summarizer",
"prompt": "The primary summarizer failed. Summarize using a simpler approach: extract the first sentence of each section.",
"triggers": ["summary:failed"],
"emits": ["summary:complete"]
},
{
"name": "output-formatter",
"prompt": "Format the summary for delivery. Note if fallback mode was used.",
"triggers": ["summary:complete"],
"emits": ["chain:complete"]
}
]
}
The on_error field on the primary agent declares what event to emit when the agent fails instead of completing normally. The fallback agent triggers on that failure event. The output formatter doesn't care which summarizer produced the result -- it triggers on summary:complete either way.
Pro tip: Always log whether the fallback path was taken. This seems obvious, but most teams skip it and then can't explain why 12% of their summaries are lower quality than the rest. The output formatter in this example checks for fallback mode -- use that flag for monitoring and quality metrics.
5. Iterative Review Loop
Agent A produces work. Agent B reviews it. If the review fails, Agent A gets another shot. This repeats up to N times.
Some work needs multiple passes. Code review, writing refinement, data validation -- these are inherently iterative. The review loop pattern lets two agents bounce work back and forth until the reviewer is satisfied or a maximum iteration count is reached.
When to use it: Code generation and review, content polish cycles, any quality assurance workflow where "good enough on the first try" is unlikely and "infinite loop" is unacceptable.
{
"name": "writing-review-loop",
"agents": [
{
"name": "writer",
"prompt": "Write (or revise) the article based on the given topic and any reviewer feedback.",
"triggers": ["chain:start", "review:revision-needed"],
"emits": ["draft:ready"]
},
{
"name": "reviewer",
"prompt": "Review the draft. If it meets quality standards, approve it. If not, provide specific feedback for revision.",
"triggers": ["draft:ready"],
"emits": ["review:approved", "review:revision-needed"],
"max_iterations": 3
},
{
"name": "publisher",
"prompt": "Format the approved draft for publication.",
"triggers": ["review:approved"],
"emits": ["chain:complete"]
}
]
}
Notice the writer has two triggers: chain:start for the initial run and review:revision-needed for rework cycles. The reviewer emits one of two events -- approve or send back. max_iterations: 3 is the safety valve: after three review cycles, the chain stops regardless, preventing infinite loops.
Pro tip: The iteration cap is non-negotiable. Without it, a picky reviewer agent and a stubborn writer agent will loop forever, burning tokens and your patience. Three iterations is a good default -- most meaningful quality improvements happen in the first two passes, and the third is diminishing returns. If your work still isn't good enough after three rounds, the problem is in the prompts, not the loop count.
Combining Patterns
These five patterns are composable. A real production chain might use a sequential pipeline where one stage contains a fan-out, another stage has conditional branching, and the whole thing has error recovery wired up on critical agents. The patterns nest and combine:
- A content pipeline (sequential) where the research stage fans out to three sources (fan-out/fan-in), the writing stage loops with a reviewer (iterative review), and the publishing stage has a fallback for when the CMS API is down (error recovery).
- A support system that triages (conditional branching) into three priority levels, each with its own sequential pipeline, and all three pipelines have fallback agents for API failures.
Start simple. Build a sequential pipeline first. Add fan-out when you need parallelism. Add branching when you need routing. Add error recovery when you're in production. Add review loops when quality matters more than speed.
The chain definitions are JSON files in your repo. They compose, they diff, they version. That's the point.
Ready to build? Start with a two-agent chain in five minutes, or join the waitlist to get your own Mentiko instance.
Get new posts in your inbox
No spam. Unsubscribe anytime.