Ir al contenido principal
Human-in-the-Loop: When Your AI Agent Must Stop

Human-in-the-Loop: When Your AI Agent Must Stop

AI Integration
5 min readPor Daily Miranda Pardo

The agent works perfectly in staging. Fifty test cases, all pass. You deploy to production.

Three weeks later: the invoicing agent generated a duplicate charge for a client. The support agent refunded €2,100 that didn't qualify. The lead classifier rejected what turned out to be your biggest prospect of the quarter.

Not bugs. Not model failures. The agent did exactly what it was designed to do, correctly, in scenarios your tests didn't cover.

The missing piece: human oversight at the right moment.

The Most Common Architecture Mistake

Most teams implement AI agents as linear flows: trigger → LLM → action. Works in staging because inputs are controlled. Production is different.

In production the agent encounters:

  • Ambiguous inputs where even the model's confidence is borderline
  • Irreversible actions — charges, deletions, external emails, API mutations — that cost real money or relationships if wrong
  • Edge cases that don't appear in your test dataset

The solution is not more tests. It's designing the agent to stop and ask when it should stop and ask.

The Three HITL Patterns That Actually Work

1. Confidence Threshold on the Decision

Most LLMs, especially with structured outputs, can return a confidence score alongside their decision. If that score is below your threshold, don't execute — interrupt.

type AgentDecision = {
  action: "approve_refund" | "reject_lead" | "send_invoice";
  confidence: number; // 0.0 → 1.0, produced by the LLM
  reasoning: string;
  payload: Record<string, unknown>;
};

async function executeWithHITL(decision: AgentDecision): Promise<void> {
  if (decision.confidence < 0.85) {
    await requestHumanApproval(decision);
    return; // agent pauses here
  }
  await executeAction(decision);
}

The 0.85 threshold isn't universal. Start at 0.90, measure interrupt frequency, lower it gradually as you validate the pattern with real data.

2. Hardcoded Business Rules

Some actions should always require human approval, regardless of model confidence:

type BusinessRule = (decision: AgentDecision) => boolean;

const ALWAYS_ESCALATE: BusinessRule[] = [
  (d) => d.action === "delete_record",
  (d) => (d.payload.amount as number) > 5_000,
  (d) => d.payload.isFirstPurchase === true,
  (d) => d.payload.accountAge === "new",
];

function requiresHuman(decision: AgentDecision): boolean {
  if (decision.confidence < 0.85) return true;
  return ALWAYS_ESCALATE.some((rule) => rule(decision));
}

This isn't a limitation — it's a safety contract. The agent knows what it can decide autonomously and what must be escalated. Define your rules based on business risk, not technical complexity.

3. Async Approval with State Checkpoint

The hard part: the agent needs to pause, persist its state, notify a human, and resume when approved. Without a checkpoint, resumption means restarting from scratch — which may have side effects.

// 1. Save checkpoint before pausing
const checkpointId = await db.checkpoints.create({
  agentState: JSON.stringify(currentState),
  pendingDecision: decision,
  expiresAt: new Date(Date.now() + 24 * 60 * 60 * 1000),
  status: "pending",
});

// 2. Notify the human (Telegram, Slack or email)
await notify({
  to: process.env.APPROVER_CONTACT,
  message: `Pending decision: ${decision.reasoning}`,
  approveUrl: `${BASE_URL}/api/hitl/approve?id=${checkpointId}`,
  rejectUrl:  `${BASE_URL}/api/hitl/reject?id=${checkpointId}`,
});

// 3. Approval webhook — /api/hitl/approve/route.ts
export async function POST(req: Request) {
  const { id, approved } = await req.json();
  const cp = await db.checkpoints.findById(id);

  if (!cp || cp.status !== "pending") {
    return Response.json(
      { error: "invalid or expired checkpoint" },
      { status: 400 }
    );
  }

  if (approved) {
    await executeAction(cp.pendingDecision);
    await db.checkpoints.update(id, { status: "approved" });
  } else {
    await db.checkpoints.update(id, { status: "rejected" });
  }

  return Response.json({ ok: true });
}

One key detail: the checkpoint expires in 24 hours. An agent waiting indefinitely for human approval is a stuck process. Define the expiration and the fallback: auto-reject, further escalation, or an urgent alert.

What You Should NOT Gate

Every interrupt has a cost: latency, human attention, workflow complexity. Gating everything defeats the purpose of automation.

Don't use HITL for:

  • Purely informational actions: reading data, generating reports, summarizing emails
  • High-confidence, low-risk flows: actions with 99%+ confidence in well-tested patterns
  • Time-sensitive automations: if the value is speed, a 30-minute approval window kills it
  • Reversible actions: if an action can be undone with one click, let the agent run and fix it post-hoc

HITL is for irreversibility and uncertainty. Use it surgically.

The Real Distribution in Production

In the systems we implement at DAILYMP for enterprise AI agents, the observed distribution after the first few weeks is consistent:

  • 3–5% of decisions end up in human approval
  • 95% flow autonomously without intervention
  • 100% are logged in the audit trail with full decision context

That's exactly what it should look like. The agent doesn't decide everything — it decides what it can decide with guarantees.

How We Design It From the First Commit

When we implement AI integrations for our clients, HITL isn't a production patch: it's part of the initial design.

  1. Risk mapping: which actions are irreversible? which have monetary or relational impact?
  2. Threshold calibration: we monitor confidence distributions for the first 2 weeks, then adjust
  3. Notification routing: who approves what, different escalation paths for different teams
  4. State persistence: every agent that might interrupt uses a checkpoint system from day one
  5. Audit trail: every decision — autonomous or human-approved — is logged with full context

The result: agents that can be trusted with real production load because the system knows when to stop.

Conclusion

An autonomous agent without HITL is not a production agent — it's a staging agent that accidentally reached production. The confidence threshold, business rule gates, and async checkpoints described here aren't optional complexity. They're the architecture of a system that can be trusted.

If you're building AI agents and haven't designed the interruption points yet, start there. Everything else — observability, evals, persistent memory — builds on a foundation that includes human supervision by design.

We design agents with human oversight built in from the first commit →

Compartir artículo

LinkedInXWhatsApp

¿Procesos repetitivos en tu empresa?

Descarga gratis el Mapa de Automatización IA — los 5 procesos que más tiempo roban y cómo resolverlos.

Sin spam. Solo el PDF. Puedes darte de baja cuando quieras.

Escrito por Daily Miranda Pardo

Ayudo a empresas a automatizar procesos, crear agentes IA y conectar sistemas inteligentes.