Building a 3-Agent Pipeline Without a Platform Team: What Actually Broke
I spent three weeks building a three-agent pipeline. No platform team, no DevOps support, just me and a lot of error logs. The pipeline works now, mostly. But pretending it was smooth would be dishonest. This is what actually happened.
Table of Contents
- Why Three Agents Instead of One
- The Sequencing Pattern That Actually Worked
- Error Handling Between Agents (The Hard Part)
- When I Almost Added a Fourth Agent (And Why I Didn't)
- The Infrastructure You Actually Need
- What I'd Do Differently
Why Three Agents Instead of One
The goal was simple: take user research data, generate insights, and produce a summary document. One agent could technically do this. But one agent doing three things means one point of failure and zero visibility into which step broke.
Three agents means three clear responsibilities:
Agent 1: Data Parser
Reads raw research transcripts, extracts quotes, tags themes. Output is structured JSON.
Agent 2: Insight Generator
Takes the JSON, identifies patterns, connects themes across sources. Output is numbered insights with evidence.
Agent 3: Document Builder
Formats insights into readable summaries with proper context and citations.
Analogy: Think of it like a kitchen brigade. The prep cook doesn't also plate the food. Clear handoffs mean you know exactly where the burnt garlic came from.
The real reason for three agents? Debugging. When Agent 2 produces garbage, I know the problem is in pattern matching, not data extraction. When you have one giant agent, every failure becomes a mystery.
The Sequencing Pattern That Actually Worked
I tried parallel execution first. All three agents running simultaneously felt efficient. It was a disaster.
Agent 2 would start before Agent 1 finished, get partial data, and hallucinate the rest. Agent 3 would timeout waiting for insights that never came. The logs were chaos.
The pattern that works is boring and linear:
Each agent polls a status store (I use Redis) before starting. If the previous agent hasn't marked itself complete, the next one waits. Simple. Boring. It works.
Here's the pseudo-pattern:
def run_agent_2():
while not status_store.get('agent1_complete'):
time.sleep(5)
input_data = load_from_s3(status_store.get('agent1_output'))
result = process(input_data)
save_to_s3(result)
status_store.set('agent2_complete', True)
status_store.set('agent2_output', s3_path)
No fancy orchestration framework. Just polling and flags. When Agent 2 fails, Agent 3 never starts. When Agent 1 times out, the whole pipeline stops. This is good. Silent failures are worse than loud ones.
Error Handling Between Agents (The Hard Part)
This is where solo building gets lonely. No one else to sanity check your error handling logic.
I had three types of failures:
Type 1: Agent crashes
Easy to detect. The process dies, the status flag never flips. My wrapper script catches this and sends me an alert.
Type 2: Agent completes but produces garbage
Hard to detect. Agent 2 might generate insights that technically parse as JSON but are meaningless. I added validation schemas. Every agent output gets checked against expected structure before the next agent starts.
Type 3: Agent times out mid-process
The worst. Agent 1 starts parsing, gets 60% through, then hits a rate limit. It crashes. But it already wrote partial data to S3. Agent 2 loads incomplete data and fails in confusing ways.
My solution for Type 3 failures: atomic writes. Agents write to temporary files, only move them to the final location on success. If an agent crashes, the temp file sits there but the pipeline sees no output.
| Error Type | Detection Method | Recovery Strategy |
|---|---|---|
| Agent crash | Process monitoring | Restart from last checkpoint |
| Invalid output | Schema validation | Roll back, alert, manual review |
| Timeout with partial data | Atomic write check | Discard temp files, full restart |
Schema validation looks like this:
from pydantic import BaseModel, ValidationError
class Agent1Output(BaseModel):
quotes: list[str]
themes: list[str]
metadata: dict
try:
validated = Agent1Output(**raw_output)
except ValidationError:
status_store.set('agent1_error', True)
send_alert("Agent 1 produced invalid output")
sys.exit(1)
Pydantic saved me hours of debugging. If Agent 1 returns data in the wrong shape, I know immediately. Before validation, I'd discover the problem two agents later when Agent 3 choked on malformed JSON.
When I Almost Added a Fourth Agent (And Why I Didn't)
Three weeks in, the pipeline worked but felt fragile. Agent 2 kept producing insights that were technically correct but lacked context. My brain immediately jumped to: "I need a fourth agent to add context."
I spent two days designing Agent 4. It would take insights from Agent 2, pull additional context from the original transcripts, and enrich each insight before passing to Agent 3.
Then I realized I was solving the wrong problem.
The issue wasn't missing context. The issue was Agent 2's prompt was vague. I rewrote the prompt with specific instructions: "For each insight, include which sources it came from and quote the specific evidence." Problem solved. No fourth agent needed.
Analogy: Adding another agent is like hiring another employee because your manager isn't giving clear instructions. Fix the instructions first.
When to add a fourth agent:
- The new task is genuinely distinct from existing agents
- You've optimized the current three and still have a gap
- Adding it reduces complexity rather than increases it
When NOT to add a fourth agent:
- You're trying to fix a prompt problem with more infrastructure
- You haven't fully debugged the current three
- The new agent would need to talk to multiple existing agents (creates dependency hell)
I almost added Agent 4 three times. Each time, the real solution was fixing an existing agent's prompt or adding better validation. More agents means more surfaces for failure.
The Infrastructure You Actually Need
Solo doesn't mean zero infrastructure. Here's what I couldn't skip:
Status Store (Redis)
Agents need to coordinate. Redis is simple. In-memory, fast, cheap to run. I tried using S3 for coordination by checking for file existence. It was slow and unreliable.
Object Storage (S3)
Agents pass data through files, not in-memory. When Agent 1 produces 50MB of structured data, you can't pass that as a function parameter. Write to S3, pass the path.
Monitoring (Sentry + Uptime Robot)
You need to know when things break. Sentry catches Python exceptions. Uptime Robot pings my pipeline endpoint every 5 minutes. If it's down, I get a text.
Logs (CloudWatch)
Structured logging saved me. Every agent logs its input, output, and execution time. When something breaks, I can trace exactly where.
What I didn't need:
- Kubernetes (way overkill for three Python scripts)
- Airflow (polling works fine for solo projects)
- A vector database (I'm not doing RAG, just structured processing)
Total monthly infrastructure cost: $23. Most of it is S3 storage.
What I'd Do Differently
If I rebuilt this tomorrow:
1. Start with schema validation from day one
I added Pydantic schemas in week two. Should have been day one. Every hour spent writing schemas saves ten hours of debugging.
2. Build a simple web UI earlier
I ran everything from the command line for two weeks. Finally built a basic Flask UI to trigger runs and view outputs. Should have done it week one. Debugging through a UI is infinitely easier.
3. Write integration tests before the third agent
I wrote tests after the pipeline was "done." Big mistake. When I refactored Agent 2, I broke Agent 3 and didn't realize for a day. Tests that run the full pipeline catch this immediately.
4. Keep a decision log
I made dozens of micro-decisions (Redis vs files for coordination, atomic writes, polling intervals). A month later, I forgot why I chose half of them. A simple markdown file tracking decisions would have helped.
Conclusion
Building a three-agent pipeline solo is absolutely doable. But it's not frictionless. You'll hit rate limits at 2am. Agent 2 will hallucinate nonsense because Agent 1's output had one malformed field. You'll convince yourself you need a fourth agent when you really just need a better prompt.
The wins: clear separation of concerns, debuggable failures, and a system that's actually maintainable by one person.
The reality: you're going to spend more time on error handling than on the actual agent logic. And that's fine. The error handling is what makes it production-ready.
Start simple. Add complexity only when you've proven you need it. And for the love of all that's good, use schema validation from day one.