CommandCodeAI / CommandCodeAI/command-code

[BUG] Stock harness re-bills ~15k fresh inputTokens on every call — base prefix never caches (deepseek-v4-flash)

未关闭
#803 2 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

@ahmadbilaldev 已经在做这个了。

开始于 2026年9月7日。

主要语言
没有语言数据
星标
4k
派生
350
PR 合并指标
30 天内没有已合并 PR

描述

Summary

Stock harness (zero mods, --no-skills, no MCP) re-bills ~15–19k fresh inputTokens on every model call in the same session. A trivial same-session follow-up (hihi again) bills 15207 fresh + 15104 cache — the ~15k base never enters cache while history deltas do. Same task via OpenCode harness on the same model through the same gateway bills deltas (~100–500 fresh on warm steps). Measured cost gap ~16x.

Related but distinct from #762 (that is mod-authored appendSystemPrompt churn; this repro has no mods), #626, #702.

Repro

mkdir -p /tmp/cc-cache/src && cd /tmp/cc-cache
echo 'export function add(a:number,b:number){return a+b}' > src/a.ts
# call 1
commandcode -p -t --yolo --model deepseek/deepseek-v4-flash --no-skills --output-format json "List files in src/ only, no edits." | grep model_request_end
# call 2, same session (use sessionId from call 1 result)
commandcode -p -t --yolo --model deepseek/deepseek-v4-flash --no-skills --session <SES> --output-format json "hi again, reply with one word" | grep model_request_end

Minimal proof (empty history, no tools, greeting only):

call inputTokens (fresh) cacheReadTokens outputTokens
hi (new session) 15185 7296 45
hi again (same session) 15207 15104 10

Fresh is flat; cache grows by roughly the previous call's content. The ~15k base is re-billed fresh every call and never cached.

Full task (read 3 tiny .ts files → write REPORT.md → JSDoc edit + grep, 2 user turns), 3 trials, deepseek/deepseek-v4-flash:

trial CC fresh in CC cacheR CC out CC billed (costUsd sum)
1 171883 151680 1484 $0.0399
2 171737 151680 1035 $0.0395
3 133066 112768 1039 $0.0307

Same task via opencode2 run -m commandcode/deepseek/deepseek-v4-flash (same gateway, same model): fresh ~6.7k + cache ~38k total for both turns, est ~$0.0023 at list rates. Per warm step OC bills ~100–500 fresh vs CC ~18–19k.

Billing check: costUsd matches list rates under disjoint accounting exactly, e.g. 18325*0.22 + 7936*0.007 + 80*0.66 = $0.004139852 — so the gap is billed, not a reporting artifact.

Ablations (first-call fresh inputTokens, same prompt)

flags fresh in cacheR
--tools-all (full) 18287 9344
baseline -p default tools 15253 512
--no-skills 16717 7424
default tools + --no-skills 13569 5888
minimal --tools-enable read_file,glob,grep + --no-skills 13564 5888

Floor with everything removable stripped is still ~13.5k vs OpenCode's ~5.4k cold. Remaining ~8k is base system + base tool schemas.

Suspected cause

Something in the built-in per-request prefix (~15k) changes every call so DeepSeek automatic prefix caching never matches it, while accumulated history (stable) does cache — hence flat fresh + growing cache. Candidates in dist/cli.mjs: systemPrompt({sessionId, state, permissionMode}) is state-dependent; every message carries fresh meta.createdAt: Date.now() + new UUIDs (queuedToMessages, buildUserMessage); run_end.nextState ships modState.workspace (cwd/platform/branch/gitStatus/recentCommits) + compaction basis (~15k, matches compaction.tokens: 15254 seen on the bare-hi call). Any of these re-serialized into the request prefix breaks it. The 0.33.0 "relocate volatile dynamic context block" fix improved history caching but the base block itself still looks volatile.

Environment

  • commandcode@1.49.1, linux x64, deepseek/deepseek-v4-flash, --effort max (default from config)
  • Zero mods (mods list empty), no MCP servers, taste file 86 bytes
  • OpenCode2 v0.0.0-beta-19135 control via api.commandcode.ai/provider/v1, same model, same fixture

Impact

Same work costs ~16x more ($0.037 vs $0.0023) and each call re-pays the full base prefix, so long sessions scale as O(calls × base) instead of O(base + deltas). A dev-mode diagnostic that warns when the built-in system-prefix bytes change between turns (as proposed in #762 for mods, but applied to the stock prefix) would have caught this.

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。