Background

By 2025, AI Agents are nothing new. The real competition has shifted to Multi-Agent systems โ€” letting multiple agents coordinate, divide work, and collaborate autonomously.

No matter how capable a single agent is, it hits a wall on complex tasks: the context window overflows, and trying to pack search + writing + editing + image generation + speech synthesis into one prompt makes quality unpredictable. Breaking the task into multiple specialized agents, each doing one thing, actually gives you more control.

But that raises the question: how do multiple agents coordinate? This post compares the two dominant architectural patterns and explains why I ended up choosing the Supervisor model for my podcast auto-generation pipeline.

Two Dominant Architectural Patterns

When designing a Multi-Agent system, you typically encounter two design patterns:

1. Network / Peer-to-Peer

Agents communicate directly with each other โ€” no central controller. Each agent can decide on its own who to talk to and what to pass along.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Agent A โ”‚โ—„โ”€โ”€โ”€โ–บโ”‚ Agent B โ”‚
โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
     โ”‚               โ”‚
     โ–ผ               โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Agent C โ”‚โ—„โ”€โ”€โ”€โ–บโ”‚ Agent D โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    ๏ผˆๆฏๅ€‹ Agent ้ƒฝๅฏไปฅ่ทŸไปปๆ„ Agent ๆบ้€š๏ผ‰

Best for: open-ended discussions, brainstorming, multi-perspective debates. Risks: unpredictable flow, easy to fall into infinite loops, difficult to debug.

2. Supervisor

A central Supervisor Agent evaluates the current state and decides which agent to dispatch next. Worker agents execute their task and report back; the Supervisor decides what happens next.

                โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                โ”‚ Supervisor โ”‚
                โ”‚  (ๅ”่ชฟ่€…)   โ”‚
                โ””โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
           โ–ผ          โ–ผ          โ–ผ
      โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
      โ”‚Worker A โ”‚ โ”‚Worker B โ”‚ โ”‚Worker C โ”‚
      โ”‚(ๆœๅฐ‹)   โ”‚ โ”‚(ๆ’ฐๅฏซ)   โ”‚ โ”‚(ๆ ก็จฟ)   โ”‚
      โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
    ๏ผˆWorker ๅช่ทŸ Supervisor ๆบ้€š๏ผŒๅฝผๆญคไธ็›ดๆŽฅๅฐ่ฉฑ๏ผ‰

Best for: task pipelines with clear steps, quality gates, and trackable progress. Advantages: predictable flow, clear separation of concerns, straightforward fault tolerance.

Comparison

Dimension

Network (P2P)

Supervisor

Control

Decentralized, agents negotiate

Centralized, Supervisor dispatches

Predictability

โŒ Low, paths are dynamic

โœ… High, explicit state machine

Debug difficulty

๐Ÿ˜ฐ High, complex message flows

๐Ÿ˜Œ Low, every step is logged

Best task type

Open-ended discussion, creative work

Production pipelines with defined steps

Extensibility

Adding agents requires rethinking topology

Just register a new Worker with the Supervisor

Fault tolerance

Each agent handles its own errors

Supervisor owns the degradation strategy

Why I Chose the Supervisor Pattern

The core reason: the Supervisor only needs to know "who can do what," and Workers only need to know "how to do this one thing well."

That separation is clean:

  • Supervisor handles "orchestration" โ€” who goes first, who goes next, what happens on failure.
  • Workers handle "specialized execution" โ€” search is search, writing is writing, editing is editing.

This mirrors the Single Responsibility Principle (SRP) in software engineering โ€” each agent does exactly one thing and reports back when done.

In practice, most AI automation tasks have clear sequential dependencies (you need the search results before you can write, and the draft before you can edit). The Supervisor pattern is a natural fit for this kind of pipeline workflow.

How Agents Coordinate: Shared State Is the Only Communication Channel

In the Supervisor pattern, agents never communicate directly with each other. All coordination flows through a shared State object:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           ๅ…ฑไบซ็‹€ๆ…‹๏ผˆShared State๏ผ‰             โ”‚
โ”‚                                             โ”‚
โ”‚  rawSources โ† Research ๅฏซๅ…ฅ                  โ”‚
โ”‚  podcastMarkdown โ† Writer ๅฏซๅ…ฅ               โ”‚
โ”‚  editorFeedback โ† Editor ๅฏซๅ…ฅ                โ”‚
โ”‚  coverImagePath โ† CoverArt ๅฏซๅ…ฅ              โ”‚
โ”‚  audioPath โ† TTS ๅฏซๅ…ฅ                        โ”‚
โ”‚  errors โ† ๆ‰€ๆœ‰ Agent ๅฏๅฏซๅ…ฅ๏ผˆappend ๆจกๅผ๏ผ‰     โ”‚
โ”‚                                             โ”‚
โ”‚  Supervisor ่ฎ€ๅ– State โ†’ ๆฑบๅฎšไธ‹ไธ€ๆญฅ           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Each agent's interaction pattern is simple:

  • Read: pull its required input from State (e.g., Writer reads rawSources)
  • Write: push its output back to State (e.g., Writer writes podcastMarkdown)
  • Doesn't need to know: who ran before it, or who runs next

