跪拜 Guibai
← Back to the summary

Four Agent Orchestration Patterns That Actually Ship

Four Advanced Orchestration Patterns

Part 5 of the series · Previous: Part 1Part 2Part 3Part 4


Once you've mastered basic agent chaining, parallel, and pipeline, the patterns that recur in real work boil down to just a few. This article covers the four most-used patterns, each with core code and design rationale.


Pattern 1: Quality Gate — Multi-Dimensional Review Then Revise

After writing an article or a piece of code, a single agent checking end-to-end tends to miss things. Let multiple agents each check one dimension, then have one final agent synthesize the feedback and revise.

// Phase 1: Write the first draft
const draft = await agent(`Write an article about ${TOPIC}`, { phase: 'write draft' })

// Phase 2: Three simultaneous reviews (haiku is enough, cheap)
const [tech, style, readability] = await parallel([
  () => agent(`Check for technical errors:\n${draft}`, { label: 'tech review', model: 'haiku' }),
  () => agent(`Check for AI-flavor and clichés:\n${draft}`, { label: 'style review', model: 'haiku' }),
  () => agent(`Check readability from a beginner's perspective:\n${draft}`, { label: 'readability', model: 'haiku' }),
])

// Phase 3: One agent synthesizes all three opinions and revises
const final = await agent(
  `Original:\n${draft}\n\nTech feedback: ${tech}\nStyle feedback: ${style}\nReadability feedback: ${readability}\n
   Technical errors must be fixed, style issues must be fixed, readability suggestions adopted selectively.`,
  { phase: 'synthesize and revise' }
)

Design points:


Pattern 2: Batch Production — Pipeline for Multiple Audiences, Each on Their Own Track

Same topic, different audiences, multiple versions produced simultaneously without waiting for each other.

const audiences = [
  { name: 'beginner', prompt: 'start from zero, use lots of analogies' },
  { name: 'experienced developer', prompt: 'direct comparisons, give code' },
  { name: 'tech manager', prompt: 'focus on efficiency and ROI, no code snippets' },
]

const results = await pipeline(
  audiences,
  // Stage 1: Search for materials (managers search for different content)
  (a) => agent(
    a.name === 'tech manager'
      ? `Search for efficiency improvement cases and data on ${TOPIC}`
      : `Search for tutorials and hands-on examples on ${TOPIC}`,
    { model: 'haiku' }
  ).then(materials => ({ a, materials })),

  // Stage 2: Outline
  ({ a, materials }) => agent(
    `Create an outline for ${a.name}. ${a.prompt}\nMaterials: ${materials}`
  ).then(outline => ({ a, outline })),

  // Stage 3: Write first draft
  ({ a, outline }) => agent(
    `Write a first draft for ${a.name}. ${a.prompt}\nOutline: ${outline}`
  ).then(draft => ({ audience: a.name, draft })),
)

Design points:


Pattern 3: Review and Verify — Multi-Dimensional Check → Deduplicate → Verify Each Finding Individually

False positives are the biggest fear in code review. Four dimensions each check once, deduplicate, then assign an independent agent to each finding to try to refute it; only confirmed ones are kept.

// Phase 1: Four-dimensional parallel review (use schema to get structured results directly)
const DIMENSIONS = [
  { key: 'bugs', prompt: 'check for logic errors, missing await' },
  { key: 'security', prompt: 'check for injection, sensitive info leaks' },
  { key: 'performance', prompt: 'check for unnecessary serialization, redundant computation' },
  { key: 'style', prompt: 'check naming, simplifiable code' },
]

const FINDINGS_SCHEMA = {
  type: 'object',
  properties: {
    findings: {
      type: 'array',
      items: {
        type: 'object',
        properties: { description: { type: 'string' } },
        required: ['description'],
      },
    },
  },
  required: ['findings'],
}

const allFindings = await parallel(
  DIMENSIONS.map(d => () =>
    agent(`Review ${TARGET}. ${d.prompt}`, {
      model: 'haiku',
      schema: FINDINGS_SCHEMA,
    }).then(result => result.findings.map(f => ({ ...f, dimension: d.key })))
  )
)

// Deduplication: pure JS
const seen = new Set()
const unique = allFindings.flat().filter(f => {
  const key = f.description.slice(0, 40)
  if (seen.has(key)) return false
  seen.add(key)
  return true
})

// Phase 2: Assign one agent per finding to try to refute it (pipeline, slow ones don't block fast ones)
const verified = await pipeline(
  unique,
  (finding) => agent(
    `Read ${TARGET}. Someone says there's a problem here: "${finding.description}"
     Please verify. If confirmed output CONFIRMED, if false positive output FALSE, if uncertain treat as FALSE.`
  ).then(verdict => verdict.startsWith('CONFIRMED') ? finding : null)
)

const realIssues = verified.filter(Boolean)

Design points:


Pattern 4: Loop-Until-Dry — When You Don't Know the Total, Loop Until No New Findings

Tasks like finding hardcoded paths or security vulnerabilities — you don't know how many there are in total. One agent searching once will definitely miss some, so run multiple rounds, changing the angle each round, until two consecutive rounds produce no new findings.

const STRATEGIES = [
  'Use grep to search for absolute path patterns',
  'Check config files for hardcoded paths',
  'Check Shell and JS scripts for paths',
  'Check docs for real user paths',
]

const allFound = new Set()
let dryRounds = 0
let round = 0

while (dryRounds < 2) {
  round++
  const strategy = STRATEGIES[(round - 1) % STRATEGIES.length]

  const found = await agent(
    `${strategy}. Known findings (don't repeat):\n${[...allFound].join('\n') || 'none'}`,
    { model: 'haiku' }
  )

  const lines = found.split('\n').filter(l => l.match(/\/Users\//))
  const newOnes = lines.filter(l => !allFound.has(l))

  if (newOnes.length === 0) {
    dryRounds++
  } else {
    dryRounds = 0
    newOnes.forEach(l => allFound.add(l))
  }
}

return { total: allFound.size, items: [...allFound] }

Design points:


How to Choose

Multiple subtasks independent, results need to be combined → parallel
Multiple items going through the same multi-step process → pipeline
After writing, need multi-dimensional check then revise → Quality Gate (parallel + synthesize)
Findings need to be verified for truth → Review and Verify (parallel + deduplicate + pipeline)
Unknown total, need repeated investigation → loop-until-dry (while)

These patterns can be combined. For example, the Review and Verify pattern uses both parallel and pipeline simultaneously.


Summary

Quality Gate:     write → parallel multi-dimensional check → one person synthesizes and revises
Batch Production:  pipeline for multiple audiences each on their own track, .then() passes params
Review and Verify: parallel check → JS deduplicate → pipeline refute one by one
loop-until-dry:    while loop + change strategy + stop after N consecutive rounds with no new findings