iToverDose/Software· 12 JUNE 2026 · 12:04

Master Claude API Function Calling with Multi-Tool Workflows

Learn how to integrate Claude’s function calling into your applications with step-by-step guides for single, parallel, and controlled tool use. Includes error handling and complete agent examples.

DEV Community5 min read0 Comments

Claude’s function calling—officially termed tool use—enables seamless integration of external tools into AI workflows. Unlike other models, Claude doesn’t execute code directly. Instead, it generates structured requests to invoke your tools, receives the results, and continues the conversation. This approach unlocks powerful automation for applications ranging from stock trackers to contact managers.

How to Define and Implement Tools in the Claude API

A tool definition in the Claude API consists of three critical components: a name, a description, and an input_schema formatted as JSON Schema. These fields guide Claude’s decision-making process, determining when to invoke a tool and how to structure its arguments.

To use tools, install the Anthropic SDK and set your API key:

pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-..."

Here’s a practical example of defining a tool that retrieves stock prices:

tools = [
    {
        "name": "get_stock_price",
        "description": "Fetch the current price of a stock by its ticker symbol.",
        "input_schema": {
            "type": "object",
            "properties": {
                "ticker": {
                    "type": "string",
                    "description": "Stock ticker symbol, e.g., 'AAPL' or 'GOOGL'",
                },
                "currency": {
                    "type": "string",
                    "enum": ["USD", "EUR", "GBP"],
                    "description": "Currency to return the price in. Defaults to USD.",
                },
            },
            "required": ["ticker"],
        },
    }
]

When Claude decides to use a tool, its response includes a tool_use block containing the tool’s name, arguments, and a unique id. This structured output makes it easy to parse and execute the requested action.

Building the Tool-Use Loop for Multi-Step Workflows

Tool use operates as a continuous loop between the AI and your application. The process involves:

  • Sending the current conversation and tool definitions to the Claude API.
  • Checking the response for a tool_use block. If none exists, the AI has completed its task.
  • Executing each requested tool and collecting results.
  • Appending the AI’s response and tool results to the conversation history before repeating.

Below is a Python implementation of this loop:

from anthropic import Anthropic

client = Anthropic()

def get_stock_price(ticker: str, currency: str = "USD") -> str:
    prices = {"AAPL": 230.15, "GOOGL": 178.32, "MSFT": 415.50}
    price = prices.get(ticker.upper())
    if price is None:
        return f"No data available for ticker '{ticker}'"
    return f"{ticker.upper()}: {price} {currency}"

tools = [...]  # Use the tool definition from above
messages = [{"role": "user", "content": "What’s Apple’s stock price?"}]

while True:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        tools=tools,
        messages=messages,
    )

    if response.stop_reason != "tool_use":
        print(response.content[0].text)
        break

    messages.append({"role": "assistant", "content": response.content})
    tool_results = []

    for block in response.content:
        if block.type == "tool_use" and block.name == "get_stock_price":
            result = get_stock_price(**block.input)
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": result,
            })

    messages.append({"role": "user", "content": tool_results})

This loop ensures Claude can chain multiple tool calls when necessary, creating dynamic workflows that adapt to user requests.

Handling Parallel Tool Calls with Efficient Workflows

Claude supports parallel tool execution, allowing it to request multiple tools in a single response. For example, a user might ask for both a stock price and an exchange rate simultaneously. The API’s structure handles this seamlessly by returning multiple tool_use blocks, each with a unique id.

To extend the previous example, add a tool for currency conversion:

def get_exchange_rate(from_currency: str, to_currency: str) -> str:
    rates = {("USD", "EUR"): 0.92, ("EUR", "USD"): 1.09}
    rate = rates.get((from_currency.upper(), to_currency.upper()))
    if rate is None:
        return f"No exchange rate available for {from_currency} -> {to_currency}"
    return f"1 {from_currency.upper()} = {rate} {to_currency.upper()}"

tools.append({
    "name": "get_exchange_rate",
    "description": "Retrieve the exchange rate between two currencies.",
    "input_schema": {
        "type": "object",
        "properties": {
            "from_currency": {
                "type": "string",
                "description": "3-letter currency code, e.g., 'USD'",
            },
            "to_currency": {
                "type": "string",
                "description": "3-letter currency code, e.g., 'EUR'",
            },
        },
        "required": ["from_currency", "to_currency"],
    },
})

The existing loop already accommodates parallel calls. It iterates over each tool_use block and returns a corresponding tool_result for every tool_use_id, ensuring results are matched correctly regardless of order.

Controlling Tool Selection for Predictable Outcomes

The Claude API offers granular control over tool selection through the tool_choice parameter. Options include:

  • `{"type": "auto"}` (default): Claude autonomously decides whether to use a tool.
  • `{"type": "any"}`: Forces Claude to invoke at least one tool from the provided list.
  • `{"type": "tool", "name": "..."}`: Mandates the use of a specific tool.
  • `{"type": "none"}`: Prevents any tool usage, ensuring only text responses.

Forcing tool selection is particularly useful for structured output. For instance, to extract and save contact details:

save_contact_tool = {
    "name": "save_contact",
    "description": "Store extracted contact information.",
    "input_schema": {
        "type": "object",
        "properties": {
            "name": {"type": "string", "description": "Full name of the contact"},
            "email": {"type": "string", "description": "Email address"},
            "phone": {"type": "string", "description": "Phone number with country code"},
        },
        "required": ["name", "email"],
    },
}

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=[save_contact_tool],
    tool_choice={"type": "tool", "name": "save_contact"},
    messages=[{
        "role": "user",
        "content": "Reach out to John Doe at john@example.com, phone +1 555-1234.",
    }],
)

contact = response.content[0].input
print(contact)  # Output: {'name': 'John Doe', 'email': 'john@example.com', 'phone': '+1 555-1234'}

Additionally, setting "disable_parallel_tool_use": True in tool_choice ensures exactly one tool call per response.

Streaming Tool Inputs for Real-Time Processing

For applications requiring real-time feedback, the Claude API supports streaming tool inputs. This feature allows you to process partial JSON inputs as they arrive, enabling dynamic interactions.

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    tools=tools,
    messages=messages,
) as stream:
    for event in stream:
        if event.type == "content_block_delta" and event.delta.type == "input_json_delta":
            print(event.delta.partial_json, end="", flush=True)

final = stream.get_final_message()
for block in final.content:
    if block.type == "tool_use":
        print(block.name, block.input)

Streaming enhances user experience by reducing latency, particularly in chat interfaces where immediate feedback is critical.

Building a Scalable Multi-Tool Agent

The techniques outlined above can be combined to create a robust multi-tool agent. Start with a core set of tools, implement the looping mechanism, and expand functionality as needed. Error handling should be a priority—validate tool inputs, handle API rate limits, and provide fallback responses when tools fail. This modular approach ensures your agent remains flexible and maintainable as requirements evolve.

The future of AI-driven automation lies in seamless tool integration. By mastering Claude’s function calling capabilities, developers can build sophisticated workflows that bridge the gap between natural language and executable actions.

AI summary

Learn how to integrate Claude’s function calling into applications with step-by-step guides for single, parallel, and controlled tool use. Includes error handling and complete agent examples.

Comments

00
LEAVE A COMMENT
ID #KU7C6H

0 / 1200 CHARACTERS

Human check

7 + 2 = ?

Will appear after editor review

Moderation · Spam protection active

No approved comments yet. Be first.