This means agents are fully decoupled. You can swap any agent's implementation at any time (e.g., replace a Gemini Writer with a Claude Writer) โ€” as long as the State field contracts remain the same, no other agent is affected.

LangGraph State Management: Annotations and Reducers

LangGraph uses Annotation to define shared state โ€” this is the foundation of all Multi-Agent coordination.

Core concept: each field can have its own reducer

Ordinary state management is "last write wins," but that breaks down in Multi-Agent scenarios. For example, if Agent A records an error and Agent B records an error, without a reducer B's error would overwrite A's.

LangGraph's solution is to let each field define its own reducer (merge strategy):

export const PodcastAnnotation = Annotation.Root({
  // ๆ™ฎ้€šๆฌ„ไฝ๏ผšๅพŒๅฏซ่ฆ†่“‹๏ผˆ้ ่จญ่กŒ็‚บ๏ผ‰
  date: Annotation<string>,
  podcastMarkdown: Annotation<string>,

  // append reducer๏ผšๆ–ฐๅ€ผ่ฟฝๅŠ ๅˆฐ้™ฃๅˆ—๏ผŒไธ่ฆ†่“‹่ˆŠๅ€ผ
  errors: Annotation<AgentError[], AgentError[]>({
    reducer: (existing, update) => [...existing, ...update],
    default: () => [],
  }),

  // merge reducer๏ผšๅˆไฝต็‰ฉไปถ็š„ key-value
  retryCount: Annotation<Record<string, number>>({
    reducer: (existing, update) => ({ ...existing, ...update }),
    default: () => ({}),
  }),
})

How reducers work

Reducer type

Behavior

Use case

None (default)

Last write wins

Fields written by a single agent (podcastMarkdown)

append

New value appended to array

Fields multiple agents may write (errors)

merge

Merge object keys

Counters, state tracking (retryCount)

custom

Any custom logic

Special requirements

Why does this matter?

The most common bug in Multi-Agent systems without reducers is state being silently overwritten. Consider this scenario:

  1. CoverArt Agent and TTS Agent run in parallel.
  2. CoverArt hits an error and writes errors: [{ agent: 'coverArt', message: '...' }].
  3. TTS also hits an error and writes errors: [{ agent: 'tts', message: '...' }].
  4. Without an append reducer, TTS's error overwrites CoverArt's โ€” you'll never know the cover generation failed.

With an append reducer, both errors are preserved. This is table-stakes for Multi-Agent state management.

Design Concept: Implementing Supervisor with LangGraph StateGraph

I use LangGraph's StateGraph to implement the Supervisor. The core ideas are:

  1. Shared State: all agents read from and write to the same State object (using Annotation as described above).
  2. Nodes: each agent is a node.
  3. Edges: define execution order between nodes.
  4. Conditional Edges: the Supervisor reads State to decide which path to take next.
START โ†’ Research โ†’ Writer โ†’ Editor โ”€โ”ฌโ”€โ†’ Publisher โ†’ [CoverArt + TTS] โ†’ END
                     โ–ฒ               โ”‚
                     โ”‚    (score < 60, retry โ‰ค 2)
                     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                      ๅ›ž้ฅ‹่ฟด่ทฏ๏ผšๅธถ่‘—ๅ•้กŒๆธ…ๅ–ฎ้‡ๅฏซ

Implementation: Podcast Auto-Generation Pipeline

I built a "Tech News Podcast Auto-Generator" using this architecture. Six agents, each with a dedicated role:

Agent

Responsibility

Technology

๐Ÿ” ResearchAgent

Search for the latest AI news (8-12 items)

Claude CLI + web_search

โœ๏ธ WriterAgent

Turn news sources into a podcast article

Gemini 3.1 Pro

๐Ÿ“ EditorAgent

Quality scoring + removing AI artifacts

Gemini 3.1 Pro + regex

๐Ÿ“ฆ PublisherAgent

Assemble frontmatter and write MDX file

Filesystem

