Multi-Agent Communication Patterns
Part 15's orchestrator-and-sub-agents pattern is genuinely one real architecture, not the only one. This part covers three more, each suited to a genuinely different, real coordination shape.
Pattern 1: sequential pipeline — each real agent's output feeds the next
def run_content_pipeline(topic: str) -> dict:
research = research_agent(f"Research background on: {topic}")
draft = writer_agent(f"Write a draft using this research: {research}")
edited = editor_agent(f"Review and improve this draft: {draft}")
return {"research": research, "draft": draft, "final": edited}This real pattern genuinely differs from part 15's orchestrator — there's no coordinating agent making real, dynamic decisions about WHICH agent to call; the real sequence is fixed in code, and each agent's real output becomes the next one's real input, directly. Genuinely simpler and more predictable than an orchestrator, at the cost of real, fixed inflexibility if the actual sequence needs to vary by situation.
Pattern 2: parallel fan-out with synthesis
import concurrent.futures
def run_parallel_research(topic: str) -> str:
with concurrent.futures.ThreadPoolExecutor() as executor:
futures = {
"pricing": executor.submit(research_agent, f"Research pricing for: {topic}"),
"features": executor.submit(research_agent, f"Research features for: {topic}"),
"reviews": executor.submit(research_agent, f"Research customer reviews for: {topic}"),
}
results = {key: f.result() for key, f in futures.items()}
return synthesize_findings(results) # a real, final LLM call
# combining all threeThree, genuinely independent real research agents run concurrently — directly extending the AI Projects series' own batch-processing pattern into agent territory — then a real, final synthesis step combines the independent results. This real pattern is genuinely faster in wall-clock time than running the same three research tasks sequentially, since they don't depend on each other's real output.
Parallel fan-out is the correct real choice specifically when sub-tasks are genuinely INDEPENDENT — pricing, features, and reviews research don't need each other's results to proceed. Part 15's orchestrator pattern is correct when sub-tasks genuinely DEPEND on each other, or the right next step depends on real, dynamic reasoning about what's already been done.
Pattern 3: peer-to-peer debate — two real agents critiquing each other
def run_debate(proposal: str, rounds: int = 2) -> str:
critic_feedback = ""
for round_num in range(rounds):
critic_feedback = critic_agent(f"Critique this proposal: {proposal}\n\nPrior feedback: {critic_feedback}")
proposal = proposer_agent(f"Revise this proposal based on real feedback: {proposal}\n\nFeedback: {critic_feedback}")
return proposalA real, genuinely different pattern — two agents with deliberately opposing real roles (propose vs. critique) iterating together, directly extending the LLM & Advanced AI series' own re-ranking judge concept into a real, multi-round refinement loop. Genuinely useful for a task where quality benefits from real, structured adversarial review — refining GreenDesk's real onboarding email copy before it reaches part 15's Welcome Content Agent, for instance.
A real, practical decision framework across all four patterns
Tasks depend on real, DYNAMIC decisions about what to do next:
orchestrator (part 15)
Tasks follow a real, FIXED, known sequence: sequential pipeline
Tasks are genuinely INDEPENDENT and can run concurrently: parallel
fan-out
A task benefits from real, structured adversarial refinement: debateThe real, honest cost of every multi-agent pattern
Every pattern here involves MULTIPLE real LLM calls per overall
task — genuinely, meaningfully more real API cost than a single
agent handling the same task alone, directly extending the LLM &
Advanced AI series' own honest cost accountingReaching for a multi-agent architecture because it sounds more sophisticated, rather than because the real task genuinely has multiple, distinct, real sub-problems that benefit from separation. A single, well-scoped agent (parts 6, 11, 13) is the correct, simpler, cheaper real choice for a task that doesn't genuinely decompose into independent or sequential real sub-tasks.
Next: agent planning and task decomposition — how an agent (or an orchestrator) actually breaks a large, real goal into the smaller, real steps these patterns coordinate.