Extend model responses by giving the model access to custom tools it can invoke during a conversation.
Tool calling lets you describe functions to a model and have it decide when and how to call them. Instead of returning plain text, the model can emit a structured call that your code executes; you then feed the result back and the model continues. This turns a single-turn completion into a reliable, multi-step agent loop.
The loop has three steps:
tools array describing one or more functions. The model reads the descriptions and decides if any should be called.finish_reason is tool_calls and message.tool_calls lists one or more calls — each with a name and arguments (a JSON string).tool role message with the result. The model reads the result and produces a final answer.Pass tools as an array of objects. Each tool has type: "function" and a function object with name, description, and a JSON Schema parameters.
When the model wants to call a tool, its response looks like this:
You execute get_account_balance("ACC-1029"), then continue the conversation by appending both the assistant's tool-call message and a tool role message with the result:
The model then produces a natural-language answer using the tool result.
A model may decide to call multiple tools in a single turn. The tool_calls array will contain more than one entry. Execute each independently, then reply with one tool message per call — matching tool_call_id for each.
Reply with two tool messages (order doesn't matter as long as tool_call_id matches).
tool_choice#By default the model decides whether to call a tool. You can override this:
| Value | Effect |
|---|---|
"auto" | Model decides (default) |
"none" | Model may not call any tool |
"required" | Model must call at least one tool |
{"type": "function", "function": {"name": "my_fn"}} | Model must call this specific function |
Set "stream": true alongside tools. Tool call data arrives in delta chunks — the delta object carries a tool_calls array with incremental arguments strings. Concatenate arguments deltas per index until the stream ends, then parse the full JSON.
description to decide when to call the tool. Be specific about what the function returns and when it's appropriate.required if the function cannot run without it. Optional params give the model flexibility.arguments is a model-generated JSON string — parse it and validate before passing to real functions.finish_reason after every response. Keep looping until you see "stop".