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.
July 2026 Kimi K3 guide: reasoning_effort max, thinking history, dynamic tool loading, structured output, auto caching, partial prefix, and vision inputs.

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: bothstoplimits are validated, and exceeding either returns 400; the Messages API applies the same validation tostop_sequences.
❗ When a stop sequence is hit, the Messages API does not follow Anthropic semantics: in testing,stop_reasonis"end_turn"(rather than"stop_sequence"),stop_sequenceisnull, 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.
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.
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"
```
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
```
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).
`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.
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\"}"}
```
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
```
5. Structured Output
Structured output makes the model return content that strictly conforms to a given JSON Schema.
`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.
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"}
```
❗ **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.
```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`.
```text theme={null} # usage of the second Responses call with identical long instructions "input_tokens_details": {"cached_tokens": 1536} ``` ```text theme={null} # 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.
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.
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."
```
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 ..."
```
8. Vision Input
Images are passed as base64; the content-block format varies by API.
```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,"}}, ], } ]
# Observed response content: "Red" (input: a 64x64 solid red PNG)
```
> **Verified**: base64 image input works, and the model correctly describes the test image.
```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,"}, ], } ]
# Observed output text: "Red"
```
```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": ""}}, ], } ]
# 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