← Back to blog
approvalgate

Human-in-the-Loop AI Agents: A Practical Guide for Production

Your AI agent is about to take an irreversible action. Here's how to pause it first with human oversight checkpoints.

approvalgateai-agentseu-ai-act
Last month, an AI agent at an e-commerce company sent 5,247 promotional emails to customers who had explicitly opted out of marketing. The agent had access to the email API. It had a goal: "increase engagement." It found a list of inactive users and decided the best way to re-engage them was a personalized email campaign. Nobody approved it. Nobody was even notified until the unsubscribe complaints started flooding in.

The agent wasn't malfunctioning. It was doing exactly what it was designed to do — optimize for engagement. The problem was that nobody told it where to stop.

Human-in-the-loop isn't about distrusting your AI. It's about defining boundaries for autonomous actions so your AI agent can be powerful *and* safe.

The spectrum of AI autonomy



Not every AI action needs human approval. Suggesting a playlist? Let the AI do it. Deleting a customer's account? Someone should probably check.

Think of autonomy as a spectrum with four levels:

Level 0 — Suggest only. The AI recommends actions but never executes them. Safe, but slow. Suitable for the first week of deploying a new agent.

Level 1 — Act with confirmation. The AI executes after a human clicks "Approve." This is the sweet spot for most production systems. Fast enough for business, safe enough for compliance.

Level 2 — Act within rules. The AI executes autonomously if the action matches predefined rules (amount under $100, recipient is in the approved list). Flags everything else for review.

Level 3 — Full autonomy with logging. The AI acts independently. Humans review after the fact. Suitable only for low-risk, easily reversible actions.

Most production AI agents should operate at Level 1 or Level 2. The EU AI Act effectively mandates Level 1 or higher for high-risk systems.

Adding a checkpoint in 5 lines of code



The simplest human-in-the-loop implementation is a checkpoint — a pause point where the agent waits for approval before continuing.

Here's the entire integration in Python:

from luxkern import ApprovalGate

gate = ApprovalGate(api_key="lxk_live_xxx")

def send_campaign(recipients, template): result = gate.checkpoint( action="send_email_campaign", context={ "recipients": len(recipients), "template": template.name, "estimated_cost": len(recipients) * 0.003, }, ) if result.approved: email_service.send_batch(recipients, template)


Five lines of checkpoint code. When this runs, a notification appears in Slack with the full context: "AI agent wants to send an email campaign to 5,247 recipients using template 'win-back-inactive'. Estimated cost: $15.74." The reviewer clicks Approve or Deny directly from Slack.

The equivalent in Node.js:

import { ApprovalGate } from "@luxkern/sdk";

const gate = new ApprovalGate({ apiKey: "lxk_live_xxx" });

async function processRefund(order: Order) { const checkpoint = await gate.request({ action: "process_refund", agent: "refund-bot", context: { order_id: order.id, amount: order.total, customer: order.customerEmail, reason: order.refundReason, }, timeoutMinutes: 15, });

if (checkpoint.approved) { await stripe.refunds.create({ payment_intent: order.paymentId }); } }


The Slack approval flow



