One rule
Do not let the model directly execute risky actions. Let it request the action, then pause and ask a human before the tool runs.
Risky means money, messages, database writes, deletes, external posts, or anything hard to undo.
What to gate
Your agent can call safe read-only tools without approval. For example, searching your own notes or checking a timetable file is usually fine.
Add approval when the tool changes the world. Think UPI payment, sending an email to a professor, creating a GitHub issue, deleting a record, or updating a team database.
Approval flow
Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.
0 of 5 done
Simple approval wrapper
This is a plain Python pattern you can use around the call-result loop you built earlier. The important part is that approval happens before the real tool function runs.
For a hackathon demo, terminal approval is acceptable. In a deployed app, use a stored state so the run can resume after approval.
APPROVAL_REQUIRED = {
"send_email",
"create_github_issue",
"update_database",
"make_payment"
}
TOOLS = {
"search_notes": search_notes,
"send_email": send_email,
"create_github_issue": create_github_issue,
}
def needs_approval(tool_name):
return tool_name in APPROVAL_REQUIRED
def ask_for_approval(tool_name, args):
print("Approval needed")
print("Tool:", tool_name)
print("Args:", args)
choice = input("Type approve or reject: ").strip().lower()
return choice == "approve"
def execute_tool_call(tool_call):
tool_name = tool_call["name"]
args = tool_call["arguments"]
if needs_approval(tool_name):
approved = ask_for_approval(tool_name, args)
if not approved:
return {
"ok": False,
"error": "Human rejected this tool call",
"tool": tool_name
}
result = TOOLS[tool_name](**args)
return {"ok": True, "result": result}Show enough detail
Approval is not useful if the human sees only “send_email”. Show the final recipient, subject, body preview, and attachments if any.
For database writes, show the table or collection, record id, changed fields, and old versus new value when you can.
Do not fake safety
A common mistake is asking for approval after the tool has already run. That is only a notification, not an approval gate.
Another mistake is blocking forever with no saved state. Current human-in-the-loop systems pause runs for pending approvals, then resume after approve or reject. Production systems should preserve state across that pause.
SDK idea
Some agent SDKs include this pattern. OpenAI’s Python Agents SDK can pause runs for pending approvals; pending items appear in interruptions, and you approve or reject before resuming.
LangChain also documents human-in-the-loop middleware for approval, editing, or rejection before tool execution. It notes that high-stakes actions like database writes and financial transactions are good cases for this.
Do this now
Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.
0 of 5 done