Deep Expertise Track · Lesson 6

Concurrent Orchestration

Multi-agent Pattern 2: fan-out/fan-in, parallel specialists

Concurrent Orchestration: Parallel Specialists

Lesson 6 — Multi-agent Pattern 2: fan-out/fan-in, multiple agents working simultaneously

What you'll learn
  1. What concurrent orchestration is (fan-out/fan-in, scatter-gather)
  2. How it maps to Anthropic's "Parallelization" workflow
  3. When to use sectioning vs voting (the two sub-patterns)
  4. Build a 4-agent stock analysis system that runs in parallel

The Pattern

┌──────────────────────────────────────────────────────────┐ │ CONCURRENT ORCHESTRATION │ │ (fan-out / fan-in / scatter-gather) │ │ │ │ ┌─▶ Agent A ──▶ Result A ──┐ │ │ Input ──▶ Init ──┼─▶ Agent B ──▶ Result B ──┤─▶ Agg ──▶ Output │ ├─▶ Agent C ──▶ Result C ──┤ │ │ └─▶ Agent D ──▶ Result D ──┘ │ │ │ │ ALL agents get the SAME input. │ │ ALL agents run simultaneously (parallel). │ │ Results are AGGREGATED (vote, merge, or synthesize). │ │ Agents do NOT talk to each other. │ └──────────────────────────────────────────────────────────┘

Source: Microsoft Azure — AI Agent Orchestration Patterns

Two Sub-Patterns

Sub-patternWhat it doesExample
SectioningBreak task into independent subtasks, each handled by a specialistFundamental analysis agent + Technical analysis agent + Sentiment agent + ESG agent — each analyzes the same stock from their angle
VotingRun the SAME task multiple times, aggregate for higher confidence3 agents review code for bugs. If 2+ flag the same issue, it's confirmed.

Source: Anthropic — Building Effective Agents (Parallelization section)

Real-World Example: Stock Analysis

Microsoft's guide describes a financial services firm using concurrent agents for stock evaluation:

STOCK ANALYSIS (concurrent, 4 specialists) ┌─▶ Fundamental Agent ──▶ "Revenue up 18%" ──┐ Ticker: SBIN ───────┼─▶ Technical Agent ──▶ "Bullish RSI" ──┤ ├─▶ Sentiment Agent ──▶ "Positive news" ──┤─▶ Investment └─▶ ESG Agent ──▶ "Low ESG risk" ──┘ Recommendation All 4 run simultaneously. Results combined into one recommendation.

Build It: Parallel Stock Analysis

import asyncio
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
import os

llm = ChatOpenAI(model="deepseek-chat", api_key=os.getenv("DEEPSEEK_API_KEY"),
                 base_url="https://api.deepseek.com", temperature=0.3)

# 4 specialist agents — each gets the SAME input
agents = {
    "fundamental": ChatPromptTemplate.from_messages([
        ("system", "You are a fundamental analyst. Analyze the stock's financials, revenue trends, "
                   "and competitive positioning. Be concise (3-4 sentences)."),
        ("user", "Analyze: {ticker}"),
    ]) | llm,
    
    "technical": ChatPromptTemplate.from_messages([
        ("system", "You are a technical analyst. Analyze price patterns, momentum, and indicators. "
                   "Be concise (3-4 sentences)."),
        ("user", "Analyze: {ticker}"),
    ]) | llm,
    
    "sentiment": ChatPromptTemplate.from_messages([
        ("system", "You are a sentiment analyst. Assess market sentiment, news, and analyst opinions. "
                   "Be concise (3-4 sentences)."),
        ("user", "Analyze: {ticker}"),
    ]) | llm,
    
    "risk": ChatPromptTemplate.from_messages([
        ("system", "You are a risk analyst. Assess downside risks, regulatory concerns, and worst-case scenarios. "
                   "Be concise (3-4 sentences)."),
        ("user", "Analyze: {ticker}"),
    ]),
}

async def run_analysis(ticker: str):
    # Fan-out: all agents run concurrently
    tasks = {name: (chain if isinstance(chain, type(llm)) else chain).ainvoke({"ticker": ticker}) 
             for name, chain in agents.items()}
    results = {}
    for name, task in tasks.items():
        results[name] = await task
    
    # Fan-in: aggregate results
    summary = "\n\n".join(f"### {name.title()} Analysis\n{r.content}" 
                          for name, r in results.items())
    
    # Synthesize with a final LLM call
    synthesis = llm.invoke(
        f"Based on these 4 analyses, give a HOLD/SELL recommendation:\n\n{summary}"
    )
    return synthesis.content

result = asyncio.run(run_analysis("SBIN"))

When to Use vs Avoid

Use whenAvoid when
Independent perspectives neededAgents need to build on each other's work
Time-sensitive (parallel = faster)Results contradict and no clear resolution
Multiple specialties on same problemShared state needs coordination
Higher confidence via votingResource constraints (API rate limits)

The one-sentence summary

Concurrent orchestration runs multiple specialist agents simultaneously on the same input, then aggregates — best when you need diverse perspectives or voting for higher confidence, but requires a conflict resolution strategy.

Practice Drill

  1. Create stock-research-agent/concurrent_analysis.py with the code above
  2. Run it for SBIN. How long does it take? Compare with your sequential agent from Lesson 5.
  3. Add a 5th agent: "competitive positioning" agent
  4. Try the voting pattern: run 3 copies of the SAME agent and compare outputs. Are they consistent?
⚡ Quick Check
Q1: What's the difference between sectioning and voting?
Show answer

Sectioning divides the task into different subtasks (fundamental, technical, sentiment). Voting runs the same task multiple times and aggregates for confidence (3 code reviewers, majority rules). Sectioning = different specialists. Voting = same specialist, multiple times.

Q2: What aggregation strategy would you use if 4 agents give contradictory stock recommendations?
Show answer

Options: (1) LLM-synthesized summary that weighs all perspectives, (2) Weighted voting (fundamental + risk weigh more than sentiment), (3) Present all 4 views to the human and let them decide. The right answer depends on the use case. For investment decisions, presenting all views + a synthesis is best.

Want to see these patterns in action?

Explore the live apps built with these agent architectures.

Explore the Lab →

← Back to Deep Expertise Track