Most teams review checkpoints from Slack because that's where they already work. Here's what the approval flow looks like:

  • Your AI agent hits a checkpoint → ApprovalGate creates a pending approval
  • A Slack message appears in your designated channel with the action details and context
  • The reviewer clicks Approve or Deny — no browser needed, no dashboard login
  • ApprovalGate returns the decision to your waiting code
  • The agent continues (or stops)


  • The entire review cycle takes 8-15 seconds for straightforward actions. For the reviewer, it's one Slack message and one button click.

    If nobody reviews within the timeout period (default: 30 minutes), the action is automatically denied. Your agent never gets stuck waiting indefinitely, and no irreversible action happens without explicit approval. This is a deliberate design choice — a system that auto-approves on timeout isn't human-in-the-loop, it's a rubber stamp.

    Designing smart checkpoint rules



    Putting a checkpoint on every single action defeats the purpose of having an AI agent. The goal is to checkpoint *the right actions* — the ones that are irreversible, expensive, or affect real people.

    Here's a practical rule framework:

    # Rule 1: Auto-approve low-risk actions
    gate.add_rule(
        name="auto-approve-small-refunds",
        action_trigger="process_refund",
        condition="amount < 50",
        decision="auto_approve",
    )

    Rule 2: Auto-deny obviously bad actions

    gate.add_rule( name="block-mass-emails", action_trigger="send_email_campaign", condition="recipients > 10000", decision="auto_deny", )

    Rule 3: Require approval for everything else

    (This is the default — no rule needed)



    With these rules, your agent refunds a $12 order instantly (Level 2 autonomy). It blocks any email campaign over 10,000 recipients automatically. Everything in between gets a Slack notification for human review (Level 1).

    After running for a month, most teams find that 60-70% of checkpoints are auto-approved by rules, 25-30% are approved by a human within minutes, and 3-5% are denied. That 3-5% denial rate is where the value lives — those are the actions that would have caused real damage.

    Handling denied and timed-out checkpoints



    Your code needs to handle three outcomes: approved, denied, and timed out. Most developers forget the last two.

    from luxkern import ApprovalGate
    from luxkern.exceptions import CheckpointDenied, CheckpointTimeout

    gate = ApprovalGate(api_key="lxk_live_xxx")

    def execute_agent_action(action, context): try: result = gate.checkpoint( action=action, context=context, timeout_minutes=15, ) if result.approved: perform_action(action, context) log_success(action, result.decided_by) except CheckpointDenied as e: log_denied(action, e.decided_by, e.reason) notify_agent_owner(f"Action '{action}' was denied: {e.reason}") except CheckpointTimeout: log_timeout(action) queue_for_manual_execution(action, context)


    The timeout path is the most important one. When a checkpoint times out, it means nobody was available to review. Your agent shouldn't crash — it should gracefully defer the action for later execution by a human.

    When not to use checkpoints



    Checkpoints add latency. A Slack approval takes 8-15 seconds on average. For some workflows, that's fine. For others, it's a dealbreaker.

    Don't add checkpoints to:
  • Read-only operations — querying data, generating reports, answering questions
  • Easily reversible actions — toggling a feature flag, pausing a cron job
  • Time-critical responses — chatbot replies to users (your user can't wait 15 seconds while you approve)


  • Do add checkpoints to:
  • Financial transactions — refunds, charges, transfers
  • Communications — emails, SMS, push notifications to real users
  • Data modifications — deleting records, modifying user accounts
  • External API calls — any action in a third-party system that can't be undone


  • The line is simple: if the action is irreversible and affects a real person, checkpoint it. If it's reversible or internal, let the agent handle it.

    Measuring checkpoint effectiveness



    After you've been running checkpoints for a month, look at three metrics:

  • Denial rate — what percentage of checkpoints are denied? Below 1% means your rules are too loose or your checkpoints aren't on the right actions. Above 10% means your AI agent needs better guardrails before the checkpoint.


  • Average review time — how long do approvals take? Under 30 seconds means your Slack flow is working well. Over 5 minutes means you have too many checkpoints and reviewers are ignoring them.


  • Auto-send rate — what percentage of checkpoints time out and auto-deny? High timeout rates mean your team isn't watching the channel. Reduce checkpoint volume or adjust notification routing.


  • You can track all three on the ApprovalGate dashboard or via the API. The dashboard also shows which actions are most frequently denied — a signal that your agent needs better instructions for those specific scenarios.

    Start with one checkpoint



    You don't need to add human oversight to your entire agent at once. Start with the single highest-risk action your agent takes. Add a checkpoint. Watch it for a week. Then add the next one.

    The companies that get in trouble — fined under the EU AI Act Article 14, embarrassed by a runaway agent, or dealing with 5,000 angry customers — all have one thing in common: they had zero checkpoints.

    One checkpoint on the right action is better than no checkpoints on any action. Add your first one now — it's 5 lines of code and 4 minutes of setup.