◉CLAUDE LABJP
●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…●2.1.301 — Adds the vim % motion, LaTeX math rendering in the VS Code panel, and a retry-watchdog limit for usage-limit waits (10/15)●2.1.299 — Conversations over 200K tokens left idle about 54 minutes get compacted; MCP allow rules now match only the server they name●SONNET 4.5 — Retires on the Claude API on 11/30, 45 days left. Migrate to Sonnet 5.5●WINDOWS — Reports say hooks break silently only on Japanese-locale Windows; check the character encoding first●FAST MODE — Opus 5.5 fast mode is out of research preview and no longer needs the beta header (10/15)●NEW — I Put a Ten-Line Promise File at the To…
Articles/API & SDK
⬡ API & SDK/2026-04-21Advanced

Inserting Approval Gates Into Your Agents — A Production Design for Human-in-the-Loop With the Claude API

Once you put an agent in production, the requirement 'please get a human to approve just this specific decision' appears within days. This guide walks through the design patterns for retrofitting approval gates and handling suspend/resume correctly, with working code.

human-in-the-loopagent14approvaltool-use24production111

✦ Premium Article

When you hand tools to an agent, it usually works remarkably well. The problem is the small percentage of cases that slip past "usually," where something irreversible happens.

The first time I ran an agent in production, what scared me most wasn't bugs — it was the agent working too correctly. Once you list a payment API, an email sender, or a database DELETE as available tools, Claude will call them without hesitation when it decides they're needed. A flow that behaved perfectly in tests can, under real user edge cases, execute tools in an unexpected order. Before you notice, a wrongly-addressed invoice is sitting in a customer's inbox, or a partial refund has gone through to the wrong account.

This article covers production design patterns for inserting Human-in-the-Loop (HITL) — the pattern where a human steps in for specific decisions — into Claude API's standard tool_use / tool_result loop, with working code. Instead of giving up on autonomy entirely, the trick is to decide in advance where you'll stop, who approves, and what they'll see. The rest of this article walks through that design space end to end, starting from the risk framing and ending with a three-step rollout for an agent you're already running.

What to Think About Before Your Agent "Just Runs" Something

Before designing HITL, articulate what you actually want to stop. This is not purely a technical question; it's a business-risk question. Teams that skip this step tend to put approval on every single tool call, and approval fatigue sets in until nobody actually reads the requests. The slide is easy to picture: approvals start detailed, then degrade to "looks fine," then become a keyboard reflex.

You can reduce the design axes to three:

  • Irreversibility: Can the operation be undone? (payments, contract signing, external emails, DNS changes)
  • Blast radius: Does the impact stay inside one internal user, or does it touch external customers or public systems?
  • Amount / compliance threshold: Should the gate activate only above certain monetary thresholds, or when personal data, regulated data, or cross-jurisdictional data is involved?

Classify every tool along these axes into Red (always approve), Yellow (approve under conditions), and Green (automatic). Document this before writing code. Red means you always stop, Yellow means threshold logic, Green means run as usual. When the classification is explicit, the human reviewer also has a clear sense of what they're evaluating in each request. Putting this matrix in a shared document also gives you something product managers and legal reviewers can read and challenge, which is far harder to do with raw code.

A Common Misconception — "Approving Everything" Is Not Safer

It feels intuitively correct that more approval gates mean more safety, but in production it increases incidents. Humans who repeatedly receive monotonous approval requests stop reading them and start rubber-stamping — a familiar failure in any system that leans on a human to confirm what a machine has already decided.

I don't have a hard number to offer, but my sense is that once approval requests pile up day after day, reviewers start skimming — and sooner than you'd expect. The courage to remove gates and the quality of your Yellow thresholds determine the quality of production operations. At design time, estimate how many approvals per day each gate will fire. If the real number exceeds the estimate, loosen the threshold or add automation logic instead of burying your reviewers. It helps to track a simple metric: "what percentage of requests are rejected?" If that number is essentially zero for a given gate, the gate is probably providing no value, only cost.

Five Places Where You Can Insert an Approval Gate