๐ŸŽจ CoverArtAgent

Generate cover image

Gemini Image + sharp

๐ŸŽ™๏ธ TTSAgent

Generate multi-voice dialogue audio

Gemini + VoAI TTS

Full Architecture Diagram

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        LangGraph StateGraph                         โ”‚
โ”‚                        (Supervisor ๅ”่ชฟ่€…)                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                     โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚ Research  โ”‚โ”€โ”€โ”€โ–ถโ”‚  Writer  โ”‚โ”€โ”€โ”€โ–ถโ”‚  Editor  โ”‚โ”€โ”€โ”€โ–ถโ”‚  Publisher   โ”‚  โ”‚
โ”‚  โ”‚  Agent   โ”‚    โ”‚  Agent   โ”‚โ—€โ”€โ”€โ”€โ”‚  Agent   โ”‚    โ”‚    Agent     โ”‚  โ”‚
โ”‚  โ”‚          โ”‚    โ”‚          โ”‚ๅ›ž้ฅ‹ โ”‚          โ”‚    โ”‚              โ”‚  โ”‚
โ”‚  โ”‚ Claude   โ”‚    โ”‚ Gemini   โ”‚่ฟด่ทฏ โ”‚ Gemini   โ”‚    โ”‚  Filesystem  โ”‚  โ”‚
โ”‚  โ”‚ CLI +    โ”‚    โ”‚ 3.1 Pro  โ”‚(โ‰ค2) โ”‚ 3.1 Pro  โ”‚    โ”‚  MDX ๅฏซๅ…ฅ    โ”‚  โ”‚
โ”‚  โ”‚web_searchโ”‚    โ”‚          โ”‚    โ”‚          โ”‚    โ”‚              โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                                         โ”‚          โ”‚
โ”‚                                              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”     โ”‚
โ”‚                                              โ”‚   ๅนณ่กŒๅŸท่กŒ     โ”‚     โ”‚
โ”‚                                         โ”Œโ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”  โ”‚
โ”‚                                         โ”‚CoverArt โ”‚  โ”‚  TTS    โ”‚  โ”‚
โ”‚                                         โ”‚ Agent   โ”‚  โ”‚  Agent  โ”‚  โ”‚
โ”‚                                         โ”‚ Gemini  โ”‚  โ”‚ Gemini  โ”‚  โ”‚
โ”‚                                         โ”‚ Image + โ”‚  โ”‚ + VoAI  โ”‚  โ”‚
โ”‚                                         โ”‚ sharp   โ”‚  โ”‚         โ”‚  โ”‚
โ”‚                                         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                                              โ–ผ            โ–ผ       โ”‚
โ”‚                                             END          END      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Key Code Walkthrough

1. Shared State Definition (LangGraph Annotation)

All agents read and write the same State. Annotation defines the data structure and reducers:

import { Annotation } from '@langchain/langgraph'

export const PodcastAnnotation = Annotation.Root({
  // โ”€โ”€โ”€ ่ผธๅ…ฅ โ”€โ”€โ”€
  date: Annotation<string>,
  config: Annotation<PodcastConfig>,

  // โ”€โ”€โ”€ ๅ„้šŽๆฎต็”ขๅ‡บ โ”€โ”€โ”€
  rawSources: Annotation<NewsSource[]>,        // Research ๅฏซๅ…ฅ
  podcastMarkdown: Annotation<string>,          // Writer ๅฏซๅ…ฅ
  editorFeedback: Annotation<EditorFeedback>,   // Editor ๅฏซๅ…ฅ
  cleanedContent: Annotation<string>,           // Editor ๅฏซๅ…ฅ
  coverImagePath: Annotation<string | null>,    // CoverArt ๅฏซๅ…ฅ
  audioPath: Annotation<string | null>,         // TTS ๅฏซๅ…ฅ

  // โ”€โ”€โ”€ ๆŽงๅˆถๆฌ„ไฝ โ”€โ”€โ”€
  errors: Annotation<AgentError[]>({
    reducer: (existing, update) => [...existing, ...update],
    default: () => [],
  }),
  retryCount: Annotation<Record<string, number>>({
    reducer: (existing, update) => ({ ...existing, ...update }),
    default: () => ({}),
  }),
})

Key point: errors uses an append reducer so later agents can't overwrite earlier error records.

2. StateGraph Assembly: Nodes + Edges + Conditional Routing

import { StateGraph, END } from '@langchain/langgraph'

