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

# Kimi K3 Hands-On Guide: New Parameters & API Support Matrix

> July 2026 Kimi K3 guide: reasoning_effort max, thinking history, dynamic tool loading, structured output, auto caching, partial prefix, and vision inputs.

<Frame>
  <img src="https://mintcdn.com/aihubmix/wEvKQkflgAoXIvcL/images/blogs/kimi-k3-guide.webp?fit=max&auto=format&n=wEvKQkflgAoXIvcL&q=85&s=e5ee6a08fd7642ff6c7f917811961710" alt="Kimi K3 hands-on guide: thinking mode, dynamic tool loading, and context caching" width="2400" height="1260" data-path="images/blogs/kimi-k3-guide.webp" />
</Frame>

> This article covers the new parameters and usage notes for [Kimi K3](https://aihubmix.com/model/kimi-k3). On AIHubMix, K3 is available through the Chat Completions, Responses, and Claude-compatible Messages APIs. See also: [Moonshot official platform docs](https://platform.moonshot.ai/docs).
>
> The "Verified" conclusions and sample responses in each section come from actual calls made on 2026-07-17 through the AIHubMix APIs (Chat Completions / Responses / Messages).

## 1. Model Specs at a Glance

| Item             | Value                                                         |
| :--------------- | :------------------------------------------------------------ |
| Context window   | 1M tokens                                                     |
| Max output       | `max_completion_tokens` defaults to 131,072, up to 1,048,576  |
| Input modalities | Text, images (for video input see the Moonshot official docs) |
| Thinking mode    | On by default; `reasoning_effort` only supports `"max"`       |
| Stop sequences   | `stop` allows at most 5 entries, each no longer than 32 bytes |

> **Verified**: both `stop` limits are validated, and exceeding either returns 400; the Messages API applies the same validation to `stop_sequences`.
>
> ❗ **When a stop sequence is hit, the Messages API does not follow Anthropic semantics**: in testing, `stop_reason` is `"end_turn"` (rather than `"stop_sequence"`), `stop_sequence` is `null`, and the visible text before the stop word may be empty. Clients that rely on these two fields to detect truncation should take note.

```text theme={null}
# stop with 6 entries / a 33-byte entry -> HTTP 400
"Invalid request: stop array too long. Expected an array with maximum length 5, but got an array with length 6 instead"
"Invalid request: stop sequence must not be longer than 32, but got 33 instead"
```

## 2. Thinking Mode: `reasoning_effort` Only Supports `max`

K3's thinking is on by default, and `reasoning_effort` only supports a single level: `"max"`.

**Multi-turn conversations must pass the thinking history back verbatim**: per Moonshot's official documentation, K3 is trained with preserved thinking, so in multi-turn conversations the previous assistant message must be passed back **complete and unmodified** (including the thinking content). Missing thinking history leads to unstable output quality. If you use a session-management framework or a proxy layer, confirm the thinking content is passed back untrimmed.

<Tabs>
  <Tab title="Chat Completions">
    Thinking content is returned in the `reasoning_content` field of the response; in multi-turn conversations, pass the previous assistant message (including `reasoning_content`) back verbatim.

    ```text theme={null}
    from openai import OpenAI

    client = OpenAI(
        base_url="https://aihubmix.com/v1",
        api_key="<AIHUBMIX_API_KEY>",
    )

    completion = client.chat.completions.create(
        model="kimi-k3",
        reasoning_effort="max",
        messages=[
            {"role": "user", "content": "A snail is at the bottom of a 10-meter well. Each day it climbs 3 meters, but each night it slides back 2 meters. How many days does it take to reach the top?"}
        ],
    )

    print(completion.choices[0].message.reasoning_content)
    print(completion.choices[0].message.content)
    ```

    ```text theme={null}
    # Multi-turn: pass the previous assistant message back verbatim
    messages = [
        {"role": "user", "content": "What is the capital of France?"},
        {"role": "assistant", "content": "Paris.", "reasoning_content": "<reasoning_content from the previous response>"},
        {"role": "user", "content": "And its population?"},
    ]
    ```

    > **Verified**: the response returns `reasoning_content`; after passing the previous assistant message (including `reasoning_content`) back verbatim, subsequent turns answer normally.
  </Tab>

  <Tab title="Responses">
    Thinking content is returned as a `reasoning` output item; in multi-turn conversations, append the previous turn's output items (`reasoning` + `message`) back into `input` verbatim.

    ```text theme={null}
    from openai import OpenAI

    client = OpenAI(
        base_url="https://aihubmix.com/v1",
        api_key="<AIHUBMIX_API_KEY>",
    )

    response = client.responses.create(
        model="kimi-k3",
        input="Answer in one word: capital of France",
    )

    # Observed response.output item types: ["reasoning", "message"]; text: "Paris"
    # Multi-turn: input = [first user message] + response.output + [next user message]
    # Observed second-turn answer with output items passed back: "Berlin"
    ```
  </Tab>

  <Tab title="Messages">
    Thinking content is returned as native `thinking` content blocks; in multi-turn conversations, pass the previous assistant content blocks (including the thinking blocks) back verbatim.

    ```text theme={null}
    from anthropic import Anthropic

    client = Anthropic(
        api_key="<AIHUBMIX_API_KEY>",
        base_url="https://aihubmix.com"
    )

    response = client.messages.create(
        model="kimi-k3",
        max_tokens=4096,
        messages=[
            {"role": "user", "content": "Answer in one word: capital of France"}
        ],
    )

    # Observed response.content block types: ["thinking", "text"]; text: "Paris"
    # Multi-turn: pass response.content back verbatim as the assistant message
    ```
  </Tab>
</Tabs>

## 3. Sampling Parameters Are Fixed

K3's sampling parameters are fixed by the vendor: `temperature` 1.0, `top_p` 0.95, `n` 1, and `presence_penalty` / `frequency_penalty` 0. The official recommendation is to omit these parameters from requests.

> **Note**: the fixed sampling values are part of the official spec and cannot be verified from response signals; follow the official recommendation and omit these parameters.

## 4. Tool Calling and Dynamic Tool Loading

`tools` supports up to 128 tools; `tool_choice` supports forcing and disabling tool calls. K3 also supports dynamic tool loading: injecting new tools mid-conversation via the `tools` field of a system message (a message shape specific to the Chat API).

<Tabs>
  <Tab title="Chat Completions">
    `tool_choice` supports `auto` / `none` / `required`; `required` forces the model to call a tool. Dynamic tool loading: the tool-injecting system message carries no `content`, the injected tools take effect for subsequent turns, and the message must be included again in every request.

    ```text theme={null}
    messages = [
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Hello."},
        {"role": "assistant", "content": "Hi, how can I help you?"},
        # Inject a new tool mid-conversation: tools field only, no content
        {
            "role": "system",
            "tools": [
                {
                    "type": "function",
                    "function": {
                        "name": "get_time",
                        "description": "Get the current time",
                        "parameters": {"type": "object", "properties": {}},
                    },
                }
            ],
        },
        {"role": "user", "content": "What time is it now?"},
    ]
    ```

    ```text theme={null}
    # tool_choice="required" with prompt "Hello" -> the model is forced to call the tool
    "finish_reason": "tool_calls",
    "tool_calls": [{"function": {"name": "get_weather", "arguments": "{\"city\":\"New York\"}"}}]
    ```

    > **Verified**: `tool_choice: "required"` forces a tool call even for unrelated prompts; `"none"` suppresses tool calls; tools injected mid-conversation via a system message without `content` can be called normally.
  </Tab>

  <Tab title="Responses">
    Tool definitions use a flat structure (`name` at the top level); forcing a call likewise uses `tool_choice: "required"`, and calls are returned as `function_call` output items. Dynamic tool loading support is in progress; for now, declare all tools in the top-level `tools` parameter.

    ```text theme={null}
    response = client.responses.create(
        model="kimi-k3",
        input="Hello",
        tools=[{
            "type": "function",
            "name": "get_weather",
            "description": "Get weather for a city",
            "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
        }],
        tool_choice="required",
    )

    # Observed output contains: {"type": "function_call", "name": "get_weather", "arguments": "{\"city\":\"London\"}"}
    ```
  </Tab>

  <Tab title="Messages">
    Tools use the Anthropic format (`input_schema`); force a call with `tool_choice: {"type": "any"}` and disable calls with `{"type": "none"}`. ❗ **Kimi K3's official Messages (Anthropic-compatible) endpoint does not support dynamic tool loading**: in testing, the injecting message returns 200, but the injected tool has no effect (the model cannot call it). Declare all tools in the top-level `tools` parameter.

    ```text theme={null}
    response = client.messages.create(
        model="kimi-k3",
        max_tokens=4096,
        tools=[{
            "name": "get_weather",
            "description": "Get weather for a city",
            "input_schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
        }],
        tool_choice={"type": "any"},
        messages=[{"role": "user", "content": "Hello"}],
    )

    # Observed: stop_reason "tool_use"; content contains a tool_use block calling get_weather
    ```
  </Tab>
</Tabs>

## 5. Structured Output

Structured output makes the model return content that strictly conforms to a given JSON Schema.

<Tabs>
  <Tab title="Chat Completions">
    `response_format` supports `json_schema` with `strict` mode.

    ```text theme={null}
    completion = client.chat.completions.create(
        model="kimi-k3",
        messages=[
            {"role": "user", "content": "Paris is the capital of France. Extract the city name."}
        ],
        response_format={
            "type": "json_schema",
            "json_schema": {
                "name": "extract",
                "strict": True,
                "schema": {
                    "type": "object",
                    "properties": {"city": {"type": "string"}},
                    "required": ["city"],
                },
            },
        },
    )

    # Observed response content: {"city":"Paris"}
    ```

    > **Verified**: the output is valid JSON conforming to the schema.
  </Tab>

  <Tab title="Responses">
    Structured output is declared via `text.format`.

    ```text theme={null}
    response = client.responses.create(
        model="kimi-k3",
        input="Paris is the capital of France. Extract the city name.",
        text={
            "format": {
                "type": "json_schema",
                "name": "extract",
                "strict": True,
                "schema": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]},
            }
        },
    )

    # Observed output text: {"city":"Paris"}
    ```
  </Tab>

  <Tab title="Messages">
    ❗ **Kimi K3's official Messages (Anthropic-compatible) endpoint does not support structured output**: the structured-output fields are silently ignored — the request returns HTTP 200 with free-form text, with no error or fallback notice, and downstream JSON parsing will fail. When you need structured output, use the Chat Completions or Responses API.
  </Tab>
</Tabs>

## 6. Context Caching Is Automatic

K3's context caching is enabled automatically, with no parameters required. When a repeated long prefix hits the cache, the hit amount is reported in usage (the field name varies by API). Cache pricing is on the [model page](https://aihubmix.com/model/kimi-k3).

<Tabs>
  <Tab title="Chat Completions">
    ```text theme={null}
    # usage of the second call with an identical long prefix
    "prompt_tokens_details": {"cached_tokens": 1536}
    ```

    > **Verified**: the second request with an identical long prefix reports the hit in `usage.prompt_tokens_details.cached_tokens`.
  </Tab>

  <Tab title="Responses">
    ```text theme={null}
    # usage of the second Responses call with identical long instructions
    "input_tokens_details": {"cached_tokens": 1536}
    ```
  </Tab>

  <Tab title="Messages">
    ```text theme={null}
    # usage of the second Messages call with an identical long system prompt
    "cache_read_input_tokens": 1536
    ```
  </Tab>
</Tabs>

## 7. `partial` Prefix Completion

Prefix completion makes the model continue generating from a given prefix, well suited to code completion and format-controlled output.

<Tabs>
  <Tab title="Chat Completions">
    Pass `"partial": true` in the last assistant message.

    ```text theme={null}
    messages = [
        {"role": "user", "content": "Write a haiku about the sea."},
        {"role": "assistant", "content": "Waves fold into foam,", "partial": True},
    ]

    # Prefix: "Waves fold into foam,"  ->  continuation returned by the model
    # salt hangs in the air—
    # moon pulls the tide home.
    ```

    > **Verified**: generation continues from the given prefix without repeating it.
  </Tab>

  <Tab title="Responses">
    Pass the prefix as an assistant message at the end of the `input` array; no `partial` parameter is needed.

    ```text theme={null}
    response = client.responses.create(
        model="kimi-k3",
        input=[
            {"role": "user", "content": "Write a haiku about the sea."},
            {"role": "assistant", "content": "Waves fold into foam,"},
        ],
    )

    # Observed continuation: "salt hangs in the air— / moon pulls the tide home."
    ```
  </Tab>

  <Tab title="Messages">
    The same capability is achieved with the protocol's native assistant prefill, with no `partial` parameter — pass the prefix as the last assistant message.

    ```text theme={null}
    response = client.messages.create(
        model="kimi-k3",
        max_tokens=4096,
        messages=[
            {"role": "user", "content": "Write a haiku about the sea."},
            {"role": "assistant", "content": "Waves fold into foam,"},
        ],
    )

    # Observed continuation: "salt wind carries the gull's cry— / tide pulls ..."
    ```
  </Tab>
</Tabs>

## 8. Vision Input

Images are passed as base64; the content-block format varies by API.

<Tabs>
  <Tab title="Chat Completions">
    ```text theme={null}
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is the dominant color of this image? One word."},
                {"type": "image_url", "image_url": {"url": "data:image/png;base64,<BASE64>"}},
            ],
        }
    ]

    # Observed response content: "Red"  (input: a 64x64 solid red PNG)
    ```

    > **Verified**: base64 image input works, and the model correctly describes the test image.
  </Tab>

  <Tab title="Responses">
    ```text theme={null}
    input = [
        {
            "role": "user",
            "content": [
                {"type": "input_text", "text": "What is the dominant color of this image? One word."},
                {"type": "input_image", "image_url": "data:image/png;base64,<BASE64>"},
            ],
        }
    ]

    # Observed output text: "Red"
    ```
  </Tab>

  <Tab title="Messages">
    ```text theme={null}
    messages = [
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "What is the dominant color of this image? One word."},
                {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "<BASE64>"}},
            ],
        }
    ]

    # Observed response text: "Red"
    ```
  </Tab>
</Tabs>

## 9. Verified Reference: Latency and Usage of a Long Single-Call Task

K3's thinking is fixed at the max level, so single requests for complex tasks take significantly longer than on typical models. Measured data from a single-file HTML game generation task (one prompt with a reference image, generated in one shot with no iteration): the single request took 2,541 seconds (about 42 minutes), with 74,994 completion tokens, of which 54,486 (73%) were thinking tokens; the final output was 1,275 lines of directly runnable code, with `finish_reason` `stop`.

Client-side recommendations:

* Set client timeouts to minutes or longer, and prefer streaming for long tasks;
* Leave ample headroom in `max_completion_tokens` — in this case thinking alone consumed 54,486 tokens.

## 10. Capability × API Support Matrix

Every cell in the table below was verified on 2026-07-17 through actual calls to the AIHubMix production APIs; each cell shows the parameter / field syntax for the corresponding API.

| Capability                   | Chat Completions                              | Responses                                    | Messages                                                                                                                                       |
| :--------------------------- | :-------------------------------------------- | :------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- |
| Thinking content in response | ✅ `reasoning_content` field                   | ✅ `reasoning` output item                    | ✅ `thinking` content block                                                                                                                     |
| Thinking history pass-back   | ✅ assistant message passed back verbatim      | ✅ output items passed back verbatim          | ✅ content blocks passed back verbatim                                                                                                          |
| Force / disable tool calls   | ✅ `tool_choice: "required"` / `"none"`        | ✅ `tool_choice: "required"`                  | ✅ `{"type": "any"}` / `{"type": "none"}`                                                                                                       |
| Dynamic tool loading         | ✅ system message with `tools` (no `content`)  | ➖ Support in progress                        | ❗ Unsupported on the official Messages (Anthropic-compatible) endpoint                                                                         |
| Structured output            | ✅ `response_format` (json\_schema + strict)   | ✅ `text.format` (json\_schema)               | ❗ Unsupported on the official endpoint; fields are **silently ignored** (200 + free-form text) — use Chat / Responses instead                  |
| Automatic cache-hit metering | ✅ `usage.prompt_tokens_details.cached_tokens` | ✅ `usage.input_tokens_details.cached_tokens` | ✅ `usage.cache_read_input_tokens`                                                                                                              |
| Prefix completion            | ✅ `"partial": true`                           | ✅ assistant prefill                          | ✅ assistant prefill (protocol-native)                                                                                                          |
| Vision input                 | ✅ `image_url` (base64)                        | ✅ `input_image` (base64)                     | ✅ `image` content block (base64)                                                                                                               |
| Stop sequences               | ✅ `stop` (limits validated)                   | ➖ Support in progress                        | ❗ `stop_sequences` limits validated identically, but on a hit neither `stop_reason: "stop_sequence"` nor the `stop_sequence` value is returned |

## FAQ

**Which APIs does K3 support on AIHubMix?**
Chat Completions (`/v1/chat/completions`), Responses (`/v1/responses`), and the Claude-compatible Messages API (`/v1/messages`).

**Can thinking be disabled or turned down?**
No. K3's thinking is on by default, and `reasoning_effort` only supports the single `"max"` level.

**Why must `reasoning_content` be passed back in multi-turn conversations?**
K3 is trained with preserved thinking; Moonshot requires the previous assistant message to be passed back complete and unmodified. Missing thinking history leads to unstable output quality.

**What are the limits on the `stop` parameter?**
At most 5 stop sequences, each no longer than 32 bytes; exceeding either limit returns a 400 error.

**Does the Messages API support structured output?**
❗ No. Kimi K3's official Messages (Anthropic-compatible) endpoint silently ignores structured-output fields (returning 200 with free-form text and no error). For structured output, use `response_format` on Chat Completions or `text.format` on Responses.

**Why do single K3 requests take so long?**
K3's thinking is fixed at the max level, and thinking tokens make up a large share on complex tasks (73% of completion tokens in the measured case). Set client timeouts to minutes or longer and use streaming.

***

For pricing and real-time status, see the [Kimi K3 model page](https://aihubmix.com/model/kimi-k3); for more models, visit the [model gallery](https://aihubmix.com/models).

Last updated: 2026-07-17
