Action Restrictions and Permissions › Confirmation Steps for Risky Actions
AI Agent HandbookAll chapters Action Restrictions and Permissions › Confirmation Steps for Risky ActionsOne section · Sections in this chapter4 / 11 ↓
Some actions are too risky to perform automatically, even if they're technically allowed. For these, you want the agent to ask for confirmation first.
Think about how your smartphone handles this. When an app wants to access your camera, it doesn't just do it. It asks: "Allow this app to access your camera?" You have to explicitly approve.
Your agent should do the same for high-stakes actions. Here's how to implement confirmation for email sending:
## Using Claude Sonnet 4.5 for multi-turn confirmation flows
import os
from anthropic import Anthropic
class AgentWithConfirmation:
def __init__(self):
self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
self.pending_actions = {}
def run(self, user_message, conversation_history=None):
"""Run the agent with confirmation support"""
if conversation_history is None:
conversation_history = []
# Add user message to history
conversation_history.append({
"role": "user",
"content": user_message
})
# Define tools with confirmation requirement
tools = [{
"name": "send_email",
"description": "Send an email. Requires user confirmation before sending.",
"input_schema": {
"type": "object",
"properties": {
"to_address": {"type": "string"},
"subject": {"type": "string"},
"body": {"type": "string"}
},
"required": ["to_address", "subject", "body"]
}
}]
# Call the model
response = self.client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=conversation_history,
tools=tools
)
# Check if agent wants to use a tool
if response.stop_reason == "tool_use":
tool_use = next(block for block in response.content if block.type == "tool_use")
if tool_use.name == "send_email":
# Store the pending action
action_id = "email_001"
self.pending_actions[action_id] = tool_use.input
# Ask user for confirmation
confirmation_message = f"""I'm ready to send this email:
To: {tool_use.input['to_address']}
Subject: {tool_use.input['subject']}
Body: {tool_use.input['body']}
Do you want me to send this email? (Reply 'yes' to confirm or 'no' to cancel)"""
return confirmation_message, conversation_history
# Return normal response
return response.content[0].text, conversation_history
def confirm_action(self, action_id, confirmed):
"""Execute or cancel a pending action based on user confirmation"""
if action_id not in self.pending_actions:
return "No pending action found."
action = self.pending_actions[action_id]
if confirmed:
# Execute the action
result = send_email_restricted(
action['to_address'],
action['subject'],
action['body']
)
del self.pending_actions[action_id]
return f"Confirmed. {result}"
else:
# Cancel the action
del self.pending_actions[action_id]
return "Action cancelled."Let's see this in action:
User: Send an email to alice@example.com with subject "Meeting Tomorrow"
and body "Let's meet at 2pm"
Agent: I'm ready to send this email:
To: alice@example.com
Subject: Meeting Tomorrow
Body: Let's meet at 2pm
Do you want me to send this email? (Reply 'yes' to confirm or 'no' to cancel)
User: yes
Agent: Confirmed. Email sent to alice@example.comThe agent prepares the action but doesn't execute it. It shows you exactly what it's about to do and waits for your approval. Only when you say "yes" does the email actually get sent.
This pattern works for any risky action:
- Deleting files: Show which files will be deleted
- Making purchases: Show the item and price
- Posting to social media: Show the exact content to be posted
- Modifying data: Show what will change
The key is to make the confirmation specific. Don't just ask "Is this okay?" Show exactly what will happen so the user can make an informed decision.