export function buildGraph() {
  const graph = new StateGraph(PodcastAnnotation)
    // ่จปๅ†Š็ฏ€้ปž๏ผˆๆฏๅ€‹ Agent ้ƒฝๆ˜ฏไธ€ๅ€‹ function๏ผ‰
    .addNode('research', researchAgent)
    .addNode('writer', writerAgent)
    .addNode('editor', editorAgent)
    .addNode('publisher', publisherAgent)
    .addNode('coverArt', coverArtAgent)
    .addNode('tts', ttsAgent)

    // ้ †ๅบๅŸท่กŒ
    .addEdge('__start__', 'research')
    .addEdge('research', 'writer')
    .addEdge('writer', 'editor')

    // ๆขไปถ่ทฏ็”ฑ๏ผšEditor ๆฑบๅฎš่ฆ้‡ๅฏซ้‚„ๆ˜ฏๆ”พ่กŒ
    .addConditionalEdges('editor', routeAfterEditor, {
      publisher: 'publisher',
      writerRetry: 'writerRetry',
    })

    // Publisher ๅพŒ๏ผšๅนณ่กŒๅŸท่กŒ CoverArt + TTS
    .addConditionalEdges('publisher', routeAfterPublisher, {
      coverArt: 'coverArt',
      tts: 'tts',
      end: 'end',
    })

    .addEdge('coverArt', END)
    .addEdge('tts', END)

  return graph.compile()
}

Key point: addConditionalEdges is the Supervisor's core mechanism โ€” it reads the current State and decides which path to take next.

3. Worker Agent Implementation (WriterAgent as an Example)

Each Worker does exactly one thing: receive State, execute the task, write back the result:

export async function writerAgent(
  state: PodcastState
): Promise<Partial<PodcastState>> {
  const model = await createVertexModel({
    model: state.config.writerModel,
    temperature: 0.8,
  })

  // ๅฆ‚ๆžœๆ˜ฏ retry๏ผŒๅธถๅ…ฅ Editor ็š„ๅ›ž้ฅ‹
  let feedbackContext = ''
  if (state.editorFeedback && !state.editorFeedback.passed) {
    feedbackContext = state.editorFeedback.issues
      .map(i => `- ${i}`)
      .join('\n')
  }

  const prompt = buildWriterPrompt(state.date, newsContext) + feedbackContext
  const response = await model.invoke([{ role: 'user', content: prompt }])

  return {
    podcastMarkdown: response.content.trim(),
    currentStep: 'writing_done',
  }
}

The Worker doesn't need to know which iteration it's on, who ran before it, or who runs next. It just focuses on producing a good draft.

Feedback Loop: The Quality Gatekeeper Pattern

This is the most powerful aspect of the Supervisor pattern โ€” you can design feedback loops.

Writer โ”€โ”€draftโ”€โ”€โ–ถ Editor โ”€โ”€scoreโ”€โ”€โ”ฌโ”€โ”€โ–ถ โœ… Pass โ†’ Publisher
                                  โ”‚
                            โŒ Fail (score < 60)
                                  โ”‚
                    Rewrite with feedback (max 2 retries)
                                  โ”‚
                                  โ””โ”€โ”€โ–ถ Writer
function routeAfterEditor(state: PodcastState): string {
  // ้€š้Ž โ†’ ไธ‹ไธ€ๆญฅ
  if (state.editorFeedback?.passed) return 'publisher'

  // ๆฒ’้€š้Žไฝ†้‚„ๆœ‰้‡่ฉฆๆฌกๆ•ธ โ†’ ๅธถๅ›ž้ฅ‹้‡ๅฏซ
  const retries = state.retryCount?.['writer'] ?? 0
  if (retries < MAX_WRITER_RETRIES) return 'writerRetry'

  // ่ถ…้Ž้‡่ฉฆๆฌกๆ•ธ โ†’ ๅธถ่ญฆๅ‘Š็นผ็บŒ
  return 'publisher'
}

Analogy: Coding Agent Scenario

The same pattern applies to code review:

Coding Agent โ”€โ”€submit codeโ”€โ”€โ–ถ Supervisor Agent โ”€โ”€reviewโ”€โ”€โ”ฌโ”€โ”€โ–ถ โœ… Pass โ†’ Merge
                                                          โ”‚
                                                    โŒ Security issue / violation
                                                          โ”‚
                                          Fix with feedback (max N retries)
                                                          โ”‚
                                                          โ””โ”€โ”€โ–ถ Coding Agent

The Supervisor only evaluates "does this code have problems," and the Coding Agent only "fixes based on feedback." Responsibilities are clear and don't bleed into each other.

Fault Tolerance and Degradation Strategies

In a Multi-Agent system, not every agent is equally critical. A well-designed Supervisor needs tiered fault tolerance:

