Tool Use & Function Calling

Implement Claude's tool use capabilities to extend functionality with external APIs and functions

Last updated: May 2025

Understanding Tool Use

Claude's tool use feature allows it to call external functions and APIs to extend its capabilities beyond text generation. This enables Claude to perform actions like calculations, data retrieval, file operations, and integration with external services.

Key Capabilities

  • • External API integration
  • • Real-time data retrieval
  • • Mathematical computations
  • • File system operations
  • • Database queries
  • • Third-party service calls

Use Cases

  • • Data analysis workflows
  • • Customer support automation
  • • Content management systems
  • • Research and fact-checking
  • • Business process automation
  • • Educational applications

The Complete Tool Use Loop

Tool use follows a request-response cycle where Claude decides when tools are needed, your application executes them, and Claude synthesizes the results into a final response.

The 5-Step Cycle

1.
User Request: Your application sends a message to Claude with available tools defined
2.
Claude Responds: Claude analyzes the request and decides which tools (if any) to use, returning tool_use blocks
3.
Your Code Executes: You extract tool names and parameters, execute the tools in your environment
4.
Return Results: You send tool results back to Claude in a tool_result message
5.
Final Response: Claude synthesizes tool results with its knowledge to provide a complete answer

Conceptual Flow (Pseudo-code)

// Step 1: Define your tools
tools = [
  { name: "calculator", description: "...", input_schema: {...} },
  { name: "get_weather", description: "...", input_schema: {...} }
]

// Step 2: Send initial request to Claude
response = claude.messages.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [{ role: "user", content: "What's 25 * 47?" }],
  tools: tools
})

// Step 3: Check if Claude wants to use tools
if response.stop_reason === "tool_use":
  // Extract tool use information
  for tool_use in response.content:
    if tool_use.type === "tool_use":
      tool_name = tool_use.name
      tool_input = tool_use.input

      // Step 4: Execute the tool
      result = execute_tool(tool_name, tool_input)

      // Step 5: Send results back to Claude
      final_response = claude.messages.create({
        model: "claude-sonnet-4-5-20250929",
        messages: [
          ...previous_messages,
          response,  // Claude's tool request
          { role: "user", content: [
            { type: "tool_result", tool_use_id: tool_use.id, content: result }
          ]}
        ],
        tools: tools
      })

// Now final_response contains Claude's answer using the tool results

See official Anthropic documentation for language-specific implementation details.

Defining Tools

Tools are defined using JSON schemas that specify the function name, description, and parameters. Here's how to structure tool definitions:

Basic Tool Structure

{
  "name": "get_weather",
  "description": "Get weather information for a specific location",
  "input_schema": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "The city and state/country"
      },
      "units": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "Temperature units"
      }
    },
    "required": ["location"]
  }
}

Calculator Tool Example

{
  "name": "calculator",
  "description": "Perform mathematical calculations",
  "input_schema": {
    "type": "object",
    "properties": {
      "expression": {
        "type": "string",
        "description": "Mathematical expression to evaluate"
      }
    },
    "required": ["expression"]
  }
}

Implementation Examples

Python Implementation

⚠️ SECURITY WARNING

This calculator example uses eval() for demonstration purposes only. NEVER use eval() with user input in production - it allows arbitrary code execution and complete system compromise.

Production alternative: Use ast.literal_eval() or safe expression evaluation libraries like numexpr or simpleeval.

import anthropic
import json

def calculator(expression):
    """Safely evaluate mathematical expressions"""
    try:
        result = eval(expression)
        return {"result": result}
    except:
        return {"error": "Invalid expression"}

def get_weather(location, units="fahrenheit"):
    """Mock weather function"""
    return {
        "location": location,
        "temperature": 72,
        "units": units,
        "condition": "sunny"
    }

# Tool definitions
tools = [
    {
        "name": "calculator",
        "description": "Perform mathematical calculations",
        "input_schema": {
            "type": "object",
            "properties": {
                "expression": {"type": "string"}
            },
            "required": ["expression"]
        }
    },
    {
        "name": "get_weather",
        "description": "Get weather information",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {"type": "string"},
                "units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
            },
            "required": ["location"]
        }
    }
]

