Anthropic Tool Use Function Calling Integration into Application

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1 servicesAll 1566 services
Anthropic Tool Use Function Calling Integration into Application
Medium
~2-3 business days
FAQ
AI Development Areas
AI Solution Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1212
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    822

Anthropic Tool Use (Function Calling) Integration in Application

Tool Use is a mechanism that allows Claude to call functions in your application. The model does not execute code directly: it returns structured JSON with the tool name and arguments, and your code executes the tool and returns the result. This is the foundation for building agents with access to real data and actions.

Basic Tool Use Loop

import anthropic
import json
from typing import Any

client = anthropic.Anthropic()

# Tool definitions
TOOLS = [
    {
        "name": "search_database",
        "description": "Search customers in CRM by parameters",
        "input_schema": {
            "type": "object",
            "properties": {
                "query": {"type": "string", "description": "Search query"},
                "limit": {"type": "integer", "description": "Number of results", "default": 10},
                "status": {
                    "type": "string",
                    "enum": ["active", "churned", "trial"],
                    "description": "Status filter"
                }
            },
            "required": ["query"]
        }
    },
    {
        "name": "send_email",
        "description": "Send email to customer",
        "input_schema": {
            "type": "object",
            "properties": {
                "to": {"type": "string"},
                "subject": {"type": "string"},
                "body": {"type": "string"},
            },
            "required": ["to", "subject", "body"]
        }
    }
]

# Tool dispatcher
def execute_tool(tool_name: str, tool_input: dict) -> Any:
    if tool_name == "search_database":
        return search_crm(**tool_input)
    elif tool_name == "send_email":
        return send_email_via_smtp(**tool_input)
    raise ValueError(f"Unknown tool: {tool_name}")

def run_agent(user_message: str) -> str:
    """Complete agentic loop with tool use"""
    messages = [{"role": "user", "content": user_message}]

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

        # No tool calls — return final answer
        if response.stop_reason == "end_turn":
            for block in response.content:
                if hasattr(block, "text"):
                    return block.text
            return ""

        # Process tool_use blocks
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                print(f"Calling tool: {block.name}({block.input})")
                result = execute_tool(block.name, block.input)

                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": json.dumps(result, ensure_ascii=False),
                })

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

Parallel Tool Calls

Claude can call multiple tools in one response. Use asyncio for parallel execution:

import asyncio

async def execute_tool_async(tool_name: str, tool_input: dict) -> tuple[str, Any]:
    """Asynchronous tool execution"""
    result = await asyncio.to_thread(execute_tool, tool_name, tool_input)
    return tool_name, result

async def run_agent_async(user_message: str) -> str:
    messages = [{"role": "user", "content": user_message}]

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

        if response.stop_reason == "end_turn":
            return next((b.text for b in response.content if hasattr(b, "text")), "")

        # Execute all tools in parallel
        tool_use_blocks = [b for b in response.content if b.type == "tool_use"]

        results = await asyncio.gather(*[
            execute_tool_async(b.name, b.input)
            for b in tool_use_blocks
        ])

        tool_results = [
            {
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": json.dumps(result, ensure_ascii=False),
            }
            for block, (_, result) in zip(tool_use_blocks, results)
        ]

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

Force Tool Call

# tool_choice="required" — Claude must call at least one tool
# tool_choice={"type": "tool", "name": "..."} — call specific tool

response = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    tools=TOOLS,
    tool_choice={"type": "tool", "name": "search_database"},
    messages=[{"role": "user", "content": "Find customers with trial status"}],
)

Tool Error Handling

# Pass errors back to the model — it adapts behavior
try:
    result = execute_tool(block.name, block.input)
    tool_results.append({
        "type": "tool_result",
        "tool_use_id": block.id,
        "content": json.dumps(result),
    })
except Exception as e:
    tool_results.append({
        "type": "tool_result",
        "tool_use_id": block.id,
        "content": f"Error: {str(e)}",
        "is_error": True,  # Model knows about error and can correct
    })

Practical Case: CRM Assistant

Task: Sales managers spent 20–30 min preparing for meetings (CRM search, recent contacts, open tasks).

Tools: get_customer_info, get_deal_history, get_recent_activities, create_task, get_calendar.

Result: meeting preparation — 2 min via dialog with assistant.

Timeline

  • Basic tool use loop with 2–3 tools: 2–3 days
  • Parallel calls + error handling: 1–2 days
  • Production-ready with logging and retry: 1 week