Where you place the gate along the agent's lifecycle trades off implementation complexity against safety. I usually choose from these five and combine them per project.

1. Just Before Tool Execution (Most Common)

Insert a gate immediately after Claude returns a tool_use block and before you actually call the tool. A human reviews the input parameters; if acceptable, you execute, otherwise you send back a rejection or correction message. The implementation is the simplest, and you can tune Red/Yellow/Green on a per-tool basis. It's also the easiest to explain to stakeholders, which matters more than it sounds when you're getting buy-in from legal or compliance teams.

2. Before Returning the Tool Result

After the tool runs, check the result before passing it back to Claude. For example, you might filter out personally identifiable information from database query results, or strip out rows that belong to customers outside a permitted region. Because you intercept before Claude uses the data for further reasoning, this suits privacy-sensitive or data-leak-prone cases. It's especially useful when the tool itself is safe to run (it only reads) but the content it returns might steer the agent into regulated territory.

3. Dynamic Gate Based on Parameter Values

The tool itself doesn't require approval, but the gate triggers only for specific inputs — for example, "auto-approve refunds under ¥10,000, require approval above." This is the design that most often balances operations load and safety, and it's almost always my first recommendation for a new project. You can compose several dimensions into the trigger: amount, customer tier, time of day, rate of the same operation within a short window. Each dimension you add is another lever for tuning later.

4. Plan Review at Session Start

Let Claude produce "just the plan" first, have a human review it, then start execution. This is useful for long-running agents or critical business processes, but you need a separate design for what happens when Claude tries to call new tools mid-session. The usual pattern is to allow a pre-approved set of tools to run freely after plan approval, while any tool outside the plan triggers a normal per-call gate. It's more state to track, but the user experience for both the agent and the operator is much smoother.

5. Fallback Gate on Anomaly Detection

The agent runs fully autonomous most of the time, with a human only stepping in when error rates or unexpected tool-call patterns appear. It requires integration with monitoring metrics, so implementation cost is higher, but it's worth adopting when you don't want to drop your automation rate. A simple starting point: if the agent calls the same tool more than N times within M minutes, or if two consecutive tool calls return errors, pause for review. These signals catch runaway loops and regression regressions without affecting normal traffic.

For the first iteration on a project, I recommend starting from #3 (dynamic gate). It's the pattern that fails the least. #1 and #2 are simple but tend to invite approval fatigue. #4 and #5 are more complex. Adding #1 or #5 later is easier because you'll have operations data to calibrate thresholds. This sequencing is the opposite of what looks "safer on paper," and it's the single most common mistake I see in initial HITL designs.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You'll stop struggling to identify which operations are too risky to automate — you'll have a clear framework with five placement options for approval gates and three decision axes
✦You'll be able to suspend and resume the tool_use / tool_result loop, and you'll have concrete code connecting Claude API with Slack and email approval flows
✦You'll understand how to prevent production-specific incidents like privilege escalation, double execution, and expired approvals, with audit logs and timeout designs that stand up to compliance review
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

⬡ API & SDK2026-09-03
Don't Hand Your Agent the Tool That Commits — Sorting Tools Into Advise, Prepare, and Commit
Before you wrap irreversible actions in an approval gate, decide which ones never belong in the tool list at all. A three-tier inventory, a rewritten tool definition, and a small script that flags commits hiding in your schema.
⬡ API & SDK2026-05-26
Stabilizing Claude API Structured Responses in Production — Notes on tool_use, JSON Schema, and Layered Validation
Getting Claude to return JSON takes a few lines. Keeping that JSON usable in production is a different problem. Here is the layered design I landed on after running a wallpaper classification pipeline through Claude API, built around tool_use, JSON Schema, and domain validation.
⬡ API & SDK2026-05-22
Why tool_result could not be submitted Keeps Coming Back, and How to Build a Recovery Handler That Actually Holds
Run a Claude agent long enough and one day it starts: 'tool_result could not be submitted', back to back, and retries change nothing. The error message hides four completely different root causes. Here is what I learned debugging it on the always-on agent jobs I run as an indie developer, with the TypeScript recovery handler I now ship in production.