DEV Community

Yong Yu
Yong Yu

Posted on Originally published at yongboyu.hashnode.dev

Kimi K3.1 Pro From K2.x Code: Fields That Now Error, the Default max Effort, and Cache-Write Math for Agent Loops

Attributed compile + one small offline run on my box

Primary source: Moonshot AI, Kimi K3.1 Pro quickstart (Kimi API Platform docs, released 2026-10-23/24), plus the Model Parameter Reference, Context Caching best practices, and K3.1 Pro pricing.

Community reports that shaped the angle: 甲维斯, Kimi K3.1 Pro已测,国模终于来一个能打的!? (掘金, 2026-10-24); Kimi K3.1 Pro 发布, 比 K3 快、性能逼近 Opus,但额度 10 分钟就烧光了 (V2EX, 2026-10-24); 硅星人Pro, 实测Kimi K3.1 (人人都是产品经理, 2026-10-26). Cost framing: Max Woolf, OpenAI and Anthropic cut their LLM prices by up to 80% within a few months. Why? (2026-10-25).

Capability claims are Moonshot's or the testers'. This box has no MOONSHOT_API_KEY, so I did not call kimi-k3.1-pro. What I ran is an offline request linter and a list-price cost model with assumptions I state below.


Moonshot shipped Kimi K3.1 Pro over the weekend: a post-trained K3 with a 1M-token context, a -highspeed variant, and open weights promised "by Nov 4". Chinese dev communities spent Saturday and Sunday on it. The posts I read agree on two things: it is a clear step up from K3 (games, Blender, front-end polish), and people are surprised by how fast their quota disappears. The V2EX thread title literally says the quota burns out in ten minutes.

Both observations come back to the request you send. K3.1 Pro has no thinking switch, its effort defaults to the most expensive setting, several sampling knobs are now hard errors, and caching changed to a separate write line. Meanwhile Moonshot's API pricing docs say K2 models close to new sign-ups on Oct 31 and are planned to retire by the end of December, so plenty of K2.x code is about to be pointed at K3.x with only the model string changed.

This post is the migration checklist I would want, plus cost math built from the published rates rather than vibes.

What changed between a K2.x request and K3.1 Pro

From the parameter reference, kimi-k3.1-pro and kimi-k3.1-pro-highspeed share kimi-k3's constraints:

field K2.6 K3.x / K3.1 Pro
thinking on/off switch (extra_body) not accepted; it always thinks
reasoning_effort not supported low / high / max, default max
temperature 1.0 thinking / 0.6 non-thinking fixed 1.0
top_p, n, penalties fixed fixed (0.95 / 1 / 0)
tool_choice: "required" error supported
context 256K 1M, flat price across the window

"Fixed" in Moonshot's docs means passing another value returns an error. So the classic K2.6 call with temperature=0.6 and thinking: disabled fails twice on K3.1 Pro. Two quieter rules matter more for cost:

  1. Return the whole assistant message, reasoning_content included, in multi-turn and tool loops. Preserved Thinking is always on, and the docs warn the model may lose reasoning context if you drop it. A content-only history is also a different prefix from the one the server just cached.
  2. Changing reasoning_effort mid-session invalidates prefix-cache hits. Pick the level before the conversation starts.

Why the default eats quota

You cannot turn thinking off; the FAQ suggests low if reasoning runs long. If your client never sends reasoning_effort, every call runs at max. Reasoning tokens bill as output at $10 / 1M (standard) or $20 / 1M (highspeed). In an agent loop that cost lands on every turn.

That fits what testers describe without needing any secret: 甲维斯 ran his comparisons at High, not the default, and a V2EX reply notes that the per-token price cut came with more tokens per task, so task cost didn't fall. Both of those are their observations. I can't measure them without a key.

Caching: writes are now a line item

K3.x bills input as three mutually exclusive parts: cache hits, cache writes, and uncached. Published K3.1 Pro list rates (USD / 1M):

input output cache hit write 5m write 1h
kimi-k3.1-pro 2.00 10.00 0.20 2.00 4.00
kimi-k3.1-pro-highspeed 4.00 20.00 0.20 4.00 8.00
kimi-k3 (for reference) 3.00 15.00 0.30 3.00 6.00

The mechanics from the caching guide:

  • The cache matches prefixes, stored in blocks; a partial block is billed as a miss.
  • Default TTL is 5m; pass prompt_cache_options: {"mode": "implicit", "ttl": "1h"} for longer gaps. A hit renews the entry for free.
  • TTL is locked at first write. You can't upgrade a live entry to 1h.
  • Chat Completions reports usage.prompt_tokens_details.cached_tokens and ...cache_write_tokens; with streaming you need stream_options.include_usage=true to get them.

