Pattern Guide
SPINE has two main orchestration patterns:
| Pattern | How it runs | When to use |
|---|---|---|
| Fan-Out | Parallel | Independent tasks that can run together |
| Pipeline | Sequential | Steps that depend on each other |
Fan-Out (Parallel)
Run multiple tasks at once, then combine the results. Good when tasks don’t depend on each other.
Parent Envelope
▿ ▿ ▿
Analyst A
Analyst B
Analyst C
▿ ▿ ▿
Aggregate Results
When to use it
| Scenario | Example |
|---|---|
| Multi-source research | Query multiple docs at once |
| Parallel analysis | Security, style, and logic review |
| Independent subtasks | Generate tests for multiple functions |
| Competitive evaluation | Compare approaches |
Pseudo example
tasks = [
{ message: "Analyze source A", agent: "analyst-a" },
{ message: "Analyze source B", agent: "analyst-b" },
{ message: "Analyze source C", agent: "analyst-c" }
]
result = fan_out(parent_envelope, tasks, max_workers: 5)
Cost
pie title Fan-Out Cost Breakdown (3 agents)
"Orchestrator (1x)" : 1
"Parallel Agents (3x)" : 3
"Aggregation (0.5x)" : 0.5
Total: ~4.5x single-agent cost. Trade-off: more expensive, but faster wall-clock time.
Pipeline (Sequential)
Process data through stages where each stage feeds the next. Good for transformations that build on each other.
Stage 1
Analyze
Analyze
➜
Stage 2
Extract
Extract
➜
Stage 3
Transform
Transform
➜
Stage 4
Synthesize
Synthesize
When to use it
| Scenario | Example |
|---|---|
| Document processing | Parse → Extract → Summarize |
| Data transformation | Fetch → Clean → Analyze → Report |
| Build processes | Lint → Test → Build → Deploy |
| Staged analysis | Explore → Plan → Implement → Verify |
Pseudo example
steps = [
{ name: "analyze", prompt: "You are an analyst." },
{ name: "extract", prompt: "Extract key findings." },
{ name: "synthesize", transform: combine_results }
]
result = pipeline(parent_envelope, steps)
ToolEnvelope
Both patterns wrap operations in a ToolEnvelope for traceability.
Trace examples
Fan-out:
graph TB
subgraph fanout["Fan-Out Trace"]
R1["root: research-task-001"] --> O["orchestrator"]
O --> AS["agent-security ∥"]
O --> AST["agent-style ∥"]
O --> AL["agent-logic ∥"]
R1 --> AGG["aggregator"]
end
subgraph pipe["Pipeline Trace"]
R2["root: document-process-001"] --> S1["stage-1-analyze"]
R2 --> S2["stage-2-extract"]
R2 --> S3["stage-3-transform"]
R2 --> S4["stage-4-synthesize"]
end
style R1 fill:#2563eb,stroke:#93c5fd,color:#fff
style R2 fill:#2563eb,stroke:#93c5fd,color:#fff
style O fill:#7c3aed,stroke:#a78bfa,color:#fff
style AGG fill:#0d9488,stroke:#5eead4,color:#fff
style AS fill:#f59e0b,stroke:#fcd34d,color:#000
style AST fill:#f59e0b,stroke:#fcd34d,color:#000
style AL fill:#f59e0b,stroke:#fcd34d,color:#000
Combining Patterns
Fan-out inside a pipeline
Run parallel tasks as one stage:
Prepare
➜
A
B
C
➜
Synthesize
Pipelines inside fan-out
Run independent pipelines in parallel:
graph LR
D[Dispatch] --> P1["Pipeline 1: Docs"]
D --> P2["Pipeline 2: Code"]
D --> P3["Pipeline 3: Tests"]
P1 --> AG[Aggregate]
P2 --> AG
P3 --> AG
style D fill:#2563eb,stroke:#93c5fd,color:#fff
style P1 fill:#7c3aed,stroke:#a78bfa,color:#fff
style P2 fill:#7c3aed,stroke:#a78bfa,color:#fff
style P3 fill:#7c3aed,stroke:#a78bfa,color:#fff
style AG fill:#0d9488,stroke:#5eead4,color:#fff
Which Pattern?
| Factor | Fan-Out | Pipeline |
|---|---|---|
| Task independence | High | Low |
| Order matters | No | Yes |
| Speed priority | Wall-clock time | Throughput |
| Error isolation | Good | Cascading risk |
| Debugging | Parallel traces | Linear flow |
graph TB
Q{"Which pattern?"} -->|"Tasks independent?\nNeed speed?\nPartial results OK?"| FO["Fan-Out ∥"]
Q -->|"Steps depend on each other?\nOrder matters?\nNeed checkpoints?"| PL["Pipeline →"]
style Q fill:#f59e0b,stroke:#fcd34d,color:#000
style FO fill:#7c3aed,stroke:#a78bfa,color:#fff
style PL fill:#0d9488,stroke:#5eead4,color:#fff
Logging
Everything logs to ./logs/YYYY-MM-DD/*.json:
- Full envelope with trace hierarchy
- Token usage and cost estimates
- Timing
- Experiment IDs
Tips
Fan-out
- Set reasonable max_workers
- Handle partial failures
- Don’t go overboard on parallelism - cost adds up
- Use meaningful component names for debugging
Pipeline
- Make stages idempotent for safe retries
- Validate between stages
- Log intermediate results
- Use transform functions to shape data
Both
- Start simple
- Watch costs
- Always use ToolEnvelope
- Test failure modes
Related Docs
- Architecture Overview - system design and components
- Tiered Enforcement Protocol - when to use each capability level