Day 4: Implement the “Human-in-the-Loop” Circuit Breaker

Build a Production-Grade AI Support Agent for ShopStream (Python) ~5 min read 15 min hands-on

Some actions need a person

After Day 3 the agent can move money. For a $5 partial refund on a late delivery that's exactly what you want: instant, cheap, happy customer. For a $160 refund on a chair, or the fiftieth refund in a minute, it isn't. Real support systems separate actions by risk: low-risk actions run automatically, high-risk ones wait for a human, and when something looks wrong at scale, the system stops itself. This lesson adds both: a human-in-the-loop approval queue and a circuit breaker.

What you build

supportdesk/guard.py, wired into the agent before every tool call:

  • Risk threshold. process_refund above REFUND_AUTO_LIMIT (default $50) is held: a row goes into a new approvals table and the tool returns {"status": "pending_approval", "approval_id": N}. The customer hears "needs a quick review by our team".

  • Approvals API. GET /approvals lists pending requests; POST /approvals/N/approve runs the refund using the idempotency key stored with the request, then marks it approved. Approving twice returns 409 and never refunds twice. /reject declines.

  • Circuit breaker. A classic three-state breaker counts automatic refunds in a sliding window. More than BREAKER_MAX_REFUNDS (5) in BREAKER_WINDOW_S (60 s) and it opens: refunds are refused for BREAKER_COOLDOWN_S (30 s). Then it goes half-open and lets exactly one trial refund through; if that succeeds, it closes.

  • Partial refunds. The model now understands "refund $20 on ORD-1001", so small, auto-approvable refunds are possible even on expensive items.

Why a breaker, not just a limit

A per-request limit ($50) protects against one bad decision. It does nothing against many small ones: a prompt-injection campaign, a bug in your intent rules, or a confused model looping through a customer's orders. The breaker watches the rate of an action across all conversations and fails closed when that rate looks abnormal. It's the same pattern that protects a service from hammering a failing dependency, pointed at your own agent.

Read the full lesson free

This lesson is one of the first 3 in its course, free with an account — the full article, implementation guide and scripts. No card needed.

Already a member? Sign in