DeepSeek’s prompt cache gives a 50× discount on cached tokens. The cache matches on the prefix of the request — everything before the first differing byte. If the prefix changes between turns, the cache misses and costs spike.
The cache-stable prefix consists of:
DynamicContextBoundary.Both are serialized deterministically (MarshalCacheStable sorts tools
by name and canonicalizes JSON-Schema keys). Any change to either
component invalidates the cache.
ComputeFingerprint (in internal/llm/prefix_drift.go) hashes:
SystemSHA256 = SHA-256 of the static system promptToolsSHA256 = SHA-256 of canonical serialized tool specs (sorted by name, with canonicalized JSON-Schema)CombinedSHA256 = SHA-256 of SystemSHA256:ToolsSHA256Tool specs are fully serialized (name, description, parameters) and canonicalized before hashing:
This means tool description changes and schema changes (but not key order differences) will trigger drift detection.
PrefixMonitor runs inside runStep, after the request is assembled
but before Stream is called:
EventInfo with which component
changed (sys, tools, or sys+tools). The TUI status line shows
a ⚠ cache:<which> badge.The monitor is lightweight — three SHA-256 hashes per turn.
| Source | Component | Example |
|---|---|---|
| Hook/skill injection at session start | sys | First turn pins after injection; expected |
| MCP server reconnect | tools | Tool set changes mid-session |
| Hot-reload of hooks/skills | sys | System prompt rebuilt with new content |
dsc init rewrites config |
tools | New MCP servers added |
⚠ cache:sys: Check if hooks or skills modified
the system prompt after the first turn. Usually caused by a
SessionStart hook that runs on every Run call rather than once.⚠ cache:tools: An MCP server reconnected or a
tool was added/removed mid-session. This is expected after MCP
reconnects.PromptBuilder.Build() and hook output for
non-deterministic content (timestamps, random IDs).After a run, use dsc trace inspect <trace.jsonl> to verify prefix
stability and cache savings. The report includes a cache evidence line:
cache 99.6% | hit 48700000 | miss 190000 | saved CNY 47.73 | prefixes 1 | expected_miss 1
static_prefix_hash values seen. A stable run
has exactly 1; drift produces 2+.llm.CacheSavings.