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

Jul 29, 2026 · AIHubMix · 8 min read · Tutorial

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

This article covers the new parameters and usage notes for Kimi K3. On AIHubMix, K3 is available through the Chat Completions, Responses, and Claude-compatible Messages APIs. See also: Moonshot official platform 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.
# 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.
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.

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)
# 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.
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.

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"

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.

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

3. Sampling Parameters Are Fixed

K3's sampling parameters are fixed by the model provider: 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).
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.

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?"},
]
# 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.
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.

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\"}"}

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.

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

5. Structured Output

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

response_format supports json_schema with strict mode.

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.
Responses

Structured output is declared via text.format.

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"}

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.

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.
Chat Completions

# 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.
Responses
# usage of the second Responses call with identical long instructions
"input_tokens_details": {"cached_tokens": 1536}

Messages

# usage of the second Messages call with an identical long system prompt
"cache_read_input_tokens": 1536

7. partial Prefix Completion

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

Pass "partial": true in the last assistant message.

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.
Responses

Pass the prefix as an assistant message at the end of the input array; no partial parameter is needed.

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."

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.

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 ..."

8. Vision Input

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

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.
Responses
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"

Messages

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"

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; for more models, visit the model gallery.

Last updated: 2026-07-17

More from the blog