你的 AI 账单里,90% 在为别人打工

小岛AI 2026 / 05 / 13

最近 Berry Xia 发了一条推,我看完之后盯着屏幕发了一会儿呆。

他在转述 Andrej Karpathy 的一个观察,大概意思是,你每个月交给 AI 公司的账单里,有 90% 根本就没在帮你干活。

Karpathy 是谁你可能知道,OpenAI 早期研究科学家,特斯拉 AI 总监,神经网络领域做基础研究的那种人,GitHub 在这里,几百万关注,不是爱抖机灵的人。他说这话,是认真的。

原推在这里

然后我想了想,发现这话有点刺痛。

因为 Claude Code 的 token 计数就在那里,每次对话都在涨,我以为这是代价,是用 AI 干活就得交的租金,是进步的成本。但 Karpathy 说,不是的。那 90% 是废气。

所以我认真想了一下,我的账单里,到底烧掉了什么。


先说清楚一件事,不然后面讲不清楚,token 到底是什么。

Token(令牌)是 AI 处理文字的最小计费单位,不是字也不是词,更像是词语被切开的碎片。一个中文字差不多对应 1 个 token,一个英文单词大概 0.7 个 token,具体取决于模型用的分词器。你发给 AI 的每一个字,AI 回给你的每一个字,全部换算成 token 来计费。

所以「上下文」就是你一次对话里发给 AI 看的所有内容的总和,包括你们之前的对话记录、你粘贴进去的代码、你的系统提示、你这次的问题本身,加在一起就是这次请求的「上下文长度」,乘以单价,就是这次对话的成本。

这件事的底层机制是这样的,现在大多数大语言模型用的都是 Transformer 架构(注意力网络,让模型通过让每个词跟其他每个词互相「看一眼」来理解语义关系),在处理你的请求时,上下文越长,这个注意力计算的量是平方级增长的,成本随之上涨。

所以贵不是因为 AI 厉害,是因为你给它看的东西太多了。

这个认知本身挺重要,很多人觉得 AI 贵是命,是这个技术的固有属性。但「贵」的相当一部分来自上下文长度,而长度这件事是可以控制的。命和选择,差距很大。

那 90% 具体浪费在哪几种情况?

第一种,也是最普遍的,叫过度加载文件。

你在用 Cursor 或者 Claude Code 写代码,想改一个函数,然后出于某种「我怕它不知道背景」的心理,顺手把整个 src/ 目录都加进上下文,或者直接让它搜索 Codebase,就怕漏掉什么关键信息。

我理解这个冲动。跟人解释问题的时候,你本能地会想把所有相关背景都交代清楚,给对方一个完整的图景。但 AI 不是同事。同事看了背景之后可以主动过滤,只关注跟问题相关的部分,消化背景的成本由他的大脑承担。AI 不一样,它要对你给的每一行字收费,不管那行字跟你的问题有没有关系。

你想改一个 parseDate 函数,但把 types/、utils/、components/、stores/ 全粘进去了,AI 看了几千行跟日期解析毫无关系的代码,然后给你改了三行函数。那几千行的钱,就这么烧掉了。而且不会让回答变得更好,parseDate 就是个独立的函数,它不需要知道你的整个 Redux store 长什么样。

第二种,是默认开最贵的模型处理所有任务。

Claude Opus 4.7 和 Claude Sonnet 之间的能力差距是存在的,但不是每个任务都需要顶配。「帮我解释一下这个报错信息」、「帮我写个这个函数的单元测试」、「这段代码的变量名能不能改得更清楚一点」,这些任务 Sonnet 完全可以处理,但很多人默认把所有任务都扔给最贵的模型。就像用核弹打蚊子,蚊子确实死了,但代价有点不成比例。

价格差距不是一点点,Opus 4.7 的 API 价格大概是 Sonnet 的三到四倍。如果你 80% 的任务其实不需要 Opus 级别的推理能力,但你一直在付 Opus 的钱,这个差距日积月累就很可观了。

第三种,是 Agent 模式下的重复上下文。

