Human-in-the-Loop (HITL)

Require human approval before your AI agent takes action.

What is HITL?

Human-in-the-Loop (HITL) is a governance pattern where agent actions are paused and queued for human approval before execution. This is the strictest form of oversight, ideal for high-risk or irreversible actions.

When to Use HITL

  • Financial transactions - Payments, transfers, refunds
  • Data modifications - Deletes, updates to critical data
  • External communications - Emails, messages to customers
  • System changes - Configuration updates, deployments
  • Compliance-sensitive - Actions requiring audit trails
⚠️
Latency Impact
HITL blocks execution until approval. Only use for actions where the delay is acceptable.

Enabling HITL

Via SDK

hitl_agent.py
from turingpulse import instrument, GovernanceDirective

@instrument(
    agent_id="financial-agent",
    governance=GovernanceDirective(
        hitl=True,
        reviewers=["finance@company.com", "compliance@company.com"],
        escalation_timeout=3600,  # Escalate after 1 hour
        auto_reject_after=86400,  # Auto-reject after 24 hours
    )
)
def process_refund(user_id: str, amount: float, reason: str):
    """This function will pause for approval before executing."""
    return payment_service.refund(user_id, amount, reason)

Via UI

  1. Navigate to Governance → Policies
  2. Click Create Policy
  3. Select Human-in-the-Loop (HITL)
  4. Choose the workflow to apply
  5. Configure reviewers and timeouts
  6. Save and enable

Conditional HITL

Apply HITL only when certain conditions are met:

conditional_hitl.py
from turingpulse import instrument, GovernanceDirective

@instrument(
    agent_id="financial-agent",
    governance=GovernanceDirective(
        hitl=True,
        # Only require approval for high-value transactions
        hitl_condition=lambda ctx: (
            ctx.metadata.get("amount", 0) > 10000 or
            ctx.metadata.get("action") == "delete" or
            ctx.metadata.get("risk_score", 0) > 0.8
        ),
        reviewers=["finance@company.com"],
    )
)
def process_transaction(action: str, amount: float):
    # Small transactions proceed automatically
    # Large transactions wait for approval
    return execute_transaction(action, amount)

HITL Workflow

1. Action Triggered

When an instrumented function is called with HITL enabled:

  • Execution pauses before the function body runs
  • A review request is created in TuringPulse
  • Reviewers are notified via configured channels

2. Review Queue

Reviewers see the pending action in the Review Queue:

  • Action Details - Function name, arguments, metadata
  • Context - User info, session history, risk indicators
  • Workflow Info - Which agent/workflow triggered

3. Review Actions

  • Approve - Allow the action to proceed
  • Reject - Block the action (raises exception)
  • Modify - Edit parameters and approve
  • Escalate - Forward to another reviewer

4. Execution Resumes

After approval, the function executes normally. After rejection, a HITLRejectedException is raised.

Handling Rejections

handle_rejection.py
from turingpulse import instrument, GovernanceDirective
from turingpulse.exceptions import HITLRejectedException

@instrument(
    agent_id="financial-agent",
    governance=GovernanceDirective(hitl=True, reviewers=["admin@company.com"])
)
def process_refund(user_id: str, amount: float):
    return payment_service.refund(user_id, amount)

# Handle rejection gracefully
try:
    result = process_refund("user-123", 500.00)
    print(f"Refund processed: {result}")
except HITLRejectedException as e:
    print(f"Refund rejected: {e.reason}")
    print(f"Rejected by: {e.reviewer}")
    # Notify user, log, etc.

Timeouts and Escalation

Escalation

If a review isn't completed within the timeout, escalate to additional reviewers:

governance = GovernanceDirective(
    hitl=True,
    reviewers=["level1@company.com"],
    escalation_timeout=1800,  # 30 minutes
    escalation_reviewers=["level2@company.com", "manager@company.com"],
    escalation_channels=["pagerduty://critical"],
)

Auto-Approve/Reject

Prevent indefinite blocking with automatic resolution:

governance = GovernanceDirective(
    hitl=True,
    reviewers=["admin@company.com"],
    
    # Auto-approve after 4 hours (for low-risk actions)
    auto_approve_after=14400,
    
    # Or auto-reject after 24 hours (for time-sensitive actions)
    auto_reject_after=86400,
)
⚠️
Use Carefully
Auto-approve should only be used for lower-risk actions where the cost of delay exceeds the risk of the action.

HITL Configuration

OptionTypeDescription
hitlboolEnable HITL governance
hitl_conditioncallableFunction to determine if HITL applies
reviewerslist[str]Email addresses of reviewers
escalation_timeoutintSeconds before escalation
escalation_reviewerslist[str]Reviewers for escalation
escalation_channelslist[str]Alert channels for escalation
auto_approve_afterintSeconds before auto-approval
auto_reject_afterintSeconds before auto-rejection

Best Practices

  • Use conditions - Apply HITL conditionally to avoid overwhelming reviewers with low-risk actions.
  • Set appropriate timeouts - Balance urgency with reviewer availability.
  • Configure escalation - Ensure actions don't get stuck if primary reviewers are unavailable.
  • Provide context - Include relevant metadata to help reviewers make informed decisions.
  • Monitor queue depth - Track review queue size to ensure adequate reviewer capacity.

Next Steps