Case study · Architect · 40 min
Agentic Workflow with Human Approval Gates
Orchestrate a multi-step business agent that drafts actions, pauses for human approval on irreversible steps, then resumes reliably.
agentsHITLworkflows
Interview opener
Agent proposes actions that need human approval in enterprise.
- 1.How do you represent pending actions durably?
- 2.Approver is offline — timeout policy?
- 3.Audit trail for regulators?
Strong signals
Hit 0/3
Weak signals (avoid)
- Fire tools then ask forgiveness
- No durable state for approvals
Requirements
- Workflow: intake → research → draft email/CRM update → approve → execute
- Human SLA: approvals within 4 business hours; reminders at 2h
- Idempotent execution; full audit; resume after deploy
- Scale: 2,000 workflows/day; 30% need approval
Back-of-envelope Estimation
| Metric | Calculation | Result |
|---|---|---|
| Workflows/day | 2,000 | 2,000 |
| LLM calls/workflow | ~5 | 10,000 |
| Tokens/day | 10K × 2.5K | 25M (~$50) |
| Approvals/day | 0.3 × 2,000 | 600 |
| Approver load | 600 × 2 min | 20 hours |
| Queue storage | state machines × 30d | modest |
API Design
| Endpoint | Method | Description |
|---|---|---|
| POST /v1/workflows | POST | Start workflow with input payload |
| GET /v1/workflows/{id} | GET | State, history, pending approval |
| POST /v1/approvals/{id}/decide | POST | { approve|reject|edit, notes } |
| POST /v1/workflows/{id}/resume | POST | Internal worker resume after approval |
Data Model
| Entity | Key fields | Notes |
|---|---|---|
| workflows | id, type, state, cursor, tenant_id | Durable state machine |
| steps | workflow_id, name, input, output, status | Append-only log |
| approvals | id, workflow_id, reviewer, decision | Blocks execute step |
| outbox | event_id, payload, sent | Reliable side effects |
High-level Design
API → Workflow engine (Temporal-like)
├ step: research (LLM + tools) → save artifacts
├ step: draft (LLM) → create approval record
├ WAIT human decision (timer + reminders)
├ step: execute tools via outbox (idempotent keys)
└ step: notify requester
Crash/deploy: resume from cursor; never re-send without idempotencyDeep Dive: Approval UX & Safety
- Show diff of proposed CRM fields and email body with sources
- Allow edit-then-approve; treat edits as new model-visible feedback
- Separate draft identity from execute identity (least privilege)
- Timeouts: auto-escalate to secondary approver, never auto-approve irreversible actions
Bottlenecks at Scale
- Approver bottlenecks — load-balance queues by skill
- Long-running waits — durable timers, not thread sleeps
- Duplicate executes on retry — outbox + idempotency keys mandatory
Failure Modes & Monitoring
| SLO | Target | Alert |
|---|---|---|
| Approval SLA | < 4 business h | Remind + escalate |
| Duplicate side effects | 0 | Page |
| Workflow success | > 95% | Warn |
| Stuck in WAIT | < 2% > 24h | Sweep job |
Related practice topics
Attempt the case aloud first. Then unlock a staff model answer outline.