# Claude API call with tools
client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-sonnet-4-5-20250929",  # Latest Sonnet 4.5
    max_tokens=1024,
    tools=tools,
    messages=[{
        "role": "user",
        "content": "What's 25 * 47? Also, what's the weather like in Paris?"
    }]
)

JavaScript/Node.js Implementation

⚠️ SECURITY WARNING

The calculator example uses the Function() constructor, which is similar to eval() and poses serious security risks with untrusted input.

Production alternative: Use safe expression evaluation libraries like mathjs, expr-eval, or jexl.

import Anthropic from '@anthropic-ai/sdk';

const anthropic = new Anthropic();

// Tool functions
const tools = {
  calculator: (params) => {
    try {
      const result = Function('"use strict"; return (' + params.expression + ')')();
      return { result };
    } catch (error) {
      return { error: 'Invalid expression' };
    }
  },
  
  get_weather: (params) => {
    // Mock implementation
    return {
      location: params.location,
      temperature: 22,
      units: params.units || 'celsius',
      condition: 'partly cloudy'
    };
  }
};

async function handleToolUse() {
  const message = await anthropic.messages.create({
    model: 'claude-sonnet-4-5-20250929',
    max_tokens: 1024,
    tools: [
      {
        name: 'calculator',
        description: 'Perform mathematical calculations',
        input_schema: {
          type: 'object',
          properties: {
            expression: { type: 'string' }
          },
          required: ['expression']
        }
      }
    ],
    messages: [{
      role: 'user',
      content: 'Calculate 15% tip on a $84.50 bill'
    }]
  });
  
  return message;
}

Advanced Patterns

Multi-Step Workflows

Chain multiple tool calls together for complex operations.

Example Flow:
  • 1. Search for relevant documents
  • 2. Extract key information
  • 3. Perform calculations
  • 4. Generate summary report

Error Handling

Implement robust error handling for tool failures.

Best Practices:
  • • Return descriptive error messages
  • • Validate input parameters
  • • Implement retry logic
  • • Provide fallback options

Authentication

Handle API keys and authentication securely.

Security Tips:
  • • Use environment variables
  • • Implement rate limiting
  • • Validate user permissions
  • • Log API usage

Performance Optimization

Optimize tool performance for better user experience.

Optimization Strategies:
  • • Cache frequent results
  • • Batch similar operations
  • • Use async operations
  • • Monitor response times

Controlling Tool Selection with tool_choice

The tool_choice parameter gives you precise control over when and which tools Claude uses.

"auto" (Default)

Claude decides whether to use tools based on the request. May use tools, may not.

When to use: General conversations where tools are optional

"any"

Claude MUST use at least one tool. Guarantees tool execution.

When to use: Workflows requiring guaranteed data fetching or actions

{type: "tool", name: "..."}

Force Claude to use a specific tool by name.

When to use: Deterministic workflows requiring specific tool execution

Usage Examples

// Auto (default) - Claude decides
claude.messages.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [...],
  tools: tools,
  tool_choice: {"type": "auto"}  // Optional, this is default
})

// Any - Force at least one tool use
claude.messages.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [...],
  tools: tools,
  tool_choice: {"type": "any"}  // Guarantees tool execution
})

// Specific tool - Force exact tool
claude.messages.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [...],
  tools: tools,
  tool_choice: {"type": "tool", "name": "get_weather"}  // Must use get_weather
})
⚡ Best Practices
  • • Use "auto" for conversational interfaces where flexibility is desired
  • • Use "any" for workflows that require tool execution (e.g., data pipelines)
  • • Use specific tool forcing sparingly - reduces Claude's flexibility and reasoning
  • • If forcing specific tools, ensure the request actually needs that tool

Parallel Tool Calling

🚀 New in Claude Sonnet 4.5