现在很多人开始用 Claude Code 或者 Cursor Agent 模式跑更长的任务,比如「帮我重构这个模块」、「按照这个需求实现这个功能」,AI 会分多步来做,每一步都发一次新的 API 请求。问题在于,每次请求里,它需要把整个对话历史、相关文件、工具调用结果都重新带上,因为 AI 没有持久记忆(Persistent Memory,跨请求的持续记忆),每次请求都是独立的,靠重传上下文来维持「我上一步做了什么」的状态。

如果你的任务跑了 20 步,每步带着 5000 token 的历史记录,那就是 10 万 token 只为了说「我还记得之前发生了什么」。任务越长,这个开销越大。这也是为什么 Agent 模式的账单总是让人觉得「怎么这么贵」。

第四种,也是很多人没意识到的,是「知识重建成本」。

你每次新开一个对话,AI 对你的项目是完全陌生的,你的代码规范、技术偏好、项目架构、你不想让它做的事,它都不知道,你得在对话里重新说一遍。「这个项目用 pnpm」、「测试框架是 vitest」、「不要用 any 类型」、「这个工具函数已经在 /lib/utils.ts 里有了不要重写」,这些话每次开新对话就要说一遍,这是上下文,是钱,是可以省掉的钱。


好,那怎么办。

先说最直接的,精细化控制上下文。

不是说给 AI 的信息越少越好,信息少了 AI 没法工作,回答质量下降,你得重新问,白花了请求的钱还没解决问题,那反而亏了。

是说只给相关的。

用 Claude Code 时,不要 @整个目录,而是 @具体的文件,甚至精确到文件里的具体函数。你想修改 parseDate,就把那个函数的上下文发给它,再附上相关的测试用例,这比把整个 utils/ 目录都发过去精准得多,大概率回答也更准,因为模型的注意力更集中。

Cursor 里类似,@file 尽量精确,避免无目的的 Codebase 搜索,除非你真的不知道问题在哪儿。

需要 AI 理解「项目的整体结构」时,比把所有文件都塞进去更有效的方式,是用文字描述,写一段几百字的项目说明,这个项目是干什么的,用了哪些技术,核心模块怎么分的,重要的约定是什么。这段描述的信息密度比代码文件高得多,能用 300 个 token 传递的信息,如果靠文件内容传,可能要 3000 个 token。

而且这段描述可以固定下来放在配置文件里,每次自动带入,这就引出下一个话题了。


提示词缓存(Prompt Caching),一个存在很久但用的人很少的功能。

它的原理大概是这样,你每次发请求,上下文里有一部分是固定不变的,比如你的系统提示(System Prompt,告诉 AI 它是谁、应该怎么行动的那段文字),比如你的项目背景说明,比如 CLAUDE.md 的内容。这些东西每次对话都要发,但内容几乎一字不差。

提示词缓存让你可以把这部分内容标记为「可缓存」,第一次发时服务端会把这段上下文的计算结果存下来,之后 5 分钟内有同样内容的请求,这段就不用重新计算了,只收很少的「缓存读取费」,大概是正常计算价格的 10%。

Anthropic 的官方文档在这里

OpenAI 有类似机制

实际节省有多大?算一个简单的账,你有一段 2000 token 的系统提示,每天发 60 次请求。如果每次都重新计算,就是 2000 × 60 = 12 万 token 每天。用缓存的话,第一次全价,5 分钟内的后续请求这段只收 10%,也就是 200 token 等价的价格。如果你的使用频率比较密集,节省是很显著的。

Claude Code 在最新版本里会对符合条件的内容自动启用缓存,不需要手动配置。但如果你在自己调 Anthropic API 或者搭 Agent 框架,可以在请求体里手动加 cache_control 参数来指定哪些内容走缓存。

有点子牛逼的一个用法,你可以把一份很长的参考文档(比如你想让 AI 反复查阅的设计文档、代码规范、API 文档)放进缓存,然后反复问关于这份文档的问题,只有第一次是全价,之后 4 分 59 秒内的每次问答,那份文档都只收十分之一的读取费。对于那种「我想把这份文档当知识库来用」的场景,这个功能特别合适。


多模型路由(Multi-model Routing)。

核心思路很简单,不同复杂度的任务,用不同价位的模型。

这是 2025 年开始在工程圈里越来越普遍的一种实践。Karpathy 提到他见过的一种策略,日常代码补全和简单问答用性价比高的模型,真正需要深度推理的任务再上 Claude Opus。对于 AI 使用量大的团队或者个人开发者,这种分层能显著降低成本。

