场景说明:Claude Sonnet 4.6 + extended thinking + 工具调用,多轮对话场景下用 3 个 cachePoint 累积命中 5 轮,与不开 cache 对比节省 ≈ 65%。
三处 cachePoint 的位置:① system 末尾、② tools 末尾、③ 最后一个 assistant 回复的最后一个非 thinking block 之后。每轮请求前先 strip 掉旧的 ③,再挂到最新位置。
生产落地小贴士
- A cachePoint 不要钉在 thinking(reasoningContent)块之后 —— Bedrock 会在 schema 校验阶段直接拒绝(
ValidationException),客户端能立刻感知。
- B 真实节省请用响应里的
cacheReadInputTokens / cacheWriteInputTokens / inputTokens 三个字段监控验证,不要凭直觉。
- C 模型 / cp 布局 / thinking 配置不同时,命中行为可能有差异,上线前用自己的真实流量复测一次最稳。
术语速查(理解动画里在演示什么)
- content block
- Bedrock Converse API 里
messages[i].content 数组的一个元素,每个 block 类型独立(text / toolUse / toolResult / reasoningContent / cachePoint 等)。动画左侧每条消息里被分隔开的小方块就是一个 block。1 个 block ≠ 1 个 token,一个 text block 可能含几千 token。
- prefix
- 从 prompt 开头到某个边界为止的连续 content block 序列。cache 命中的是"起点对齐 + 终点对齐到历史端点"的最长 prefix,不是任意相同片段。中间任何一个 token 不一致,从那点之后都不命中。
- cache 端点
- 每个 cachePoint 标记的位置都是一个候选 prefix 端点。cache 里存的是"端点位置 → 这条 prefix 已写入",不是按 block 单独存。多轮对话本质是端点链不断往后延。
- cache_write 段
- "上一次端点(或 prompt 起点)→ 当前请求最后一个 cp"之间的所有 content block,整段一起写入 cache。一段 cw 通常跨多个 block。比如动画里 r2 的 cw=486 token 实际是 r1 reasoning + r1 text + 2 个 toolUse + 2 个 toolResult 共 6 个 block 整段写入。
- ~20 boundary 限制
- 服务端从当前 cp 往前扫描时,最多看 ~20 个 content block 边界找匹配端点(数的是 block 数,不是 token 数)。长对话超 ~20 时,1 cp 布局会扫不到 system+tools 段,需要靠 system / tools 自己挂 cp 兜底。
- 每个 cp 独立检索
- 一个 request 里多个 cp 各自做回看,互不干扰。这是为什么 3 cp 比 1 cp 抗长对话的根因(cp ① cp ② 永远扫得到 system+tools,不受 ~20 预算影响)。注:AWS 没公开承诺这点,是本项目实测观察。
- cp 之后的内容
- 当前请求里最后一个 cp 之后到 prompt 末尾的内容(典型场景:每轮新加的 user message),不参与命中检索、不写入 cache,按 1.0× 计入
inputTokens。要等下一轮把 cp 挂在更后面才进 cache。