Function / tool calling
Function calling lets models request structured calls to your own functions. This guide explains what it is, when to use it, and how to pass tools in a request, with a minimal example. It covers the request-response flow, best practices, and common pitfalls, so you can integrate external capabilities reliably with any supported model.
What is function calling
Function calling (also called tool calling) lets a model ask your application to run a specific function with structured arguments. Instead of just generating text, the model can output a request like get_weather({"city": "Tokyo"}). Your code executes that function, then sends the result back to the model to continue the conversation.
This turns the model into a reasoning engine that can interact with databases, APIs, and other services while you keep control over what actually runs.
When to use function calling
Use function calling when the model needs to:
- Fetch live data — weather, stock prices, account balances, order status.
- Perform actions — send an email, create a calendar event, update a CRM record.
- Run calculations or queries — evaluate complex math, query a database, search internal docs.
- Interact with external systems — call a payment gateway, trigger a webhook, control a device.
Avoid function calling when the task is purely conversational or when the model can answer from its own knowledge. Also avoid it for tasks that require deterministic output without external state — plain prompting is simpler.
How to pass tools in a request
Tools are described in the API request using a JSON schema. Each tool has a name, a description, and a parameters object that defines the expected arguments.
Here is a minimal example in Python using the OpenAI-compatible chat completions format:
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}
]
response = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools,
tool_choice="auto"
)
The model may respond with a tool_calls array instead of plain text. You then execute the function and send the result back as a tool message.
The request-response flow
- You send a request with a user message and a list of available tools.
- The model decides whether to call a tool. If so, it returns a
tool_callsobject with the function name and arguments. - You execute the function in your own code.
- You send the result back as a message with
role: "tool"and the matchingtoolcallid. - The model uses the result to generate a final answer or call another tool.
This loop can repeat multiple times within a single conversation.
Best practices
- Keep tool descriptions clear and specific — the model relies on them to choose the right tool.
- Define strict parameter schemas — include types, descriptions, and required fields.
- Limit the number of tools — too many options can confuse the model or increase latency.
- Handle errors gracefully — return structured error messages so the model can recover or ask for clarification.
- Validate arguments — never trust the model's output blindly; check types and ranges before executing.
- Set a timeout and retry policy — external functions may fail; the model should not hang indefinitely.
Common pitfalls
- Ambiguous tool names or descriptions — the model may pick the wrong tool or skip it entirely.
- Missing required parameters — if the schema is incomplete, the model may omit critical arguments.
- Overlapping tools — two tools that do similar things can cause inconsistent behavior.
- Forgetting to send tool results — the conversation will stall if you don't return the function output.
- Ignoring safety — never let the model execute arbitrary code or access sensitive systems without your explicit validation.
Example: multi-step tool use
Suppose you have two tools: getuser and sendemail. A user asks: "Email Alice the latest report."
The model might first call getuser({"name": "Alice"}) to retrieve her email address. After you return the result, it calls sendemail({"to": "alice@example.com", "subject": "Latest report", "body": "..."}). You execute the send, return a success message, and the model confirms completion.
This pattern works across all supported models on our platform. You can switch between Claude, GPT, DeepSeek, Qwen, GLM, and Kimi without changing your tool definitions, as long as the model supports function calling.
Summary
Function calling connects models to your code. Define tools with clear schemas, pass them in the request, and handle the model's tool calls in your application. Use it for live data, actions, and external integrations — but keep validation and safety under your control.