Note the highspeed row: cache hits cost the same $0.20, so a cache-heavy agent on highspeed costs well under twice as much. Don't estimate it by doubling.

The run: a linter and a toy agent bill

runs/26-kimi-k3-1-pro/preflight.py has no network calls. It does two things.

1. Lint request bodies against the documented rules. Output from my run (trimmed):

- k2.6 code with model swapped only
    ERROR thinking is K2.x-only; remove it (K3.x always thinks)
    ERROR temperature=0.6 is fixed at 1.0; omit it
    WARN top_p=0.95 is fixed at 0.95; omit it
    WARN reasoning_effort omitted -> server default 'max' (most tokens)
- multi-turn, content-only history
    WARN messages[1] assistant without reasoning_content: send the complete assistant message back
- vision with public URL
    ERROR messages[0] public image URL; use base64 data: or ms://
- effort switch high -> low on turn 2
    WARN effort changed high->low mid-session: prefix cache invalidated
Enter fullscreen mode Exit fullscreen mode

The ERROR lines are my reading of the docs, not server responses. I haven't seen the real error payloads.

2. Price a toy agent session from usage-shaped numbers. My assumptions, not measurements: 40 turns, 20k-token stable prefix (system + tools + repo notes), +3k tokens of tool output per turn, 2k output tokens per turn (reasoning included), and every turn resends the full history.

kimi-k3.1-pro            5m TTL, no idle gaps            $1.99  (hit 4.56M, write 0.14M, out 0.08M)
kimi-k3.1-pro            5m TTL, 3 human pauses >5 min   $2.62
kimi-k3.1-pro            1h TTL, same 3 pauses (<1h)     $2.26
kimi-k3.1-pro            1h TTL, no idle gaps            $2.26
kimi-k3.1-pro-highspeed  5m TTL, no idle gaps            $3.06
kimi-k3                  5m TTL, no idle gaps            $2.98
output sensitivity (k3.1-pro): 1k/turn $1.43 · 2k $1.99 · 4k $3.10 · 8k $5.32
Enter fullscreen mode Exit fullscreen mode

What I take from it:

  • Cache reads dominate tokens, not necessarily dollars. Hits are 97% of input tokens here but only $0.91 of the $1.99; writes are $0.27. Output is under 2% of all tokens and costs $0.80. Woolf's point that cache-read price drives agent cost holds for token share; at a 50:1 output-to-hit price ratio, output still decides a big slice of the bill. That's why the default effort matters.
  • Output per turn is the steepest knob. Going from 2k to 8k output tokens per turn multiplies this session cost by ~2.7×. That is the range where an effort level would act. I have not measured how many tokens low/high/max actually produce.
  • Human pauses re-write the cache. With three >5-minute gaps, 5m costs $2.62 vs 1h at $2.26. With no gaps, 1h stays at $2.26 while 5m is $1.99, because every write is billed at double. Choose by how your users actually behave.
  • Highspeed is ~1.5× here, not 2×, because hits are priced the same.

Migration steps I'd actually do

  1. Delete thinking, temperature, top_p, n, and penalty fields from K3.x code paths (keep them for any K2.6 path until December).
  2. Set reasoning_effort explicitly. Start at high for agents, A/B against max on your own tasks, and keep it constant for the session.
  3. Append the full assistant message object, not message.content.
  4. Move timestamps, request IDs, and anything per-turn out of the system prompt and to the end of the message list.
  5. Log cached_tokens and cache_write_tokens per call; turn on include_usage when streaming. The bill is now three numbers, not one.
  6. Use 1h TTL only where humans pause; otherwise the default is cheaper.

What I did not test

No live calls: no latency, no quality, no real token counts per effort level, no error payloads, no verification that the block size or TTL behavior matches the docs, no Anthropic-compatible /anthropic/v1/messages endpoint, no Kimi Code or membership quota behavior (the V2EX complaints are about plans, not API billing). The official quickstart I fetched still had placeholder benchmark figures in its overview, so I'm not quoting benchmark numbers. Third-party rankings and the testers' results belong to them. When the weights land, the same linter rules may not apply to self-hosted servers.


Written by YongBo Yu, AI engineer in Toronto. More at yongbo-yu.vercel.app and GitHub.

Top comments (0)