ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Claude Code 的 Prompt Caching 到底在缓存什么?从 settings.json 配置到长 Session 省 token 实测

Claude Code 的 Prompt Caching 到底在缓存什么?从 settings.json 配置到长 Session 省 token 实测 1. 长 Session 越聊越贵问题到底出在哪如果你用 Claude Code 连续改一个项目十几轮之后大概率会注意到一个现象明明这一轮只敲了一句「把刚才那个函数再改一下」终端里也没多出多少字但 token 统计里的 input 数字却大得吓人。很多人第一反应是「是不是 Claude Code 偷偷把整个仓库都塞进去了」其实不是。要理解这件事得先接受一个前提模型在不同 API 请求之间没有天然记忆。Claude Code 每发一条消息都会产生一次全新的 API 请求。为了让模型知道前面发生了什么这次请求必须重新携带系统指令、工具定义、项目规则CLAUDE.md、此前的用户消息、Claude 的回答、工具调用结果、已经读过的代码内容再加上你这一轮的新问题。所以「Claude Code 靠 Prompt Caching 重用历史上下文来省钱」这句话准确的理解不是「它发现以前发过就不发了」而是这些上下文在逻辑上依然是模型这一轮必须看到的输入但服务器发现其中一大段前缀此前已经处理过于是复用那部分的处理结果只重新处理后面新增或变化的部分。这就是 Prompt Caching 的核心也是长 Session 能省下大量 token 成本的根源。这篇就围绕 Claude Code 的 Prompt Caching从它到底缓存什么、settings.json 里怎么配、到怎么验证命中一步步拆开讲。2. Prompt Caching 到底在缓存什么2.1 它缓存的是 Prompt 前缀不是文本片段Prompt Caching 更准确的名字应该叫 Prompt Prefix Cache。把一次请求抽象成A B C DA 是系统指令B 是工具定义和项目规则C 是已经发生的长对话D 是刚输入的新问题。下一轮请求变成A B C D E只要前面的A B C D与上一轮精确匹配API 就有机会从缓存读取这一大段已经处理过的前缀只为新增的 E 和新的响应承担正常处理成本。这里「前缀」两个字是关键。命中依赖的是精确匹配不是语义相似。「修复登录 Bug」和「修复登录问题」在人看来意思一样对前缀缓存来说却是两段不同内容。前缀里某个位置一变它后面的所有内容都处于新前缀之下缓存就断了。2.2 Claude Code 的三层 Prompt 结构Anthropic 官方把 Claude Code 的 Prompt 大致拆成三层顺序是刻意设计的层级内容变化频率系统提示层核心指令、工具定义、输出风格极低项目上下文层CLAUDE.md、自动记忆、相关规则低对话层用户消息、Claude 回答、工具结果持续增长变化最少的内容放最前面不断新增的内容放后面就是为了让缓存更容易找到稳定的公共前缀。底层 API 还按 tools、system、messages 的顺序构建缓存层级越靠前的内容改变潜在影响越大。2.3 它不缓存整个仓库也不等于 KV Cache两个常见误区要纠正。第一Prompt Caching 不是「把整个代码仓库缓存起来」。项目文件只有在 Claude Code 真正读取后内容才进入对话上下文成为可缓存前缀的一部分。你编辑一个此前读过的文件历史里那次旧读取不会被改写Claude Code 会追加一条系统提醒说文件变了需要最新内容时它会重新读。新内容追加在末尾所以普通编辑通常不会破坏之前的缓存。第二它不等于 Transformer 内部的 KV Cache。KV Cache 解决单次生成过程中避免重复计算此前 token 的注意力Prompt Caching 解决的是不同 API 请求之间前缀的重用。更严谨的说法是「API 保存并复用已经处理过的 Prompt 前缀状态」而不是断言服务器一定以某种特定形式长期存放 KV 张量。2.4 和 CLAUDE.md、Context Window、/compact 的区别这几个概念经常被混在一起用一张表理清概念回答的问题Context Window这一轮模型最多能看到多少上下文CLAUDE.md / Auto Memory跨 Session 有哪些项目知识可以重新加载Prompt Caching已存在的相同前缀跨请求重复出现时能否降低处理成本/compact上下文本身太长时把旧历史总结成摘要缓存命中不等于那部分 token 从 Context Window 消失了。哪怕 140000 个 token 通过 Cache Read 拿到它们依旧占用上下文窗口。缓存降低的是重复处理的成本和延迟不是把上下文压缩成零。而 /compact 会改变对话层前缀原来的对话缓存自然无法直接匹配两者解决的是不同问题。3. settings.json 里与缓存相关的配置骨架3.1 先搞清楚哪些配置会影响缓存Claude Code 的缓存行为一部分是自动的一部分可以通过 settings.json 干预。需要先明确缓存是按模型区分的切换模型、改变 Effort Level、连接或断开 MCP Server、启用禁用插件、移除工具都可能导致前缀变化、缓存失效。所以配置的核心思路是——让稳定内容尽量靠前且不变让动态内容尽量后置。3.2 一份可复制的配置骨架下面这份settings.json骨架重点是把容易变化的动态信息从系统提示里挪出去减少前缀抖动。你可以按自己项目调整{ env: { ANTHROPIC_BASE_URL: https://taotoken.net/api, ANTHROPIC_AUTH_TOKEN: 你的API_KEY, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: 1 }, permissions: { allow: [ Read, Grep, Glob ], deny: [] }, enableAllProjectMcpServers: false, autoMemoryEnabled: true }几个要点说明。ANTHROPIC_BASE_URL指向接入地址ANTHROPIC_AUTH_TOKEN填你在控制台生成的 Key。enableAllProjectMcpServers设为 false是为了避免长 Session 中途 MCP 工具集合变动导致系统提示前缀变化。工具定义位于非常靠前的 Prompt 层一旦工具集合变了后面整段对话都可能需要重建缓存。3.3 关于 TTL 的选择Anthropic API 提供 5 分钟和 1 小时两种主要 TTL。5 分钟缓存的首次写入按普通 input 价格的 1.25 倍计费后续读取只有 0.1 倍1 小时写入是 2 倍读取同样 0.1 倍。官方明确说5 分钟缓存经历一次成功读取就有经济价值1 小时缓存经历两次读取后开始有成本优势。如果你是按 token 计费的 API Key 方式Claude Code 默认选成本更低的 5 分钟 TTL。连续编码时每隔一两分钟交互一次缓存能一直保持温热离开终端很久再回来旧缓存可能已过期这一轮就要重新建立所以会明显更慢更贵。4. 验证缓存是否命中4.1 看 usage 里的三类 token判断缓存是否工作最直接的方式是看 API 返回的 usage 数据。它会把 token 分成三类input_tokens本轮按正常价格处理的普通输入cache_creation_input_tokens本轮正在建立新缓存的部分cache_read_input_tokens本轮从缓存读取、按约 0.1 倍价格计费的部分一个健康的信号是长 Session 里cache_read_input_tokens很大而cache_creation_input_tokens相对稳定。如果每一轮cache_creation_input_tokens都很高、cache_read_input_tokens一直很低说明前缀里有东西在不断变化导致匹配失败。4.2 用一段脚本观察命中趋势你可以写个小脚本把每轮返回的 usage 记下来观察趋势import json def summarize_usage(usage): read usage.get(cache_read_input_tokens, 0) create usage.get(cache_creation_input_tokens, 0) normal usage.get(input_tokens, 0) total read create normal ratio read / total if total else 0 print(finput{normal} create{create} read{read} 命中占比{ratio:.2%}) return ratio # 假设 response 是某轮 API 返回 # summarize_usage(response[usage])连续跑几轮如果命中占比稳步上升说明前缀稳定、缓存工作良好。如果某轮突然掉下来就要回想这一轮是不是切了模型、改了 Effort、动了 MCP 或插件。4.3 一个简化的省钱估算假设一段稳定前缀有 100000 个 token连续 10 次请求忽略新增小段和 output。用 5 分钟缓存第一次建立缓存是100000 × 1.25 125000个标准单位后面 9 次命中是100000 × 9 × 0.1 90000合计 215000。完全无缓存则接近 1000000。仅这一段不变前缀理论成本就降了约 78.5%。真实账单不会正好是这个数因为每轮还有新 input、output、thinking 和新的 Cache Write但足以说明为什么长 Session 的 cache_read 会大得惊人、费用却没线性增长。5. 本篇常见错排查5.1 长 Session 里 cache_creation 一直很高这是最典型的缓存不命中信号。常见原因前缀里混入了每轮都变的内容比如时间戳、随机 ID、动态 Git 信息被塞到了靠前位置。一个 Agent 的 Prompt 只多了几十个动态 token如果它们出现在系统提示靠前处破坏的可能是其后几万甚至几十万 token 的缓存。排查方法是检查系统提示和项目上下文里有没有动态字段把它们挪到消息尾部。5.2 切换模型后突然变贵缓存按模型区分。一个被 Sonnet 缓存的长对话不能直接给 Opus 当同一个缓存条目用。用/model切换后即使对话文字完全相同下一次请求也要重新处理完整历史为新模型建立缓存。Effort Level 同样是缓存键的一部分中途改变 Effort 也可能带来一次完整 Cache Miss。所以偶尔某一轮特别贵不一定是生成了大量代码可能只是前缀变了。5.3 升级 Claude Code 后恢复旧会话很贵新版本往往会修改系统提示或工具定义。升级后恢复一个很长的旧会话旧对话现在位于新的系统提示后面第一轮可能需要重新处理整段历史成为整个 Session 里费用特别高的一次请求。这不是 bug是前缀变了。5.4 误以为删本地文件能清缓存Prompt Cache 主要发生在服务器端不是 Claude Code 在本机建了个大缓存目录。删除本地临时文件并不等于清空模型侧缓存。另外Claude Code 的 Prompt 里包含工作目录、平台、Shell、OS 版本、自动记忆路径等信息所以缓存范围往往接近「机器加目录」。同一目录里的并行 Session 更容易构建匹配前缀不同工作目录甚至同一仓库的不同 worktree都可能因工作目录不同而产生不同前缀。6. 把缓存用起来接入与验证理解原理之后落地其实就三步配好接入地址、生成 Key、跑起来看 usage。接入地址用https://taotoken.net/apiKey 在控制台生成。生成后填进上面那份 settings.json 的ANTHROPIC_AUTH_TOKEN就能开始观察缓存行为了。如果你更想先直观感受模型对话和缓存命中效果可以直接在模型对话里试几轮长上下文如果是要长期跑编码和 Agent 任务建议用 Coding Plan 把长 Session 的成本结构固定下来。生成和管理 Keyhttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi_keys接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc模型对话验证https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentchat长期编码与 Agenthttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding_plan配好之后回到第 4 节那段脚本连续跑几轮盯着cache_read_input_tokens和cache_creation_input_tokens的比值。这个比值稳步走高就说明你的长 Session 正在按预期复用前缀token 成本也就从「每轮重算全部历史」变成了「只算新增后缀」。
返回列表