<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Token优化 on KnightLi的博客</title>
        <link>https://www.knightli.com/tags/token%E4%BC%98%E5%8C%96/</link>
        <description>Recent content in Token优化 on KnightLi的博客</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Mon, 18 May 2026 18:30:24 +0800</lastBuildDate><atom:link href="https://www.knightli.com/tags/token%E4%BC%98%E5%8C%96/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>Claude Code 省 Token 指南：模型、MCP、CLAUDE.md 和 Skills 怎么影响缓存</title>
        <link>https://www.knightli.com/2026/05/18/claude-code-prompt-cache-token-optimization/</link>
        <pubDate>Mon, 18 May 2026 18:30:24 +0800</pubDate>
        
        <guid>https://www.knightli.com/2026/05/18/claude-code-prompt-cache-token-optimization/</guid>
        <description>&lt;p&gt;Claude Code 长任务里，Prompt Cache 命中率会直接影响成本和速度。很多人只知道“缓存能省 Token”，但不清楚哪些操作会让缓存突然失效。&lt;/p&gt;
&lt;p&gt;理解它并不难：每次请求都可以看成一条从左到右的上下文链条：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-text&#34; data-lang=&#34;text&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;tools -&amp;gt; system -&amp;gt; CLAUDE.md / skills -&amp;gt; messages
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;越靠左的内容越稳定，缓存收益越大；越靠左的内容一变，后面的缓存也更容易跟着失效。反过来，越靠右的内容变化，影响范围越小。&lt;/p&gt;
&lt;p&gt;所以优化 Claude Code 的 Prompt Cache，不是靠玄学，而是靠一个原则：任务开始前把模型、MCP、Skills、CLAUDE.md 等基础上下文准备好，任务中途尽量不要改。&lt;/p&gt;
&lt;h2 id=&#34;prompt-cache-缓存的不是文字本身&#34;&gt;Prompt Cache 缓存的不是文字本身
&lt;/h2&gt;&lt;p&gt;Prompt Cache 不是简单地把提示词字符串存起来。对 Transformer 模型来说，更关键的是前缀上下文经过注意力层计算后的 Key/Value 状态，也就是常说的 KV cache。&lt;/p&gt;
&lt;p&gt;这意味着两个事实：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;同一段上下文，只要前缀保持稳定，就可以在后续请求中复用一部分计算结果。&lt;/li&gt;
&lt;li&gt;如果模型、工具定义、系统提示词或前缀消息发生变化，之前的缓存就可能无法复用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Anthropic 官方文档也把失效层级概括为 &lt;code&gt;tools -&amp;gt; system -&amp;gt; messages&lt;/code&gt;。工具定义变化会影响整段缓存，系统层变化会影响 system 和 messages，messages 层变化则主要影响消息缓存。&lt;/p&gt;
&lt;p&gt;Claude Code 里还会额外涉及 &lt;code&gt;CLAUDE.md&lt;/code&gt;、Skills、MCP、插件和子代理等上下文，所以实际使用时更容易踩到缓存失效点。&lt;/p&gt;
&lt;h2 id=&#34;缓存杀手一中途切换模型&#34;&gt;缓存杀手一：中途切换模型
&lt;/h2&gt;&lt;p&gt;切模型是影响最大的操作。&lt;/p&gt;
&lt;p&gt;Prompt Cache 是按模型隔离的。Opus、Sonnet、Haiku 这类模型的结构和权重不同，同一段文本算出来的 KV cache 也不同。你在 Opus 里跑了很长上下文，再切到 Sonnet，并不能让 Sonnet 复用 Opus 的缓存。&lt;/p&gt;
&lt;p&gt;这会带来一个反直觉结果：中途为了省钱切模型，可能反而让前面已经积累的缓存全部失效。原本可以按 cache read 价格读取的上下文，需要重新写入和计算。&lt;/p&gt;
&lt;p&gt;更稳妥的做法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主对话尽量固定一个模型。&lt;/li&gt;
&lt;li&gt;需要便宜模型处理支线任务时，用 subagent 隔离出去。&lt;/li&gt;
&lt;li&gt;让支线代理完成搜索、探索、整理，再把结果摘要交回主对话。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样主对话的长上下文尽量不动，缓存命中率更稳定。&lt;/p&gt;
&lt;h2 id=&#34;缓存杀手二中途新增-mcp-或重载插件&#34;&gt;缓存杀手二：中途新增 MCP 或重载插件
&lt;/h2&gt;&lt;p&gt;MCP 会向 Claude Code 提供工具。新增 MCP 服务器后，工具列表会变化，而工具定义处在上下文链条最左侧。&lt;/p&gt;
&lt;p&gt;从 Prompt Cache 的角度看，工具列表一变，后面的 system 和 messages 都可能需要重新计算。尤其是 MCP 很多时，工具定义本身就可能占用大量 Token，缓存失效的代价会很明显。&lt;/p&gt;
&lt;p&gt;不过有一个细节：Claude Code 通常在会话启动时读取 MCP 配置。你中途改了配置，当前 session 不一定立刻受影响。真正需要小心的是触发重新加载的动作，例如重启、恢复会话、重新加载插件或让工具列表重新组装。&lt;/p&gt;
&lt;p&gt;建议是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开始长任务前，一次性装好需要的 MCP。&lt;/li&gt;
&lt;li&gt;不要做一半才发现缺工具，再安装并重载。&lt;/li&gt;
&lt;li&gt;对大型 MCP 工具集，优先考虑按需加载或减少默认启用数量。&lt;/li&gt;
&lt;li&gt;不常用的 MCP 不要长期挂在默认配置里。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果工具定义稳定，Prompt Cache 才有长期命中的基础。&lt;/p&gt;
&lt;h2 id=&#34;缓存杀手三中途修改-claudemd&#34;&gt;缓存杀手三：中途修改 CLAUDE.md
&lt;/h2&gt;&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; 是 Claude Code 的项目记忆文件，适合放构建命令、测试命令、架构约定、代码风格和项目注意事项。&lt;/p&gt;
&lt;p&gt;它对 Claude Code 很有用，但也会进入上下文。官方帮助文档说明，&lt;code&gt;CLAUDE.md&lt;/code&gt; 会在 session 开始时读取，并作为用户消息提供给 Claude；它也会使用 Anthropic 的 Prompt Cache。首次请求会按完整输入计费，后续请求如果在缓存有效期内命中，就按更低的 cache read 成本处理。&lt;/p&gt;
&lt;p&gt;问题在于：&lt;code&gt;CLAUDE.md&lt;/code&gt; 是内容寻址的。你一改文件内容，旧缓存就对不上了。&lt;/p&gt;
&lt;p&gt;所以不要在长任务中途频繁改 &lt;code&gt;CLAUDE.md&lt;/code&gt;。更好的方式是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;任务开始前先检查 &lt;code&gt;CLAUDE.md&lt;/code&gt; 是否够用。&lt;/li&gt;
&lt;li&gt;把稳定规则写进去，把临时指令放在当前对话里。&lt;/li&gt;
&lt;li&gt;如果只是一次性任务，不要为了临时需求修改长期记忆文件。&lt;/li&gt;
&lt;li&gt;如果必须改，最好在一个阶段结束后再开始新 session。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt; 应该是稳定的项目说明，而不是每轮任务都改的便签。&lt;/p&gt;
&lt;h2 id=&#34;缓存杀手四中途安装或更新-skills&#34;&gt;缓存杀手四：中途安装或更新 Skills
&lt;/h2&gt;&lt;p&gt;Skills 也是上下文的一部分。安装新 Skill、更新 Skill，或者让 Skill 列表发生变化，都会让注入到会话里的上下文不同。&lt;/p&gt;
&lt;p&gt;这类变化通常不会在当前 session 里立刻完整生效，而是在重新加载、恢复会话或新开会话时体现出来。问题是，一旦重新组装 messages，旧缓存就可能命中不了。&lt;/p&gt;
&lt;p&gt;建议和 MCP 类似：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;开始任务前先确认需要哪些 Skills。&lt;/li&gt;
&lt;li&gt;同一类任务尽量固定 Skill 集合。&lt;/li&gt;
&lt;li&gt;不要在一个长任务中途边做边装 Skill。&lt;/li&gt;
&lt;li&gt;如果安装了新 Skill，最好把它当成新阶段的开始。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对经常做内容生产、代码审查、部署、翻译的工作流，可以把常用 Skills 固定下来，让上下文结构尽量稳定。&lt;/p&gt;
&lt;h2 id=&#34;缓存杀手五空闲时间超过-ttl&#34;&gt;缓存杀手五：空闲时间超过 TTL
&lt;/h2&gt;&lt;p&gt;Prompt Cache 不是永久保存。常见默认有效期是几分钟级别，Anthropic 文档和 Claude Code 相关说明里都提到过 5 分钟左右的缓存窗口。超过 TTL 后，即使你发送完全一样的请求，服务端也可能已经清掉缓存。&lt;/p&gt;
&lt;p&gt;这也是很多长任务用户的体感来源：刚才还很省，去喝杯咖啡回来，再发下一步，Token 又突然涨上去了。&lt;/p&gt;
&lt;p&gt;长任务尤其容易遇到这个问题。你可能要看 Claude Code 的输出、检查文件、跑测试、思考下一步，这些操作一不小心就超过 5 分钟。&lt;/p&gt;
&lt;p&gt;如果你的使用环境支持，可以在长任务前启用 1 小时 Prompt Cache TTL：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;export&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;ENABLE_PROMPT_CACHING_1H&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;m&#34;&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;在 Windows PowerShell 里可以写成：&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-powershell&#34; data-lang=&#34;powershell&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;$env:ENABLE_PROMPT_CACHING_1H&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;1&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;需要注意的是，1 小时缓存写入成本通常会高于 5 分钟缓存写入成本。它不适合所有短任务，但对大型代码库、长对话、复杂多步骤开发任务，往往比频繁缓存过期更划算。&lt;/p&gt;
&lt;h2 id=&#34;怎么安排一次更省-token-的-claude-code-长任务&#34;&gt;怎么安排一次更省 Token 的 Claude Code 长任务
&lt;/h2&gt;&lt;p&gt;比较稳的流程可以这样做：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;任务开始前选定模型，不要中途频繁切换。&lt;/li&gt;
&lt;li&gt;提前启用需要的 MCP，不用的 MCP 先关掉。&lt;/li&gt;
&lt;li&gt;检查 &lt;code&gt;CLAUDE.md&lt;/code&gt;，只保留稳定、关键、长期有效的规则。&lt;/li&gt;
&lt;li&gt;提前准备好本次任务需要的 Skills。&lt;/li&gt;
&lt;li&gt;如果是复杂任务，考虑启用 1 小时 TTL。&lt;/li&gt;
&lt;li&gt;把大任务拆成几个阶段，但每个阶段内部尽量保持上下文结构稳定。&lt;/li&gt;
&lt;li&gt;需要探索支线问题时，用 subagent 或单独 session，不要污染主对话。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这套做法的目标不是绝对不让缓存失效，而是避免那些代价最高、最容易被忽略的失效。&lt;/p&gt;
&lt;h2 id=&#34;一个简单判断标准&#34;&gt;一个简单判断标准
&lt;/h2&gt;&lt;p&gt;你可以用一句话判断某个操作是否危险：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;这个操作会不会改变模型、工具定义、系统上下文或会话开头的固定消息？&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;如果答案是会，那它大概率会影响 Prompt Cache。越靠近上下文链条左侧，影响越大。&lt;/p&gt;
&lt;p&gt;常见操作可以这样理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;切模型：高风险，模型缓存隔离。&lt;/li&gt;
&lt;li&gt;新增 MCP 或重载插件：高风险，工具列表变化。&lt;/li&gt;
&lt;li&gt;修改 &lt;code&gt;CLAUDE.md&lt;/code&gt;：中高风险，项目记忆变化。&lt;/li&gt;
&lt;li&gt;安装 Skills：中高风险，注入上下文变化。&lt;/li&gt;
&lt;li&gt;普通对话继续追问：低风险，主要追加 messages。&lt;/li&gt;
&lt;li&gt;空闲超过 TTL：高风险，服务端缓存过期。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;小结&#34;&gt;小结
&lt;/h2&gt;&lt;p&gt;Claude Code 的 Prompt Cache 优化，关键不是背参数，而是让会话前缀稳定。&lt;/p&gt;
&lt;p&gt;模型不要随便切，MCP 和 Skills 不要边做边装，&lt;code&gt;CLAUDE.md&lt;/code&gt; 不要当临时草稿频繁改，复杂任务尽量延长 TTL。只要这些基础动作稳定下来，Claude Code 在长任务里的 Token 成本和响应速度都会更可控。&lt;/p&gt;
&lt;p&gt;最实用的一句话是：开始前配好，开始后少动。&lt;/p&gt;
&lt;h2 id=&#34;参考资料&#34;&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-use-with-prompt-caching&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Anthropic：Tool use with prompt caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://support.claude.com/en/articles/14553240-give-claude-context-claude-md-and-better-prompts&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Claude Help Center：CLAUDE.md and prompt caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://code.claude.com/docs/en/mcp&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Claude Code Docs：Connect Claude Code to tools via MCP&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        </item>
        
    </channel>
</rss>
