DocumentationTools

Build

Tools

Describe your functions to the model. It decides when to call one, your code runs it and returns the result.

On this page
  1. The full round trip
  2. Example
  3. Good to know

The full round trip

  1. You describe the function

    Its name, what it does and its parameters, in JSON Schema.

  2. The model requests the call

    Instead of text, it returns tool_calls with the arguments.

  3. Your code runs it

    The model runs nothing itself. You stay in control of what happens.

  4. The model answers

    With the result sent back in a tool message, it writes its answer.

Example

A function that says whether an invoice is paid. The response shown is from the first call, when the model asks for the function.

import json

tools = [
    {
        "type": "function",
        "function": {
            "name": "invoice_status",
            "description": "Payment status of an invoice.",
            "parameters": {
                "type": "object",
                "properties": {"number": {"type": "string"}},
                "required": ["number"],
            },
        },
    }
]
messages = [
    {
        "role": "user",
        "content": "Has invoice 2026-114 been paid?",
    }
]

first = client.chat.completions.create(
    model="flash", messages=messages, tools=tools
)
call = first.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)

# Run the function, then return its result with the call id.
result = {
    "number": args["number"],
    "status": "paid",
    "paid_on": "2026-10-02",
}
messages.append(first.choices[0].message)
messages.append(
    {
        "role": "tool",
        "tool_call_id": call.id,
        "content": json.dumps(result),
    }
)

final = client.chat.completions.create(
    model="flash", messages=messages, tools=tools
)
print(final.choices[0].message.content)
Response
{
  "role": "assistant",
  "content": null,
  "tool_calls": [
    {
      "id": "call_7f3a",
      "type": "function",
      "function": { "name": "invoice_status", "arguments": "{\"number\": \"2026-114\"}" }
    }
  ]
}

Good to know

  • An empty tool list is removed along with tool_choice, as if you had sent none.
  • parallel_tool_calls lets the model request several functions at once.
  • Check the arguments before acting. The model can be wrong, your code decides.