Sonnet 4.5 introduces enhanced parallel tool calling, allowing Claude to invoke multiple tools simultaneously for dramatically faster execution and more efficient workflows. This is particularly powerful when tasks are independent and don't rely on each other's results.

✅ When to Use Parallel

  • Independent queries: Fetching weather for multiple cities
  • Batch operations: Processing multiple files simultaneously
  • Data aggregation: Querying different databases at once
  • Multi-source research: Searching multiple APIs in parallel

⚠️ When to Use Sequential

  • Dependent operations: Each step needs previous results
  • Rate-limited APIs: Services with strict concurrency limits
  • Transactional workflows: Database operations requiring order
  • State management: Operations that modify shared state

Parallel Execution Example

When Claude receives a request requiring multiple independent tool calls, it can execute them all in parallel. Here's what happens behind the scenes:

// User request:
"What's the weather in New York, London, and Tokyo?
Also calculate 25 * 47 and what's 15% of 200?"

// Claude makes PARALLEL tool calls:
[
  { name: 'get_weather', input: { location: 'New York' } },
  { name: 'get_weather', input: { location: 'London' } },
  { name: 'get_weather', input: { location: 'Tokyo' } },
  { name: 'calculator', input: { expression: '25 * 47' } },
  { name: 'calculator', input: { expression: '200 * 0.15' } }
]

// Result: All 5 operations complete in the time of 1!

Performance Comparison

Sequential (Old Way)
Tool 1: 2s
Tool 2: 2s
Tool 3: 2s
Tool 4: 2s
Tool 5: 2s
Total: 10 seconds
Parallel (Sonnet 4.5)
All 5 tools: 2s
(executed simultaneously)
Total: 2 seconds

🚀 80% faster execution with parallel tool calling!

Implementation Tips

  • • Automatic behavior: Claude decides when to use parallel execution - no special configuration needed
  • • Design for parallelism: Make tools stateless and independent when possible
  • • Handle all responses: Your code must process multiple tool_use blocks in a single API response
  • • Test edge cases: Ensure your tools can handle concurrent execution safely
  • • Monitor performance: Track actual speedups in your specific use cases
🔧 Critical Implementation Details
Response contains ARRAY of tool_use blocks:

When Claude uses parallel tools, response.content will contain multiple tool_use blocks in a single response. Your code must loop through and execute all of them.

Execution order not guaranteed:

Tools may complete in any order. Don't assume sequential execution - design tools to be order-independent.

Tools must be thread-safe:

If tools modify shared state, ensure proper locking/synchronization. Prefer stateless tools for parallel execution.

Return ALL tool results together:

Execute all tools, collect results, then send all tool_result messages back to Claude in a single follow-up request.

Handling Multiple tool_use Blocks (Example)

// Claude's response with multiple tool_use blocks
response = {
  "content": [
    { "type": "tool_use", "id": "toolu_1", "name": "get_weather", "input": {"location": "NYC"} },
    { "type": "tool_use", "id": "toolu_2", "name": "get_weather", "input": {"location": "London"} },
    { "type": "tool_use", "id": "toolu_3", "name": "calculator", "input": {"expression": "25*47"} }
  ],
  "stop_reason": "tool_use"
}

// Your code must handle ALL tool_use blocks
tool_results = []
for content_block in response.content:
  if content_block.type === "tool_use":
    // Execute the tool
    result = execute_tool(content_block.name, content_block.input)

    // Collect result with original ID
    tool_results.append({
      "type": "tool_result",
      "tool_use_id": content_block.id,  // Must match original ID!
      "content": result
    })

// Send ALL results back together
final_response = claude.messages.create({
  model: "claude-sonnet-4-5-20250929",
  messages: [
    ...previous_messages,
    response,  // Claude's tool request
    { "role": "user", "content": tool_results }  // All results
  ]
})

Real-World Use Cases

E-commerce Price Comparison

Query 5 different retailer APIs simultaneously for product prices instead of waiting for each sequentially. 5x faster price updates.

Content Localization

