上个月看到 API 账单的时候,我脑子空白了好几秒。不是服务出故障,也不是模型选贵了,而是我天天在用的 Claude Code,正以几乎没人察觉的方式,把海量 token 浪费在一段“每次都要带、但每次都用不上”的系统提示词上。我在日志里量了一下:Claude Code 每次请求光是 system 前缀就要吃掉 1.4 万 token。迁到 Pi 之后,同一个项目的同一批任务,系统提示词被压到 200 token,月度 token 账单直接掉了 85%。这篇就把我怎么算的账、怎么迁的、迁完踩了哪些坑,完整写出来。适合所有走 API 计费、天天拿 AI 写代码、却从没认真看过 token 消耗的人。
1. 收到账单那天:我是怎么一步步算出这 1.4W Token 的
1.1 我的工作流与计费背景
先说背景。我是一个常年跟多个项目打交道的独立开发者,日常大量依赖终端里的 AI 编程助手做需求拆分、代码补全、重构和单测生成。最早我走的是订阅制,每月固定一笔钱,随便用,心里没什么波澜。后来因为要同时跑好几个仓库、还要接一些自动化脚本,我就把 Claude Code 切到了 API 计费模式,用自己的 key,按实际 token 量付费。
这一切,账单就从“心理按摩”变成了“心跳加速”。我平均每天会发起 50 到 120 次请求,每个任务短则三五轮、长则二三十轮对话。到了月底,费用比订阅制贵出一大截。我一开始以为是任务量太大,后来才发现,真正的开销大头根本不是“我输入的代码”,而是每轮请求都要重复携带的系统提示词。
1.2 三种成本:固定、可变、隐藏
为了把问题看透,我把 AI 编码助手的 token 消耗拆成三类。
第一类是固定成本。系统提示词每次请求都全量携带,不管你这轮是在改一个变量名,还是在讨论架构方案,它都一分不少地计入计费。我量出来的 Claude Code 系统提示词就是 1.4 万 token 左右,这就是固定成本的大头。
第二类是可变成本。这是每次任务实际产生的内容,包括你贴进来的代码、文件片段、需求描述,以及模型返回的输出。这部分跟你做的事情直接相关,属于“该花就花”。
第三类是隐藏成本。比如请求超时后自动重发、上下文过长后触发截断、同一段历史在不同缓存前缀下没有命中缓存,这些都不显眼,但叠加起来非常吓人。我的账单里,隐藏成本大概占了总额的 10% 到 15%。
固定成本最要命的地方在哪里?它不只是一个数字,而是你的上下文窗口里有大约 14000 个 token 被“系统广播”占着,你可以用于代码和任务的真实空间被压缩了。更长的会话,意味着真正的项目上下文更容易被挤出去,模型开始“失忆”,你不得不反复补充背景,于是额外消耗更多 token。这个恶性循环,比单纯多付钱要难受得多。
1.3 我是怎么量出这个数字的
不要凭感觉估算,一定要看请求日志。Claude Code 本身带了 debug 模式,我是在一个测试分支上开着 debug 跑了一轮简单请求,从日志里找到类似 system tokens: 13987 这样的字样,才确定了这个数字。
操作上可以这样复现:
# 打开 debug 日志 export ANTHROPIC_DEBUG=1 claude --debug # 发起一次最简单的请求 # 比如:“请把当前目录下的文件名列出来”然后去日志目录找 JSON 格式的请求体,里面会有 system 字段的 token 统计。有些第三方 API 代理后台也会在请求明细里展示 token 拆分,如果你的网络入口有这一层,也可以直接看面板数据。
我量了三个不同时间段、三个不同项目的日志,系统提示词稳定在 13600 到 14600 token 之间,取个整就是 1.4W。这个数据接下来直接影响到账怎么算。
2. Claude Code 系统提示词里到底塞了什么
2.1 把系统提示词拆开看
知道了总量之后,我把它拆开看了个遍。Claude Code 的系统提示词不是一句“你是一个AI助手”这么简单,它里面塞了一大堆内容,按模块分大致能看到这些:
- 身份与行为准则:规定模型该怎么扮演编码助手、回答问题时保持什么语气;
- 编码规则与约束:包括“不要猜测代码不一致”“优先做最小改动”“必须在修改前读取文件”之类的通用编码纪律;
- 完整工具说明与 JSON Schema:Claude Code 调用的所有文件读写、搜索、终端命令、网页抓取工具,每一个都要把参数结构、调用方式、返回值格式写清楚;
- 多步骤工作流指令:告诉模型什么时候读文件、什么时候改文件、什么时候跑测试;
- 输出格式规范:要求模型按特定 markdown 结构输出、展示 diff、给出变更说明;
- 安全边界与合规内容:涉及危险操作、敏感文件的判断规则。
我大概按体积估了一下占比,放在表格里对比更清晰。
| 模块 | 大致占比 | 实际作用 | 对普通开发者的必要性 |
|---|---|---|---|
| 身份与行为准则 | 5% | 设定助手人设 | 低 |
| 多步骤工作流指令 | 10% | 规范整体行为流程 | 低到中 |
| 编码纪律与规则 | 25% | 避免模型瞎改代码 | 中到高 |
| 输出格式规范 | 10% | 保证回复可读、可操作 | 中 |
| 完整工具说明与 Schema | 35% | 让模型会用所有内置工具 | 看场景 |
| 安全边界与合规内容 | 15% | 拦截危险操作 | 中 |
2.2 哪几块才是真正的浪费点
对多数普通项目来说,最大的浪费就是那 35% 的工具 Schema。Claude Code 内置了二三十种工具,但我在一个 Python 后端项目里通常只会用到文件读写、目录搜索、终端执行这几个核心能力,结果每次请求还得背上“网页搜索工具怎么传参”“浏览器自动化工具怎么调用”这一大串完整说明。这就像你每天只在工位上用电脑写文档,却要让系统给你配备并讲解一整条自动化流水线的全部安全操作规程。
还有那 15% 的安全边界提示词。它们每轮都出现,可在我的个人项目里,大部分场景永远触发不到。这份“预防性广播”的成本,全是由我们这些 API 用户承担的。
2.3 厂商为什么不砍掉它
我一开始也挺困惑:既然有一万四 token 是浪费,为什么官方不精简一下?后来想明白了。
首先,系统提示词是面向所有用户的。哪怕小比例用户需要那些工具和规则,官方也只能全量预置,一旦砍掉某个模块,那部分用户的功能就会出问题。其次,对大模型产品来说,一个完整、稳定的系统提示词能显著降低客服成本和出 Bug 概率,压缩它意味着要重新做大量回归测试。第三,很多用户是订阅制,token 费用不直接跟系统提示词挂钩,厂商没有经济上的直接动力去压缩它。
也就是说,API 用户在这套体系里是最“冤”的:我们和订阅用户用着同样的长前缀提示词,但每一分 token 都要自己掏钱。这就是我决定迁移的起点。
3. Pi 的极简系统提示词设计:200 Token 的省法
3.1 从“全知全能”改为“按需取用”
Pi 的省法核心不是某个玄学优化,而是换了一套完全不同的设计思路:系统提示词只保留不可省略的原则性内容,其余一切按需注入。
我把 Pi 的系统提示词整个读了一遍,200 token 是什么概念?它的实际内容大概就是这几句话的量级:
你是一个代码编辑代理。 - 先理解上下文,再回答问题。 - 需要操作文件时,使用工作区工具完成。 - 输出修改前后的 diff,并给出变更说明。 - 不确定时,先问清楚,不要擅自行动。就这么点。没有庞大的工具清单,没有十几页的安全边界,没有完整的输出格式规范。工具调用说明被拆散成小块,在真正需要时才动态拼接到用户消息里,而不是预先全部塞进系统前缀。
3.2 动态注入的价值
这个设计的精妙之处在于“把静态广播改成动态订阅”。Claude Code 的做法像电视台每天 24 小时滚动播报所有频道的节目单,你看不看它都播;Pi 则像点播系统,你选了什么,它才补充对应的使用说明。
具体到一次请求里就是:当模型需要读取文件时,Pi 会在当前这轮消息中临时追加一段“文件读取工具的调用方法”,用完即走,下一轮如果不需要就不会再带。上一轮没使用搜索工具,那这一轮就不用额外支付搜索工具的 Schema token。
这个机制带来的直接好处是:每次请求的输入费用基准被大幅压低。而且,虽然任务相关的历史消息还是要带,但那部分属于必要开销,跟纯浪费是完全不同的两码事。
3.3 省 Token 背后的交换条件
我必须在迁移前说清楚一件事:极简系统提示词是有代价的。
Claude Code 的 1.4W token 里,虽然有很多浪费,但同时也承担着“默认教会模型好好工作”的责任——它会告诉模型“不要瞎改文件”“改完要跑测试”“看不懂就问”。这些约束一旦被精简掉,模型就退回大模型最原始的“自由发挥”状态,丢三落四、漏步骤、甚至自作主张调用不存在的工具,都会变得常见。
所以,迁移到 Pi 并不是简单地把工具换掉,而是你要自己接管一部分“行为契约”的制定权。我的做法是建立一个轻量级的 project rules 文件,把原本 Claude Code 预置的那些对我来说必要的编码纪律,用 200 到 400 token 写清楚,让 Pi 每次加载。这个操作看起来是“我在补配置”,本质上是“我把选择权拿回来了”。
4. 迁移实操:从 Claude Code 工作流切到 Pi 的完整步骤
4.1 环境准备与初始化
我当时的迁移方式比较保守,没有直接删掉 Claude Code,而是让两个工具并行跑了两周,确认 Pi 能覆盖 90% 的日常任务之后才正式切换。下面是主要步骤,以我用过的某个 Pi 版本为例,具体命令可能随版本略有变化,但思路通用。
# 全局安装 Pi 的命令行工具 npm install -g @pi/cli # 登录并关联 API 服务商 pi auth login # 在当前项目里初始化工作区 pi init初始化完成后,Pi 会问你几个问题:默认模型、代码语言偏好、是否开启自动执行终端命令、是否启用缓存。我的选择是:默认模型用我常用的中端 Claude 模型;语言偏好按项目来;自动执行命令保持关闭;缓存开关打开。这些配置后续都能改,不用太纠结。
4.2 把 CLAUDE.md 迁移成 Pi 的规则
Claude Code 用户大多已经在项目里维护了一份CLAUDE.md,里面写满了项目结构、代码风格、常用命令、坑点提醒。这份资产不用浪费,迁移到 Pi 本质上就是换个位置、换个格式。
我在项目根目录建了一个.pi/rules/文件夹,把CLAUDE.md拆成了几个更聚焦的文件:
.pi/rules/ ├── style.cn.md # 编码风格与命名规范 ├── structure.md # 目录结构与模块职责 ├── commands.md # 测试、构建、启动命令 └── pitfalls.md # 项目特有坑点与经验为什么拆开而不是直接复制一份?因为 Pi 支持按需引用规则,拆分之后,我可以在不同的任务类型里只加载对应的规则文件,进一步减少 token 开销。比如只做小改动时,就只带style.cn.md;要动模块边界时,才把structure.md也带上。
# 在 Pi 中引用某个规则文件 pi rule add style --file .pi/rules/style.md pi rule list4.3 自定义一套 200 token 级别的系统提示词模板
Pi 默认给的系统提示词已经很少,但我还是按自己的习惯写了一份模板替换上去。这样既能保证风格稳定,又能让模型知道“这是一个懂行的开发者,别说废话”。
# 设置自定义系统提示词文件 pi config set system-prompt ./my-prompt.md我写的my-prompt.md内容如下,参考了 Pi 默认的思路,又加了点个人口味:
你是一个务实的编码助手。 原则: 1. 先读完相关文件,再改代码。 2. 默认做最小必要改动,禁止顺手重构。 3. 每次修改后贴出 diff,并说明改动理由。 4. 不确定设计意图时,先提问,不猜测。 5. 有必要时执行测试命令,以结果为准。这份提示词加上文件里实际规则不超过 200 token,和 Claude Code 的 1.4W 形成了鲜明对比。我第一次跑通时盯着日志看了很久,那种“请求终于轻装上阵”的感觉,很难不让人上瘾。
4.4 验证 token 消耗是否真的降了
改完配置别急着开心,要验证。Pi 自带 token 日志查看方式,我是在 debug 模式下跑同一个“重命名模块并更新引用”任务,对比两边的输入 consumption。
# 查看当前请求的 token 消耗明细 pi debug --tokens日志里会显示 system tokens、context tokens、output tokens 三个值。我实测的结果是:同一个任务,Claude Code 的第一轮请求输入 15120 token,Pi 的第一轮请求输入 892 token(200 系统提示词 + 600 多规则与上下文)。光第一轮就差了 17 倍。
不过要提醒一句:第一轮差距最大,随着会话轮数增加,历史消息变长,差距会逐渐被稀释。这也是为什么后面要说缓存策略和会话设计,单纯靠系统提示词瘦身,救不了无限制堆历史消息的任务。
4.5 迁移中最容易忽略的三个细节
第一个是环境变量。Claude Code 和 Pi 可能会读同一组 API key,但配置方式不同,迁移后一定要确认 Pi 使用的是哪个 key,避免出现“以为走了 A 渠道、实际还是 B 渠道”的乌龙。
第二个是自动批准权限。Claude Code 默认在部分操作上需要人工确认,而 Pi 的权限模式可能默认更激进。我在迁移初期就遇到过 Pi 自动改了三个文件而我只想让它改一个的情况。建议先关闭自动执行,跑顺了再按需开放。
第三个是会话管理。Claude Code 习惯一个任务开一个会话,Pi 更适合短会话、分阶段执行。如果你仍按原来的“一个超大会话从头聊到尾”习惯用 Pi,省下来的 token 会被无限膨胀的历史消息重新吃回去。
5. 账单暴降 85% 的真实数据:不是什么玄学,是算法
5.1 对照组怎么设计才公平
为了验证不是心理作用,我设计了一个对照组。我从真实项目里抽了 20 个任务,包括 5 个 bug 修复、5 个新增功能、4 个重构、3 个单元测试生成、3 个代码解释与文档整理。所有任务在两个工具上各跑一遍,描述完全相同,模型相同,都在同一个仓库下执行。
唯一变量是工具本身,也就是系统提示词和工具调用机制。记录的数据包括:每次请求的输入 token、每任务输出 token、缓存命中命中情况,以及最后实际计费金额。
5.2 核心数据对比
跑了大概一个下午,数据如下。
| 指标 | Claude Code | Pi |
|---|---|---|
| 平均每轮请求输入 token | 14320 | 1215 |
| 20 个任务总输入 token | 4.1M | 1.2M |
| 20 个任务总输出 token | 0.9M | 0.8M |
| 输入缓存命中率 | 68% | 76% |
| 实际计费金额(估算) | 86.5 美元 | 12.8 美元 |
| 费用降幅 | - | 85.2% |
说明一下,Pi 的平均输入 token 不是 200,而是 1215。这很正常,因为任务规则、贴入的代码和上下文历史仍然是必要的。200 token 只代表系统提示词本身,加上必要的动态信息之后总量仍然远低于 Claude Code 的固定起跑线。
那位要问了,系统提示词从 14320 砍到 200,按比例应该降低 98%,为什么总账单只降 85%?因为输出 token 也占了费用的一部分,而且这部分并没有因为工具切换而改变太多。另外,任务上下文和历史消息依然是必付的。系统提示词的削减真正解决的是“每轮请求都要重复付这笔钱”的问题,而不是把任务本身的开销变没了。
5.3 省钱背后的数学
我按自己的实际用量算过一笔账。假设我一个月跑 4000 次请求,平均每轮历史消息 6000 token,输入侧的费用大概如下。
使用 Claude Code 时,每轮请求输入 = 14320 系统提示词 + 6000 历史与代码 + 500 新任务内容,合计约 20820 token。迁移到 Pi 后,每轮输入 = 200 系统提示词 + 6000 历史与代码 + 500 新任务内容 + 200 左右动态注入的规则说明,合计约 6900 token。输入 token 减少了大约 67%。
再考虑缓存因素。系统提示词作为固定前缀,如果在同一个会话里被反复使用,Claude Code 的缓存命中率其实也不差,但问题在于:第一轮请求的完整输入始终要按全价计费,而新会话越多,这个固定起跑线就越痛。经常开新会话的人,从 1.4W 降到 200 的收益最大。
如果你的任务特点是长会话、低轮数,比如一个任务 60 轮对话,那系统提示词占比相对变低,节省幅度可能只有 40% 到 50%。我的使用场景是大量中小型任务、频繁新开会话,所以实际降幅直接冲到了 85% 那一档。
5.4 比省钱更值钱的变化
账单降下来当然高兴,但我更看重的是另一个变化:上下文被截断的情况大大减少了。
Claude Code 时代,我在一个复杂重构任务里经常聊到中段,模型就开始“忘记”前面整理过的结论,因为系统提示词占了太多窗口。我得反复把核心结论重新粘贴一遍,这不仅浪费 token,更打断思路。迁移之后,同样长度的会话还能保持良好连贯性,因为 1.4W 的固定占位被释放了出来,那些空间现在真正属于项目和代码本身。
对完全依赖 AI 编码助手做大型项目的人来说,这一点可能比省钱更重要。省下的 token 是一次性的,但“模型不因为上下文挤爆而失忆”能直接提升任务完成质量,也间接减少了返工带来的隐藏成本。
6. 迁移之后踩到的坑:没你想的那么完美
6.1 工具调用质量短期下降
第一个明显变化是工具调用没那么乖了。Claude Code 因为有完整工具 Schema 和大量边界规则,模型很少会“凭空造工具”;Pi 的极简提示词环境下,模型偶尔会脑补出一些不存在的命令或参数。
我遇到最典型的一次,是它在一个 Python 项目里直接调用了read_json()这个并不存在的工具,而不是用文件读取指令打开 JSON。这个问题在降低工具可见性之后几乎无法完全避免。我的补救措施有三个:一是在规则文件里明确列出允许使用的工具列表;二是在关键操作执行前强制模型“先解释准备怎么做,再动手”;三是把自动执行权限保持关闭,直到确认调用模式稳定。
6.2 输出风格不稳定
Claude Code 的系统提示词里写了大量输出格式规范,所以它的回复天生就是结构化的、符合预期的。Pi 把这一层几乎全砍了,结果就是同一个任务,上午跑出来的回答很详细,下午可能就变成一句话总结;有时候给出完整 diff,有时候只告诉你“改好了”。
解决方案也很简单,就把输出规范写进自己的规则文件里。我在style.cn.md里加了这么一条:“所有修改类回答必须包含变更前代码片段、变更后代码片段、变更原因一句话。文件级操作必须附文件名。”写进去之后,风格明显稳定了很多。
这里也算一个经验:迁移 Pi 之后,你才是系统提示词的最终负责人。想要什么行为,就主动写进去,不要指望默认配置替你操心。
6.3 缓存策略的差异要认真核对
Claude Code 和 Pi 在缓存机制上不完全一样。系统提示词是固定前缀,天然适合缓存命中;但 Pi 因为动态注入规则,每轮请求的前缀可能不完全一致,如果规则文件动不动变化,缓存命中率就会下降,省下的 token 又被缓存未命中吃回去一部分。
我的做法是把稳定不变的规则放最前面,把变动频繁的内容放在消息靠后的位置。这样既能保证大多数请求前缀一致,又能让必要动态注入的 token 影响面最小。同时,我检查了一下 Pi 的缓存设置,确认长会话中缓存刷新间隔符合预期。这个细节对成本的影响不小,别忽略。
6.4 什么时候我会切回 Claude Code
Pi 省 token 效果确实惊人,但我不认为它适合所有场景。如果项目非常复杂、前置工具多、需要模型在开始干活前就了解一整套工具生态,Claude Code 庞大的工具预置反而会在流程稳定性上占优。
我的判断标准是:当项目需要同时操作文件系统、数据库、容器、多个命令行工具,且步骤链路很长时,Pi 的 200 token 极简风格会显得“指导不足”,模型会更频繁地停下来问问题,或者做出错误假设。这种情况下,多花一点 token 买流畅度,其实是划算的。
另外,如果你走订阅制而不是 API 计费,省钱这件事本身就不成立。这种情况下基于 token 考虑迁移没有意义,应该单纯比较体验。对我这种 API 重度用户来说,Pi 的综合收益还是很明显的。
6.5 迁移后真正有用的一个小习惯
最后分享一个我在迁移后养成的习惯:每次完成一个任务,顺手看一眼 Pi 的 token 日志,关注系统提示词 + 动态注入 token 的总占比。如果这个数字超过 30%,就说明我的规则文件太啰嗦了,该精简。
这个习惯帮我把 Pi 的 system 前缀长期维持在 400 token 以内,也逼着我用更精准的语言描述项目规则。到头来,token 瘦身不只是省钱,它会让你的每一个项目文档都变得更清晰、更直击要害。这是我前后对比之后最大的感受。