Tool Calling
Build agent workflows with OpenAI-compatible tools and function calls.
Tool Calling
Tool calling lets a model ask your application to run a function, fetch data, or execute a workflow before producing a final answer.
Qufas AI accepts OpenAI-compatible tools and tool_choice parameters on POST /v1/chat/completions. Tool definitions are forwarded through the provider layer without changing the OpenAI-compatible response shape.
Tool Definition
Define each tool as a function with a name, description, and JSON Schema parameters.
1{2 "type": "function",3 "function": {4 "name": "get_weather",5 "description": "Get current weather for a location.",6 "parameters": {7 "type": "object",8 "properties": {9 "location": {10 "type": "string",11 "description": "City and region, for example Los Angeles, CA."12 },13 "unit": {14 "type": "string",15 "enum": ["celsius", "fahrenheit"]16 }17 },18 "required": ["location"]19 }20 }21}Examples
The model does not execute your function. Your application reads message.tool_calls, runs the matching function, then sends the tool result back as the next message.
1import json2from openai import OpenAI3 4client = OpenAI(5 api_key="qf_sk_xxxxx",6 base_url="https://qufas-ai.vercel.app/v1",7)8 9tools = [10 {11 "type": "function",12 "function": {13 "name": "get_weather",14 "description": "Get current weather for a location.",15 "parameters": {16 "type": "object",17 "properties": {18 "location": {19 "type": "string",20 "description": "City and region, for example Los Angeles, CA.",21 },22 "unit": {23 "type": "string",24 "enum": ["celsius", "fahrenheit"],25 },26 },27 "required": ["location"],28 },29 },30 }31]32 33messages = [34 {35 "role": "user",36 "content": "What is the weather in Los Angeles?"37 }38]39 40response = client.chat.completions.create(41 model="kimi-k2.7-code",42 messages=messages,43 tools=tools,44 tool_choice="auto",45 parallel_tool_calls=True,46)47 48message = response.choices[0].message49 50if message.tool_calls:51 messages.append(message)52 53 for tool_call in message.tool_calls:54 args = json.loads(tool_call.function.arguments)55 result = {56 "location": args["location"],57 "temperature": "72",58 "unit": args.get("unit", "fahrenheit"),59 "condition": "sunny",60 }61 62 messages.append(63 {64 "role": "tool",65 "tool_call_id": tool_call.id,66 "name": tool_call.function.name,67 "content": json.dumps(result),68 }69 )70 71 final_response = client.chat.completions.create(72 model="kimi-k2.7-code",73 messages=messages,74 )75 76 print(final_response.choices[0].message.content)Tool Calling Flow
Tool calling is an application loop. Qufas returns the model's requested function calls; your application executes them and sends the result back with role tool.
1User2 |3 v4Qufas Chat Completion5 |6 v7Assistant tool_calls8 |9 v10Developer executes function11 |12 v13role=tool result14 |15 v16Final assistant responseResponse Format
When the model chooses to call a tool, the assistant message includes tool_calls and the finish reason is tool_calls.
1{2 "id": "chatcmpl_xxxxxxxxx",3 "object": "chat.completion",4 "created": 1750000000,5 "model": "kimi-k2.7-code",6 "choices": [7 {8 "index": 0,9 "finish_reason": "tool_calls",10 "message": {11 "role": "assistant",12 "content": null,13 "tool_calls": [14 {15 "id": "call_xxxxxxxxx",16 "type": "function",17 "function": {18 "name": "get_weather",19 "arguments": "{\"location\":\"Los Angeles, CA\"}"20 }21 }22 ]23 }24 }25 ],26 "usage": {27 "prompt_tokens": 92,28 "completion_tokens": 18,29 "total_tokens": 11030 }31}Tool Results
Send the function result back with role tool and the matching tool_call_id. The model can then produce the final response using the returned data.
1[2 {3 "role": "user",4 "content": "What is the weather in Los Angeles?"5 },6 {7 "role": "assistant",8 "content": null,9 "tool_calls": [10 {11 "id": "call_xxxxxxxxx",12 "type": "function",13 "function": {14 "name": "get_weather",15 "arguments": "{\"location\":\"Los Angeles, CA\"}"16 }17 }18 ]19 },20 {21 "role": "tool",22 "tool_call_id": "call_xxxxxxxxx",23 "name": "get_weather",24 "content": "{\"temperature\":\"72\",\"condition\":\"sunny\"}"25 }26]Parallel Tool Calls
Some models can return multiple tool calls in one assistant message. Always iterate over the full tool_calls array instead of assuming there is only one function call.
Run independent tool calls in parallel in your application when it is safe to do so, then append one tool message for each result.
Set parallel_tool_calls to true to allow multiple calls when the selected provider supports it. Set it to false when your application prefers a single call.
Streaming Tool Calls
With stream: true, tool calls can arrive incrementally in choices[0].delta.tool_calls. Accumulate the function name and arguments by index until the stream ends.
1data: {"id":"chatcmpl_xxxxxxxxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_xxxxxxxxx","type":"function","function":{"name":"get_weather","arguments":""}}]},"finish_reason":null}]}2 3data: {"id":"chatcmpl_xxxxxxxxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"location\":"}}]},"finish_reason":null}]}4 5data: {"id":"chatcmpl_xxxxxxxxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"Los Angeles, CA\"}"}}]},"finish_reason":null}]}6 7data: {"id":"chatcmpl_xxxxxxxxx","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}]}8 9data: [DONE]Accumulate chunks with the same index. In the example above, the final reconstructed function call is:
1{2 "name": "get_weather",3 "arguments": "{\"location\":\"Los Angeles, CA\"}"4}Tool Choice
| Value | Behavior |
|---|---|
| auto | Allow the model to decide whether to call a tool. |
| none | Prevent the model from calling tools. |
| {"type":"function","function":{"name":"get_weather"}} | Force a specific function when supported. |
required is not supported. Use auto, none, or a named function choice.
Tool Calling Errors
Qufas validates tool definitions before forwarding the request. Invalid schemas return a standard 400 invalid_request_error.
Invalid tool schema
1{2 "error": {3 "message": "Invalid tool definition.",4 "type": "invalid_request_error",5 "param": "tools",6 "code": "invalid_parameter"7 }8}Unsupported tool parameter
If a selected model or provider does not support tool calling, return a clear OpenAI-compatible error instead of a provider-specific response.
1{2 "error": {3 "message": "The selected model does not support tool calling.",4 "type": "invalid_request_error",5 "param": "tools",6 "code": "unsupported_parameter"7 }8}Was this page helpful?