Translate content into 10 languages in parallel using translation APIs. From 30 seconds to 3 seconds for complete localization.

Multi-Database Analytics

Query PostgreSQL, MongoDB, and Redis simultaneously for different metrics. Aggregate dashboard data 3x faster.

Token & Cost Considerations

Understanding how tool use affects token consumption and costs is crucial for building efficient applications.

📥 Input Token Costs

  • Tool definitions consume input tokens on every request
  • Large tool schemas (complex parameters) = more tokens
  • Multiple tools = linear token growth
  • Optimization: Keep descriptions concise but clear

📤 Output Token Costs

  • tool_use blocks in Claude's response count as output tokens
  • Tool parameters passed back count toward output
  • Final synthesized response = additional output tokens
  • Parallel calls don't reduce tokens, just time

💰 Cost Optimization with Prompt Caching

Prompt Caching allows you to cache tool definitions across requests, dramatically reducing costs for applications with stable tool sets.

Without Caching
10 tools × 200 tokens each = 2,000 tokens/request
1,000 requests = 2,000,000 input tokens
Cost: ~$6.00
With Caching ✓
First request: 2,000 tokens (cached)
Next 999 requests: ~200 cached tokens
Cost: ~$0.62 (90% savings!)

See Prompt Caching documentation for implementation details. Cache TTL is 5 minutes.

💡 Best Practices for Cost Efficiency

Use Prompt Caching for stable tool sets
Keep tool descriptions concise but informative
Only include tools relevant to the conversation
Use tool_choice: "any" only when necessary
Don't send 50+ tools "just in case"
Don't use verbose parameter descriptions
Don't duplicate similar tools
Don't ignore caching opportunities
📊 Token Estimation Example
Typical tool definition: ~150-300 tokens per tool
tool_use response: ~50-150 tokens (name + parameters)
Final synthesis: Varies by complexity (100-500+ tokens)
Example single tool request: ~500-800 total tokens (input + output)

Common Tool Examples

Database Query Tool

Execute SQL queries against a database safely.

{
  "name": "query_database",
  "description": "Execute SQL queries",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": {"type": "string"},
      "table": {"type": "string"},
      "limit": {"type": "integer", "maximum": 100}
    },
    "required": ["query", "table"]
  }
}

File Operations Tool

Read, write, and manipulate files in the system.

{
  "name": "file_operations",
  "description": "File system operations",
  "input_schema": {
    "type": "object",
    "properties": {
      "operation": {"type": "string", "enum": ["read", "write", "list"]},
      "path": {"type": "string"},
      "content": {"type": "string"}
    },
    "required": ["operation", "path"]
  }
}

API Integration Tool

Make HTTP requests to external APIs.

{
  "name": "api_request",
  "description": "Make HTTP API requests",
  "input_schema": {
    "type": "object",
    "properties": {
      "url": {"type": "string"},
      "method": {"type": "string", "enum": ["GET", "POST"]},
      "params": {"type": "object"},
      "headers": {"type": "object"}
    },
    "required": ["url", "method"]
  }
}

Best Practices

Tool Design ✓

  • Write clear, descriptive tool names
  • Provide detailed parameter descriptions
  • Include examples in descriptions
  • Use proper JSON schema validation
  • Keep tool scope focused and specific
  • Return structured, consistent responses

Common Pitfalls ✗

  • Overly complex tool definitions
  • Missing input validation
  • Poor error handling
  • Exposing sensitive operations
  • Inconsistent response formats
  • Not handling API rate limits

Practice Projects

Project 1: Personal Assistant

Build a personal assistant that can check weather, perform calculations, and manage a simple task list.

Tools: Weather API, Calculator, Task Storage
Project 2: Content Analyzer

Create a system that can fetch web content, analyze text sentiment, and generate summaries.

Tools: Web Scraper, Text Analysis, File Operations
Project 3: Data Dashboard

Build a system that queries databases, performs calculations, and generates visualizations.

Tools: Database Queries, Chart Generation, Email Notifications