Repository navigation
Replies: 2 comments
|
Update from OP, verified on 0.1.2-alpha.4 ( Re-verification on 0.1.2-alpha.4
New finding: the z.ai OpenAI-compatible endpoint already honors Anthropic-style
|
| before (implicit cache only) | after (cacheControlFormat: anthropic) |
|
|---|---|---|
zai coding-plan route (api.z.ai), turn-level hit rate |
70.5% (9 steps) | 86.9% (14 steps) |
open.bigmodel.cn route, turn-level hit rate |
75-88% typical | 90.8% (15 steps) |
| "prefix unchanged but full miss" crashes | one step at 3.4% (~76K cached tokens lost, 93K recomputed) 22 s after a sibling session's ~104K cold start on the same key; two requests 17 s apart both 0%; total loss across 74 s / 3 min idle gaps | zero crashes in 29 steps |
| recovery right after a 0% cold-start step | could stay near 0% for consecutive steps | 97.4% within 7 s |
| steady-state tool-loop steps | 95-99.9% (already fine) | 93.2-99.1% (unchanged, as expected) |
Notes on methodology: client-side prefix hygiene was verified byte-identical throughout (system prompt 18334 chars, diff = 0 across every request; runtime-context snapshots are append-only), so the "before" crashes were purely server-side eviction in a node-local implicit cache -- exactly what explicit breakpoints eliminate. The A/B sessions are different real-workload sessions (not synthetic replays), but with comparable multi-step tool-loop patterns. Since cached tokens still count against Coding Plan usage, this is roughly a 2x effective-quota difference on heavy multi-tool workloads.
Upgraded proposal
Given that both z.ai endpoints (international api.z.ai and CN open.bigmodel.cn) demonstrably accept Anthropic-style cache_control, and OpenCode already ships exactly this at scale:
- Default
cacheControlFormat: anthropicfor the built-inzai/zai-coding-cnproviders, so every GLM user gets explicit cache anchoring out of the box. Worst case is an endpoint ignoring a well-formed optional field; measured upside is +16-20 pts turn-level hit rate and the elimination of eviction-driven full misses. - The original ask stands unchanged: expose
sendSessionAffinityHeaders/sessionAffinityFormatasofferinstead ofwithhold-- still a useful complementary layer (notably for routes/endpoints that lackcache_controlsupport), just no longer the only lever.
Happy to share the analysis scripts (zstd session-log frame decoder + per-step usage extractor) if anyone wants to reproduce the numbers.
|
I feel like I used to get forever use out of my ZCode sub but using it within Hermes or grok build is noticably more token heavy |
Uh oh!
There was an error while loading. Please reload this page.
Summary
When DSH talks to
glm-5.3-flashthrough the built-inzaiprovider (OpenAI-compatible endpointhttps://api.z.ai/api/coding/paas/v4), prompt-cache hit rates are poor even though DSH itself constructs a perfectly stable request prefix. Measured on a real working session (DSH 0.1.2-alpha.2): 70.5% hit over the first user turn, 3.4% on a single step, and 0% on two consecutive requests 17 seconds apart.The GLM Coding Plan bills cached tokens as normal session usage, so a collapsed cache directly burns roughly 2-3x more quota than necessary. The same workflows on clients that anchor caching (ZCode, OpenCode) drain noticeably less.
What I measured (session-log forensics)
I decoded the session JSONL (multi-frame zstd) and diffed every recorded request header plus per-step usage events:
request/headerevents.z.ai's implicit context cache is shared per API key, so any concurrent activity - subagents, AgentTeams members, plugin background forks (e.g. a periodic "idle checkpoint" review that replays an ~87k-token seed) - evicts everyone else's entries. With 3-4 active chains the cache pool is a tug of war.
Why it happens (source-level)
pi-ai already implements everything needed, but for the
zaicompat profile it is all switched off - and DSH's compat gate makes it unconfigurable:detectCompat()for zai setscacheControlFormat: undefinedandsendSessionAffinityHeaders: false(@earendil-works/pi-aiopenai-completions.js);COMPLETIONS_COMPAT_GATEmarkssendSessionAffinityHeaders/sessionAffinityFormataswithhold, so they cannot be enabled fromsettings.yaml;prompt_cache_keyis only sent toapi.openai.com(or with long retention).So every request is an unanchored, best-effort implicit-prefix-cache request: no session affinity to pin routing, no cache breakpoints, no cache key. Upstream pi issue #6083 (already fixed in DSH: send
thinking.clear_thinking: false) proved this endpoint's caching is unusually sensitive; affinity anchoring is the remaining half of the fix. ZCode and OpenCode show what anchored caching is worth on this plan.Proposal
sendSessionAffinityHeadersandsessionAffinityFormatfromwithholdtoofferin the dsh-llm-pi-ai compat gate, so asettings.yamlprovider profile can enable pi-ai's existing affinity implementation (session_id+x-client-request-id+x-session-affinityheaders, plusprompt_cache_key) forzai/zai-coding-cnroutes. Static per-providerheadersconfig cannot substitute: the affinity value must be the per-session id, which only the host can inject.zairoutes - worst case the endpoint ignores unknown headers, so the blast radius is zero.cacheControlFormat: anthropicfor routes whose endpoint accepts Anthropic-style cache breakpoints (e.g. z.ai's/api/anthropic).Happy to share the session-log decoding/analysis scripts if useful.
All reactions