본문으로 건너뛰기
노트
이 페이지는 아직 번역되지 않아 영어로 표시됩니다.

Tool calling

A model can ask your code to run a function, such as looking up an order or querying a database, and then answer with the result. The model never runs anything itself: it returns the function's name and arguments, your code runs it, and you send the result back in the next request.

Use a model whose page on Models lists tool calling under Capabilities. A model without it ignores tools and answers in text, without an error.

This sample is a file we run against the service before publishing:

# pip install openai
# Tool calling: the model asks for a function, your code runs it and sends the
# result back, and the model answers with it. Any chat model whose page lists
# tool calling works the same way.
import json
import os
from openai import OpenAI

client = OpenAI(
base_url=os.getenv("OCEANTOKEN_BASE_URL", "https://api.oceantoken.ai/v1"),
api_key=os.environ["OCEANTOKEN_API_KEY"],
)


def get_weather(city):
# Your own code runs here: a database, an internal API, anything.
return {"city": city, "temperature_c": 18, "sky": "cloudy"}


tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "The current weather in a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string", "description": "City name, for example Lisbon"}},
"required": ["city"],
},
},
}
]

messages = [{"role": "user", "content": "What is the weather in Lisbon right now?"}]
message = client.chat.completions.create(model="openai/gpt-5-mini", messages=messages, tools=tools).choices[0].message
called = False

# While the model asks for tools, run each one and send the results back.
while message.tool_calls:
called = True
messages.append({
"role": "assistant",
"content": message.content,
"tool_calls": [call.model_dump() for call in message.tool_calls],
})
for call in message.tool_calls:
result = get_weather(**json.loads(call.function.arguments))
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
message = client.chat.completions.create(model="openai/gpt-5-mini", messages=messages, tools=tools).choices[0].message

# A model that ignores `tools` answers without calling them, and that is not an error.
if not called:
raise SystemExit("the model answered without calling the tool")
print(message.content)

How the loop works​

  1. Describe your functions in tools: a name, a description the model reads to decide when to call it, and parameters as a JSON Schema.
  2. The model asks for a call. The answer's finish_reason is tool_calls, and choices[0].message.tool_calls lists each call with an id, the function name and its arguments as a JSON string.
  3. Run it and send the result back. Append the model's message with its tool_calls, then one tool message per call, carrying the call's tool_call_id and your result as a string.
  4. Ask again with the same tools. The model answers, or asks for more calls; repeat until tool_calls is empty.

Arguments come from the model, so validate them before you act on them, exactly as you would user input.

Choosing when the model calls​

tool_choice controls it:

ValueEffect
"auto" (default)The model decides.
"required"The model must call at least one tool.
"none"The model must answer in text.
{"type": "function", "function": {"name": "get_weather"}}The model must call this function.

Several calls at once​

A model whose page lists parallel tool calls can ask for several calls in one message, for example the weather in two cities. Run each and send one tool message per tool_call_id, in any order; the loop above already does. Send "parallel_tool_calls": false to get one call at a time.

Streaming​

With stream=True, a call arrives in pieces under choices[0].delta.tool_calls: the first piece of each call carries its index, id and name, and the following pieces add to arguments. Join the pieces by index, and run the calls once the stream ends with finish_reason tool_calls. SDK helpers such as the Vercel AI SDK do this for you (Call tools).

With the Anthropic Messages API​

On /v1/messages tools take the Anthropic shape, for every chat model: tools with name, description and input_schema; the model answers with tool_use blocks and stop_reason tool_use; you send the results back as tool_result blocks in a user message. The Anthropic SDK works unchanged with the base URL https://api.oceantoken.ai.

Costs​

Tool definitions are part of the prompt and are billed as input tokens on every request that carries them, and each round trip is a separate request. Long, unchanging tool lists are a good fit for prompt caching.

Next​