← All work
Multi-agent · Human-in-the-loop · LangGraph

Twenty specialist agents, two human sign-offs

Marketing-technology company · active engagement · 2025–2026 · Backend and agent architecture

The AI can propose. Only a person can release.

A marketing-campaign platform where AI drafts the strategy and the outreach, but an expert and then the client approve before anything moves — and a crashed run picks up where it stopped.

Orchestration
LangGraph, fan-out into 4 branches, fan-in
Human gates
Expert → client, per-gate authorisation
Models
Anthropic, OpenAI, Gemini; Perplexity for research
Tests
~1,300 test functions, 147 files

What they needed

A platform that produces marketing strategies and runs lead outreach at scale. The AI never publishes or contacts anyone on its own, and an interrupted run loses no work.

What I built

A strategy pipeline of twenty specialist agents that fan out, come back together, and stop at two gates: an expert reviews, then the client approves. A lead pipeline that qualifies leads by explicit rules (no AI guesswork on who to contact), enriches them and syncs with the CRM. It listens to LinkedIn outreach events and drafts replies that a human approves before sending. Every run keeps a decision trace and a cost line per agent.

What changed

The client has a system where approvals are enforced in code, runs are resumable, and every model call has a price tag. (This engagement is ongoing; no outcome figures are claimed.)

Under the hood
  • Strategy DAG as a LangGraph StateGraph; each subagent is its own class with its own prompt module and typed Pydantic input/output. A conditional edge skips the client gate when routing returns BLOCKED.
  • Gates via interrupt() with per-gate caller authorisation; every run records per-node human | logic sources and an immutable decision trace.
  • Durability: Firestore checkpointer; a run paused in a dead process is rebuilt by class name + thread id; mid-DAG entry for partial re-runs. Approvals are first-write-wins and idempotent because LangGraph re-runs a node on resume; an append-only ledger records every delivery attempt; reconciliation retries are capped, then dead-lettered.
  • Cost control: token tracker (model, tokens, cost per call per agent), usage quotas → 429, hard cap on concurrent campaigns.
  • Lead pipeline: rule-based three-tier qualification (auto / human review / exclude) with a written reason per lead; enrichment via Apollo and Apify; HubSpot two-way CRM sync built; LinkedIn outreach webhooks reference-counted in a Firestore transaction; reply drafts held in a review queue until a human releases them.
LangGraphFirestoreFastAPIAnthropicOpenAIGeminiHubSpot API