Workflow:Openai Openai agents python Human In The Loop Approval
| Knowledge Sources | |
|---|---|
| Domains | AI_Agents, Human_In_The_Loop, Safety |
| Last Updated | 2026-02-11 14:00 GMT |
Overview
End-to-end process for implementing a human-in-the-loop approval workflow where tool calls require explicit user approval before execution, using the SDK's interruption and RunState mechanism.
Description
This workflow demonstrates the SDK's interruption-based approval system. When a tool is configured with needs_approval=True, the Runner pauses execution when the model requests that tool, producing an interruption instead of executing it. The run result contains the pending interruptions and can be serialized to a RunState object. An external process (human reviewer, approval UI, or automated policy) examines each pending tool call and approves or rejects it. The RunState is then passed back to Runner.run() to resume execution with the decisions applied. This pattern enables safe deployment of agents that interact with sensitive systems.
Usage
Execute this workflow when your agent has access to tools that perform irreversible or sensitive actions (e.g., shell commands, database modifications, financial transactions, sending communications) and you need human oversight before those actions execute. This is critical for production deployments where autonomous tool execution poses risk.
Execution Steps
Step 1: Define Tools with Approval Requirement
Create tools and set needs_approval=True to require human approval before execution. This can be a static boolean or a callable that dynamically decides based on the tool call context. For hosted MCP tools, configure require_approval in the tool config.
Key considerations:
- needs_approval can be True (always require), False (never require), or a callable
- The callable receives the tool context and can make dynamic decisions
- ShellTool and other sensitive tools commonly use this pattern
- Multiple tools on the same agent can have different approval requirements
Step 2: Initial Agent Execution
Call Runner.run() with the agent and user input. If the model generates a tool call that requires approval, the run pauses and returns a RunResult with a non-empty interruptions list instead of a final output.
Key considerations:
- The run does not raise an exception on interruption; it returns normally
- Check result.interruptions to detect pending approvals
- result.final_output may be None if the run was interrupted before completion
Step 3: Serialize to RunState
Call result.to_state() to serialize the current execution state into a RunState object. This state captures the full conversation history, pending tool calls, and all context needed to resume execution later.
Key considerations:
- RunState is serializable (can be stored in a database, sent over HTTP, etc.)
- The state includes all pending interruptions that need decisions
- Multiple interruptions can exist simultaneously if multiple tools need approval
Step 4: Process Approval Decisions
Iterate over the interruptions and present each pending tool call to the human reviewer. For each interruption, call state.approve() or state.reject() to record the decision. Optional always_approve or always_reject flags auto-decide future calls to the same tool.
Key considerations:
- state.approve(interruption) allows the tool to execute
- state.reject(interruption) blocks the tool and sends a rejection message to the model
- always_approve=True auto-approves all future calls to that tool in this run
- always_reject=True auto-rejects all future calls to that tool in this run
Step 5: Resume Execution
Pass the RunState back to Runner.run() to resume execution. The Runner replays approved tool calls, feeds rejected tool results to the model, and continues the agent loop. If new tool calls requiring approval arise, the process repeats.
Key considerations:
- The resume call may produce new interruptions if additional tool calls need approval
- Use a while loop checking result.interruptions to handle multiple approval rounds
- The final result is obtained when no more interruptions remain