March 14, 2026

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.

Try SiliconBridge Free