Tool and function calling API in every format
Let the model call your functions in every format, define a tool, read the call, send the result back, and see what each model family supports.
On this page
Tool calling lets the model ask your program to run a function, such as fetching the weather or searching your database, and then answer with the result. The model never runs anything itself: it returns the function name and the arguments, your code runs it, and you send the result back in the next request.
The loop#
Describe your tools#
Send a list of tools in the request, each with a name, a description and a JSON Schema for its arguments. A clear description is what makes the model call the right tool.
Read the call#
When the model wants a tool, the reply holds a call with the tool name and its arguments instead of a final answer, and the stop reason says so.
Run it and send the result#
Run the function in your code, then send a new request with the whole conversation: the model's call, followed by your result linked to the call's id. The model then answers, or calls another tool.
The same tool in each format#
- Chat Completions: tools in
toolswithtype: "function"andfunction.parameters. The call comes inmessage.tool_callswithfinish_reason: "tool_calls". Send the result as a message withrole: "tool"and thetool_call_id. - Responses: tools in
toolswithtype: "function"andparameters. The call is anoutputitem of typefunction_callwith acall_id. Send the result as aninputitem of typefunction_call_outputwith the samecall_id. - Messages: tools in
toolswithinput_schema. The call is atool_useblock withstop_reason: "tool_use". Send the result as atool_resultblock in ausermessage, with thetool_use_id. - Gemini: tools in
toolswithfunctionDeclarations. The call is afunctionCallpart. Send the result as afunctionResponsepart in auserturn.
Full requests with captured replies: Chat Completions, Responses, Messages and Gemini.
Sending the result back#
In Chat Completions, the second request repeats the conversation, adds the model's call as it came, and then your result:
[
{ "role": "user", "content": "What is the weather in Cairo?" },
{ "role": "assistant", "content": null, "tool_calls": [
{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Cairo\"}" } }
] },
{ "role": "tool", "tool_call_id": "call_1", "content": "{\"temp_c\": 31, \"sky\": \"clear\"}" }
]In Messages, the call and the result are blocks:
[
{ "role": "user", "content": "What is the weather in Cairo?" },
{ "role": "assistant", "content": [
{ "type": "tool_use", "id": "toolu_1", "name": "get_weather", "input": { "city": "Cairo" } }
] },
{ "role": "user", "content": [
{ "type": "tool_result", "tool_use_id": "toolu_1", "content": "{\"temp_c\": 31, \"sky\": \"clear\"}" }
] }
]What each family supports#
- Every family accepts
toolsin Chat Completions and Messages, and Claude and GPT in Responses. - Forcing a tool with
tool_choiceworks for Claude and GPT. Gemini models choose for themselves in Chat Completions and Messages; in generateContent usetoolConfig. parallel_tool_callshas an effect for GPT models only. Claude models may call several tools in one reply; handle every call before you answer.- For a JSON answer from Claude, define one tool whose schema is the shape you want and force it with
tool_choice: the arguments are your JSON.
Tips#
- Check the arguments before you run anything: the model can send a wrong value.
- Keep tool results short and factual; long results cost input tokens on every later request.
- Return errors as results, such as
{"error": "city not found"}, so the model can recover.
Was this page helpful?