工具调用基础(tool_use 块)
Tool use (a.k.a. function calling) is how Claude reaches outside its own context — to query a database, call an API, or run code. Critically, Claude never executes your tool. It requests a call; your application runs it and feeds the result back. This request/response handshake is the foundation of every agent.
Defining a tool
A tool is a name, a description, and a JSON Schema for its inputs:
The description is the selection mechanism — Claude reads it to decide whether and when to call the tool. Vague or overlapping descriptions cause the wrong tool to fire. Be prescriptive about when to call it, not just what it does.
The four-step loop
- You send
messagesplus atoolsarray. - Claude responds with
stop_reason: "tool_use"and atool_useblock containing a uniqueid, thename, andinput(already parsed JSON matching your schema). - You execute the function and send the output back as a
tool_resultblock in a newusermessage, referencing the sametool_use_id. - Claude reads the result and either answers (
end_turn) or requests another tool.
The tool_use_id is the thread that ties a result to its request — it is mandatory and must match exactly.
When a tool fails, return the result with "is_error": true and an informative message so Claude can adapt rather than silently retry.
Controlling tool use with tool_choice
tool_choice | Behavior |
|---|---|
{"type": "auto"} | Claude decides whether to use a tool (default) |
{"type": "any"} | Claude must use some tool |
{"type": "tool", "name": "..."} | Claude must use this tool |
{"type": "none"} | Claude may not use tools |
Forcing a single tool (type: "tool") is the classic trick for reliable structured extraction — Claude is compelled to emit arguments matching your schema.
Parallel and multiple tools
Claude can return several tool_use blocks in one response. Execute them all and return all tool_result blocks together in the next user message before continuing. Always append Claude's full content (including the tool_use blocks) to your history — dropping them breaks the loop.
Parsing inputs safely
Treat input as parsed JSON via your SDK (block.input), and never raw-string-match the serialized form — recent models may escape Unicode or slashes differently. The SDK already gives you a parsed object.
Exam focus
Remember the loop: tool_use (Claude requests) -> you execute -> tool_result (you return, matching tool_use_id) -> Claude continues. Claude does not run tools itself. The tool description drives selection. Know the four tool_choice modes, that forcing a tool yields structured output, that errors use is_error: true, and that multiple tool_use blocks need all their results returned together.