When using official tools such as web search with
kimi-k3, use the Formula API official tools channel described on this page (OpenAI protocol, standard function tool); the example below has been verified with kimi-k3.Choose an official tool to use
The following table lists the currently available official tools:Full example: call the web_search official tool
The following Python example uses the web-search official tool to show the full call chain (it only depends on requests). You can also interactively experience the capabilities of Kimi models and tools in the Kimi Development Workbench.
Using official tools through the Formula API follows the standard function tool flow of the OpenAI protocol, in 4 steps:
GET /v1/formulas/{uri}/tools— fetch the tool declarations (urisuch asmoonshot/web-search:latest);POST /v1/chat/completions— send the tool declarations; the model returns standardfunction-typetool_calls;POST /v1/formulas/{uri}/fibers— execute exactly whattool_callsspecifies (name+argumentspassed through verbatim; this step produces the tool_call billing);POST /v1/chat/completions— send the assistant message (withtool_calls) and therole: "tool"results to get the final answer.
moonshot/web-search:latest; set FORMULA_URI to another official tool’s formula URI to try it: moonshot/convert:latest, moonshot/web-search:latest, moonshot/rethink:latest, moonshot/random-choice:latest, moonshot/mew:latest, moonshot/memory:latest, moonshot/excel:latest, moonshot/date:latest, moonshot/base64:latest, moonshot/fetch:latest, moonshot/quickjs:latest, moonshot/code-runner:latest
The examples on this page use the latest model
kimi-k3 by default. K3 configures reasoning effort with the top-level reasoning_effort request field (supports "low" / "high" / "max", default "max"). To use another model such as kimi-k2.6 or kimi-k2.5, just replace the model field — parameter configurations differ across models. See the Model Parameter Reference.requests and set the MOONSHOT_API_KEY environment variable before running.
Understand the Formula concept
Before calling official tools, you need to understand Formula: it is a lightweight script engine collection that transforms Python scripts into “instant computing power that can be triggered by AI with one click” — developers only need to focus on writing code, while the platform handles startup, scheduling, isolation, billing, and recycling. Formulas are called through semantic URIs (such asmoonshot/web-search:latest). Each formula contains a declaration (telling the AI what it can do) and an implementation (Python code), and the platform automatically handles all underlying details (startup, isolation, recycling, etc.), making tools easy to share and reuse in the community. You can experience and debug these tools in Kimi Playground, or call them through the API in your applications.
Call a Formula directly to run a tool
A formula URI generally consists of 3 parts, for examplemoonshot/web-search:latest: web-search is its name; the namespace currently only supports moonshot; and latest is the default tag.
For example, to call web search, you can send an HTTP request like this:
web-search was set as protected when created, so its result appears in the context.encrypted_output field, in a format similar to ----MOONSHOT ENCRYPTED BEGIN----... ----MOONSHOT ENCRYPTED END----; this content can be passed directly into the tool call.
Integrate official tools with Chat Completions
As shown in Is 3214567 a prime number? An example of Tool Calls, when using official tools with Chat Completions, there are several key points you need to align between the Formula API and the model.Fetch the tool definition and append it to the tools field
Given a formula URI (for example moonshot/web-search:latest), append it directly to the URL to request the tool declarations:
tools field from the response (always an array of dicts) and append it to your request’s tools list — the platform guarantees this list is API-compatible.
Note that:
- If
type=function, you need to ensurefunction.nameis unique within a single API request, otherwise the chat completion request will be considered invalid and immediately returned with a 400 error (invalid_request_error, with a message likefunction name get_weather is duplicated); - If you use multiple formulas at the same time, you need to maintain your own
function.name->formula_urimapping for future reference.
Handle the tool call returned by the model
If the chat completion returnsfinish_reason=tool_calls, the model has triggered a tool call, and the response looks like this:
choices[0].message.tool_calls[0].function.name you can tell that web_search needs to be called, and the formula_uri corresponding to web_search is moonshot/web-search:latest. Copy choices[0].message.tool_calls[0].function from the response in full as the body, and send a request to ${MOONSHOT_BASE_URL}/formulas/${FORMULA_URI}/fibers.
Note that although the function.arguments output by the model is valid JSON in content, it is still an encoded string in format — you don’t need to escape it; just use it directly as the body of the call.
Handle the Fiber result and continue the conversation
A Fiber is a “process snapshot” of a specific execution, containing logs, Tracing, and resource usage, which is convenient for debugging and auditing. Thestatus of the POST result may be succeeded or various types of errors; when it succeeds, the result looks like this:
encrypted_output, while in general the result is output — this output is your input for the next round. When continuing the request, arrange the messages as follows:
Notes
- The model may return more than one
tool_calls; you must return results for alltool_callsfor the model to continue, otherwise the request will be considered invalid and rejected; - If the assistant message has
tool_calls, the next messages must be exactly the samerole=toolmessages as thetool_calls, andtool_call_idmust be aligned one-to-one with the previoustool_calls.id:- If there are multiple
tool_calls, the order is not sensitive; - The ids of the
tool_callsoutput by the model are always unique, and the ids in therole=toolmessages must also be aligned with them; - The uniqueness requirement is only local to the
tool_calls-response in this round, not for the entire conversation or globally.
- If there are multiple