Failure scenario

Handling

Severity

Research search fails

Writer generates from LLM's own knowledge

โš ๏ธ Degrade

Editor fails repeatedly

Publish with warning

โš ๏ธ Degrade

CoverArt generation fails

Article publishes without cover

๐Ÿ’ก Acceptable

TTS synthesis fails

Article publishes without audio

๐Ÿ’ก Acceptable

Publisher write fails

Abort the pipeline

๐Ÿ”ด Hard failure

Design principle: failures in the core pipeline (Research โ†’ Write โ†’ Edit โ†’ Publish) need graceful degradation; failures in supplementary features (Cover, TTS) should not impact the main flow.

Notes and Gotchas

Practical pitfalls

  • Use reducers for shared state: if multiple agents write to errors simultaneously without an append reducer, they'll overwrite each other. LangGraph's Annotation reducer is a lifesaver.
  • Parallel agents must be truly independent: CoverArt and TTS can run in parallel because they have no data dependency on each other. If there is a dependency, sequential execution is required.
  • Always cap feedback loops: a feedback loop without MAX_RETRIES is an infinite loop. I set mine to 2; after that, the pipeline continues with a warning.
  • Different agents can use different models: Research uses Claude (strong search reasoning), Writer/Editor use Gemini (cheap + long context), TTS uses a dedicated voice API. Mixing models often yields better results than using one model for everything.

Performance reference

Mode

Time

Description

Text only (skip-tts + skip-cover)

~2 min

Research โ†’ Writer โ†’ Editor โ†’ Publisher

With cover

~3 min

Adds CoverArt generation

Full pipeline

~4 min

CoverArt + TTS running in parallel

When not to use Supervisor

  • If the task is inherently open-ended (multi-agent debates, creative brainstorming), Supervisor actually limits agent autonomy.
  • If you only have 2 agents and the flow is linear, just chain them directly โ€” no need to bring in the full Supervisor architecture.

Conclusion

The core of Multi-Agent isn't "more agents = better." It's clear division of labor + predictable flow.

Three design principles for the Supervisor pattern:

  1. Supervisor owns orchestration, Workers own execution โ€” single responsibility, each does its job.
  2. Feedback loops ensure quality โ€” the Editor/Reviewer acts as gatekeeper, sending work back when it doesn't pass.
  3. Tiered fault tolerance โ€” core pipeline degrades gracefully; supplementary features fail gracefully.

If you're planning a Multi-Agent system, I'd suggest first asking yourself: "does this task have a clear sequential order?" If yes, the Supervisor pattern is the most stable starting point.

Dark mode admin panel displaying an AI agent workflow with multiple stepsDark UI showing AI content generation form and multi-agent workflow

Author

Mark Ku

10 ๅนดไปฅไธŠ็š„่ปŸ้ซ”ๅทฅ็จ‹ๅธซ๏ผŒๅš้ŽๅŒ—็พŽ้›ปๅ•†่ˆ‡ AI SaaS ่จ‚้–ฑๆ”ถ่ฒป็ณป็ตฑใ€‚Read More

Found this useful?

The author's free tools, daily podcasts and newsletter are all here.

Mark Ku ยท This article is licensed under CC BY 4.0. Credit the author and link back to the original when reusing it.

Comments

Subscribe to Newsletter

Subscribe to get new posts delivered instantly โ€” never miss a tech share.

By submitting, you agree to receive emails. You can anytime.

Popular Posts

View all
Mark Ku
ยทยท633

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution

Oracle Cloud Always Free Tier: Linux Host and Static IP for a $0 Cloud Solution
Mark Ku
ยทยท464

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.

Say Goodbye to Postman's Fee Trap! A Hands-on Guide to Bruno, the Open-Source Git-Native API Testing Powerhouse.
Mark Ku
ยทยท249

A Free, Open-Source, Notion-like Knowledge Base โ€” A Complete Guide to Deploying and Backing Up Outline Wiki

A Free, Open-Source, Notion-like Knowledge Base โ€” A Complete Guide to Deploying and Backing Up Outline Wiki
Mark Ku
ยทยท205

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1

Building an Efficient API Management Platform: Deploying Kong Gateway from Scratch - Part 1
Mark Ku
ยทยท202

Setting Up Samba on Ubuntu to Share Folders with Windows 11

Setting Up Samba on Ubuntu to Share Folders with Windows 11
Mark Ku
ยทยท198

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning

Training Your Own AI Voice: Hardware Requirements, Open-Source Model Comparison, and LoRA Fine-Tuning