ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Claude Code 的 Prompt Caching 到底在缓存什么,为什么几十万 Cache Read Token 反而是省钱信号|TaoToken 统一 Key 通道实测

Claude Code 的 Prompt Caching 到底在缓存什么,为什么几十万 Cache Read Token 反而是省钱信号|TaoToken 统一 Key 通道实测 1. 先搞清楚 Claude Code 的 Cache Read Token 到底在缓存什么如果你最近认真看过 Claude Code 的/usage输出大概率会被一组数字吓到普通 input 只有一两千 tokenoutput 也就几千可 cache read 那一栏直接飙到几十万甚至上百万。我第一次看到 940.0k cache read 的时候第一反应是这玩意儿是不是在偷偷烧我的钱。先说结论Cache Read Token 高在长会话里通常是省钱信号不是浪费信号。要理解这件事得先把 Claude Code 从聊天框的认知里拽出来。你在终端敲一句帮我修一下这个路由 bugClaude Code 实际发给模型的上下文远不止这句话。它至少包含这几层Claude Code 自己的系统提示词System Prompt描述它是个什么 Agent、该怎么用工具、输出格式是什么工具定义Tool DefinitionsRead、Edit、Bash、Grep、Glob 这些工具的 JSON Schema工作目录、Git 状态、平台、Shell、OS 版本等环境信息项目规则文件比如CLAUDE.md已经读取过的源码、搜索结果、测试输出历史对话轮次和工具调用结果这些内容加起来几万到几十万 token 很正常。而 Claude Code 是个 Agent Loop读文件 → 跑测试 → 分析报错 → 改代码 → 再跑测试每一步都是一次独立的模型请求每次请求都带着前面累积的全部上下文。Prompt Caching 缓存的就是这些前缀。更准确地说它缓存的是从 Prompt 开头到某个 Cache Breakpoint 之间的完整前缀在模型内部对应的 KV 表示Key-Value 中间状态。下一轮请求如果前缀完全一致就不用从第一个 token 重新做一遍 Prefill 计算直接复用。所以那 940k cache read 的真实含义是有 94 万个 token 本来要按普通 Input 价格重新算一遍现在走了缓存通道单价只有普通输入的十分之一。这里有个特别容易搞混的公式记住它基本就不会误判账单Total Input Cache Read Cache Creation Regular Input三个指标各管一段指标含义单价以 Sonnet 4.6 为例input_tokens本轮新增、未缓存的输入$3 / 百万 tokencache_creation_input_tokens正在建立缓存前缀的输入$3.75 / 百万5 分钟 TTLcache_read_input_tokens命中缓存的历史前缀$0.30 / 百万output_tokens模型真正生成的新内容按输出价计费倍率关系很好记5 分钟 Cache Write 是普通输入的 1.25 倍1 小时 Cache Write 是 2 倍Cache Read 是 0.1 倍。拿一段稳定的 10 万 token 上下文连续用 10 次算笔账完全不用缓存10 次全按普通输入约 3 美元用 5 分钟缓存第一次写入约 0.375 美元后面 9 次读取 90 万 cache read token 约 0.27 美元合计约 0.645 美元。同一批重复上下文成本从 3 美元降到 0.645 美元省了大约 78.5%。还有个关键点Prompt Caching 是前缀缓存不是答案缓存。它不会把历史回答直接拿出来复用当前这一轮的答案仍然是模型实时生成的。缓存命中要求缓存点之前的 Prompt 段 100% 一致包括文本和图像。所以它更像计算缓存而不是语义缓存。理解了这一层再看 Claude Code 的/usage思路就该从总共出现了多少 token切换成这些 token 分别落在哪个计费通道。Cache Read 大说明命中率高真正该警惕的是稳定上下文反复 Cache Miss每一轮都按普通 Input 或频繁 Cache Write 重新算。2. 把 endpoint 切到 TaoToken 统一 Key 通道的前置准备搞清楚了缓存机制接下来要解决一个实际问题怎么稳定地观察 Cache Read Token 的变化并且让多个工具、多个项目共用一套 Key 和 endpoint。我试过在本地同时跑 Claude Code、Cline、Codex 这类工具每个都单独配一遍 Anthropic Key改起来很烦而且不同工具对 Base URL 的写法还不一样。这时候把 endpoint 统一到一个通道会省事很多。TaoToken 提供的就是这样一个统一 Key 通道官网在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 入口是 https://taotoken.net/api 。在动手之前先把三件套准备好这是后面所有配置的基础Base URLhttps://taotoken.net/apiAPI Key在控制台创建形如sk-开头的一串字符Model ID比如claude-sonnet-4-6、claude-opus-4-8这类具体以你账号里可用的模型为准这三样东西缺一不可。很多人配置失败不是网络问题而是只填了 Base URL 忘了 Model ID或者 Key 复制时带了空格。先创建 Key。打开控制台页面 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 登录后在 API Keys 区域新建一个 Key。建议按用途分开建比如claude-code-dev、cline-test这样后面看用量时能区分是哪个工具在消耗。创建完 Key 之后先别急着往 Claude Code 里塞用一条 curl 验证通道本身是通的curl https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-6, max_tokens: 64, messages: [ {role: user, content: 只回复两个字收到} ] }把$TAOTOKEN_API_KEY换成你自己的 Key。如果返回里能看到content字段和正常的usage结构说明通道没问题。这一步很重要因为如果直接跳到 Claude Code 配置一旦报错你分不清是 Key 的问题、Base URL 的问题还是 Claude Code 自身配置的问题。关于 Key 的存放别硬编码在脚本里。用环境变量export TAOTOKEN_API_KEYsk-你的key写进~/.zshrc或~/.bashrc新开终端生效。这样 Claude Code、Cline、curl 都能复用同一个变量改 Key 只改一处。还有一点要提醒不要把生产数据库的凭据、真实用户数据塞进测试 Prompt。缓存机制本身是内存态、按组织隔离的但测试阶段养成好习惯没坏处。前置准备做到这里就够了一个可用的 Key、一个验证过的 Base URL、一个明确的 Model ID。接下来进入真正的配置环节。3. 可复制的 settings 配置片段与缓存命中验证这一节是重点直接给可复制的配置。Claude Code 的配置主要落在~/.claude/settings.json部分场景也会用到项目级的.claude/settings.json。先看全局配置。打开或新建~/.claude/settings.json写入下面这段{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: sk-你的key, ANTHROPIC_MODEL: claude-sonnet-4-6, ANTHROPIC_SMALL_FAST_MODEL: claude-sonnet-4-6 }, cleanupPeriodDays: 30 }几个字段说明一下ANTHROPIC_BASE_URL指向 TaoToken 的 API 入口注意这里不带任何路径后缀就是https://taotoken.net/apiANTHROPIC_AUTH_TOKEN填你的 Key。有些版本读ANTHROPIC_API_KEY如果前者不生效就换成后者试ANTHROPIC_MODEL主模型 IDANTHROPIC_SMALL_FAST_MODEL处理轻量任务比如生成 commit message用的模型cleanupPeriodDays本地 session transcript 的保留天数和 Prompt Cache 是两码事别搞混如果你更习惯用环境变量而不是 settings.json等价写法是export ANTHROPIC_BASE_URLhttps://taotoken.net/api export ANTHROPIC_AUTH_TOKENsk-你的key export ANTHROPIC_MODELclaude-sonnet-4-6两种方式选一种就行同时配可能互相覆盖反而排查困难。配置写完后重启 Claude Code让它重新读取 settings。然后做一次缓存命中验证这是本篇最核心的动作。验证步骤第一步在一个真实项目目录里启动 Claude Code让它读几个文件。比如请阅读 package.json 和 src/router/index.ts然后告诉我这个项目用的什么路由方案第二步等它回答完紧接着追问一个基于上文的问题基于你刚才读到的路由配置如果我要加一个全局前置守卫应该改哪个文件第三步输入/usage查看统计。预期结果第一次请求里cache_creation_input_tokens会比较高因为它在建立缓存前缀第二次请求里cache_read_input_tokens会明显上升而input_tokens保持很小。这就是缓存命中的直接证据。如果第二次请求的 cache read 依然是 0说明前缀没匹配上常见原因在下一节展开。再补一个多工具共用的场景。如果你同时用 Cline它的 MCP 配置里也要写全三件套。以 Cline 的配置为例{ mcpServers: { taotoken: { command: npx, args: [-y, modelcontextprotocol/server-fetch], env: { BASE_URL: https://taotoken.net/api, API_KEY: sk-你的key, MODEL_ID: claude-sonnet-4-6 } } } }注意这里 Base URL、Key、Model ID 三件套一个都不能少。Cline 这类工具如果只填了 Base URL 没填 Model ID请求会直接失败或者回落到默认模型导致你观察到的 cache read 数据对不上。如果你用的是 Codex 的auth.json体系思路一样把 endpoint 指向https://taotoken.net/apiKey 填进去模型 ID 写清楚。不同工具的字段名不同但三件套的逻辑不变。配置完成后建议固定一个测试项目每次改配置后都跑一遍上面那三步验证。这样你能快速判断是配置生效了还是缓存没命中。4. 一次完整的缓存命中率验证与结果解读上一节给了配置和验证步骤这一节把一次完整验证的过程和结果讲透让你看到数字时知道该怎么读。假设我在一个 Angular 项目里跑了一次典型的多轮会话。第一轮让 Claude Code 读package.json、src/app/app-routing.module.ts、src/app/guards/auth.guard.ts和CLAUDE.md。第二轮让它基于这些内容分析路由守卫的加载顺序。第三轮让它改一个文件并跑测试。跑完三轮后/usage大致会呈现这样的形态input_tokens: 1.2k output_tokens: 5.3k cache_creation_input_tokens: 50.0k cache_read_input_tokens: 940.0k先别被 940k 吓到。拆开看第一轮读文件建立缓存前缀cache_creation上升cache_read接近 0第二轮前缀命中cache_read大幅上升input_tokens只包含新增的那句追问第三轮前缀继续命中cache_read再涨一截cache_creation只增加新写入的尾部940k cache read 意味着大约 94 万个 token 走了 0.1 倍单价的通道。如果这些 token 全部按普通输入算成本是它的 10 倍。这里要理解 Claude Code 的 Automatic Caching 机制它会随着对话推进自动把 Cache Breakpoint 往后移。第一轮缓存 System User1 Assistant1 User2第二轮前面部分从缓存读只把新增的 Assistant2 User3 写入新缓存第三轮继续往后推。开发者不需要手工管理 Breakpoint。怎么判断缓存是否健康看两个信号一是cache_read在长会话中应该持续增长。如果它长期接近 0而input_tokens或cache_creation反复很高说明前缀一直在变缓存没命中。二是input_tokens应该保持相对小。它代表本轮真正新增、未缓存的内容。如果它突然变得很大说明有大量内容没走缓存。哪些操作会破坏缓存前缀这是实战里最容易踩的坑工具定义变化。打开或关闭 Web Search 会改变 System Prompt导致 System 和 Message 层缓存失效在 System Prompt 里塞当前时间、随机 UUID。每次请求前缀都不同缓存永远命中不了JSON 序列化顺序不稳定。内容语义相同但字节序列不同前缀 Hash 就变了图像的增加和删除会影响 Message 层缓存不同工作目录可能导致 System Prompt 不同因为里面包含工作目录、Git 状态、平台、Shell 等信息Anthropic 把缓存层级描述为tools → system → messages前面层级一变后面全部失效。所以稳定内容要尽量靠前动态内容靠后。关于 TTL 的选择。默认 5 分钟命中后生命周期会刷新所以活跃会话能连续维持缓存。5 分钟缓存写入是 1.25 倍只要后续命中一次总成本 1.25x 0.1x 1.35x而不用缓存两次是 2x一次命中就开始省钱。1 小时缓存写入是 2 倍需要命中两次才回本2x 0.1x 0.1x 2.2x对比三次普通输入 3x。Claude Code 这种高频多轮场景默认 5 分钟就很合适。关于最小缓存长度。不同模型要求不同Sonnet 系列一般是 1024 tokenOpus 部分型号是 4096 token。低于这个长度即使配了 cache_control 也不会真正建立缓存而且 API 不一定报错。所以验证时要确保前缀足够长读几个真实文件是必要的。关于本地 Session Cache 和 Prompt Cache 的区别。Claude Code 会在~/.claude/projects/保存 session transcript用于/resume默认保留 30 天。这是本地缓存和 Prompt Cache 完全不是一回事。删掉本地目录不会清理 Prompt CachePrompt Cache 也不会把你的代码仓库长期存在本地。验证做到这里你应该能明确回答这次会话的 cache read 是多少、命中率如何、哪些内容走了缓存通道。接下来处理报错。5. 本篇常见报错排查401、local proxy failed 与 reading choices配置和验证过程中报错基本集中在几类。这一节按真实报错逐个拆。报错一401 UnauthorizedAPI Error: 401 {type:error,error:{type:authentication_error,message:invalid x-api-key}}原因通常是 Key 不对。排查顺序先确认ANTHROPIC_AUTH_TOKEN或ANTHROPIC_API_KEY里的 Key 没有多余空格、换行。从控制台复制时经常带上尾部空格。再确认 Key 没有过期或被删除。去 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 检查 Key 状态。最后确认你用的字段名对。有些 Claude Code 版本读ANTHROPIC_API_KEY有些读ANTHROPIC_AUTH_TOKEN。两个都试一下或者干脆在 settings.json 里两个都写。报错二local proxy failed / connection refusedError: connect ECONNREFUSED 127.0.0.1:xxxx local proxy failed这类报错说明请求根本没发到目标 endpoint而是被本地某个代理配置拦截了。检查环境变量里有没有残留的HTTP_PROXY、HTTPS_PROXY、ALL_PROXYsettings.json 里有没有指向本地端口的配置系统级代理设置是否影响终端清掉这些之后直接用第 2 节的 curl 命令验证通道能通再回到 Claude Code。报错三reading choices of undefinedTypeError: Cannot read properties of undefined (reading choices)这个报错通常出现在用 OpenAI 兼容格式调用、但返回结构不匹配的时候。Claude 的原生 Messages API 返回的是content数组不是choices。如果你用的工具默认按 OpenAI 格式解析就会读不到choices。解决办法是确认工具用的是 Anthropic 原生协议Base URL 指向https://taotoken.net/api而不是 OpenAI 兼容路径。同时确认 Model ID 是 Claude 系列不是 GPT 系列。报错四OAuth / 登录态相关报错OAuth error: invalid_grant如果你之前用官方账号登录过 Claude Code本地可能残留 OAuth 凭据和新的 Key 配置冲突。清理~/.claude/下的凭据缓存或者用独立的配置目录启动。报错五缓存不命中cache_read 长期为 0这个不算报错但最影响成本。排查前缀是否 100% 一致包括工具定义System Prompt 里有没有动态内容时间、UUID、随机 IDJSON 序列化顺序是否稳定前缀长度是否达到模型的最小缓存要求工作目录是否频繁变化报错六模型 ID 无效model: claude-xxx not found确认 Model ID 拼写正确并且在你账号的可用模型列表里。三件套里 Model ID 最容易写错尤其是版本号后缀。排查完这些基本能覆盖 90% 的配置问题。核心原则是先用 curl 验证通道再验证 Claude Code 配置最后看缓存命中。分层排查比一股脑改配置高效得多。6. 把 endpoint 固定到统一通道后怎么持续观察 Cache Read配置跑通、报错排完最后一步是让它稳定运行并持续观察。把 endpoint 固定到 TaoToken 统一 Key 通道之后最大的好处是多个工具、多个项目共用一套 Key 和 Base URL。你不需要在每个工具里重复配置改一处全局生效。观察 Cache Read 时数据来源也统一了。持续观察的三个动作第一固定一个测试项目。每次改配置或升级 Claude Code 后跑一遍第 3 节的三步验证对比 cache read 的变化。这样能快速发现配置回退。第二定期看/usage的 Usage Breakdown。Claude Code 新版会显示更详细的分解当 Long Context 或 Cache Miss 占比异常时会给出 Behavior Flag。看到 flag 就去查前缀稳定性。第三区分计费通道做成本分析。把 token 分成四类看普通 Input 是新增未缓存输入Cache Write 是建立前缀Cache Read 是命中历史前缀Output 是真正生成的新内容。健康的长会话里Cache Read 应该占大头。几个实用技巧把稳定内容前置。工具定义、System Instruction、项目规范放前面动态内容放后面。这是提升命中率最直接的办法。避免在 System Prompt 里注入时间戳和随机 ID。如果业务需要放到 messages 尾部。如果基于 Claude Agent SDK 做自动化 Agent注意excludeDynamicSections这个选项它能把工作目录、Git 状态等 session 相关信息移出 System Prompt让静态部分跨 session 共享缓存。多轮对话优先用 Automatic Caching复杂系统再考虑 Explicit Breakpoint。Breakpoint 最多 4 个有 20 个 Block 的 Lookback Window历史缓存点被推太远可能找不到。关于成本的心理模型。看到几十万 cache read 不要慌先算它替代了多少普通输入。940k cache read 按 0.1 倍单价算相当于 94k 普通输入的成本。如果这些内容本来要按普通输入重复算成本是它的 10 倍。真正该警惕的是稳定上下文反复 Cache Miss。关于隐私。Prompt Caching 用的是内存中的 KV 表示和内容 Hash不是把原始 Prompt 持久化到磁盘。缓存条目在 TTL 结束后清理不同组织之间不共享缓存。这一点在选通道时值得留意。最后回到那个核心公式Total Input Cache Read Cache Creation Regular Input。看懂这四个数字的分布就看懂了 Claude Code 背后的 token 经济学。模型能力决定它能不能完成任务而 Context Management 和 Prompt Caching 决定同样的任务要花多少推理成本。把 endpoint 固定到统一通道持续观察 Cache Read 的变化你就能在长会话里既保住效果又控住成本。
返回列表