【Claude Code-System Prompt实测】归属指纹块与兼容端保留关键字错误:当 metadata 被误送进 prompt

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

摘要

Claude Code attribution block 不只会影响第三方 gateway 的 prompt cache,还可能触发 provider 的协议校验错误。anthropics/claude-code #24168 的 issue reporter 在 Claude Code v2.1.37 + Bedrock 场景中观察到:x-anthropic-billing-header 被作为 system prompt text block 发送后,触发 400 x-anthropic-billing-header is a reserved keyword

这个问题的本质是 metadata 和 model-visible prompt 的边界被打穿了。归属、计费、trace、fingerprint、租户标识这类信息应该属于传输层或网关审计层;一旦被塞进 system prompt,它就会同时进入模型上下文、provider 关键字校验、缓存 key、日志链路和安全策略。

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

证据层级

官方文档可以支撑两点:Claude Code 存在 attribution block / gateway 处理建议;Bedrock Anthropic Messages API 有自己的请求结构和 role 约束。x-anthropic-billing-header is a reserved keyword 这个具体报错来自 GitHub issue,是工程案例,不是 AWS 官方规格。本文把它作为 provider profile 的拒绝用例,而不是通用协议事实。

为什么 reserved keyword 会出现在 prompt 里

正常情况下,计费归属信息应该放在:

• HTTP header。
• gateway metadata。
• request side channel。
• 审计事件。

问题发生在兼容链路中:为了把 Claude Code 的 attribution 信息带到下游,某些实现把它作为 text block 放进 system prompt。这样会产生两个后果:

1、provider 把它当成模型可见内容,而不是传输 metadata。
2、如果字段名命中 provider 保留关键字,就会在请求入站校验阶段被拒绝。

AWS Bedrock Anthropic Claude Messages API 要求 system prompt 使用 system 字段,messages 承载 user / assistant 对话。x-anthropic-billing-header is a reserved keyword 是 #24168 中的 Bedrock 报错案例,兼容层应把它作为 provider profile 的拒绝用例:这类名字不应作为 prompt text 进入 Bedrock 请求。

兼容层应建立 metadata 防火墙

推荐在 gateway 入口建立 MetadataFirewall

type MetadataFirewallPolicy = {
  reservedKeywords: string[];
  modelVisibleAllowlist: string[];
  headerAllowlist: string[];
  stripFromPrompt: RegExp[];
  preserveAsMetadata: boolean;
};

它做三件事:

1、从 system prompt / content block 中识别 attribution、billing、fingerprint、trace 类文本。
2、从 model-visible prompt 中剥离这些内容。
3、按 provider profile 决定是否转成 header、metadata 或审计事件。

优先修复路径仍然是上游配置:Claude Code docs 提供 CLAUDE_CODE_ATTRIBUTION_HEADER=0,可省略 attribution block。网关侧 sanitizer 是防御层,用来处理旧客户端、代理链路残留或第三方兼容实现;它不应替代官方开关。Anthropic first-party API 会在处理前剥离 attribution block,因此 first-party prompt caching 不受影响。

示例:

system text block:
  x-anthropic-billing-header: cc_version=...; cch=...

after firewall:
  prompt blocks: []
  metadata: {
    client_family: "claude_code",
    attribution_present: true,
    attribution_hash: "hmac:..."
  }

provider profile 要包含保留关键字

不同 provider 的限制不同。兼容层不应只维护一个全局正则,而应把限制放进 provider profile:

type ProviderProfile = {
  name: "anthropic" | "bedrock" | "vllm" | "openai-compatible" | "local";
  reservedPromptPrefixes: string[];
  reservedHeaders: string[];
  supportsCustomHeaders: boolean;
  stripsClaudeCodeAttribution: boolean;
};

对 Anthropic first-party profile,可依据官方 LLM gateway 文档标记 stripsClaudeCodeAttribution: true。Bedrock / 第三方 gateway profile 默认应为 false,除非实测证明会剥离。Bedrock profile 还应把 x-anthropic-billing-header 作为 prompt 中不允许出现的拒绝用例。

前缀稳定化中的 strip / normalize 策略见第 13 篇 归属指纹块剥离与前缀稳定化;日志侧如何只保留 HMAC 和结构化 metadata,见第 14 篇 请求前缀可观测性

不要用 prompt 文本模拟 header

有些兼容层为了图省事,会把上游 header 拼进 system prompt:

You are Claude Code.
x-trace-id: ...
x-anthropic-billing-header: ...

这会造成五类副作用:

副作用 原因
provider 400 prompt 中出现保留关键字
cache miss trace / fingerprint 每轮变化
prompt 泄露 header 被模型看到并可能输出
安全边界混乱 模型可见内容影响审计/计费
指令污染 header-like 文本被模型当作指令上下文

正确方式是把 header、metadata、prompt 三层分开。

sanitizer 的位置

sanitizer 应该在 provider adapter 之前执行:

raw request
  -> parse prompt blocks
  -> metadata firewall
  -> provider reserved keyword check
  -> prefix cache planner
  -> provider renderer

如果 sanitizer 放在 renderer 之后,它只能处理序列化后的字符串,容易误删正常内容;如果放在 cache planner 之后,动态 metadata 已经污染了 cache key。

失败模式

失败模式 触发原因 修复策略
Bedrock 返回 reserved keyword 400 x-anthropic-billing-header 进入 prompt text prompt sanitizer 剥离并转 metadata
自定义 gateway 缓存异常 billing / trace 文本参与 body hash metadata 不进入 cacheable prefix
归因信息丢失 sanitizer 直接删除 保存 HMAC hash 和结构化 metadata
误删用户提到的 header 名 全文无上下文正则 只处理系统前缀早段和 header-like block
provider 差异无法表达 所有后端共用 sanitizer provider profile 分层

验证清单

• 构造包含 x-anthropic-billing-header 的 system text block,Bedrock profile 下应在发送前剥离。
• 构造普通用户消息提到同名字符串,不应被错误删除。
• 构造 attribution block,确认 prompt 中删除、metadata 中保留 HMAC。
• 构造 provider reserved keyword 列表,确认命中时 fail closed 或 sanitize。
• 构造 cache key,确认 sanitizer 发生在 cache key 计算之前。
• 构造审计日志,确认不会落盘完整 attribution 原文。

参考链接

anthropics/claude-code #24168
Claude Code Environment Variables
Claude Code LLM Gateway
AWS Bedrock Anthropic Claude Messages API
LiteLLM Claude Code Tracking
Portkey Claude Code

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