How it works
1
Define tools
Send
tools with your request, each with a name, a description, and JSON Schema parameters.2
The model calls a tool
If the model decides to use a tool, the response has
finish_reason: "tool_calls" and one or more entries in message.tool_calls, each with an id, the function name, and JSON arguments.3
Run the tool and return the result
Append the assistant message to the conversation, then add one
tool message per call, directly after it, with the call’s id as tool_call_id and the result as content.4
The model answers
Send the conversation again. The model uses the results to answer, or calls more tools.
Example
Control tool use
tool_choice controls whether the model calls a tool:
Set
parallel_tool_calls to false to allow at most one tool call per turn. tool_choice and parallel_tool_calls are allowed only when tools is supplied.
Strict mode
Setfunction.strict to true on a tool to enable strict schema adherence for its arguments. Its parameters must then follow the rules for strict structured outputs: every object sets additionalProperties: false and requires all of its properties, and some JSON Schema keywords aren’t supported.
Limits
- Up to 128 tools per request.
- Function names are 1 to 64 characters.
Tips
- Write descriptions for the model: say what the tool does and when to use it, and describe each parameter.
- Keep the assistant message that made the tool calls in the conversation, unchanged, including any
reasoning_content. See Reasoning. - If you build the assistant message yourself, give each tool call its
id,type: "function", and afunctionwithnameandarguments, and give eachtoolmessage atool_call_id. A missing field returns a400error whoseparamnames it, such asmessages[1].tool_calls[0].function.arguments. - Send exactly one
toolmessage for each tool call, even when the tool fails; describe the error incontentso the model can recover. - Put the
toolmessages directly after the assistant message that made the calls, in any order, before any other message. A call without a result, a result for a call that isn’t in that assistant message, a second result for the same call, or two calls with the sameidreturns a400error whoseparamnames the message. - When streaming, tool calls arrive in fragments that you accumulate by
index.