> ## Documentation Index
> Fetch the complete documentation index at: https://platform.kimi.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kimi K3 API Tool Calling Best Practices

> When your agent has a large tool inventory, use dynamic loading, tool_choice, and thinking effort to control token usage and improve tool-selection accuracy.

When your agent has access to dozens or hundreds of tools, don't put every tool definition into the request — they eat up context and make the model more likely to pick the wrong tool. This guide walks through a tool-orchestration setup on Kimi K3: retrieve candidate tools with a search tool first, then inject tool definitions into the conversation on demand.

## Declare a search tool, not all your tools

At the start of a conversation, declare only a single `search_tools` function — implemented by your backend — plus a small set of core tools you expect to use in every turn:

```json theme={null}
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_tools",
        "description": "Search available tools by keyword and return matching tool names and summaries",
        "parameters": {
          "type": "object",
          "properties": {
            "query": {
              "type": "string",
              "description": "Search keyword, e.g. github or database"
            }
          },
          "required": ["query"]
        }
      }
    }
  ]
}
```

In the system prompt, advertise the domain tags the model can search (for example, a tool catalog or business domains) so it knows to call `search_tools` first when it needs a tool. No matter how large your total inventory is, each request then only carries a handful of tool declarations.

## Use tool\_choice to force first-turn retrieval

The model may choose not to call any tool and answer from memory. To make sure it retrieves before answering, set `tool_choice: "required"` on the first turn:

```json theme={null}
{
  "model": "kimi-k3",
  "messages": [{"role": "user", "content": "Help me create a GitHub PR"}],
  "tools": ["..."],
  "tool_choice": "required"
}
```

After retrieval, switch `tool_choice` back to `"auto"` for subsequent requests. Changing `tool_choice` does not invalidate the prefix cache, so you can adjust it per request. See [Tool Choice](/guide/use-tool-choice) for all accepted values.

## Inject tool definitions on demand

When `search_tools` returns candidate tools, your application inserts the full declarations of the matching tools into `messages` via a `system` message carrying a `tools` field. The tools become visible to the model starting from that message's position:

```json theme={null}
{
  "role": "system",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "create_github_pr",
        "description": "Create a pull request in the given repository",
        "parameters": {
          "type": "object",
          "properties": {}
        }
      }
    }
  ]
}
```

Dynamic declarations use exactly the same format as the top-level `tools` field — no second schema to maintain — and coexist with globally declared tools. Dynamic tool declarations apply per request and are not retained by the server. In the next request, the client can keep the original declaration so the tool remains available and the prefix cache can be reused, or remove it. If the tool is not declared elsewhere, the model cannot call that tool, and the changed prefix may miss the cache. See [Dynamically Loaded Tools](/guide/use-dynamic-tool-loading) for full usage.

## Pick the thinking effort for the task

Thinking effort currently supports only the `max` level (default); lower levels, once available, will cut cost and latency for lightweight tasks such as simple Q\&A or argument construction.

Note that K3 currently supports only `reasoning_effort: "max"`; decide on this setting before the conversation starts. Appending a dynamic tool declaration to the end of `messages` does not affect the cached prefix; removing or modifying an earlier tool declaration may affect cache hits after the point of change. Changing `tool_choice` does not invalidate the prefix cache. See [Thinking Effort](/guide/use-thinking-effort) for the trade-offs.

<Danger>
  **Switching `effort` currently does not affect prefix-cache hits.** Thinking effort currently supports only the `max` level. Once more levels are available, switching levels may invalidate the cache, so it is still recommended to decide on the `effort` level before the conversation starts and avoid switching it mid-session.
</Danger>

## The complete flow

1. Conversation start: top-level `tools` carries only `search_tools` plus a few core tools;
2. First-turn retrieval: `tool_choice: "required"` forces the model to call `search_tools`;
3. Inject on demand: insert tool definitions via a `system` message based on the retrieval results;
4. Call directly: the model calls the loaded tools in subsequent generations;
5. Cost trade-off: decide on the top-level `reasoning_effort` setting before the conversation starts.

## Related reading

* [Dynamically Loaded Tools](/guide/use-dynamic-tool-loading)
* [Tool Choice](/guide/use-tool-choice)
* [Thinking Effort](/guide/use-thinking-effort)
* [Use Kimi API for Tool Calls](/guide/use-kimi-api-to-complete-tool-calls)
* [Model Parameter Reference](/api/models-overview)
