OpenAI's July launch of ChatGPT Work lets people decide when an agent needs approval before acting. Google DeepMind's AI Control Roadmap describes supervisors that can block risky actions and escalate findings for human review. Approval is becoming part of the agent runtime, not a dialog box added after launch.
For a customer-facing chatbot, start by assigning every action to one of five execution modes. Do this before writing the tool prompt or connecting the production API.
| Execution mode | Use when | Example | Required evidence |
|---|---|---|---|
| Answer automatically | No external state changes | Explain the return policy from an approved source | Source and answer log |
| Act, then notify | Low impact, reversible, expected | Save a visitor's language preference | Result, undo path, notification |
| Ask the visitor | The visitor owns the choice and understands the consequence | Submit a lead form or book a displayed time slot | Exact values, consequence, explicit confirmation |
| Request staff approval | The business owns the risk or must verify an exception | Issue a refund or change an account entitlement | Identity, policy check, proposed change, named approver |
| Block the action | Prohibited, irreversible, or outside the bot's authority | Reveal credentials or bypass account recovery | Refusal reason and safe alternative |
This approval matrix is the core artifact. The remaining work is making each decision understandable, narrow, expiring, and auditable.
Classify the Consequence Before the Tool
A tool name does not reveal its risk. update_customer could correct a nickname or replace the email used for account recovery. create_ticket could open a harmless support case or send private medical details to a third party.
Score the proposed effect across these dimensions:
- Money: Does it charge, refund, discount, credit, or create a contractual commitment?
- Identity: Does it change a login, email, phone number, membership, role, or recovery method?
- Privacy: Does it reveal, copy, export, retain, or delete personal or confidential data?
- External visibility: Does it send a message, publish content, create a ticket, or notify another person?
- Reversibility: Can a human restore the exact previous state quickly and completely?
- Scale: Does the action affect one record, a customer account, or every user?
- Policy judgment: Is the bot applying a clear rule, or deciding whether an exception is deserved?
The highest-risk dimension should set the approval mode. A $0 profile edit still needs stronger control if it changes the recovery email. A reversible draft can be automatic even if the final publication requires approval.
Do not let the model calculate this category from scratch on every turn. Store a server-side policy beside the tool definition. The model may propose refund_invoice, but application code should decide that refunds above $50 require staff approval and that refunds above $500 are unavailable to the chatbot entirely.
This complements the chatbot tool-permissions checklist. Permissions limit what the runtime can reach; approvals decide when an allowed capability may be used.
Ask the Person Who Owns the Decision
“Human in the loop” is incomplete unless you name the human.
Visitor confirmation proves intent. It is appropriate when the visitor understands the choice and has authority over it: send my contact details, reserve this displayed time, or cancel my own request.
Staff approval proves business authorization. It belongs with refunds, unusual discounts, policy exceptions, account restrictions, data exports, and changes that require access the visitor cannot grant.
Specialist review proves qualified judgment. Legal claims, regulated advice, fraud flags, medical triage, and security incidents should route to an owner who can evaluate the issue, not merely the first available support agent.
One click cannot substitute for another. A visitor cannot approve the company's exception to a refund rule. A support agent cannot consent to sharing the visitor's data. Some actions need both decisions in sequence.
Identity must also be established outside the chat text. A person typing “I am the account owner” is a claim, not authentication. For account-specific actions, bind the conversation to a verified session or move the user through a trusted verification step before presenting the approval.
The AI-to-human handoff guide helps when the conversation itself must move to a person. An approval workflow is narrower: the chatbot can continue gathering context while one specific proposed action waits for a decision.
Show an Approval Packet, Not a Vague Question
“Would you like me to proceed?” invites accidental approval because it hides what will happen. The approval surface should show the final operation in stable fields.
| Field | What the approver must see |
|---|---|
| Action | A plain-language verb and system operation, such as “Refund invoice” and refund_invoice |
| Target | The exact account, order, booking, message, or record affected |
| Change | Before and after values, or the precise payload to be sent |
| Reason | The visitor's request plus the policy rule or exception being applied |
| Consequence | Money, access, disclosure, notification, or deletion caused by approval |
| Reversibility | How to undo the action, who can do it, and any time limit |
| Evidence | Verified identity, source policy, transcript excerpt, and relevant system state |
| Expiry | When the proposal becomes invalid and must be rebuilt |
Generate the packet from server-validated values, not a model-written summary alone. A concise model summary can help the reviewer, but the amount, recipient, target ID, and proposed fields must come from the actual tool payload.
Simon Willison's recent Datasette Agent release offers a useful implementation detail: before a database write, it displays the SQL, parameters, target database, and required permissions. The reviewer sees the operation, not just the agent's promise that the change is safe.
Worked Example: Cancel and Refund an Annual Plan
Consider a visitor who writes:
Visitor: Cancel our annual plan and refund the last payment. We stopped using it. Chatbot: I can help prepare that request. Please sign in so I can verify the account and retrieve the invoice and cancellation terms. [Visitor completes verification] Chatbot: I found annual invoice INV-1842 for $480, paid 18 days ago. The standard policy allows self-service cancellation but requires staff review for an annual refund. I can cancel renewal now and send a $480 refund request for approval. Proposed changes: - Renewal: active -> canceled at period end - Refund: $480 to the original payment method - Service access: remains active through 2027-06-26 Submit both changes? Visitor: Yes.
The visitor's “Yes” authorizes the cancellation request and confirms the proposed facts. It does not authorize the business to make a policy exception. The runtime creates a pending approval instead of calling the refund API:
approval_id: apr_7K2M policy_version: billing-2026-07-01 action: refund_invoice target: INV-1842 amount: 480.00 currency: USD destination: original_payment_method identity: verified_account_owner policy_result: staff_review_required reason: customer reports product no longer in use expires_at: 2026-07-15T14:00:00Z idempotency_key: refund-INV-1842-v1
A billing reviewer receives the policy result, invoice state, relevant transcript lines, and exact payload. If approved, server code rechecks that the invoice is still refundable, uses the idempotency key once, records the provider result, and tells the visitor what happened. If rejected, the bot reports the decision without inventing a different remedy.
That sequence separates four jobs: the model gathers and explains, identity services verify, policy code routes, and a staff member approves the exception.
Prevent Approval From Becoming a Rubber Stamp
Approval friction should be proportional, but it must remain meaningful.
Freeze the payload. Approval applies to one hash of one proposed action. If the amount, recipient, target, or policy result changes, invalidate the decision and ask again.
Expire pending requests. Inventory, account state, permissions, and policies change. Short expiries prevent yesterday's evidence from authorizing today's action.
Separate approve from edit. If the reviewer changes the refund from $480 to $240, that is a new proposal. Record the change and obtain any visitor confirmation the revised action requires.
Limit batch scope. “Approve all future refunds” is a permission grant, not an approval. Route role and policy changes through the chatbot admin security process.
Make rejection useful. Give reviewers structured reasons such as identity failed, policy mismatch, amount incorrect, duplicate request, or needs specialist. Those labels reveal where the chatbot's preparation fails.
Never treat silence as consent. Timeouts should leave the action unexecuted. A customer leaving the page or a staff member ignoring a queue is not approval.
Measure the Workflow After Launch
Conversation quality metrics will not show whether approvals are slowing work or preventing mistakes. Track the decision path separately.
| Metric | Formula | Diagnostic value |
|---|---|---|
| Approval rate | Approved proposals / decided proposals | A sudden drop can reveal weak evidence or policy drift |
| Revision rate | Proposals changed before approval / decided proposals | Shows whether the bot prepares accurate payloads |
| Median decision time | Median of decision time minus creation time | Exposes queues that strand customers |
| Expiry rate | Expired proposals / created proposals | Finds abandoned or badly routed approvals |
| Execution failure rate | Failed executions / approved proposals | Catches stale state, API errors, and broken retries |
| Reversal rate | Reversed actions / executed approvals | Reveals approvals that looked valid but caused harm |
Review a sample of approved actions as well as rejected ones. A high approval rate can mean the automation is excellent, or that reviewers are clicking through without reading. Compare the packet to the final system change and inspect reversals, complaints, duplicate side effects, and policy exceptions.
Use failed proposals as test cases. The AI chatbot QA workflow turns real conversations into regression checks; add expected approval mode, required evidence, and forbidden action to each consequential scenario.
Test the Paths Nobody Demonstrates
Before enabling a write-capable tool, test more than the successful approval:
- The visitor rejects the proposal.
- The visitor changes a key value after seeing the packet.
- Staff approves after the request expires.
- Two staff members approve the same request at once.
- The underlying order changes while approval is pending.
- The API succeeds but the response times out.
- The API fails after approval and the model tries again.
- A different user opens the approval link.
- The model proposes a blocked action under a safer tool name.
- The approver edits the payload in browser developer tools.
Each test needs an observable result: no side effect, one side effect, a fresh proposal, a safe error, or an audit event. “The bot apologized” is not a pass condition.
Autonomy Ends Where Consequence Begins
The useful boundary for a chatbot is not answers versus actions. It is low-consequence work versus decisions that spend money, change access, expose data, bind the business, or create a hard-to-reverse outcome.
Assign every tool an execution mode, ask the person who owns the decision, show the exact payload, freeze it after approval, and reconcile the final result. That gives the chatbot room to remove repetitive work without asking a human to supervise every sentence—or trusting a fluent answer with authority it should never hold.
No credit card required.



