Core Concept
Human-in-the-Loop (HITL)
Protocol-level human oversight for autonomous agent decisions
What is HITL?
Human-in-the-Loop enables AI agents to request explicit human approval before executing critical actions. The approval workflow is managed at the protocol level, making it:
- •Channel-agnostic - Works with SMS, email, voice, push notifications, or any communication method
- •LLM-managed - AI interprets natural language responses for approval/rejection
- •Auditable - All decisions logged with timestamps and user IDs
- •Time-bounded - Approvals expire after a configurable timeout
When to Use HITL
Recommended
- • High-value transactions ($100+)
- • Personal data sharing
- • Irreversible actions
- • Regulatory compliance
- • First-time services
Consider Carefully
- • Low-value routine tasks
- • Time-sensitive operations
- • Fully autonomous agents
- • Public information queries
How It Works
- 1Agent Negotiation - Your agent negotiates with a service provider
- 2Create Approval - Agent creates approval request in Amorce
- 3Notify Human - Your app notifies the user via their preferred channel
- 4Human Response - User responds with natural language (e.g., "yes", "sounds good")
- 5LLM Interpretation - AI interprets the response as approve/reject
- 6Submit Decision - Decision submitted to Amorce protocol
- 7Agent Proceeds - Agent completes or cancels the transaction
Channel Options
HITL is protocol-level, meaning the Amorce SDK doesn't send notifications directly. You choose how to communicate with humans:
📱SMS (Twilio)
"Sarah needs approval: Book table for 4. Reply YES/NO"
One-click approve/reject links in email body
🎙️Voice (Vapi.ai)
"Say approve or decline to continue"
📲Push Notifications
Native mobile app notifications with actions
Code Example (Python)
from amorce import AmorceClient
# 1. Agent negotiates with service
response = client.transact(
service_contract={"service_id": "srv_restaurant"},
payload={"intent": "book_table", "guests": 4}
)
# 2. Request human approval
approval_id = client.request_approval(
transaction_id=response['transaction_id'],
summary="Book table for 4 guests at Le Petit Bistro",
details=response['result'],
timeout_seconds=300
)
# 3. Your app notifies human (SMS/email/push/etc.)
notify_user_via_sms(
message=f"Approve booking? {approval_id}"
)
# 4. Check approval status
status = client.check_approval(approval_id)
if status['status'] == 'approved':
# 5. Finalize transaction
client.transact(
service_contract={"service_id": "srv_restaurant"},
payload={"intent": "confirm"}
)LLM Interpretation
HITL supports natural language responses instead of rigid YES/NO:
import google.generativeai as genai
# Human responds: "sounds good to me!"
human_response = "sounds good to me!"
# LLM interprets intent
interpretation = genai.GenerativeModel('gemini-pro').generate_content(
f'Is this approving or rejecting? "{human_response}"'
'Answer: APPROVE or REJECT'
).text
decision = "approve" if "APPROVE" in interpretation else "reject"
client.submit_approval(
approval_id=approval_id,
decision=decision,
approved_by="user@example.com",
comments=human_response
)Security & Audit Trail
All approval decisions are permanently logged in Amorce with:
Approval ID
Unique identifier
Transaction ID
Links to the original transaction
Decision
approve/reject/expired
Approved By
User identifier
Timestamp
When decision was made
Comments
Original human response
Best Practices
Do's
- ✓ Use clear, concise approval summaries
- ✓ Set appropriate timeout periods (consider time zones!)
- ✓ Provide context in the details field
- ✓ Handle expired approvals gracefully
- ✓ Verify human identity before submitting decisions
Don'ts
- ✗ Don't use HITL for every minor decision
- ✗ Don't set timeouts too short (<60 seconds)
- ✗ Don't expose approval IDs publicly
- ✗ Don't assume approvals will always complete
- ✗ Don't proceed on 'rejected' or 'expired' status
API Reference
Create Approval
POST /api/v1/approvalsGet Approval Status
GET /api/v1/approvals/:approval_idSubmit Decision
POST /api/v1/approvals/:approval_id/submitFor detailed API documentation, see the API Reference.