โ† Pattern library

AI

AI Tool Calling

Lets the AI invoke functions you define (lookup data, send email, create record) instead of just generating text. Foundation of "agentic" behavior.

๐ŸŒฟ

When to use this

When the AI needs to take real-world actions or fetch real-time data, not just answer from training knowledge.

aitoolsfunction-callingagentllm
โœจ Built using these library patterns:
tool-calling

What I assumed

I made these guesses to fill gaps. Let me know if any are wrong.

    Flow diagram

    Step-by-step recipe

    Copy this and paste into Cursor, Claude Code, or v0.

    PATTERN: AI Tool Calling
    INPUT: user_message, available_tools[], conversation_history
    OUTPUT: ai_response (with tool calls executed)
    
    STEPS:
      1. Define tools: each has name, description, JSON schema for inputs
      2. User sends message in chat
      3. Send message + tools list + history to LLM
      4. LLM responds with either: text reply OR tool_use block
      5. IF text reply โ†’ render and end (composable_with: chat-loop)
      6. IF tool_use โ†’ parse which tool + arguments
      7. Validate arguments against schema (Zod)
      8. Execute the tool (your function)
      9. IF tool succeeds โ†’ send result back to LLM as tool_result
      10. IF tool fails โ†’ send error back as tool_result with details
      11. LLM may chain another tool call OR produce final text response
      12. Loop steps 4-11 until LLM gives final text (with max iteration limit)
      13. Show final response to user, optionally show tools used
    
    ERROR_HANDLING:
      - Tool argument validation fails โ†’ return error to LLM, let it retry
      - Tool execution timeout (10s) โ†’ return timeout to LLM, it can apologize
      - Infinite tool loop โ†’ cap at 10 iterations, fall back to "I couldn't complete this"
      - Tool needs user permission (e.g., send money) โ†’ pause, ask user, resume
    
    EXTENSION_POINTS:
      - Streaming intermediate progress (composable_with: ["streaming-response"])
      - Document context per call (composable_with: ["rag-retrieval"])
      - Human approval for sensitive tools (composable_with: ["human-escalation"])
      - Tool result caching for idempotent tools
    

    States โ€” how things change

    StateDescriptionTransitions
    Awaiting user messageIdle, ready for input
    • Message receivedโ†’LLM thinking
    LLM thinkingAI deciding text reply or tool call
    • Text responseโ†’Awaiting user message
    • Tool call requestedโ†’Executing tool
    Executing toolRunning the requested function
    • Tool completedโ†’LLM thinking
    • Permission neededโ†’Awaiting user approval
    Awaiting user approvalSensitive tool needs human OK
    • Approvedโ†’Executing tool
    • Deniedโ†’Awaiting user message

    Easy-to-miss situations

    The kinds of edge cases that break demos.

    • What if the AI hallucinates a tool name that doesn't exist?

      medium

      AI invokes "send_invoice" but you only have "create_order" โ€” system errors out.

      Suggested handling: Catch unknown tool name, return tool_result with error: "Tool 'X' doesn't exist. Available tools: [list]". LLM will self-correct.

    • What if the AI invokes a destructive tool (delete user) without permission?

      high

      Catastrophic โ€” irreversible actions taken on user's behalf.

      Suggested handling: Mark tools as `requires_confirmation: true`. Pause and show user "AI wants to delete X โ€” approve?" before executing. Default to `false` only for read-only tools.

    • What if the AI loops calling the same tool repeatedly?

      high

      Infinite loop, runaway cost, no progress.

      Suggested handling: Hard limit at 10 tool calls per user message. After limit, force final response. Log + alert if hit often (sign of bad tool descriptions).

    • What if a tool returns sensitive data (other users' info)?

      high

      AI might leak it in response, breaching privacy.

      Suggested handling: Filter tool outputs at the boundary BEFORE returning to LLM. Strip fields the user shouldn't see (auth tokens, other-user emails). Server-side enforcement, never trust LLM.

    • What if the user wants to cancel mid-execution?

      medium

      Long tool chains (5+ steps) โ€” user clicks Stop.

      Suggested handling: Show "AI is using tools..." with Stop button. On stop, abort current tool execution + don't queue next. Don't roll back completed tools (warn user).

    Composes well with

    Combine these patterns when you need a richer flow.

    Build a flow starting from this pattern โ†’