Kimi K3.1 Pro · workflow
The tool-calling loop is: submit JSON Schema tool definitions, read the call list returned with finish_reason=tool_calls, parse each function.arguments, execute it on the client, then append the result with the matching tool_call_id and role="tool", continuing until the model returns finish_reason="stop".
The tool-calling loop is: submit JSON Schema tool definitions, read the call list returned with finish_reason=tool_calls, parse each function.arguments, execute it on the client, then append the result with the matching tool_call_id and role="tool", continuing until the model returns finish_reason="stop".
Suitable tasks: Search, database queries, web scraping, and other multi-step Agent tool workflows executed by the client.
Unsuitable tasks: Requests where the model is expected to execute local functions directly, or where unexecuted tool calls are treated as the final answer.
Applicable model version: The page's current examples use kimi-k3.1-pro by default; it also mentions that it can be replaced with kimi-k3.1-pro-highspeed, but this article does not treat Highspeed as an equivalently tested version.
Applicable client, agent, or API: Kimi API Chat Completions; the official examples use the OpenAI Python SDK or HTTP streaming responses, with the application executing the tools itself.
Recommended reasoning level and parameters: K3.1 Pro's reasoning_effort is placed at the top level of the request and accepts low, high, or max, with max as the default; the tool-calling loop itself does not require a particular level.
The following is a minimal official-format adaptation for defining a search tool; it is a workflow fragment, not a complete standalone prompt:
{
"type": "function",
"function": {
"name": "search",
"description": "Search the internet for the user's query.",
"parameters": {
"type": "object",
"required": ["query"],
"properties": {
"query": {
"type": "string",
"description": "The content to search for."
}
}
}
}
}When making a request, put one or more such objects in the top-level tools field. The function.arguments returned by the model is a serialized JSON object, which the client must deserialize before dispatching it:
assistant = completion.choices[0].message
if completion.choices[0].finish_reason == "tool_calls":
messages.append(assistant) # Preserve the assistant message containing tool_calls
for call in assistant.tool_calls:
args = json.loads(call.function.arguments)
result = tool_map[call.function.name](args)
messages.append({
"role": "tool",
"tool_call_id": call.id,
"name": call.function.name,
"content": json.dumps(result),
})Write a JSON Schema for each function that the client can actually execute; set parameters.type to object and list required and properties.
Give each tool a clear description explaining its purpose and invocation conditions; use English letters, digits, hyphens, and underscores in function names.
Put one or more tools in the top-level tools field of the initial request, and preserve the current messages.
Read choices[0].finish_reason. When it is tool_calls, message.content may be empty or may only explain which tools will be called.
Iterate over message.tool_calls, use function.name to look up the client's tool mapping, and parse the arguments with json.loads(function.arguments).
Execute each client-side function; the application is responsible for tool permissions, argument validation, timeouts, and error handling. The model does not execute functions on the application's behalf.
Append the assistant message returned by the API to messages unchanged first, then append one role="tool" message for each call.
Each tool result must include the corresponding tool_call_id and tool name, and return the result body as a string; JSON results can be serialized with json.dumps.
Multiple independent calls can be executed concurrently; the official loop example executes them one by one, but each result must still be matched independently to its own ID.
Submit the complete history to the API again; if the new finish_reason is still tool_calls, continue the loop; otherwise, return the final message.content when it is stop.
In streaming mode, use delta.tool_calls to identify calls instead of waiting until the final data chunk to recognize them for the first time; accumulate the content first, then process the tool-call fields.
In a streaming response, the initial data chunk usually provides the id, type, and function name, while subsequent chunks append function.arguments; bucket multiple calls by index and concatenate each separately.
Parse and execute only after concatenating each call's complete argument string; stop reading the stream after receiving [DONE].
The fixed outer structure of a tool definition is type="function", function.name, function.description, and function.parameters; the parameter schema uses JSON Schema.
tools can submit multiple tools at once; the model may call no tools, or return multiple different tools or multiple calls to the same tool.
A non-streaming call object includes a unique id, type="function", and function.name; function.arguments is a valid serialized JSON object.
finish_reason="tool_calls" means that the current response is requesting tool execution rather than providing the final answer to the user; after the tool results are returned, the model usually generates the final response with finish_reason="stop".
The official execution loop appends choice.message to the history, executes tool_calls one by one, and appends the tool results with role="tool", tool_call_id, name, and string content.
When multiple calls are returned at once, every tool_call must have a matching role="tool" message; a count mismatch or an ID that cannot be matched causes an error.
In streaming mode, delta.tool_calls must be merged by index; argument fragments arrive in chunks like delta.content, so an individual fragment cannot be treated as complete JSON.
The documentation says that function_call and related legacy parameters are no longer supported; use tool_calls instead. tool_calls also supports parallel calls.
The tools definitions themselves count toward the total token count, and the combined tool definitions and messages cannot exceed the model's context window.
The page explicitly states that the current examples use kimi-k3.1-pro as the default model, but function execution, parallel returns, and streaming assembly are documentation for the API tool-calling workflow; this article cannot claim that it conducted a live K3.1 Pro test.
This article's K3.1 Pro basis is the model="kimi-k3.1-pro" in the page's current code examples and the page's description of the default model; the replaceable Highspeed variant was not separately verified here.
“Client-side execution” means that the application calls its own implementation using the function name and arguments generated by the model; the API documentation does not execute network requests, control permissions, perform secure argument validation, retries, or timeout policies on the application's behalf.
The official examples use search, crawl, and placeholder search interfaces to demonstrate the workflow; these are not built-in Kimi tools and do not prove that any particular search service is connected.
Multiple tool results can be prepared in parallel, but they must still be returned one-to-one with their tool_call_id; the client must design the execution order, retry behavior, and partial-failure strategy.
If the assistant message returned by the API is omitted, or if its tool_calls field is incomplete, the next request may return tool_call_id not found; retaining this message is an ID-matching requirement, not a repeated discussion of P03 reasoning history in this article.
The documentation explains how to assemble streaming fields, but provides no K3.1 Pro latency, throughput, tool success-rate, or cost data; this article did not make a call using an API key.
Open the official Use Kimi API for Tool Calls page and confirm the page title, default model description, and tool-calling section.
Using an available Kimi API key, make a Chat Completions request with model="kimi-k3.1-pro" and tools=[...]; do not treat the page's static example as completed live validation.
Record the returned finish_reason, each tool_calls[].id, the function name, and the complete arguments; parse the arguments as JSON before executing the test tool.
Append the assistant message unchanged, append a matching role="tool" message for each call, and continue requesting until finish_reason="stop" is returned.
Separately use stream=true to check delta.tool_calls, index, and chunked argument assembly; verify single-call, multi-call, no-tool-call, and tool-error paths independently.
Check the tool-result count and ID mapping; record the request, tool execution, and final response, but do not write the API key, the user's original text, or sensitive tool arguments to logs.
This article records only the schema and execution loop made public in the official documentation; it does not claim local or live K3.1 Pro test results.
Kimi API Platform official documentation · Source date: Not disclosed · Edited: 2026-10-24
Read the original sourceKimi K3.1 Pro
Run this guide in the environment listed above. Downloading does not transfer the template or establish model availability for your account.