liveBook · Manning

Tool confirmation

As explained in Build an AI Agent (From Scratch)

Tool confirmation is a control mechanism that requires user approval before selected tools execute and supports continuing execution after approval decisions are received.

Tool confirmation blocks selected tool calls until a user approves them. The agent identifies approval-required tools, creates pending calls with human-readable messages, and resumes execution after decisions arrive. This prevents irreversible actions from running before review. section 6.3.6 section 6.3.7

A practical implementation separates tool metadata from the agent’s internal execution flow:

  • Add requires_confirmation and confirmation_message_template to BaseTool; generate approval text with the tool name and arguments. section 6.3.6
  • Extend the tool decorator so each tool can declare whether approval is required and customize the request shown to the user. section 6.3.6
  • Make act() collect pending calls instead of executing them, while immediately running tools that do not require confirmation. section 6.3.7
  • Let run() pause when pending calls exist, then let _prepare_llm_request() process returned approvals and add the resulting ToolResults to the conversation. section 6.3.7
  • Use whitelist approval: execute only approved tool_call_id values and reject pending calls absent from the approval list. section 6.3.7

Destructive versus read-only tools

Configure delete_file with requires_confirmation=True and a message naming the target file and warning that deletion cannot be undone. Leave get_weather without confirmation so it executes immediately. section 6.3.6

Listing 6.20 Modified act() method with confirmation check
async def act(
    self,
    context: ExecutionContext,
    tool_calls: List[ToolCall]
) -> List[ToolResult]:
    tools_dict = {tool.name: tool for tool in self.tools}
    pending_calls = []
    results = []

    for tool_call in tool_calls:
        tool = tools_dict.get(tool_call.name)

        # Check if confirmation is required
        if tool.requires_confirmation:
            pending = PendingToolCall(
                tool_call=tool_call,
                confirmation_message=tool.get_confirmation_message(
                    tool_call.arguments
                )
            )
            pending_calls.append(pending)
            continue  # Do not execute, do not create ToolResult

        # Execute tools that don't require confirmation
        # ... existing tool execution logic ...

    # Store pending calls in session state
    if pending_calls:
        context.state["pending_tool_calls"] = [
            p.model_dump() for p in pending_calls
        ]

    return results

Inspect the act() implementation that separates pending approval-required calls from immediately executable tools. section 6.3.7

How Build an AI Agent (From Scratch) covers it

How deep it goes
Implements tool metadata, pending state, approval lookup, pause-resume control flow, and conversation-level ToolResults.
Examples
Demonstrates confirmation for delete_file and immediate execution for the read-only get_weather tool.
What it assumes
Assumes BaseTool, tool decorators, act(), run(), execution context, and tool-call result handling already exist.
What you can do after
Operate/configure an agent that pauses for selective approvals and resumes execution without running unapproved tools.
How it connects
Connects human-in-the-loop workflows with tool decorators, execution state, callbacks, LLM requests, and ToolResults.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Build an AI Agent (From Scratch). The section links point to the parts of the book it draws on.