在 Claude Code 里敲下/usage,看到 cache read 和 cache write 两行数字,你才会具体感受到 KV Cache 命中率不是纸面概念。把模型通道改到 TaoToken 之后,问题变得更直接:Base URL 换成https://taotoken.net/api,Key 从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_kv_cache 创建,原来按会话维护的缓存还认不认?这篇文章不从 Transformer 公式讲起,而是从你改完~/.claude/settings.json那一刻开始,把“会话不重启、命中率是否还维持 90% 以上”拆成能照着做的检查步骤。核心结论先放在前面:Claude Code 的 KV Cache 仍然按会话维度维护,换的是请求出口,不是缓存规则;只要会话没断、模型 ID 没跳、系统提示词和上下文前缀稳定,低价缓存复用大概率会继续发生,但你必须用/usage和用量页自己确认,而不是凭感觉。
1. 从 /usage 里的 cache read 说起:换通道前先认清会话缓存
1.1 Claude Code 的 KV Cache 不是按项目文件缓存,而是按会话上下文
原文里反复强调一个点:KV Cache 只缓存 Key 和 Value,不缓存 Query。放到 Claude Code 里,系统提示词、工具定义、技能描述、工作区规则、历史对话、工具调用记录,这些在一轮轮请求中重复出现的内容,才有机会被缓存复用;你刚敲进去的那句新问题,属于 Query,每次都要重新算。所以 Claude Code 命中率高不高,不取决于你项目里有多少文件,而取决于同一个会话里有多少固定上下文被反复携带。
换到 TaoToken 通道后,这个逻辑没有变。你改的是ANTHROPIC_BASE_URL,让 Claude Code 把请求发到https://taotoken.net/api;模型侧仍然按上下文前缀和会话状态来判断哪些 KV 可以复用。原来在同一个项目、同一个会话里持续运行时能保住的热缓存,理论上仍然按会话维度存在。但“理论上”不够,因为 Base URL 变化后,Claude Code 可能重新初始化连接、重新拼装请求头,模型 ID 也可能被你顺手改掉。这些动作里只要有一个破坏了上下文前缀,命中率就会掉。
1.2 改通道后最该观察的三个量:命中 Token、未命中 Token、缓存写入
在 Claude Code 里输入/usage,你会看到和 Token 消耗相关的统计。不同版本字段名可能略有差异,但你要抓的核心就三类:缓存命中读取的 Token、未命中而重新计算的 Token、以及缓存写入 Token。命中率高,说明系统提示词和上下文继续走低价复用;命中率突然掉,说明有大量内容被当成全新前缀重新计算。
这也是为什么不要一改完 Base URL 就急着重启整个项目。先保留原会话,让 Claude Code 继续在旧上下文里跑一轮,再输入/usage对比改通道前后的数字。你要验证的不是“接口通不通”,而是“通完之后缓存还认不认”。如果此时命中率仍然在 90% 以上,说明会话缓存没有被通道切换打断;如果命中率明显下降,先别怀疑 TaoToken 本身,按后面第 4 节的顺序查模型 ID、会话状态、工具输出和 Base URL 写法。
2. 在 ~/.claude/settings.json 里把 ANTHROPIC_BASE_URL 指向 TaoToken
2.1 准备 API Key 与模型 ID
打开 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_kv_cache 注册并创建 API Key,Key 用占位符YOUR_API_KEY表示,不要把它写进公开仓库。模型 ID 不要去猜,也不要拿旧文章里的示例硬填,直接在同一站点的模型广场看当时可用的模型 ID,复制你要用的那个。TaoToken 在这里承担的是统一 API 和兼容通道的角色,你拿到的是一把 Key、一个 Base URL、一个可用模型 ID,然后把它们填进 Claude Code 的配置。
这一步和原文里“申请密钥、看模型名”的位置是对应的,只是入口统一到了 TaoToken。你不需要分别去多个服务商控制台找 Key,也不需要为每个模型记一套不同的地址。创建完 Key 后,模型 ID 以模型广场当时列表为准,不要编造带日期后缀或版本号的假 ID,否则 Claude Code 发出的请求会被模型侧拒绝,你也就看不到真实的缓存命中数据。
2.2 两种写法:环境变量与 settings.json
Claude Code 支持环境变量方式,也支持~/.claude/settings.json的env字段。临时验证可以用环境变量:
export ANTHROPIC_BASE_URL="https://taotoken.net/api" export ANTHROPIC_AUTH_TOKEN="YOUR_API_KEY" export ANTHROPIC_MODEL="YOUR_MODEL_ID"长期使用更推荐写进~/.claude/settings.json,格式如下:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_AUTH_TOKEN": "YOUR_API_KEY", "ANTHROPIC_MODEL": "YOUR_MODEL_ID" } }注意ANTHROPIC_BASE_URL末尾不要加/v1。TaoToken 的接口 Base URL 是https://taotoken.net/api,你把它填进工具即可;官网落地页https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_kv_cache只用来注册、创建 Key、看模型广场和看用量,不要把带 UTM 的地址填进ANTHROPIC_BASE_URL。这两个地址混用,轻则请求 404,重则你以为自己在测缓存,其实连模型都没调通。
2.3 改完先别急着重启整个项目
配置保存后,Claude Code 可能需要重新加载环境。你可以退出当前进程再进入,但进入后要做的第一件事不是马上换模型,也不是/clear,而是继续在同一个项目会话里跑一个需要携带长上下文的动作。比如让它解释一段已有代码、汇总当前目录结构、基于之前的对话继续改一个文件。目的是让系统提示词、项目规则、历史消息重新进入请求前缀,看看缓存读取是否恢复。
如果你一上来就新开项目目录、切换模型、清空会话,那么 KV Cache 的会话维度就被你主动打断了。此时/usage里的未命中 Token 会很高,但这不能证明 TaoToken 通道不缓存,只能证明你换了会话。原文里说 Claude Code 的缓存严格按会话维度维护,同一个项目、同一组任务持续在一个会话中运行,系统配置、对话历史、项目上下文会持续缓存复用;频繁重启会话、切换项目会直接清空热缓存。这个习惯在换通道后同样适用。
3. 保持原会话不重启:用 /usage 验证 KV Cache 命中率是否还维持 90% 以上
3.1 先跑一轮长上下文,让系统提示词和项目规则进入缓存
验证命中率要有基线。最稳妥的做法是:改配置前先在一个会话里跑一段长任务,输入/usage记下当时的命中情况;改完ANTHROPIC_BASE_URL和ANTHROPIC_MODEL后,不要关闭这个会话,继续追问同一个任务。这样系统提示词、工具列表、技能描述、工作区规则、之前的工具输出都还在上下文里。模型侧如果继续复用这些前缀的 KV,你就会在/usage里看到 cache read 明显高于 cache write。
长上下文不需要刻意灌水。你可以让 Claude Code 读取一个你本来就要改的模块,让它解释调用链,再让它基于解释继续改。关键是同一个会话、同一个项目、同一个模型 ID。只要这三者不变,通道从旧地址切到https://taotoken.net/api之后,缓存复用应当继续按会话走。原文里提到过长文档场景下命中率可以到 90% 以上,这里不要照搬具体数字,你要看的是自己/usage里的实时占比。
3.2 在会话里输入 /usage 看 cache read 与 cache write
/usage是 Claude Code 里最直接的观察口。你重点看缓存读取 Token 是否占输入 Token 的大头,缓存写入 Token 是否只在新增上下文时增长。如果每次追问都产生大量 cache write、cache read 很少,通常说明上下文前缀不稳定,或者会话已经被重置。此时不要只看总 Token 数,因为总 Token 高可能是正常的长上下文,关键看其中有多少走了低价复用。
这里要分清一个概念:缓存命中率高不等于“什么都不用花钱”,而是说重复内容没有重新全量计算。你的新问题、新粘贴的代码、新产生的工具输出,仍然要算未命中 Token。所以命中率是否维持 90% 以上,取决于你的会话里固定上下文占比有多高。Claude Code 本身会注入比较完整的系统提示词和工具定义,这部分天然有利于命中;如果你频繁把大量新日志、新文件塞进同一个会话,命中率被稀释也很正常。
3.3 命中率低于 90% 时先查会话是否被重置
一旦发现命中率掉下来,先排除最简单的操作:你是不是新开了终端、重新登录了 Claude Code、用了/clear、换了工作目录、改了ANTHROPIC_MODEL。这些动作都会让原来的会话缓存失效。尤其是模型 ID,Claude Code 一旦从 A 模型切到 B 模型,两个模型之间的 KV Cache 不互通,之前攒下的缓存全部作废,新模型需要从零重新计算。固定项目、固定场景尽量锁定单一模型,不要在同一会话里反复横跳。
确认会话没有断之后,再看/usage的字段是不是符合预期。如果仍然异常,可以去 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_kv_cache 的控制台查看这次调用的用量记录,对照模型 ID、请求时间和 Token 统计。这一步和原文里“查看后台用量统计”的位置对应,只是现在统一在 TaoToken 控制台完成。用量页能帮你判断请求有没有真正到达模型,而不是卡在本地配置错误上。
4. 命中率跌到 90% 以下的排查顺序:模型 ID、会话、工具输出、Base URL
4.1 模型 ID 中途切换会让 KV Cache 不互通
原文把“频繁切换模型”列为高频致命坑,这个坑在 Claude Code 换通道后更容易出现。因为你在配置里多了一个ANTHROPIC_MODEL,如果今天填一个模型,明天改另一个模型,后天又换回第一个,那么每一次切换都会让当前会话的缓存断档。模型侧不会把 A 模型的 KV 缓存拿给 B 模型复用,哪怕它们看起来都是同一家服务商。
正确做法是:一个项目周期内固定一个模型 ID,需要对比效果时另开会话、另记/usage基线,不要把生产会话当成试验场。模型 ID 从 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_content=claude_code_kv_cache 的模型广场复制,复制后不要再手改大小写或加后缀。配置里保持"ANTHROPIC_MODEL": "YOUR_MODEL_ID",实际使用时替换成你复制的那个 ID。
4.2 新开会话、新工作目录等于清空热缓存
Claude Code 的缓存按会话维度维护,这意味着“同一个项目持续运行”本身就是缓存策略的一部分。你新建一个会话,之前的历史对话、工具输出、项目规则不会自动继承;你换一个工作目录,Claude Code 重新读取的目录结构、配置文件、上下文也可能形成新的前缀。此时/usage显示大量未命中,不是通道坏了,而是热缓存没了。
如果你必须在多个项目之间切换,建议把关联性强的任务放在同一个工作空间里完成。同一业务、同一代码库、同一系列迭代,统一在一个会话中推进,让前期的上下文、工具配置、项目结构持续复用。这样命中率才有稳定的底盘。否则你会陷入一种错觉:每次刚改完配置就觉得命中率下降,其实只是每次都在冷启动。
4.3 工具输出、图片、长日志挤掉可复用上下文
Claude Code 在执行文件读取、命令运行、代码扫描后,会把工具输出放进上下文。这些内容也会参与缓存计算。如果你习惯一次读整个大文件、把完整构建日志贴进来、或者频繁让 Claude Code 处理高清截图,那么大量一次性内容会挤占上下文窗口,既增加未命中 Token,也可能把原本要复用的核心上下文挤到后面。图片尤其要注意,原文明确提到图片内容不支持 KV 缓存,每次上传都要重新做图像编码和特征提取,分辨率越高消耗越大。
在 Claude Code 里更实用的做法是按需读取:让 Claude Code 只读当前任务需要的片段,长日志先过滤关键字,截图先裁剪或降低分辨率。这样做的目的不是“省一点”,而是让同一个会话里的固定前缀保持稳定,让/usage里的 cache read 占比不被一次性内容冲垮。原文把这条列为隐形坑,换到 TaoToken 通道后依然成立,因为缓存规则在模型侧,不会因为 Base URL 变了就改变。
4.4 Base URL 多写 /v1 或 Key 没带进 settings.json
配置错误要单独查。ANTHROPIC_BASE_URL应该填https://taotoken.net/api,末尾不要加/v1。如果你写成https://taotoken.net/api/v1,Claude Code 可能在错误路径上请求,表现可能是 404 或模型不可用,此时/usage根本没有有效缓存数据。另一个常见问题是 Key 没生效:环境变量里改了,但~/.claude/settings.json里还是旧值;或者 JSON 里把ANTHROPIC_AUTH_TOKEN拼错,导致请求被拒。
排查时先确认 Claude Code 实际读取的是哪份配置。终端环境变量和settings.json可能同时存在,优先级以你的版本行为为准。最稳妥的做法是只保留一处配置,把YOUR_API_KEY替换成真实 Key,把YOUR_MODEL_ID替换成模型广场复制的 ID。改完再重启 Claude Code 进程,进入同一个项目会话,跑一轮长上下文,再看/usage。如果这时 cache read 仍然起不来,再去控制台看请求是否记上账,而不是继续在本地反复改 Base URL。
5. 让 Claude Code 在 TaoToken 通道上持续复用缓存的三个操作习惯
5.1 同一工作空间、同一会话、同一模型 ID
这三件事听起来简单,却是命中率稳定的前提。Claude Code 的系统提示词、工具定义、技能描述、工作区规则,每次请求都会重新携带;这些内容不变,缓存才能持续命中。你换工作空间,项目结构变了;你换会话,历史上下文没了;你换模型 ID,KV Cache 不互通。三个变量一起动,命中率不可能好看。
所以在 TaoToken 通道上写代码时,建议把“一个项目周期”当成“一个会话周期”。中途只改业务代码,不改模型 ID,不随便/clear,不因为换个终端就重开项目。需要验证新模型时,另开一个会话做对比,别把主会话当试验田。这样你才能在/usage里看到稳定的 cache read 曲线,而不是每次都在冷启动。
5.2 长文档和代码上下文一次性喂足,别反复分段上传
原文提到 RAG 场景里重复上传同质化文档会持续产生未命中成本。Claude Code 里没有 RAG 上传按钮,但行为相似:你反复把同一份文件拆成多段贴进对话,每贴一段都可能形成新的上下文前缀,模型需要重新计算。更合理的做法是一次性让 Claude Code 读取完整文件,或者一次性把要改的模块上下文给足,然后基于这个稳定前缀连续追问。
如果项目很大,不可能全部塞进上下文,那就固定一个“工作集”:当前任务相关的几个文件、目录结构、关键接口定义。让这个工作集在会话里保持稳定,不要每次追问都重新粘贴一遍。稳定前缀越多,缓存复用越多;一次性新内容越少,未命中 Token 越少。这比事后找各种“省 Token 技巧”更有效。
5.3 改配置后不要频繁 /clear 或重启
改完ANTHROPIC_BASE_URL和 Key 之后,你可能想/clear一下重新开始。但这会把好不容易建立的会话缓存清空。验证阶段应该保留旧会话,先观察切换后的/usage;只有确认配置稳定、需要换任务时,才考虑新开会话。频繁重启 Claude Code 进程也会让连接和会话状态重新初始化,缓存热状态被打断。
一个实用节奏是:配置改完后,在旧会话里跑两到三轮追问,记录/usage;如果命中率正常,再继续正常工作;如果异常,按第 4 节排查。不要一边改配置一边清会话,否则你分不清是通道问题还是操作问题。原文强调“保持同一会话持续运行,不频繁重启”,这条在接入配置场景里就是最低成本的优化。
6. 跑通之后去控制台对一下这次 Claude Code 调用
6.1 用同一把 Key 在模型对话里发一条测试消息
配置保存并跑过一轮后,先在 TaoToken 模型对话 里用同一把 Key 发一条测试消息,确认模型 ID 和 Base URL 没填错。模型对话能快速区分“Key 无效”“模型 ID 不存在”“通道不可用”这几类问题。如果这里正常,Claude Code 里仍然报错,就回到~/.claude/settings.json检查字段名和值,重点看ANTHROPIC_BASE_URL是不是https://taotoken.net/api,ANTHROPIC_AUTH_TOKEN是不是YOUR_API_KEY对应的真实值。
6.2 去控制台 API Keys 和用量页确认调用记录
测试消息发出后,打开 控制台 API Keys 确认 Key 状态,再看用量页有没有刚发生的请求记录。用量页能帮你判断 Claude Code 的请求有没有真正到达模型侧;如果本地/usage有数字但控制台没有记录,说明请求可能发到了旧地址或旧 Key。反过来,控制台有记录但 Claude Code 里/usage命中率低,就回到会话和模型 ID 上排查。
6.3 长期写代码看 Coding Plan,配置对照看 Claude Code 文档
如果你准备把 Claude Code 长期挂在这个通道上写代码,可以打开 Coding Plan 看套餐是否够用,再决定要不要把模型 ID 固定下来。配置字段对照可以看 Claude Code 接入文档,里面会写清楚settings.json的env结构、Base URL 写法和 Key 占位符。
回到最初那个问题:把 Claude Code 的模型通道改到 TaoToken 之后,KV Cache 命中率还按会话缓存吗?答案是,缓存规则仍然按会话和上下文前缀走,但你要自己保证会话不重启、模型 ID 不横跳、上下文前缀不被一次性内容冲散,然后用/usage看 cache read 是否继续占大头。配置改完那一刻不是终点,同一个项目会话里连续跑几轮、对比命中率,才算真正接入完成。