1. 从一次账单复盘说起:为什么我要动系统提示词
去年年底做年度成本复盘的时候,我把几个主力 AI 编程助手的账单拉出来横向对比,结果有点扎心。同样一个中型重构项目,用 Claude Code 跑完整个流程,光输入侧的 Token 消耗就比预期高出一大截。我一开始以为是自己的用法有问题——上下文塞太多、历史对话没清理、文件反复读取。排查了一圈才发现,真正的"隐形大户"是每次请求都要携带的那份系统提示词。
Claude Code 的系统提示词规模在 1.4 万 Token 左右,这个数字意味着什么?意味着你哪怕只问一句"这个函数干嘛的",背后也要先吞掉 1.4 万 Token 的固定开销。按当时主流模型的输入计价,单次请求的固定成本就摆在那里,日积月累下来非常可观。我算过一笔账:如果一天交互 200 次,光系统提示词这一项,一天就是 280 万 Token 的输入量。这个量级下,账单想不涨都难。
后来我把目光转向了 Pi 这个方案。它的系统提示词经过精简后只有 200 Token 左右,从 1.4 万砍到 200,压缩比接近 70 倍。实测迁移完成后,整体 Token 账单下降了约 85%。这个数字不是理论值,是我自己项目里跑出来的真实结果。
这篇内容适合两类人看:一类是正在用 AI 编程助手、但没仔细算过成本账的开发者;另一类是对系统提示词设计、上下文工程感兴趣,想搞清楚"提示词到底该怎么瘦身"的技术同学。我会把迁移的完整思路、每一步的操作细节、踩过的坑都摊开讲,你可以直接照着复现。
2. 系统提示词到底在干什么:先搞懂成本从哪来
2.1 系统提示词的三个核心职责
很多人对系统提示词的理解停留在"给 AI 定个角色"这个层面,其实远不止。一份完整的系统提示词通常承担三件事:
第一是行为约束。告诉模型该怎么做事、不该做什么、遇到边界情况怎么处理。比如"修改文件前必须先读取""不要臆测不存在的 API"这类规则。
第二是工具定义。AI 编程助手要能读写文件、执行命令、搜索代码,这些能力都靠工具描述来声明。每个工具的用途、参数、返回格式都要写清楚,模型才知道什么时候调用哪个。
第三是上下文注入。把当前项目结构、技术栈、约定规范等信息塞进去,让模型"知道自己在哪"。
Claude Code 的 1.4 万 Token 里,这三块都有,而且写得非常详尽。详尽本身不是坏事,问题是大部分内容对大部分请求是冗余的。你改一个 CSS 颜色,不需要知道完整的 Git 提交规范;你问一个语法问题,不需要加载整个工具链的详细说明。
2.2 固定开销的复利效应
系统提示词的成本特点是"固定且重复"。它不像对话历史那样可以裁剪,每一次 API 调用都要完整携带。这就形成了一个复利结构:
| 交互频率 | 单次系统提示词 | 日固定开销 | 月固定开销(按22天) |
|---|---|---|---|
| 50 次/天 | 1.4 万 Token | 70 万 | 1540 万 |
| 100 次/天 | 1.4 万 Token | 140 万 | 3080 万 |
| 200 次/天 | 1.4 万 Token | 280 万 | 6160 万 |
| 200 次/天(Pi) | 200 Token | 4 万 | 88 万 |
看最后两行,同样的交互频率,光系统提示词这一项,月开销从 6160 万降到 88 万。这就是 85% 降幅的主要来源。注意,这还没算上因为提示词变短、模型响应更快、上下文窗口更宽裕带来的间接收益。
2.3 为什么"砍"不等于"删"
这里要澄清一个误区。把系统提示词从 1.4 万砍到 200,不是简单地把内容删掉,而是把静态的、通用的内容,转成动态的、按需加载的内容。
打个比方:Claude Code 像是一个每次出门都把所有家当背在身上的旅行者,不管今天是要去爬山还是去开会。Pi 的做法是,出门只带钥匙和手机,需要什么再回家拿。核心思路是延迟加载和按需注入。
具体来说,原来写在系统提示词里的工具详细说明,改成工具被调用时才返回;原来写死的项目规范,改成从项目根目录的配置文件里动态读取;原来一大段的角色设定,压缩成几句最关键的约束。这样既保住了能力,又砍掉了冗余。
3. 迁移前的准备工作:别急着动手
3.1 先做一次成本基线测量
迁移之前一定要先测基线,否则你根本不知道省了多少。我的做法是选一个典型工作日,记录以下数据:
- 当天总交互次数
- 每次请求的输入 Token 和输出 Token
- 系统提示词占比(这个可以从 API 返回的 usage 字段里拆出来)
- 当天总花费
把这些记在一个表格里,作为对比基准。我用的是一个简单的脚本,每次调用后把 usage 信息追加到日志文件,晚上统一统计。这一步花不了多少时间,但能让你后面有据可依。
提示:如果你用的是按量计费,务必确认计价口径是"输入"还是"输入+输出",两者差距很大。系统提示词属于输入侧,重点看输入单价。
3.2 梳理你真正依赖的能力
不是所有人都需要完整的工具链。我建议你列一张清单,问自己三个问题:
- 我平时用得最多的三个功能是什么?(比如读文件、改代码、跑测试)
- 哪些功能我一个月都用不到一次?
- 哪些"智能"行为其实是我可以手动完成的?
我梳理下来发现,自己 90% 的交互集中在"读代码 + 改代码 + 解释"这三件事上,而 Claude Code 里有一大堆高级工具我几乎没碰过。这些用不到的工具定义,就是纯浪费。
3.3 环境与依赖确认
Pi 的部署相对轻量,但有几个前置条件要确认:
- 运行环境支持你选择的模型接口
- 项目目录结构清晰,方便动态读取配置
- 有一个可以存放精简后系统提示词的位置(通常是一个配置文件或环境变量)
我建议先在一个独立的小项目上试跑,别一上来就在主力项目上动刀。等流程跑通了,再迁移到正式环境。
4. 核心迁移实操:从 1.4 万到 200 的完整过程
4.1 第一步:拆解原系统提示词的结构
要砍,先得知道砍什么。我把 Claude Code 的系统提示词按功能分成了几大块,逐块评估:
| 模块 | 大致占比 | 是否可精简 | 处理方式 |
|---|---|---|---|
| 角色与行为约束 | 15% | 部分可精简 | 保留核心,删掉重复表述 |
| 工具定义 | 45% | 大幅可精简 | 改为按需返回 |
| 项目上下文 | 20% | 可动态化 | 改为运行时读取 |
| 输出格式规范 | 10% | 可精简 | 合并同类项 |
| 示例与边界说明 | 10% | 大部分可删 | 只留高频场景 |
工具定义是最大头,占了将近一半。这部分内容的特点是"写的时候很爽,用的时候很少"。每个工具的完整参数说明、返回值格式、错误处理,加起来就是几千 Token。而实际上,模型在调用工具时,只需要知道"有这个工具、大概干什么、关键参数是什么"就够了,细节可以在调用返回时再补充。
4.2 第二步:重写精简版系统提示词
我的精简版系统提示词控制在 200 Token 左右,结构大致是这样:
你是一个代码助手。规则: 1. 修改文件前先读取内容 2. 不确定的 API 不要臆测,先搜索 3. 保持代码风格与现有文件一致 4. 只做被要求的修改,不擅自重构 可用工具:读文件、写文件、执行命令、搜索。 项目规范见 .pi/config 文件,需要时读取。就这么几句。你可能会问,这么少够用吗?实测下来,对于日常的读写改查场景,完全够。因为模型本身的能力已经很强,系统提示词的作用是"约束"而不是"教学"。你不需要教它怎么写代码,只需要告诉它你的规矩。
关键技巧在于:把原来"教学式"的内容,改成"约束式"的。比如原来可能写了一大段"当你需要修改文件时,应该先使用读取工具获取文件内容,然后分析……",精简后就是一句"修改文件前先读取内容"。意思一样,Token 省了 90%。
4.3 第三步:工具定义的按需加载
这是省 Token 的关键一招。原来的做法是把所有工具的完整说明都塞进系统提示词,Pi 的做法是:
- 系统提示词里只列工具名称和一句话用途
- 工具被调用时,返回详细的参数说明和示例
- 如果模型调用出错,错误信息里附带正确用法
这样,只有真正被用到的工具才会产生"详细说明"的 Token 开销。我统计过,日常交互中平均只会用到 2-3 个工具,相比原来一次性加载十几个工具的完整定义,省下的量非常可观。
具体配置上,我是在 Pi 的工具注册文件里,把每个工具的description字段写得很短,把详细文档放到onCall返回里。这样模型第一次看到的是简版,调用时才拿到详版。
4.4 第四步:项目上下文的动态注入
原来写死在系统提示词里的项目信息(技术栈、目录结构、编码规范),改成运行时从项目根目录读取。我的做法是在项目根放一个.pi/config文件,里面写项目相关的约定:
language: typescript framework: react style: 2空格缩进,单引号 test: vitest系统提示词里只留一句"项目规范见 .pi/config,需要时读取"。这样,只有当模型真的需要了解项目规范时,才会去读这个文件,平时不占用 Token。
注意:动态注入的前提是模型有"主动读取"的能力和意愿。如果发现模型经常忽略这个提示,可以在系统提示词里稍微加强语气,比如"修改代码前必须读取 .pi/config"。
4.5 第五步:灰度切换与对比验证
别一次性全切。我的做法是:
- 第一周:新旧方案并行,同一类任务分别用两套跑,记录 Token 消耗和结果质量
- 第二周:以新方案为主,遇到问题回退到旧方案
- 第三周:完全切换到新方案,持续监控
对比的重点不只是 Token 数,还有结果质量。我当时的记录表大概是这样:
| 任务类型 | 旧方案 Token | 新方案 Token | 质量对比 |
|---|---|---|---|
| 单文件修改 | 1.5 万 | 0.3 万 | 持平 |
| 多文件重构 | 3.2 万 | 0.8 万 | 持平 |
| 代码解释 | 1.4 万 | 0.2 万 | 持平 |
| 复杂调试 | 4.5 万 | 1.5 万 | 略降,需补充上下文 |
可以看到,简单任务省得最多,复杂任务因为需要补充上下文,省得少一些,但整体依然可观。复杂调试那个"略降"是因为精简后模型对项目背景了解变少,需要我手动补充一些信息。这个可以通过在复杂任务前主动喂一段项目说明来弥补。
5. 成本账怎么算:85% 降幅的来源拆解
5.1 直接节省:系统提示词本身
最直接的一块。假设原来系统提示词 1.4 万 Token,现在 200 Token,单次节省 1.38 万 Token。按一天 200 次交互算,一天省 276 万 Token。这是最硬的一块。
5.2 间接节省:上下文窗口的释放
系统提示词占用的窗口变小了,意味着同样的上下文预算下,可以塞更多有用的对话历史或代码内容。反过来说,为了达到同样的效果,你需要的总 Token 更少。这块的节省不好精确量化,但实测下来大概能再贡献 10%-15% 的降幅。
5.3 隐性节省:响应速度与重试率
提示词变短,模型处理更快,首 Token 延迟降低。更重要的是,长提示词容易让模型"迷失",产生不符合预期的输出,导致重试。精简后,输出更聚焦,重试率下降。我自己的重试率从大概 15% 降到了 5% 左右,这部分省下的 Token 也不容忽视。
把这三块加起来,就是我实测的 85% 降幅。注意,这个数字会因使用习惯不同而有差异。如果你交互频率低、任务简单,降幅可能更高;如果你经常做超复杂任务,降幅可能略低,但 60% 以上是稳的。
6. 踩过的坑与排查技巧实录
6.1 精简过头导致能力下降
我一开始砍得太狠,把一些"看起来没用"的约束也删了,结果模型开始自作主张,改代码时顺手重构了无关部分。后来加回了两条关键约束:"只做被要求的修改""保持现有风格",问题就解决了。
经验:精简的是"说明性"内容,不是"约束性"内容。约束是底线,不能省。
6.2 动态读取失败
.pi/config文件有时候读不到,排查发现是路径问题。模型执行命令时的工作目录和项目根目录不一致。解决办法是在系统提示词里明确写清楚配置文件的绝对路径,或者在启动时把路径注入环境变量。
6.3 工具调用参数错误率上升
工具定义精简后,模型偶尔会传错参数。我的处理方式是在工具的错误返回里,附带正确的参数格式和示例。这样模型第一次错了,第二次就能改对,总体 Token 反而更省。
6.4 常见问题速查表
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 模型不遵守约束 | 约束被精简掉了 | 加回核心约束条款 |
| 读不到项目配置 | 路径不对 | 用绝对路径或环境变量 |
| 工具参数传错 | 定义太简 | 错误返回里补充示例 |
| 复杂任务质量下降 | 上下文不足 | 任务前主动补充背景 |
| 节省不明显 | 交互频率低 | 检查是否有其他 Token 大户 |
6.5 一个容易被忽略的细节
系统提示词里的换行和空格也占 Token。我原来写提示词喜欢用大量空行分隔,看着舒服,但每个空行都是成本。精简时把多余空行去掉,又能省一点。这个量不大,但积少成多。
7. 迁移后的日常维护与扩展思路
7.1 建立提示词版本管理
精简后的系统提示词虽然短,但也是代码,需要版本管理。我把它放在 Git 里,每次修改都记录原因和效果。这样万一改坏了,能快速回滚。
7.2 按项目类型准备多套配置
不同项目对助手的要求不一样。前端项目可能更关注样式规范,后端项目更关注接口约定。我准备了几套.pi/config模板,新项目直接复制对应模板,省去重复配置。
7.3 定期复盘 Token 账单
迁移不是一劳永逸。我每个月会看一次账单,对比系统提示词占比、平均单次消耗等指标。如果发现某类任务消耗异常,就针对性优化。
7.4 可以继续深挖的方向
系统提示词精简只是第一步。后续还可以考虑:对话历史的智能裁剪、代码上下文的按需检索、多轮交互的摘要压缩。这些方向每一个都能再挤出一些空间。我目前在做的是对话历史的自动摘要,把超过一定轮数的历史压缩成一段摘要,进一步降低长对话的成本。
我个人在实际操作中的体会是,成本优化的核心不是抠门,而是把资源花在刀刃上。系统提示词从 1.4 万砍到 200,省下的不只是钱,还有每次交互的响应速度和上下文空间。这些省下来的空间,可以用来塞真正有用的代码和需求描述,让助手更懂你在做什么。如果你也在为 AI 编程助手的账单发愁,不妨从系统提示词这一块先动手,投入产出比是最高的。