Guides · Tool calling
Tool calling: let open models call your functions
Tool calling, also called function calling, lets a model ask your code to do something it cannot do itself: look up an order, query a database, send an email or call another API. You describe the tools, the model decides when to use them and with which arguments, and your code runs them. It is the basis of every agent, and it works in the OpenAI and Anthropic formats.
- 01API format: OpenAI and Anthropic
- 02EU data centres
- 03Covered by one DPA
import json, os
from openai import OpenAI
client = OpenAI(base_url="https://api.inference.eu/v1", api_key=os.environ["INFERENCE_EU_API_KEY"])
def get_order_status(order_id: str) -> dict:
return {"order_id": order_id, "status": "shipped", "carrier": "DHL", "eta": "2026-11-05"}
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Look up the shipping status of a customer order by its id.",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string", "description": "Order id, e.g. A-10293"}},
"required": ["order_id"],
},
},
}]
messages = [{"role": "user", "content": "Where is my order A-10293?"}]
reply = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools)
msg = reply.choices[0].message
if msg.tool_calls:
messages.append(msg)
for call in msg.tool_calls:
result = get_order_status(**json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
reply = client.chat.completions.create(model="gpt-oss-120b", messages=messages, tools=tools)
print(reply.choices[0].message.content)How tool calling works
You pass a tools array with the request. Each tool has type: "function" and a function object with a name, a description and parameters written as JSON Schema. The model reads these alongside the conversation. If it decides a tool is needed, it does not answer in text; it returns message.tool_calls, each with an id, the function name and arguments as a JSON string, and finish_reason is tool_calls.
The model never runs anything. Your code parses the arguments, calls the real function, and sends the result back as a message with role: "tool" and the matching tool_call_id. The model then uses the result to answer, or asks for another tool.
Controlling when tools are used
tool_choice controls the decision. auto, the default, lets the model choose between answering and calling a tool. required forces at least one tool call, which is useful for extraction steps. none disables tools for one turn, and naming a specific function forces that function. parallel_tool_calls set to false limits the model to one call per turn, if your tools must run in order.
Good descriptions matter more than anything else. Say what the tool does, when to use it and what each parameter means, with an example value. Keep the number of tools per request manageable; a model choosing between a handful of clear tools makes fewer mistakes than one choosing between fifty.
The agent loop in practice
Real tasks often need several rounds: search, then fetch details, then act. Run a loop. Send the request; if the response has tool calls, run them, append the assistant message and each tool result, and send again; stop when the model answers in text or after a maximum number of rounds you choose.
Validate arguments before you act on them, because the model can produce a wrong id or a missing field. Treat tools that change things, such as payments or emails, with care: ask a person to confirm, or restrict them to safe values. Return errors from tools as results with a clear message, so the model can correct itself.
Formats, models and edge cases
The same tools work through the Responses API, where function calls and outputs are typed items, and through the Anthropic Messages format, where tools use input_schema and calls come back as tool_use blocks answered with tool_result. Choose the format your framework uses.
Not every model is equally good at tool use. Large instruction-tuned models such as gpt-oss-120b handle multi-step tool loops well; small models can miss calls or invent arguments. If arguments is not valid JSON, send an error back and let the model retry, or combine tools with strict schemas. Tool definitions count as input tokens on every request.
Tool calling: common questions
The questions buyers, developers and legal teams ask us most. Something missing? Ask us directly.
Related
- Structured outputsGet valid JSON that matches your schema from open models with OpenAI-compatible structured outputs. JSON mode, json_schema, strict mode and pitfalls.Guides
- Remote MCP serversConnect remote MCP servers to model requests with the OpenAI Responses mcp tool. The API lists and calls the server's tools for you, processed in the EU.Tools
- StreamingStream tokens from open models as they are generated, with OpenAI and Anthropic server-sent events. Examples, chunk format and error handling.Guides
- ResponsesUse the OpenAI Responses API format with open-weight models on inference.eu. Typed output items, built-in tools and multi-turn state, processed in the EU.Endpoints
Move your AI workloads to EU infrastructure
Tell us which models you use and roughly how much traffic you have. We reply within one working day with pricing and next steps.
- Reply within one working day
- Pricing for your volume
- DPA ready to sign