在工具操作层面,Cursor 可以在设置里为不同的任务指定不同的模型,自动补全用轻量模型,复杂推理用旗舰模型。Claude Code 支持 —model 参数手动指定,你可以给不同的场景设不同的命令别名,然后根据任务复杂度自己选。

判断用哪个模型的 heuristic 是,这个任务有「标准答案」吗?有的话,便宜的模型大概率能给出,因为它考的是记忆和检索,不是原创推理。没有「标准答案」、需要综合多角度权衡、或者涉及复杂系统设计的任务,才值得上顶级模型。

代码补全、单元测试生成、变量命名、简单的 bug 解释,这些有标准答案,不需要 Opus。

系统架构设计、性能瓶颈分析、复杂的并发问题排查、「帮我重新设计这个模块让它可以水平扩展」,这些需要真正的推理,Opus 值得。


还有一件事被低估了,就是 CLAUDE.md,或者更泛地说,项目知识文件。

每次新开对话,AI 对你的项目是一无所知的,你需要重新解释背景,这本身是上下文开销,也是效率损失,你得花时间写,AI 得花 token 读,然后才能真正开始干活。

解决方案就是把那些「每次都需要解释的东西」写成一个固定文件,让工具每次自动读取。Claude Code 的这个文件叫 CLAUDE.md,放在项目根目录,官方文档在这里。Cursor 用 .cursorrules 或者 .cursor/rules/ 目录,功能类似。

写什么进去最有价值?优先写那些如果不提 AI 会踩的坑,

「这个项目用 pnpm,不要用 npm 或 yarn 安装依赖」

「测试框架是 vitest,不要用 jest」

「严格 TypeScript,不要用 any 类型」

「数据库查询都封装在 /lib/db.ts,不要在业务层写裸 SQL」

「这个响应格式统一用 /lib/response.ts 里的 createResponse,不要自己拼对象」

这类内容的特点是,它们每次都需要说,说完 AI 就能避开很多低级错误,但如果不说,AI 很可能写出项目里格格不入的代码,你还得返工,白花了那次对话的钱。

好家伙,维护一份这样的文件跟不维护的差别真的挺大,有了它之后对话质量明显提升,不是因为 AI 变聪明了,是因为它知道这个项目的规则了,猜测时间变少,干活时间变多。

而且因为这个文件内容固定,完全可以走上面说的提示词缓存,读取成本接近可以忽略不计,等于白送了这一大块知识。


Karpathy 说「未来的竞争是上下文管理能力的竞争」,这话说得有点大,但里面有一部分是真的。

想象两个人都在用同一套 AI 工具做同一类项目。第一个人,每次对话都把整个代码库塞进去,默认用最贵的模型处理所有任务,没有配置文件,每次都在重新解释项目背景,Agent 任务跑起来账单惊人。第二个人,精确控制上下文范围,维护了一份 CLAUDE.md,简单任务用便宜模型,重复的系统提示走缓存,知道什么时候该上 Opus 什么时候 Sonnet 够用。

一年下来,两个人的账单可能差了十倍不止。但产出的代码质量,假设两个人操作都到位的话,差距没那么大。

这是一种新的效率维度,不是谁用的 AI 最聪明,是谁用 AI 用得不浪费。

这件事让我想起 Unix 哲学里有一条叫「最小惊讶原则」(Principle of Least Surprise),意思是系统的行为应该尽量符合用户的既有预期,不要制造意外。用在这里是个比喻,你给 AI 的请求应该尽量不包含让它分心的东西,让它只处理真正需要它处理的部分。上下文管理,某种程度上就是在对 AI 实践这个原则,你只给它该知道的,它只处理该处理的,账单里就会少很多惊喜。

当然,这不是什么决定胜负的事,AI 工具的单价在持续降低,上下文窗口在持续扩大,今天需要仔细优化的问题,明年可能就不是问题了。

但现在这个时间点,90% 在浪费,这个数字是真实存在的。如果你天天在花这个钱,花十分钟想清楚它到底花在哪,大概是值得的。

至少比刷到账单,然后发一会儿呆要好。