The Coordinator pattern
In lesson 10, the TriageAgent made a single Workers AI call. That produced useful analysis, but one model call trying to cover command-line forensics, identity assessment, network reputation, and activity patterns simultaneously results in breadth without depth.
The solution is fan-out + fan-in: dispatch multiple specialized analysis calls in parallel, wait for all to complete, then synthesize the results into a single triage card.
┌── Command-Line Analyzer ──┐
│ │
Incident ── Coordinator ├── Identity Analyzer ──────┤
│ ├── Synthesizer ── Triage Card
├── Network Analyzer ────────┤
│ │
└── Activity Analyzer ──────┘
Each sub-agent is a focused Workers AI call with its own system prompt. The Coordinator dispatches all four in parallel using Promise.all, then passes the combined results to a Synthesizer that produces the final triage card.
Fan-out / fan-in triage pipeline
graph LR A[Incident] --> B[Coordinator] B --> C[Command-Line Analyzer] B --> D[Identity Analyzer] B --> E[Network Analyzer] B --> F[Activity Analyzer] C --> G[Synthesizer] D --> G E --> G F --> G G --> H[Triage Card]
The dispatch pattern
The core of the Coordinator is surprisingly simple:
const [command, identity, network, activity] = await Promise.all([
analyzeCommandLine(env.AI, incident),
analyzeIdentity(env.AI, incident),
analyzeNetwork(env.AI, incident),
analyzeActivity(env.AI, incident),
]);
const triageCard = await synthesize(env.AI, {
command,
identity,
network,
activity,
});
All four analysis calls run concurrently. Because each is an independent Workers AI call, they don’t block each other. The total latency is roughly the time of the slowest sub-agent, not the sum of all four.
The four sub-agents
Each analyzer receives the same incident data but has a system prompt focused on one dimension.
Command-Line Analyzer
Focus: Decodes obfuscated commands, identifies LOLBin (Living Off the Land Binary) abuse, extracts indicators of compromise from process execution chains.
For the Malware + C2 incident, this analyzer should decode the Base64-encoded PowerShell command, identify the use of certutil or regsvr32 for code execution, and extract the C2 callback URL from the decoded payload.
Identity Analyzer
Focus: Assesses user compromise likelihood based on access patterns, risk factors (departing employee, privileged account), anomaly signals (impossible travel, off-hours access).
For the Data Exfiltration incident, this analyzer should flag the departing employee status, the off-hours access pattern, and the access to sensitive data repositories as high-risk indicators.
Network Analyzer
Focus: Evaluates destination reputation, infrastructure signals (hosting provider, domain age, certificate patterns), and traffic volume/pattern anomalies.
For the Malware + C2 incident, this analyzer should flag the C2 IP address, assess the hosting infrastructure, and note the periodic beaconing pattern in the network traffic.
Activity Analyzer
Focus: Surfaces baseline deviations by comparing current activity against the user’s historical patterns. Identifies lead-up activity (reconnaissance, staging) and correlates with other recent alerts.
For the Phishing incident, this analyzer should note the credential submission to an external URL followed by an immediate mailbox forwarding rule creation — a pattern strongly associated with BEC.
The Synthesizer
The Synthesizer is the fan-in step. It doesn’t just concatenate the four sub-agent outputs — it weighs them, checks for agreement, and produces a unified assessment.
The Synthesizer receives all four analysis results and produces a structured triage card:
{
"incident_id": "INC-2026-0042",
"severity": "P1",
"confidence": "high",
"incident_type": "malware_c2",
"summary": "Active C2 beacon via encoded PowerShell...",
"indicators": {
"ips": ["203.0.113.42"],
"domains": ["update-service.example.com"],
"hashes": ["a1b2c3d4..."],
"commands": ["powershell -enc ..."]
},
"sub_agent_agreement": "unanimous",
"recommended_next_step": "engage_response_agent"
}
Key fields:
severity— P0 through P3, derived from the sub-agent assessments. If the Command-Line Analyzer finds active C2 and the Network Analyzer confirms a known-bad destination, that’s at least P1.confidence— How certain the assessment is. High confidence when sub-agents agree; lower when they conflict.sub_agent_agreement— Whether the four sub-agents reached the same conclusion. “Unanimous” means all four agree on severity. “Split” means at least one disagrees — a signal for the analyst to look more closely.recommended_next_step— What should happen next. For active threats, it’s “engage_response_agent” (lesson 12).
Step 1: Review the Coordinator
Open sirt-workshop-app/src/agents/coordinator.ts and read the dispatch logic. Identify:
- How the four analyzer functions are imported and called
- The
Promise.allpattern for parallel execution - How the results are collected and passed to the synthesizer
- Where errors from individual sub-agents are handled (what happens if one fails?)
Step 2: Review a sub-agent
Open sirt-workshop-app/src/agents/analyzers/command-line.ts and read:
- The system prompt — this is what makes it a “command-line analyzer” rather than a generic chatbot
- How the incident data is formatted for this specific analysis dimension
- The expected output structure
Compare it mentally to the single prompt from lesson 09. The sub-agent’s prompt is narrower and deeper — it only needs to analyze command-line patterns, so it can be much more specific about what to look for.
Step 3: Review the Synthesizer
Open sirt-workshop-app/src/agents/synthesizer.ts and read how it:
- Takes the four sub-agent outputs as input
- Instructs the model to assess agreement/disagreement between sub-agents
- Produces the structured triage card with severity, confidence, and indicators
- Determines the recommended next step
Step 4: Redeploy and test
If you haven’t redeployed since lesson 10, deploy now:
npx wrangler deploy
Open your app and click Investigate on the Malware + C2 Beacon incident. You should see:
- Four analysis sections appear — one for each sub-agent (Command, Identity, Network, Activity)
- A synthesized triage card with severity, confidence, indicators, and a recommended next step
The four sub-agent analyses should each focus on their specific dimension. The Command-Line Analyzer should talk about the encoded PowerShell; the Network Analyzer should talk about the C2 IP and beaconing pattern.
Step 5: Try a different incident
Go back to the queue and investigate the Data Exfiltration incident. The sub-agent outputs should be meaningfully different:
- Identity Analyzer should flag the departing employee status as a major risk factor
- Network Analyzer should flag the personal cloud storage upload destination
- Activity Analyzer should note the off-hours access and the volume of data accessed
- Triage card should likely be P0 (confirmed data exfiltration by an insider)
This demonstrates the power of the parallel pattern: each sub-agent contributes specialized analysis that a single-call approach would blur together.
What comes next
The triage card now includes a recommended_next_step field. For active threats, it says "engage_response_agent". In lesson 12, you’ll add the Response Agent — it reads structured playbook files, matches them to the incident type, and generates a concrete action plan with per-action risk levels and approve/reject controls. That completes the core triage-to-recommendation pipeline.