指出短提示词不等于低消费、错误模型选择、冗余工具调用和上下文累积是主要浪费源,并给出针对性修复方法。
Claude Code 通常不会因为你问太多问题而变贵。它变贵,是因为每个新问题都会把一个过大尺寸的 context、错误的模型、不必要的工具,以及昨天失败过的尝试一起拖进循环。以下是我首先会修复的十个习惯。
当我的 Claude Code 用量开始攀升时,我责怪了最明显的那件事:我一定是 prompt 得太多了。
于是我尝试更短的 prompt。我不再说"请"。我删掉了例子。我把详细请求压缩成模糊的一行话,看起来非常高效,结果却产生了非常低效的输出。
Claude 搜索了更多文件,因为我没能说出正确的文件名。它猜测了我没有说明的需求。它实现了错误的形状,我纠正了,它又重试,session 于是同时积累了两种失败的方案。我在 prompt 里省了 40 个 token,却花了几千个来修复歧义。
这是第一课:短的 prompt 不等于便宜的任务。
第二课来自 Anthropic 官方的 Claude Code 成本指南。一个长时间运行的 session 会在每次请求时重新发送其对话上下文。工具调用可以在一个看似单一的回合中产生多个请求。Prompt 缓存让重复的上下文变得更便宜,但它不会让一个臃肿的 session 变得免费。一天中晚些时候的一条一行后续回复,仍然可能承载着 Claude 之前读取、运行和讨论过的所有内容的重量。
这很重要,无论你是按 API token 计费还是使用 Pro、Max、Team 或 Enterprise 订阅。API 用户看到的是直接账单。订阅用户消耗的是配额而不是按 session 显示的标价估算,但工程问题是一样的:浪费的 context 会更快达到限制,留给有用工作的空间就更少。
Anthropic 表示,Claude Code 在企业部署中平均每位开发者每个活跃日约花费 $13,90% 的用户低于每个活跃日 $30。这不是对你账单的承诺;仓库大小、模型选择、自动化程度和工作方式差异巨大。这只能证明成本是一个值得工程化处理的运营变量,而不是看不见的副作用。
在追踪了实际消耗量的来源后,我发现了十个比从 prompt 里省字更重要得多的习惯。
不要把一个 session 当作永久工作空间。在不相关的任务之间运行 /clear。
不要默认以最大努力运行最大模型。从 Sonnet 中等或高努力开始;只在真正需要艰难判断的时候才升级。
不要把 CLAUDE.md 写成百科全书。保持通用指令简洁,把专用工作流放到 Skills 或路径作用域规则里。
不要把模糊的 prompt 误认为高效的 prompt。要明确范围:结果、文件、约束和验证目标。
不要把原始日志和测试输出倾倒到主 context 中。过滤它们,或把冗长的工作隔离到子 agent 中。
不要因为装了就加载每个集成。保持 MCP Tool Search 开启,禁用未使用的服务器,在 CLI 能完成任务时优先用它。
不要为了装饰而派生 agent。每个独立的 agent 都有它自己的 context 和成本。
不要意外破坏你的 prompt-cache 优势。避免不必要的模型切换、禁用缓存的 flag,以及恢复巨大的过期 session。
不要为模型支付重复确定性工作的费用。把稳定的转换和强制检查放到脚本、hook 和代码智能工具里。
不要等到最后才发现 Claude 走了弯路。早 interrupt,给它一个可执行的完成定义。
这十条背后的原则很简单:
Token 应该用来买决策,而不是买重复。
Claude Code 不是一个只接收你最新一句话的聊天机器人。一个请求可以包含:
一个实用的简化模型是:
$$ \text{任务成本} \approx \sum_{i=1}^{n} (I_iR_i + W_iR_w + C_iR_c + O_iR_o) $$
其中 $I_i$ 是未缓存输入,$W_i$ 是缓存创建,$C_i$ 是缓存读取,$O_i$ 是输出(包括计费的 thinking),每个 $R$ 是你的模型和提供商的相关费率。
你不需要手动计算这个。重要的是这个求和。Session 不是付一次 context 的钱。它在一系列请求中处理 context。Prompt 缓存可以显著降低重复前缀的价格,但一个大的缓存前缀仍然以缓存费率消耗用量,而缓存未命中可能迫使该前缀以未缓存费率重新处理。
在改变任何东西之前,先检查实际情况:
/usage
/context
/insights
/usage 显示 session 的 token 总数和模型归属。在订阅计划上,它还可以将近期用量归因到 Skills、子 agent、插件和各个 MCP 服务器,并在长 context 或缓存未命中至少占近期用量 10% 时标记这些行为。用 d 和 w 切换最后一天和一周。
/context 显示当前 context 窗口中占用空间的内容:memory 文件、工具和对话内容。/insights 分析你的本地 session 历史,写出一份关于模式和摩擦点的 HTML 报告,而不仅仅是 token 总数。
先测量。否则成本优化就变成了另一种 prompt 迷信。
这是最大的泄漏,因为它让其他所有泄漏都反复发生。
你打开 Claude Code 来修复认证。然后你问了一个部署错误。然后你审查了一个 pull request。然后你又回到认证。这个 session 感觉很方便,因为 Claude "了解这个项目"。实际上,context 现在包含了几个任务、命令输出、被放弃的假设,以及不再重要的文件。
Anthropic 称之为 kitchen sink session。它活得越久,无关的历史就越多地搭在每个请求上。当有用的约束与陈旧材料竞争时,模型性能也会下降。
把 session 当作一个分支:一个连贯的工作流,而不是一个永久的仓库。
/rename oauth-refresh-fix
# 在任务上工作,然后在切换话题之前:
/clear
给 session 命名让你以后可以用 /resume 找到它。清除则启动一个全新的 context 并重置 /usage 显示的 session 总数。
根据情况使用正确的重置:
这里有一个微妙的成本细节:/compact 必须读取它要总结的对话,所以压缩一个巨大的 session 本身就是一个大请求。当连续性不重要时,/clear 既更干净也更便宜。
我的规则很直接:如果下一个任务值得一个不同的 git branch,它就值得一个不同的 Claude context。
使用最强的模型感觉更安全。如果 Opus 或 Fable 更有能力,为什么要整天开着它?
因为能力和努力是两个独立的成本倍增器,而且大多数编码步骤不需要两者都拉满。
当前的 Claude Code 模型别名明确表达了各自的预期角色:
努力控制着模型应用多少自适应推理。较低的努力对直接的工作更便宜更快。更高的级别花费更多 token 来追求和检查各种可能性。Anthropic 警告说,max 可能出现收益递减和过度思考,所以它应该被测试而不是被当作通用默认值采用。
从可靠完成任务的最低模型和最低努力级别开始,然后根据证据升级。
/model sonnet
/effort medium
对于一个困难的架构变更:
/model opusplan
/effort high
对于一个异常困难的推理步骤,在那里使用昂贵的模型,而不是在周围的机械性工作上。
有一个重要的例外。一个更便宜的模型在反复失败的尝试中苦苦挣扎,可能比一个更强壮的模型快速解决硬节点花费更多。优化目标是每个已完成任务的成本,而不是每个 token 的价格。
当 Claude 遇到困难时,问一个诊断问题:
它是因缺乏能力而失败,还是因缺乏 context、努力或验证器而失败?
只有第一种失败才自动证明需要更大的模型。
还要记住,中途切换模型不是免费的。Claude Code 会警告,因为下一个响应在读取对话时没有旧模型的缓存 context。要有意识地使用模型路由,特别是在大型 session 的后期。
CLAUDE.md 很强大,恰是因为它会自动加载。这也是它可能变得昂贵的原因。
每一条通用编码规则、历史解释、API 教程、目录列表和"值得了解"的注释,都会在每个会话开始时占用上下文。然后文件会被携带到可能根本不需要大部分内容的工作中。
问题不仅是 token 消耗。Anthropic 的文档指出,膨胀的 CLAUDE.md 文件可能导致 Claude 忽略你真正在乎的指令。更多的规则反而可能带来更少的遵循。
每个 CLAUDE.md 文件应控制在 200 行以内,只保留必须塑造几乎每个任务的事实:
其余全部移到与其作用域匹配的机制中:
定期运行这些命令:
/context
/doctor
/context 确认加载了哪些 memory 文件。当前版本的 Claude Code 可以使用 /doctor 通过删除 Claude 可从仓库推导的细节,来为已提交的 CLAUDE.md 文件提出精简建议。
一个陷阱:将长 CLAUDE.md 拆分为使用 @path 导入的文件可能改善组织,但导入的内容仍在启动时加载。它不会减少上下文。Skill 和路径作用域规则则不同,因为它们只在相关时才加载。
对于 CLAUDE.md 中的每一行,问自己:
删除这条会导致 Claude 反复出现代价高昂的错误吗?
如果答案是否,就删除它,或将它移到更接近需要它的工作的地方。
"改进这个代码库"是一个搜索半径极大的短提示。
Claude 必须先弄清楚"改进"是什么意思,检视仓库的广泛部分,选择自己的优先级,并猜测你会接受什么。这种探索会填满上下文。如果它的猜测与你的不同,纠正已经在代价高昂的部分发生后才会开始。
一个具体的提示可能包含更多输入 token,但通过消除搜索和返工来减少总任务 token。
给 Claude 四样东西:
修复登录 bug。
用户访问令牌过期后被重定向回登录页。
从 src/auth/tokenRefresh.ts 开始,遵循现有的 session 模式。
写一个针对 refresh-token 轮换的失败测试,进行最小的修复,
然后运行聚焦的 auth 测试套件。不要改变公共 session API。
这个提示更长。任务更便宜。
同样的原则适用于规划。Plan 模式防止在模糊的、多文件修改上代价高昂的返工,但规划本身也有开销。Anthropic 的指导非常务实:如果你能用一句话描述 diff,就跳过规划。当方法不确定、变更跨越边界或代码不熟悉时,使用探索和规划。
效率不是最少的话术,而是不确定性最小化。
冗长的工具输出是使干净会话变成垃圾场的最快方式之一。
10000 行的日志可能只包含 20 行有用的内容。完整的测试套件可能产生大量成功的输出,而 Claude 只需要三个失败。文档爬取可能在找到一条相关约束前读取了十页。如果所有这些都进入主对话,它们就会保留下来,被后续请求携带。
在模型看到数据之前先过滤。
# PowerShell:保留错误和少量周围上下文
Get-Content .\app.log |
Select-String -Pattern 'ERROR|FATAL|Exception' -Context 2,5 |
Select-Object -First 100
优先使用聚焦的检查:
只运行失败的 auth 测试文件。报告失败的测试名称、
第一个相关的堆栈跟踪,以及可能的共同根本原因。
不要返回通过测试的输出。
对于高容量操作,在 subagent 中隔离噪音:
使用一个 subagent 来运行完整测试套件。将原始输出保留在那个上下文中,
只返回失败的测试、相关错误和使用的命令。
Anthropic 明确建议对测试运行、文档获取和日志处理使用 subagent,因为只有摘要返回主对话。
对于反复出现的情况,用 hook 或脚本使过滤具有确定性。一个从测试输出中提取失败的 hook,花费普通计算来在每次运行时节省模型上下文。这是一笔划算的交易。
这里有一个更广泛的教训:模型应该接收信息,而不是被信息淹没。
MCP 使 Claude Code 变得极其有用,但一个集成并不因为你没用它就免费。
Claude 需要足够的信息来知道工具存在以及何时使用它们。现代 Claude Code 通过 MCP Tool Search 减少这种开销:工具 schema 默认延迟加载,初始只加载工具名称和 server 指令,只有当 Claude 发现并使用相关工具时,完整的定义才进入上下文。
这种优化可能被配置或习惯所破坏。
首先,保持 Tool Search 启用。除非你刻意想要每个 schema 都预先加载,否则不要设置这个:
ENABLE_TOOL_SEARCH=false
如果你使用自定义网关,在强制启用该功能之前,验证它支持 Tool Search 所需的 tool_reference 块。
其次,检查并禁用当前项目不需要的集成:
/mcp
/context
/mcp 面板可以在不删除配置的情况下关闭一个 server。/context 显示工具是否占用了有意义的空间。
第三,避免在 MCP server 上设置 alwaysLoad: true,除非它的工具确实需要在每个回合都可见。该选项故意绕过延迟加载。
第四,优先使用存在的聚焦 CLI。Anthropic 的成本指南称 gh、aws、gcloud 和 sentry-cli 等工具比等效的 MCP 集成更具上下文效率,因为它们不添加每个工具的列表。一个命令也可以精确返回 Claude 需要的字段。
最后,控制工具输出。Claude Code 会在 MCP 结果超过 10000 token 时发出警告,对于没有声明自己结果大小限制的工具,默认上限为 25000 token。把那个警告当作设计信号。用分页、过滤或更改 server 来返回紧凑的结果,而不是本能地提高上限。
广泛安装,狭窄加载。
"使用五个 agent"听起来很高级。有时候确实如此。有时候是五个独立的上下文窗口来解决一个小问题。
每个非 fork 的 subagent 都是全新启动。它需要系统提示、任务消息、工具,通常还有 CLAUDE.md 上下文,然后才能做有用的工作。Agent 队友各自维护自己的上下文,并持续消耗 token 直到退出。Anthropic 估计 agent 团队在 plan 模式下运行时,token 消耗可能是标准会话的约 7 倍。
并行减少墙上时钟时间,但不自动减少 token 使用。
在隔离产生具体价值时使用 subagent:
在以下情况下留在主对话中:
为可重复的 worker 明确路由模型:
---
name: log-triage
description: 在冗长的应用日志中查找根本错误
tools: Read, Grep
model: haiku
effort: low
maxTurns: 6
---
一个容易被忽略的当前版本细节:内置的 Explore agent 现在继承主对话的模型,而不是总是使用 Haiku。如果你的主会话运行的是一个昂贵的模型,而探索不需要它,就定义一个聚焦的自定义 explorer 并设置 model: haiku,或者在 Sonnet 上启动主工作。
对于团队,保持名单精简,使派生提示自包含,优先为普通队友使用 Sonnet,并在工作完成后关闭 agent。
正确的问题不是"我能并行化这个吗?"而是:
独立的上下文是否足以改善质量或保护主上下文,来证明其启动和协调成本是值得的?
提示缓存是 Claude Code 最重要的隐形优化之一。重复的前缀,如系统指令、工具定义和对话历史,可以按较低的缓存速率读取,而不是每次都作为新输入处理。
但缓存有边界。
根据 Claude Code 当前的计费文档:
订阅会话的缓存生命周期通常为一小时;
当订阅用量转为使用量积分时,生命周期会降至五分钟,除非设置了 ENABLE_PROMPT_CACHING_1H=1;
API key 和云服务商会话默认五分钟;以及
长时间间隔后的第一条消息可能丢失缓存并重新处理大量上下文。
Claude Code 还会在活跃会话中切换模型时发出警告,因为下一条回复会重新读取完整历史记录,而没有前一个模型的缓存上下文。
除非正在诊断特定的兼容性问题,否则不要禁用缓存。请检查环境中是否有以下标志:
DISABLE_PROMPT_CACHING
DISABLE_PROMPT_CACHING_HAIKU
DISABLE_PROMPT_CACHING_SONNET
DISABLE_PROMPT_CACHING_OPUS
DISABLE_PROMPT_CACHING_FABLE
在上下文保持"热"的状态下批量处理相关工作。避免在大型会话中来回切换模型。长时间间隔后,问自己是否需要完整的对话记录,或者摘要式会话或全新会话是否更合适。
在 Pro 和 Max 计划中,Claude Code 可以主动从摘要恢复大型陈旧会话,从而防止后续请求携带完整历史。当对话的具体细节不再重要时,请使用此功能。
最重要的是,不要混淆"已缓存"与"免费"。缓存让稳定上下文更便宜,但这不能成为永远保留无关上下文的理由。
最好的缓存策略仍然是范围清晰、会话稳定的前缀。
模型擅长在不确定性下做出判断。它们是确定性管道的昂贵替代品。
如果 Claude 反复读取同一个巨大的日志文件,反复发现同一个构建命令,反复重新格式化同一个输出,反复检查同一个禁止路径,或者反复推理同一个发布清单,你正在花费 token 来重建你的仓库本可以一次性编码的流程。
将稳定行为提升到对话之外:
使用脚本处理确定性转换;
使用钩子处理每次必须运行的检查;
使用 Skill 处理需要模型判断的可复用工作流;
使用 CLAUDE.md 提供简洁的通用指导;以及
使用代码智能插件进行符号导航和自动诊断。
例如,不要反复告诉 Claude 用 grep 读取 monorepo 直到找到某个定义。支持语言服务器的代码智能插件可以直接跳转到精确符号,并在编辑后显示类型错误。一次结构化查询可以替代多次搜索和候选文件读取。
不要反复问"记得在编辑后运行 linter"。指令只是建议性的。PostToolUse 钩子可以自动运行它。同样,PreToolUse 钩子可以在进入模型上下文之前过滤掉一万行的命令结果。
有用的分界线:
每条重复出现的指令都是编译到 harness 中的候选项。
最痛心的 token 浪费是本不该继续的工作。
Claude 选择了错误的抽象,开始编辑错误的包,或者误解了用户流程。你等着,因为也许它会恢复。十个工具调用之后,你才解释问题。Claude 现在必须理解你的纠正,同时携带失败的方法、它的输出以及它沿途打开的文件。
然后任务在没有任何可执行检查的情况下到达终点。Claude 说完成了,你发现问题,第二个修复循环开始了。
按 Esc 停止当前操作,同时保留上下文;
使用 /rewind 恢复对话、代码或两者;
如果你已经两次纠正了同一个问题,使用 /clear 并用更好的提示重启;以及
增量测试,以便在引起失败的编辑附近发现错误。
Anthropic 的最佳实践指南指出,一个干净的会话配合更精确的提示"几乎总是"胜过被反复纠正污染的长会话。
然后给 Claude 一个可执行的完成定义:
Implement the refresh-token fix. Run the focused auth tests and typecheck.
Do not stop until both commands exit successfully. Report the commands and
their final results, not an assertion that the change should work.
验证可以节省 token,因为它缩短了错误与证据之间的距离。一个针对性的测试、构建退出码、linter、输出 fixture 或浏览器截图可以闭合反馈循环,而不需要等你以后才发现遗漏。
对于无人值守的工作,提高关卡的强度:
使用 /goal 保持任务开放直到满足某个条件;
使用 Stop 钩子进行确定性检查;
使用新的 subagent 进行对抗性审查;或者
当多个独立检查确实必要时,使用工作流。
验证器不是多余的仪式。它是阻止昂贵返工逃逸出当前循环的机制。
我的低损耗 Claude Code 操作系统
如果你想把整篇文章压缩成一个可执行的工作流程,请使用这个。
任务开始时
启动一个全新的或正确命名的会话。
除非任务已经表明需要更强的能力,否则使用 Sonnet。
对于范围明确的工作设置中等努力程度,对于真正复杂的工作设置高努力程度。
给 Claude 一个锚点、预期结果、约束条件和验证目标。
只有当不确定性或影响范围合理时才使用计划模式。
关注方向,而不是每一个按键。
一旦方法明显错误,立即按 Esc。
在小批量编辑后运行针对性检查。
将详细日志、文档和广泛搜索发送到过滤后的命令或 subagent。
使用 /btw 处理一次性的附带问题。
当用量令人惊讶时,运行 /usage 和 /context。
在清除之前命名有用的会话。
使用 /clear 处理不相关的工作;不要把昨天的上下文拖到今天的任务中。
将反复发现的内容转化为简洁的记忆、Skill、脚本或钩子。
精简 CLAUDE.md 并禁用不能证明其永久上下文价值高于成本的集成。
默认姿态不是"尽可能少花费"。而是在判断力重要的地方深度投入,在重复性工作的地方几乎零投入。