【Claude Code-System Prompt实测】归属指纹块剥离与前缀稳定化:从 prompt 字符串到 cacheable prefix

非线智能API经验 [Claude Code-System Prompt实测] 第13篇

摘要

前缀稳定化是 Claude Code 跨模型缓存命中的工程核心。Claude Code 的请求前缀里既有稳定内容,也有动态内容:内置 system prompt、工具定义、MCP 描述、项目上下文相对稳定;attribution fingerprint、trace id、session id、时间戳、临时路径和最新工具结果高度动态。兼容层的任务是把两者分开,让稳定内容形成可缓存前缀,让动态内容留在 metadata 或 live window。

本文聚焦前缀稳定化落地:默认识别并剥离 x-anthropic-billing-header attribution block,或将其归一化为固定内容;支持客户端通过 CLAUDE_CODE_ATTRIBUTION_HEADER=0 上游禁用;检测 system prompt 早段的时间戳、UUID、随机 ID、动态路径;固定工具列表和 MCP 描述排序;输出前缀稳定性评分。

数据来源:非线智能Nonlinear 官网

PrefixStabilizer 的输入与输出

输入不应是一个字符串,而应是已经拆分过的 IR:

type PromptPrefixIR = {
  system: PromptBlock[];
  tools: ToolSpecIR[];
  mcp: McpDescriptorIR[];
  projectContext: PromptBlock[];
  taskState: PromptBlock[];
  liveWindow: PromptBlock[];
  metadata: Record<string, unknown>;
};

输出是稳定化后的前缀和风险报告:

type StabilizedPrefix = {
  cacheableSegments: CacheSegment[];
  dynamicSegments: CacheSegment[];
  strippedMetadata: Record<string, unknown>;
  stablePrefixHash: string; // internal cache key material
  stablePrefixHmac: string; // telemetry-safe identifier
  stabilityScore: number;
  findings: PrefixFinding[];
};

attribution block 的三种策略

策略 行为 推荐场景
strip 从 prompt 中删除,不进入模型上下文 第三方 gateway / local model 默认
normalize 替换为固定占位,例如 claude_code_attribution_present 需要保留来源信号
preserve_as_metadata 移出 prompt,进入 metadata / 审计事件 需要成本归因

直连 Anthropic API 会在处理前剥离 attribution block,因此问题主要发生在第三方 ANTHROPIC_BASE_URL、LLM gateway、本地模型,或按完整 body / prefix 做 cache key 的实现中。strip 不应丢失计费和审计信息,默认应配合 preserve_as_metadata 写入结构化 metadata。

CLAUDE_CODE_ATTRIBUTION_HEADER=0 是 Claude Code 客户端侧配置。gateway 如果只是接收请求,不能真正控制客户端是否生成该 block;它只能做服务端 strip / normalize / preserve_as_metadata。因此推荐双层防御:客户端可用环境变量上游禁用,gateway 仍在入口层做 sanitizer,处理旧客户端或代理链路残留。

动态块检测

默认检测范围应聚焦在已解析的 system prompt 早段、metadata、known attribution block 和 known session fields,不要全文粗暴正则,否则容易误删用户 prompt、代码片段、schema enum 或文件 hash。

动态来源 示例 处理
attribution header x-anthropic-billing-header strip / metadata
UUID 550e8400-e29b-41d4-a716-446655440000 移出 stable prefix
时间戳 2026-06-12T09:30:00Z 移出或归一化
session id session_abc123 metadata
临时路径 /var/folders/.../tmp/... 相对路径或占位
随机 hash 短 hex / base64 id 只标记风险,不自动删除

canonicalization:让语义相同的工具得到相同 hash

工具和 MCP 描述最常见的抖动不是内容变化,而是顺序变化。稳定化层应做 canonicalization:

1、工具按 source_type + namespace + name + version + schema_hmac 排序。
2、MCP server 优先按稳定 server id 排序;没有稳定 id 时按 server name,再用 descriptor HMAC 做 fallback。
3、同一 server 下工具按 tool name 排序;同名工具用 schema HMAC 做 tie-breaker。
4、JSON Schema 使用 canonical JSON:字段排序、去掉无意义空字段、稳定序列化。
5、description 不做语义改写,只做换行和 whitespace 规范化。

type CanonicalToolSpec = {
  key: string;
  name: string;
  description: string;
  schemaCanonicalJson: string;
  schemaHash: string;
  schemaHmac: string;
};

cache segment 规划

稳定化层应输出 cache segment,而不是只输出一个总 hash:

type CacheSegment = {
  id: string;
  type: "system" | "tools" | "mcp" | "project_context" | "task_state" | "live_window";
  stability: "static" | "semi_static" | "dynamic";
  hash: string;
  hmac: string;
  tokenEstimate: number;
  cacheable: boolean;
};

内部 cache key 可以使用 hash;生产遥测和日志应输出带环境 salt 的 HMAC,避免固定 prompt、工具名或公开 schema 被离线字典反推。

推荐分层:

Segment 是否 cacheable 失效条件
system.base Claude Code / adapter 版本变化
tools.core schema hash 变化
mcp.enabled server/tool/schema 变化
project.context 半稳定 CLAUDE.md / 项目规则 hash 变化
task.state 半稳定 用户目标或摘要变化
live.window 每轮变化
metadata.dynamic 不进入 prompt cache

稳定性评分

score = 100
  - 40 * cacheable_churn_ratio
  - 20 * dynamic_prefix_ratio
  - 15 * ordering_instability
  - 15 * role_rewrite_risk
  - 10 * cache_boundary_risk

解释:

cacheable_churn_ratio:可缓存 segment 中变化的 token 占比。
dynamic_prefix_ratio:第一个 cache boundary 之前的动态 token 占比。
ordering_instability:canonicalization 前后工具 / MCP 顺序变化比例。
role_rewrite_risk:system role 是否需要跨协议修正。
cache_boundary_risk:cache breakpoint 是否被放在动态块之后。

评分用于告警和趋势,不用于决定是否发送请求。低分应触发诊断报告。

失败模式

失败模式 触发原因 修复策略
误删用户代码或 hash 对全文做动态正则替换 只处理已解析 system 早段、metadata 和 known fields
审计归因丢失 strip 后不保存 metadata 默认配合 preserve_as_metadata
telemetry 泄露工具名 日志输出裸 hash 或内部 tool name 生产日志只输出 HMAC,名称走 allowlist
工具排序仍抖动 同名工具缺少 tie-breaker 使用 schema HMAC 做稳定排序
gateway 误以为能控制客户端 把 env var 当服务端能力 区分客户端 env var 和 gateway sanitizer

验证清单

测试 输入 期望
attribution 变化 两个不同 fingerprint strip 后 hash 相同
工具顺序变化 同一工具数组乱序 canonical hash 相同
工具 schema 变化 新增参数 tool hash 不同
MCP 顺序变化 server 返回顺序不同 mcp hash 相同
动态路径 tmp path 变化 stable hash 不变
cache boundary 错位 动态块在 breakpoint 前 stability score 降低

参考链接

Claude Code Environment Variables
Claude Code LLM Gateway
Anthropic Prompt Caching
Anthropic Mid-conversation system messages
anthropics/claude-code #50085
musistudio/claude-code-router #1220
Prompt Cache: Modular Attention Reuse

本文由非线智能API Claude Code 行业专家整理编写