Human Feedback Loops: Approval, Grading, Editing, Escalation, and Resumption
The demo works. The agent reaches a consequential step, pauses, and asks a human to approve. The human clicks approve. Then the resumed run re-executes the…

Key topics
The demo works. The agent reaches a consequential step, pauses, and asks a human to approve. The human clicks approve. Then the resumed run re-executes the payment it already sent, forgets why it paused, or continues on a plan the human just invalidated.
Nothing in that failure is about model quality. It is about the pause boundary. The moment you insert a person into an agent loop, you have introduced a suspension point, and a suspension point is a state problem before it is a UI problem.
This article assumes the loop contract from the anatomy-of-an-agent-loop material: state, action, observation, feedback, termination. Here we extend it with a human as a first-class participant. The question is not only where do I put the human. The hidden question is what must survive the pause.
Why a Human in the Loop Is Not a Blocking Call
The naive model treats the human as a synchronous function:
decision = human(proposed_action) # blocks until a value returns
if decision == "approve":
execute(proposed_action)
This is fine in a demo with one step and no side effects. It breaks the moment three things are true at once: latency is non-trivial, the process can die or be redeployed, and some actions are irreversible.
A blocking call assumes the caller stays alive, the world stays still, and the return value is the only thing that matters. Production violates all three. The human takes minutes or hours. The worker gets recycled. The downstream system the agent was reasoning about changes while it waits.
The stronger model is an interruptible state machine. The loop suspends at a defined boundary, persists enough state to reconstruct intent, and resumes without replaying committed effects. The human is not a function that returns a value. The human is an event that transitions the machine.
That reframing changes what you build. You stop asking "how do I call the human" and start asking "what is the checkpoint, what is the decision record, and what is the resume point."
Intervention timing is the first design axis:
| Timing | What the human does | Typical use |
|---|---|---|
| Pre-action | Authorizes a specific pending effect | Payments, writes, sends, deletes |
| Mid-trajectory | Corrects course between steps | Plan repair, wrong tool, bad retrieval |
| Post-action | Grades or labels an outcome | Evaluation, policy updates |
| Out-of-band | Reviews after completion | Audit, compliance, sampling |
The cost of a pause is not just wall-clock time. It is context decay (the retrieved evidence is now stale), plan staleness (the world moved), and the risk that the resumed run acts on a snapshot that no longer holds. Design for the pause, not around it.
Knowledge check
Check your understanding
Answer this question before you continue.
The Four Intervention Points and What Each One Buys You
The useful decision rule is not "which is easiest to wire up." It is "what must change." Four things can change: the action, the artifact, the policy, or the ownership of the decision.
Approval authorizes a specific pending action. It is cheap to implement and expensive in latency, and it degrades into rubber-stamping when the reviewer lacks the context to judge. Approval changes the action — it gates an effect.
Grading scores or labels an outcome. It feeds evaluation and future policy, not the current trajectory, unless you route the grade back as a correction signal. Grading changes the policy.
Editing modifies the agent's output or plan in place. It is the most information-dense intervention and the hardest to reconcile with the agent's internal state, because the human's edit and the agent's plan can now disagree. Editing changes the artifact.
Escalation is the agent (or a policy) deciding it cannot proceed and handing control up. This is a routing decision, not a review decision, and it needs its own trigger logic. Escalation changes the ownership of the decision.
The most common misuse is using approval as a substitute for a good evaluator. That converts a judgment problem into a human-throughput problem, and human throughput does not scale with your traffic.
Pick the intervention by what must change. If the action is fine but the plan is wrong, approval is the wrong tool — you want editing or mid-trajectory correction. If you cannot tell whether the outcome was good, you want grading, not a gate.
Knowledge check
Check your understanding
Answer this question before you continue.
What Must Survive the Pause: A Resumption State Contract
A human decision is only as good as the state it lands on. Separate three layers:
- Durable task state — goal, plan, completed steps, artifacts. Must survive process death.
- Ephemeral reasoning state — scratchpad, retrieved context, intermediate tool outputs. May be reconstructed or discarded.
- The pending decision itself — the thing the human is answering.
The pending decision record is the piece most teams under-build. It should carry the proposed action, the rationale, the evidence the human needs to judge it, the allowed response shape, and an expiry or staleness policy. A raw transcript is not a decision record. It is archaeology.
A minimal checkpoint looks like this:
{
"task_id": "t_8841",
"plan_version": 3,
"status": "awaiting_human",
"completed_steps": ["fetch_balance", "validate_recipient"],
"pending_action": {
"type": "transfer",
"params": {"amount": 4200, "to": "acct_991"},
"reversible": false,
"idempotency_key": "t_8841:transfer:acct_991:4200"
},
"evidence": {"balance_snapshot": "...", "policy_check": "pass"},
"decision": null,
"invalidated_steps": [],
"resume_token": "rt_7f2a",
"expires_at": "<decision-window>"
}
The fields that matter most are the ones that prevent replay. Mark which actions are reversible, which are committed, and which must never be re-executed on resume. Idempotency is not a nice-to-have here; it is the difference between a safe resume and a double charge.
Versioning the plan is the second half of the contract. If the human edits the plan, the agent needs to know which downstream steps are invalidated and which completed work still counts. Without a plan_version, the resumed agent cannot tell whether its cached reasoning is still valid.
Staleness deserves its own policy. A decision made against a world snapshot may be wrong by the time it is applied. Define what invalidates a pending approval — a balance change, a new policy, a timeout — and enforce it at resume, not at approval time.
Knowledge check
Check your understanding
Answer this question before you continue.
The Transition Trace: Approve, Execute, Commit, Resume
The checkpoint above is a snapshot. The invariant that makes resumption safe lives in the transitions between snapshots, not in the record itself. A boolean committed flag cannot prove an external effect happened, because the worker can die before, during, or after the side effect. The only reliable source of truth is the external system, reconciled through an idempotency key.
Here is the sequence that holds:
awaiting_human
└─ human approves ──────────────► approved
└─ worker claims task ─────► executing
├─ external call returns success ─► committed
├─ external call returns failure ─► rejected (retryable)
└─ timeout / ambiguous ───────────► reconciling
└─ query external by idempotency_key
├─ effect present ──────► committed
├─ effect absent ───────► approved (safe retry)
└─ cannot determine ────► escalate to human
The rule that makes this work: never mark committed before the external system confirms the effect, and never retry after an ambiguous outcome without reconciling first. A crash between executing and committed is not a lost execution — it is an unresolved one, and the reconciling branch is what resolves it.
The idempotency key is what makes reconciliation possible. Pass it to the downstream system so a retried call is deduplicated rather than duplicated. If the downstream system does not support idempotency keys, you cannot safely auto-retry an ambiguous outcome; you must reconcile or escalate. That is a real constraint, not a detail.
Resumption must reconcile the durable action record with the external system. It cannot infer effect completion from worker survival.
This is also where staleness enforcement belongs. On resume, check expires_at and the invalidation conditions before executing. If the world moved, transition to stale and re-derive the plan rather than proceeding on a snapshot that no longer holds.
Knowledge check
Check your understanding
Answer this question before you continue.
Escalation Triggers: Deciding When the Agent Should Ask
Escalation is a routing problem, and routing needs trigger logic. Two distinct conditions drive it, and conflating them produces bad thresholds.
Epistemic uncertainty is about the model's knowledge: low confidence, disagreement across samples, or an input shape the agent has not seen. A low-confidence model may still be acceptable for a reversible draft.
Effect risk is about the action: irreversibility, blast radius, or a policy gate. A high-confidence model can still require escalation because the action cannot be undone.
The trigger rule follows from both axes. Escalate when uncertainty is high or effect risk is high — but calibrate the threshold per risk domain, not globally. A stricter bar for money movement, a looser one for a draft.
Five trigger families cover most cases:
- Confidence or uncertainty signals — the model's own doubt, or disagreement across samples.
- Risk or blast radius — how much damage the action can do if wrong.
- Policy and compliance rules — hard gates that do not depend on model judgment.
- Novelty or out-of-distribution inputs — the agent has not seen this shape before.
- Repeated failure within the loop — the same step has failed twice; stop retrying.
Calibrate against observed error rates and reviewer load, not intuition. The target is a sustainable escalation rate, not zero escalations. Over-escalation burns reviewer attention and trains rubber-stamping. Under-escalation ships irreversible mistakes.
Escalation that carries no actionable question forces the human to reconstruct the agent's reasoning. That is exactly where review quality collapses. Attach the decision record, not the transcript.
The right reviewer needs the right context. Routing is not a notification; it is a match between the decision and the person who can actually make it.
Applying the Human Decision Without Corrupting the Trajectory
Once the human responds, you have three merge semantics, and each maps to a distinct state transition with a different invalidation scope:
| Decision | Transition | Invalidation scope |
|---|---|---|
| Accept | approved → executing | None; proceed with pending action |
| Modify | approved → re-derive | Artifact edit: local. Plan edit: downstream steps |
| Reject | rejected → last valid state | Failed step and its dependents |
Accept proceeds with the pending action. The transition is approved → executing → committed, with no invalidation.
Modify applies the human's edit and re-derives affected steps. Editing an artifact may be local; editing a plan can invalidate everything downstream. Record the invalidated steps in invalidated_steps so the resumed agent knows what to recompute.
Reject returns to the last valid state with a reason attached. The transition is rejected, and the reason should map to a failure class the agent can act on, not a free-text note it will ignore. "Wrong recipient" is actionable. "No" is not.
A rejection without a reason is a dead end. The decision record must be visible to the next reasoning step. Otherwise the agent re-proposes the same rejected action, and you have built a loop that argues with its reviewer. When the human's edit conflicts with the agent's constraints — a policy violation, a missing dependency — surface the conflict rather than silently overriding one side.
Feedback That Compounds: Turning Interventions into Policy
There are two loops here, and conflating them is a common mistake. The immediate loop is this decision: approve, edit, reject, resume. The outer loop is aggregated feedback that changes prompts, tools, routing, or models.
Grading is normally an outer-loop signal. It affects the current trajectory only when the workflow explicitly converts the grade into a typed correction and a resume event. Otherwise it feeds evaluation and future policy after aggregation and review. Keep that distinction clear when deciding where to put a grader.
Human grades and edits are training and evaluation signal only if they are captured in a structured, attributable form. Free-text comments rarely pinpoint the actual failure cause. A thumbs-down may not identify the failing step, so pair human signal with telemetry before you act on it.
Real-time adaptation is often unavailable or unsafe in governed systems. Periodic, reviewed updates are the realistic path for many platforms, and that is a feature, not a limitation — it keeps a human in the approval chain for changes to the agent itself.
Use human feedback to change the current trajectory when latency allows. Use it to change the system when the same failure class recurs.
That is the decision rule that keeps per-decision intervention from becoming noise.
Failure Modes and the Metrics That Catch Them
Human-in-the-loop systems degrade in predictable ways. Each has a detectable signature:
| Failure mode | Signature | Detection |
|---|---|---|
| Rubber-stamping | Approvals cluster at high confidence | Random audits, disagreement sampling |
| State loss on resume | Work redone, rejections forgotten | Replay tests, resume-path assertions |
| Ambiguous side effect | Duplicate or lost external effect | Reconciliation checks, idempotency-key audit |
| Escalation drift | Thresholds never retuned | Escalation rate trend |
| Context starvation | Fast, low-quality approvals | Time-to-decision vs. quality |
The ambiguous-side-effect row is the one that breaks the central promise of resumption. A timeout from a payment or write API is not state loss and not a post-resume error — it is a distinct recovery class. The recovery decision is one of three: reconcile against the external system, compensate with a reversing action, or escalate to a human. Retrying blindly is none of those.
The metrics worth tracking are time-to-decision, escalation rate, approval-to-rejection ratio, resume success rate, unresolved-effect count, and post-resume error rate. Resume success rate is the one teams forget, and it is the one that catches the state-loss bugs. Unresolved-effect count catches the reconciliation gaps.
And the boundary case: do not insert a human where the action is high-volume, low-risk, and reversible. There, the human is a bottleneck with no governance benefit. Autonomy with monitoring is the better design.
The Decision Rule
Choose the intervention point by what must change — the action, the artifact, the policy, or the ownership of the decision — and design the checkpoint before you design the UI. The UI is the easy part. The state contract and its transitions are what decide whether the resumed run preserves intent or quietly corrupts it.
Concretely: instrument a single agent loop with a pending-decision record, an idempotency key, and a resume test. Kill the process while a decision is pending, restart it, and assert that the resumed run preserves intent and does not replay committed effects. Then kill it again during the external call and assert that the reconciling branch resolves the ambiguous outcome instead of duplicating the effect. If it fails either test, you have found the bug before your users did.
Knowledge check
Final check
Finish the article by checking the ideas you just learned.
References
- Adaptive Data Flywheel: Applying MAPE Control Loops to AI Agent Improvement
- Human-in-the-Loop AI Agents: Deploying Agentic AI With Control | Elementum
- GitHub - baljindersingh/multi-agent-ag2: This repo demonstrates human-in-the-loop pattern and multi-agent orchestration using AG2 (AutoGen 2.0). It showcases how agents, workflows, and human oversight can be combined for reliable and controllable AI solutions. · GitHub
Research updated Sep 11, 2026


