On authorship: this question was written by the AI assistant that does most of the
development work on my addon, on my behalf and posted under my name. Flagging it
because you should know when you’re reading machine-written text.
Hi,
I maintain FreeCAD AI, an open-source CAD
assistant addon. It talks to Kimi over the OpenAI-compatible /v1/chat/completions
endpoint, kimi-k2.6, multi-turn with tool calls in most turns.
I just finished fixing a prefix-cache bug on our side: we were re-rendering history
without the reasoning_content we had actually sent, so the prefix diverged at the
first assistant message of every turn. That is the same failure yuikns described in
“Cached tokens drop when tool has interleaved thinking”
— thanks for that thread, it saved me a lot of guessing. We now store and replay
reasoning_content verbatim.
What I can’t work out from the docs is how that squares with thinking.keep.
1. On kimi-k2.6 with thinking.keep unset (the null default), is historical
reasoning_content dropped before longest-prefix matching, or after?
The field reference says the default means “The server ignores reasoning_content
from historical turns”. If “ignores” means the server strips it while re-assembling
the context, then a client that faithfully replays every reasoning block still gets a
prefix divergence at each turn boundary — because the bytes the server matches against
are not the bytes the client sent — and keep: "all" would be the only way to keep the
cache running past turn N. If “ignores” only means the model doesn’t attend to it, then
replaying it is enough and keep is irrelevant to caching. Which is it?
(For completeness: we currently send no thinking object at all, so we’re on the
default.)
2. If the answer is “set keep: \"all\"”, what happens to histories that predate
the change? A saved conversation can contain an assistant message with tool_calls
and no reasoning_content, because the client never stored it. Is that a hard error
under keep: "all", and if so, is there a supported way to migrate — drop the whole
turn, drop the tool_calls, send an empty string?
3. prompt_cache_key: the docs recommend a per-session id for multi-turn agents.
Should it stay fixed across a context compaction — where the client summarises old
turns and the prefix genuinely changes — or should compaction start a new key?
4. Block granularity. Measuring one of my own sessions (28 request pairs), the
reported cached_tokens fit floor(previous_request_prompt_tokens / 2048) * 2048 in
24 of them, and every miss was a turn boundary of the kind above. Only two distinct
values ever appeared, 12288 and 14336. Is ~2048 tokens the block granularity, i.e. is
there a size below which stabilising a prefix simply cannot show up in the bill? I ask
because I’d like to tell my users honestly when this optimisation is worth anything —
my own test sessions peaked around 15k prompt tokens and showed no measurable saving.
Happy to post before/after numbers from a longer session if that’s useful to anyone.
Thanks,
Alfred