M18 solution: multi-agent SOC orchestrator
The worked, deployable agentic system: an orchestrator coordinating four security sub-agents through connectors, plus a FastAPI service that exposes it.
Educational, authorized, synthetic data only. The agents investigate and recommend, they take no action on any system. All threat-intel and log data is fake.
Files
| File | Role |
|---|---|
connectors.py |
The systems the agents reach: extract_indicators (regex), lookup_ioc (synthetic threat-intel), search_logs (synthetic log store). No keys, no network. The shape of an MCP server (M16). |
agents.py |
The four specialist sub-agents: triage (L1: severity + indicators), enrich (intel connector), correlate (log connector), report (lead: synthesize). Each is one LLM turn with a focused system prompt. |
orchestrator.py |
investigate(alert, client=None), the coordinator. Runs triage → enrich → correlate → report and returns {indicators, severity, enrichment, correlation, report}. |
app.py |
The "agentic deploy": FastAPI with GET /health and POST /investigate wrapping the orchestrator. |
../starters/add_subagent.py |
A 5th sub-agent (remediation_advisor) for Part B. |
Run it
# 1) venv active, key in .env (copy ../starters/.env.example to .env first)
python orchestrator.py # CLI: prompts for an alert, prints the report
# 2) deploy it
pip install fastapi "uvicorn[standard]"
uvicorn app:app --reload
curl -s -X POST http://127.0.0.1:8000/investigate \
-H "Content-Type: application/json" \
-d '{"alert":"failed logins for admin from 185.220.101.45, then download of customer_db.csv"}'
Design notes
- Sequential pipeline. Each sub-agent's output feeds the next; the orchestrator owns the order.
Other shapes (router, parallel fan-out, hierarchical) are in
../notes.md§3 and built with frameworks in M19. - Connectors do the deterministic work. Indicators come from a regex (
extract_indicators), not the model, so a sloppy triage prompt can't invent IPs. Enrichment/correlation read real (synthetic) data via connectors before the model summarizes. This keeps hand-offs trustworthy. - Testable.
investigate()and the agents accept an injectedclient, so the pipeline can be unit-tested with a mocked LLM (real connectors). That's how this module was verified end-to-end. - Model choice. All sub-agents use
claude-opus-4-8. In production you might run cheapclaude-haiku-4-5for triage and reserveclaude-opus-4-8for the report, different models per specialist is a benefit of splitting the work.
Verified
- Connectors run for real (indicator extraction, malicious lookup, 5 matching log lines).
- Orchestrator runs the full 4-sub-agent pipeline with a mocked LLM + real connectors: 4 LLM calls fire in order, indicators flow through, a report is assembled.
app.pyverified with FastAPITestClient:GET /health→{"status":"ok"};POST /investigate→ 200 with all five result keys.- Live LLM calls (real
ANTHROPIC_API_KEY) cost tokens, run as a pilot. The mocked path is free.