Prompt
How do I create a human-in-the-loop approval step for agent actions?
Latest observation
Oct 9, 2026
OpenAI APIWeb search: off
A good human-in-the-loop approval step usually looks like this:
- Agent proposes an action
- System pauses
- A human reviews details
- Human approves / rejects / edits
- System continues with the approved action
Core design
1) Make actions explicit and structured
Don’t let the agent execute free-form text. Have it emit a structured “proposed action,” for example:
{
"type": "send_email",
"to": "customer@example.com",
"subject": "Order update",
"body": "Your order has shipped."
}
This makes it easy to display to a reviewer and to safely execute only after approval.
2) Insert a checkpoint before execution
When the agent wants to act, route it to an approval queue instead of directly running the action.
Typical flow:
- Agent generates action proposal
- Save proposal in database
- Notify reviewer
- Wait for decision
- On approval, execute action
- On rejection, stop or ask agent to revise
3) Give humans enough context
Show:
- The proposed action
- Why the agent wants to do it
- Relevant input/context
- Risk level
- Potential side effects
- A way to edit fields before approval
4) Support three outcomes
The reviewer should be able to:
- Approve: execute as-is
- Reject: discard or ask the agent to try again
- Edit: modify the proposal, then approve
5) Log everything
Store:
- Proposed action
- Who reviewed it
- Timestamps
- Final decision
- Executed payload
- Result / errors
This is important for auditing and debugging.
Recommended architecture
A simple pattern is:
- Agent
- plans action
- Policy layer
- decides whether approval is required
- Approval service
- stores pending actions
- presents them to humans
- Executor
- runs only approved actions
Pseudocode example
def handle_agent_action(action):
if requires_approval(action):
ticket_id = save_pending_action(action)
notify_reviewer(ticket_id)
decision = wait_for_human_decision(ticket_id)
if decision.status == "approved":
return execute_action(decision.action or action)
elif decision.status == "edited":
return execute_action(decision.edited_action)
else:
return {"status": "rejected"}
else:
return execute_action(action)
Good approval triggers
Use human approval for:
- Sending emails/messages
- Changing customer/account data
- Refunds or financial transactions
- Deleting records
- External API calls with side effects
- Anything irreversible or high impact
Useful safeguards
- Set thresholds: “approve if amount > $100”
- Require 2-person approval for sensitive actions
- Show diffs for edits
- Add timeouts and escalation
- Allow “approve once / always approve similar actions” only with care
Example UI fields
- Action type
- Target resource
- Proposed parameters
- Risk score
- Explanation
- Approve / reject / edit buttons
If you want, I can also give you:
- a LangChain/LangGraph approval-step example,
- a FastAPI + queue implementation, or
- a database schema for pending approvals.