待验证传言:
- Claude Code 对非 Claude 模型会“恶意改 prompt”导致 cache 命中率降低。
- 具体猜测:若
model_name != claude,则在 system prompt 上做细微空白字符扰动(每次响应都变),从而触发重算。
本次目标:基于最新 npm 正式包做静态取证,判断该逻辑是否存在。
- 日期:2026-02-13
- 包:
@anthropic-ai/claude-code@2.1.41 - 下载文件:
anthropic-ai-claude-code-2.1.41.tgz - 主代码:
unpack/package/cli.js
npm view @anthropic-ai/claude-code version dist-tags --json
npm pack @anthropic-ai/claude-code@2.1.41
mkdir -p unpack && tar -xzf anthropic-ai-claude-code-2.1.41.tgz -C unpackcli.js 高压缩,prettier OOM。改用 esbuild 成功展开:
npx --yes esbuild@0.25.0 unpack/package/cli.js --format=esm --target=es2022 --outfile=unpack/package/cli.esbuild.js结果:unpack/package/cli.esbuild.js(wc -l 为 284551 行)。
- prompt/cache 相关函数:
Pc1,S2z,h2z,_Jq,xR7,bR7 - model 条件分支是否影响 system prompt 文本
- whitespace/zero-width 字符注入或替换
- “prompt cache break”原因来源
unpack/package/cli.esbuild.js:114795 附近:
- 比较 system hash / tools hash / model / fastMode
- 任一变化会标记
pendingChanges - 后续在
bR7打点[PROMPT CACHE BREAK] ...
对应事件上报位于:unpack/package/cli.esbuild.js:114842
这解释了 cache miss 的常规来源,但未显示“按非 claude 模型主动篡改文本”。
unpack/package/cli.esbuild.js:251103
Pc1({ scope, querySource }) 返回结构是:
type: "ephemeral"- 可选
ttl: "1h" - 可选
scope: "global"
不含任何 prompt 文本改写。
unpack/package/cli.esbuild.js:251220 起:
q = [gK6(...), FK6(...), ...systemParts]组装 system 段T = h2z(q, ...)为 system 段添加 cache_controlmessages: S2z(...)为最近消息添加 cache_control
h2z/S2z 行为是“附加 cache_control 元数据”,不是字符串替换。见:
unpack/package/cli.esbuild.js:251442unpack/package/cli.esbuild.js:251447
FK6:unpack/package/cli.esbuild.js:72077gK6:unpack/package/cli.esbuild.js:72089
这两处输出固定说明文本/头信息,未发现“model 非 claude 时替换空格”逻辑。
检索到 whitespace 相关代码主要是:
- 统计模型返回全空白内容:
tengu_model_whitespace_response - 过滤“全空白 assistant 消息”
位置:
unpack/package/cli.esbuild.js:256173unpack/package/cli.esbuild.js:256902
这属于响应清洗,不是 system prompt 扰动。
在 @anthropic-ai/claude-code@2.1.41 的静态代码中:
- 没有找到“如果模型名不是 claude 就每次修改 system prompt 空白字符”的实现。
- 已确认的 cache miss 触发原因是常规检测:模型、system prompt、tools、fast mode 变化。
- 因此,基于当前样本,无法证明该“恶意改 prompt”传言为真。
本次是静态取证,仍有两个边界:
- 若外部“路由层/代理层”二次改写(例如第三方 router 包),该行为不在本包静态代码里。
- 若运行期远端服务按请求头策略返回不同系统段,这需要动态抓包与对照实验验证。
建议下一步(如需更强证据):
- 用同一输入、同一模型、固定环境变量,比较连续两次请求 payload(本地 hook/代理抓取)
- 对比
@musistudio/claude-code-router等路由器包,确认是否其实现导致 cache miss