Guides
Tool Calling Guide
Describe external functions with tools, validate model arguments, execute tools, and return results.
The model does not execute your functions directly. It returns a structured call intent; your application validates and executes the tool, then includes the result as a tool message in the next request.
Execution flow
Define tools and send the user question → model returns tool_calls → application executes tools and returns tool messages.
Weather tool example
import json
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["APIQIK_API_KEY"],
base_url="https://api.apiqik.com/v1",
)
tools = [{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "City name, for example Beijing",
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
},
},
"required": ["city"],
"additionalProperties": False,
},
},
}]
messages = [
{"role": "user", "content": "What is the weather in Beijing now? Use Celsius."}
]
first = client.chat.completions.create(
model="qwen-turbo",
messages=messages,
tools=tools,
tool_choice="auto",
)
assistant = first.choices[0].message
if not assistant.tool_calls:
print(assistant.content)
raise SystemExit
messages.append({
"role": "assistant",
"content": assistant.content,
"tool_calls": [
{
"id": call.id,
"type": call.type,
"function": {
"name": call.function.name,
"arguments": call.function.arguments,
},
}
for call in assistant.tool_calls
],
})
for call in assistant.tool_calls:
if call.function.name != "get_current_weather":
raise ValueError("Tool is not allowed")
arguments = json.loads(call.function.arguments)
city = arguments["city"]
unit = arguments.get("unit", "celsius")
# 实际项目在这里调用真实天气服务。
result = {
"city": city,
"temperature": 22,
"unit": unit,
"condition": "sunny",
}
messages.append({
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result, ensure_ascii=False),
})
final = client.chat.completions.create(
model="qwen-turbo",
messages=messages,
tools=tools,
)
print(final.choices[0].message.content)Parameter structure
| Field | Description |
|---|---|
tools[].type | Use function for function tools. |
function.name | A function name your application recognizes and allows. |
function.description | Explain when to use the tool so the model can select it correctly. |
function.parameters | JSON Schema describing argument types, enums, and required fields. |
tool_choice | auto lets the model choose between text and tool calls. |
message.tool_calls | Generated calls; the list may contain multiple calls. |
function.arguments | A JSON string that still needs business validation after parsing. |
tool_call_id | Associates a tool result with the corresponding model call. |
Security boundaries
- Allowlist tool names; never execute a function invented by the model.
- Validate arguments against both JSON Schema and business rules.
- Check permissions and require confirmation for database writes, payments, messages, and other side effects.
- Set tool timeouts, response-size limits, and error formats to avoid unbounded waits.
- Treat tool results as untrusted input; sanitize and redact them before returning them to the model.