Add Human-in-the-Loop to OpenAI Agents with SiliconBridge
You've built an OpenAI Agent that handles customer support tickets. It drafts responses, prioritizes escalations, and applies refunds. It's amazing. Until it refunds a customer for a non-existent order. Now you want human approval on refunds above $100.
Integrating human-in-the-loop approval into OpenAI Agents is straightforward. SiliconBridge provides a tool that agents can call to request human approval. The agent pauses. A human operator reviews the decision. The operator approves or rejects. The agent continues.
This tutorial shows you how to do it in 10 minutes with Python.
What Is Human-in-the-Loop for Agents?
Human-in-the-loop means the agent doesn't make final decisions alone. For critical actions — refunds, account changes, large transfers — the agent proposes an action and a human approves it.
This isn't micro-management. Agents still run autonomously. They just escalate high-stakes decisions to humans. Benefits:
Risk control: High-value decisions get human oversight. $100+ refunds require approval. Account deletions require confirmation.
Learning: Humans approve or reject decisions, giving the agent feedback. Over time, the agent learns to propose better decisions.
Compliance: Regulators often require human oversight on certain actions. Now you can prove humans reviewed and approved the decision.
Customer trust: Customers know their cases aren't decided by pure automation. A human verified the decision. This builds confidence.
Prerequisites
Python 3.10+: We use OpenAI's agent SDK and the SiliconBridge SDK.
OpenAI API key: Available at platform.openai.com.
SiliconBridge API key: Get one free at siliconbridge.xyz.
Install dependencies:
pip install openai siliconbridge
Step 1: Create a Basic OpenAI Agent
Start with a simple agent that handles customer support:
from openai import OpenAI
import json
# Initialize OpenAI client
client = OpenAI(api_key="your_openai_api_key")
# Define agent tools (without human approval yet)
tools = [
{
"type": "function",
"function": {
"name": "get_customer_account",
"description": "Retrieve customer account details by email",
"parameters": {
"type": "object",
"properties": {
"customer_email": {
"type": "string",
"description": "Customer's email address"
}
},
"required": ["customer_email"]
}
}
},
{
"type": "function",
"function": {
"name": "issue_refund",
"description": "Issue a refund to a customer",
"parameters": {
"type": "object",
"properties": {
"customer_email": {"type": "string"},
"amount": {"type": "number"},
"reason": {"type": "string"}
},
"required": ["customer_email", "amount", "reason"]
}
}
}
]
# Create system prompt
system_prompt = """You are a customer support agent for an e-commerce platform.
Your job is to help customers with issues like refunds, account management, and troubleshooting.
Always be professional and thorough. For refunds above $100, request human approval before processing."""
# Start conversation
messages = [
{"role": "user", "content": "I want a refund for order #12345. It cost $150."}
]
print("Starting support ticket conversation...")
print(f"Customer: {messages[-1]['content']}\n")
Step 2: Add the SiliconBridge Approval Tool
Now add the human-in-the-loop approval tool from SiliconBridge:
import time
from siliconbridge import SiliconBridge
# Initialize SiliconBridge client
sb = SiliconBridge(api_key="your_siliconbridge_api_key")
# Add the human-in-the-loop approval tool
approval_tool = {
"type": "function",
"function": {
"name": "request_human_approval",
"description": "Request human approval for a high-stakes action (e.g., refunds, account changes)",
"parameters": {
"type": "object",
"properties": {
"action_type": {
"type": "string",
"description": "Type of action (e.g., 'refund', 'account_deletion', 'password_reset')"
},
"action_summary": {
"type": "string",
"description": "Brief summary of what the agent wants to do"
},
"reasoning": {
"type": "string",
"description": "Why the agent thinks this action is appropriate"
},
"amount": {
"type": "number",
"description": "Amount if applicable (e.g., refund amount)"
}
},
"required": ["action_type", "action_summary", "reasoning"]
}
}
}
# Add to tools list
tools.append(approval_tool)
print("✓ Added human-in-the-loop approval tool")
Step 3: Implement Tool Execution with Approval Logic
Now handle the approval tool when the agent calls it:
def execute_tool(tool_name, tool_input):
"""Execute a tool or request human approval"""
if tool_name == "request_human_approval":
# Request approval from SiliconBridge
approval_request = sb.request_approval(
action_type=tool_input['action_type'],
summary=tool_input['action_summary'],
reasoning=tool_input['reasoning'],
metadata={
"amount": tool_input.get('amount'),
"timestamp": time.time()
},
timeout_seconds=300 # 5 minute approval window
)
print(f"\n⏸ Agent requesting human approval for: {tool_input['action_summary']}")
print(f" Approval ID: {approval_request['approval_id']}")
print(f" Waiting for human review...\n")
# Wait for human operator to respond
while True:
status = sb.check_approval_status(approval_request['approval_id'])
if status['status'] == 'approved':
print(f"✓ Human approved: {tool_input['action_summary']}")
return {
"approved": True,
"approval_id": approval_request['approval_id'],
"operator_notes": status.get('notes', '')
}
elif status['status'] == 'rejected':
print(f"✗ Human rejected: {tool_input['action_summary']}")
return {
"approved": False,
"approval_id": approval_request['approval_id'],
"rejection_reason": status.get('reason', 'No reason provided')
}
elif status['status'] == 'pending':
print(" Still waiting for approval...")
time.sleep(3)
else:
return {"approved": False, "error": "Approval request expired"}
elif tool_name == "issue_refund":
# Check if refund amount requires approval
amount = tool_input.get('amount', 0)
if amount > 100:
# Request approval first
approval = execute_tool(
"request_human_approval",
{
"action_type": "refund",
"action_summary": f"Issue ${amount} refund to {tool_input['customer_email']}",
"reasoning": f"Reason: {tool_input.get('reason', 'Not provided')}",
"amount": amount
}
)
if not approval['approved']:
return {"success": False, "error": f"Refund rejected: {approval.get('rejection_reason')}"}
# Process the refund
return {
"success": True,
"message": f"Refunded ${amount} to {tool_input['customer_email']}"
}
elif tool_name == "get_customer_account":
# Mock customer data
return {
"customer_email": tool_input['customer_email'],
"account_status": "active",
"total_purchases": 5,
"last_order": "Order #12345 - $150"
}
else:
return {"error": f"Unknown tool: {tool_name}"}
Step 4: Run the Agent Loop
Now run the agent with tool handling:
def run_agent_loop(user_message):
"""Run the agent loop until completion"""
messages.append({"role": "user", "content": user_message})
while True:
# Call OpenAI agent
response = client.beta.agents.messages.create(
model="gpt-4",
system=system_prompt,
tools=tools,
messages=messages
)
# Check if agent wants to use tools
if response.stop_reason == "tool_calls":
# Process tool calls
tool_results = []
for tool_call in response.tool_calls:
print(f"→ Agent calling: {tool_call.function.name}")
# Execute tool (with approval logic)
result = execute_tool(
tool_call.function.name,
json.loads(tool_call.function.arguments)
)
tool_results.append({
"type": "tool_result",
"tool_use_id": tool_call.id,
"content": json.dumps(result)
})
# Add assistant response and tool results to messages
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
else:
# Agent finished, print final response
print(f"\nAgent: {response.content[0].text}")
break
# Test the agent
run_agent_loop("I want a refund for order #12345. It cost $150.")
Step 5: Handle Operator Responses
On the human operator side (running on SiliconBridge's platform), the operator sees an approval request and responds:
# This runs on the operator's side (via SiliconBridge dashboard or SDK)
approval_id = "approval_xyz"
# Operator approves the refund
sb.approve_request(
approval_id=approval_id,
approved=True,
notes="Customer's order was damaged. $150 refund approved."
)
# Or, reject it:
sb.reject_request(
approval_id=approval_id,
reason="This customer has a history of false refund claims. Manual review required."
)
Full End-to-End Example
Here's the complete working code:
import json
import time
from openai import OpenAI
from siliconbridge import SiliconBridge
# Initialize clients
openai_client = OpenAI(api_key="your_openai_api_key")
sb_client = SiliconBridge(api_key="your_siliconbridge_api_key")
# Define tools
tools = [
{
"type": "function",
"function": {
"name": "get_customer_account",
"description": "Get customer account info",
"parameters": {
"type": "object",
"properties": {
"customer_email": {"type": "string"}
},
"required": ["customer_email"]
}
}
},
{
"type": "function",
"function": {
"name": "issue_refund",
"description": "Issue a refund",
"parameters": {
"type": "object",
"properties": {
"customer_email": {"type": "string"},
"amount": {"type": "number"},
"reason": {"type": "string"}
},
"required": ["customer_email", "amount", "reason"]
}
}
},
{
"type": "function",
"function": {
"name": "request_human_approval",
"description": "Request human approval for high-value actions",
"parameters": {
"type": "object",
"properties": {
"action_type": {"type": "string"},
"action_summary": {"type": "string"},
"reasoning": {"type": "string"},
"amount": {"type": "number"}
},
"required": ["action_type", "action_summary", "reasoning"]
}
}
}
]
system_prompt = "You are a customer support agent. For refunds over $100, request human approval."
messages = []
def handle_tool_call(tool_name, tool_input):
if tool_name == "request_human_approval":
approval = sb_client.request_approval(
action_type=tool_input['action_type'],
summary=tool_input['action_summary'],
reasoning=tool_input['reasoning'],
metadata={"amount": tool_input.get('amount')}
)
print(f"Approval request {approval['approval_id']} sent to operator")
# Poll for response
while True:
status = sb_client.check_approval_status(approval['approval_id'])
if status['status'] != 'pending':
return status
time.sleep(2)
elif tool_name == "issue_refund":
amount = tool_input.get('amount', 0)
if amount > 100:
approval = handle_tool_call("request_human_approval", {
"action_type": "refund",
"action_summary": f"Refund ${amount}",
"reasoning": tool_input.get('reason'),
"amount": amount
})
if approval.get('status') != 'approved':
return {"error": "Refund rejected"}
return {"success": True, "message": "Refund processed"}
elif tool_name == "get_customer_account":
return {"status": "active", "email": tool_input['customer_email']}
return {}
# Run agent
def run_agent(user_input):
messages.append({"role": "user", "content": user_input})
response = openai_client.beta.agents.messages.create(
model="gpt-4",
system=system_prompt,
tools=tools,
messages=messages
)
if response.stop_reason == "tool_calls":
for call in response.tool_calls:
result = handle_tool_call(call.function.name,
json.loads(call.function.arguments))
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": [
{"type": "tool_result", "tool_use_id": call.id,
"content": json.dumps(result)}
]})
return run_agent("") # Continue loop
return response.content[0].text
print(run_agent("Customer wants $150 refund for damaged order #12345"))
Testing the Integration
To test this locally without waiting for a human operator:
# Use mock mode for testing
sb_client = SiliconBridge(
api_key="your_api_key",
mock_mode=True # Simulates operator approvals
)
# Approvals auto-respond after 2 seconds (for testing)
# In production, real operators approve via the SiliconBridge dashboard
Advanced: Customizing Approval Rules
You can set custom approval rules to reduce manual work:
# Auto-approve low-value refunds
sb_client.set_approval_rules(
rules=[
{
"condition": "action_type == 'refund' AND amount <= 50",
"action": "auto_approve"
},
{
"condition": "action_type == 'refund' AND amount > 500",
"action": "escalate_to_supervisor" # Higher approval level
},
{
"condition": "action_type == 'account_deletion'",
"action": "always_require_approval"
}
]
)
Conclusion
Human-in-the-loop approval with OpenAI Agents is simple and powerful. Your agents stay autonomous but critical decisions get human oversight. Use SiliconBridge to request, track, and respond to approvals — all with a single API call.
Ready to add human oversight to your agents? Get your free API key and start building hybrid agents today.