CloudCodeTree LogoCloudCodeTree
AI NewsTutorialsAbout
CloudCodeTree Logo
CloudCodeTree
  • AI News
  • Tutorials
  • About
← Back to AI News
Give Claude a Function to Call: The Tool-Use Round Trip Every Agent Runs

Give Claude a Function to Call: The Tool-Use Round Trip Every Agent Runs

Chris Harper

3 min read

Aug 30, 2026 · 04:03 UTC

AI
Tutorial
Agents
Best Practices

What you will be able to do after this: wire any Python function — a database lookup, a search API, an internal retrieval call — into Claude as a callable tool, handle the result correctly, and understand the token overhead so costs don't surprise you.

Three things to take away:

  • Claude never executes your function — it returns a tool_use block with structured arguments; your code runs the function and sends a tool_result back so Claude can continue
  • stop_reason: "tool_use" is the signal to handle a call; stop_reason: "end_turn" means Claude is done with tools and has its final answer
  • strict: true in a tool definition guarantees Claude's output always matches your JSON schema — catch argument type errors before they reach your function

The loop, step by step:

import anthropic, json

client = anthropic.Anthropic()

# 1. Define the tool — Claude gets the name, description, and schema
tools = [{
    "name": "get_order_status",
    "description": "Look up the current status of a customer order by order ID.",
    "input_schema": {
        "type": "object",
        "properties": {
            "order_id": {"type": "string", "description": "The order ID, e.g. A42"}
        },
        "required": ["order_id"]
    },
    "strict": True   # output always matches this schema exactly
}]

messages = [{"role": "user", "content": "What is the status of order A42?"}]

# 2. First turn: Claude decides to call the tool, returns stop_reason="tool_use"
response = client.messages.create(
    model="claude-opus-5", max_tokens=1024,
    tools=tools, messages=messages,
)
tool_call = next(b for b in response.content if b.type == "tool_use")

# 3. Your code runs the actual function
result = lookup_order(tool_call.input["order_id"])  # your DB / API call

# 4. Send the result back — Claude continues and gives the final answer
messages += [
    {"role": "assistant", "content": response.content},
    {"role": "user", "content": [{
        "type": "tool_result",
        "tool_use_id": tool_call.id,
        "content": json.dumps(result)
    }]}
]
final = client.messages.create(
    model="claude-opus-5", max_tokens=1024,
    tools=tools, messages=messages,
)
print(next(b.text for b in final.content if b.type == "text"))

The cost reality: Every tool schema adds tokens to every request. On Claude Opus 5, the tool-use system prompt overhead alone is 286 tokens for tool_choice: auto and 406 tokens when using any or tool. Add ~50–150 tokens per tool definition. Ten detailed tool schemas on a short conversation can easily add 2–3k tokens per turn — size your descriptions to what Claude needs to choose correctly, not to what a human reader would want.

To skip the round-trip loop: use Tool Runner — the Anthropic SDK can execute your tools automatically and send results back without explicit handling code. Useful for simple loops; keep the manual loop when you need to log, gate, or transform results.

Sources: Tool use overview — platform.claude.com · Build a tool-using agent tutorial — Anthropic · Claude API Function Calling: Complete Guide (2026) — DEV Community