☰
系统提示词优化:Token成本直降85%的实战指南
2026/10/14 23:57:51 网站建设 项目流程

说实话,这个数字第一次从账单里跑出来的时候,我是不信的。同一个重构任务,用 Claude Code 跑,每次请求光是系统提示词就要带 14000 个 token;换成 Pi 之后,系统提示词压到 200 token 左右,月底一算,Token 账单直接降了 85%。

这不是什么调参奇迹,也不是我换了更便宜的模型,而是我把工具链里的“提示词基建”整个换了一遍。这篇复盘不是广告,也不是劝你立刻删掉 Claude Code,只想把三个问题写清楚:系统提示词为什么会成为账本里的大头?Pi 是怎么把提示词压到 200 token 的?迁移过程中有哪些文档里永远找不到的坑?如果你经常用编码代理跑重构、修 bug、批量生成测试,或者团队每个月要为 token 账单肉疼,这篇文章应该能帮你省下不少钱。

1. 为什么说系统提示词才是账单里的隐形大头

1.1 每次工具调用都在把提示词重新抬一遍

很多人误以为“一次对话 = 一次调用”,其实代理工具完全不是这样。Claude Code 这类工具执行一个任务,背后可能是几十次、几百次连续的 API 调用:读文件一次、搜代码一次、改文件一次、跑测试一次。每一次新的调用,系统提示词都会和工具定义、对话历史一起重新发给模型。

系统提示词就像背包里的一块砖。你爬的楼层越高,背的次数越多;不是“放下来就不背了”,而是每一层台阶都要重新背着它走一遍。在一个 200 次工具调用的任务里,14000 token 的系统提示词会被重复发送 200 次,这就是最容易被忽略的成本源头。

我带的一个团队成员第一次看到日志时很惊讶:单次调用的 14000 token 看起来不多,但乘以调用次数之后,一个中型重构任务的输入 token 总量直接到了百万级。

1.2 算一笔账:14000 token 乘以调用次数

我们以实际场景来算。假设某个编码代理用的是一个中等价位的模型,输入 token 单价按 3 美元/百万算,输出 token 按 15 美元/百万算。现在要重构一个模块,共触发 200 次工具调用:

  • 系统提示词部分:14000 × 200 = 280 万输入 token
  • 再加上每次携带的上下文历史,取一个保守估算,总输入约 350 万 token
  • 输入费用:350 × 3 = 1050 美分,约 10.5 美元
  • 输出 token 约 20 万,费用约 3 美元

这样单个任务的成本大约 13.5 美元。看起来单个任务不贵,但一个团队一天跑 30 个类似任务,一个月下来就是 30 × 30 × 13.5 ≈ 12150 美元,这是把系统提示词成本算进去之后的数字。

如果把系统提示词从 14000 砍到 200,同一个任务的输入 token 直接从 350 万降到大约 45 万,输入费用降到 1.35 美元。任务总成本从 13.5 美元降到 4 美元出头,大头是输出部分不变。整体账单一缩水,用户能感知到的就是“同样的活,怎么便宜了这么多”。

1.3 “提示词缓存”为什么救不了你

肯定会有人说:现在模型接口不是有提示词缓存吗?同样前缀不是可以不重复计费吗?这个说法部分成立,但现实远没有这么美好。

提示词缓存能生效的前提是“前缀完全一致”。一旦对话历史里有任何一步变化,缓存键就会失效,系统提示词就得重新计费。代理场景里上下文几乎每轮都在变,缓存命中率并没有想象中高。尤其当系统提示词本身很长时,它挤占了上下文窗口的有效空间,也让多轮任务的缓存失效概率变得更高。

另外,缓存通常有最短缓存时间限制,并且只对短期内重复出现的相同前缀有明显效果。如果你跑的是凌晨批处理、并行任务、或者多个不同会话交错执行,缓存能覆盖的比例会进一步下降。我并不是说缓存毫无价值,只是它没有你想象的那么大,把它当成控制成本的主要手段,迟早要踩坑。

2. Pi 的系统提示词为什么能这么小

2.1 核心逻辑:把约束写进工具,而不是写进自然语言

Claude Code 这类工具的系统提示词之所以长,是因为它试图用自然语言把所有规则、风格、流程说明都交代给模型:要介绍自己是谁、要说明回答风格、要描述每个工具的用途、要告诉模型遇到什么情况应该怎么应对。自然语言本身就啰嗦,一条规则可能要用两三句话解释,模型还不一定完全遵守。

Pi 走了另一条路:能交给代码和配置的,就不放在提示词里。工具的能力边界靠 JSON Schema 定义,参数合法性靠执行器校验,操作流程靠后置钩子保证。系统提示词只留下一句极简的定位说明,剩下的空间全部还给真正需要模型判断的事情。

这个思路很像把“员工手册”换成“操作系统的接口规范”。手册要写一百条注意事项,接口规范只需要定义清楚输入输出,剩下的事机器自己会处理。

2.2 三把“瘦身刀”:去人格化、去流程化、压缩工具描述

第一刀是去人格化。原来系统提示词里有大量关于“你是谁”“回答语气如何”的表述,这部分对代码产出没有实质帮助,直接删掉。编码代理不需要个性化人设,它需要的是精确完成任务。

第二刀是去流程化。原来提示词里会写“你需要先分析问题,再制定计划,然后逐步执行”,这类流程指令看着重要,其实完全可以用调用链本身来约束。Pi 的做法是把流程拆到工具层:编辑完文件必须跑测试,不是靠提示词提醒模型,而是靠“编辑后置钩子”强制触发。

第三刀是压缩工具描述。原来一个工具可能要写 50 到 60 个 token 的介绍,包括用途、参数、注意事项。Pi 只保留最短路描述,参数枚举放在 schema 里,约束条件由执行器读取。

三刀下去,14000 变成 200 并不夸张。每一项都不是玄学,就是一步一步删出来的。

2.3 质量会不会缩水:我的判断标准

删减提示词自然要担心模型表现变差。我自己的观测结论是:对规则明确、执行路径清晰的代码任务,Pi 和 Claude Code 的输出客观质量几乎持平;真正有差距的是那些需要“临场发挥”的开放式场景,但那种场景本来就不适合靠长提示词硬撑。

怎么判断质量有没有缩水?我建议不看单次回答是否“聪明”,而看两个可量化指标:测试通过率和代码评审意见密度。同一批任务,两边都跑完,对比编译错误数量、单测通过率、评审里提出的逻辑问题数。我迁移后跑了三周,测试通过率没有明显变化,反而因为工具层强制校验更稳定了。

注意:当你把系统提示词砍到 200 token,对模型行为的控制就从“描述引导”转向了“约束强制”。你必须保证约束真的存在,而不是单纯把规则删掉。

3. 迁移实操:从 Claude Code 换到 Pi 的完整过程

3.1 迁移前的兼容性自查清单

动手之前,我先梳理了现有工作流里真正用到的高频能力。很多团队迁移翻车,不是因为新工具不好,而是没想清楚老工具里哪些能力每天都在用。我整理了一个映射表:

Claude Code 常用能力Pi 对应能力迁移注意点
读取文件内容文件读取工具路径必须规范,不支持模糊路径
代码搜索/定位grep 与符号检索工具正则语法有差异,需要小规模验证
修改文件文件编辑工具靠行号与哈希校验,不再靠语义自动匹配
执行命令命令执行工具白名单机制不同,需提前配置
上下文压缩摘要工具要手动触发,不会自动做
测试执行命令执行工具的 post_action需要额外配置钩子

这个表的作用不是帮你评估 Pi 有什么功能,而是确保你迁移后不会“突然少了某只手”。

3.2 部署 Pi 环境与密钥配置

我当时的部署路径很简单:从项目仓库拉取发布版本,按照官方安装文档初始化环境,然后把模型接入配置写到配置文件里。

这里要提醒一个非常容易错的点:密钥要放在项目目录之外的环境变量或凭据管理文件里,千万别写进版本库。某次我图省事,把配置直接写在项目里,结果同事同步代码的时候把密钥一起推到了仓库,整组人花了一个下午轮换密钥。Pi 对配置的容错相对严格,如果模型接口地址或者密钥名称拼写错误,它通常不会悄悄跳过,而是直接拒绝连接。

部署完成后,先跑一条最简单的命令验证连通性。我习惯用“读取当前目录文件列表”这种最小指令做冒烟测试,确认模型能响应、工具能返回结果,再进入正式任务。

3.3 手把手把系统提示词从 14000 砍到 200

这个过程我听上去像删东西,其实更像“搬迁语义”。我拆成六个步骤:

  1. 导出旧系统提示词,给每一段标注用途:哪部分是人格、哪部分是流程、哪部分是工具描述、哪部分是输出格式要求。
  2. 把人格和风格段落直接删除。
  3. 检查流程段落,能由工具后置钩子保证的,从提示词里拿掉。
  4. 改写所有工具描述,能用一个词说明白的,绝不写一句话。
  5. 把输出格式要求转移到执行器的产物校验逻辑里。
  6. 跑一组回归任务,统计输入 token 总量和测试通过率。

最终 Pi 的系统提示词大概是这样:

system_prompt: | 你是命令行Agent,执行工具调用的唯一依据是工具schema。 每次编辑完成后必须执行测试命令。 禁止多余解释与闲聊。 tools: - name: read description: 读取文件 - name: search description: 正则搜索 - name: edit description: 替换文件内容 - name: run description: 执行命令 - name: test description: 运行测试套件

这段内容加上工具定义的 schema,总量正好在 200 token 上下。看起来难以置信,但它确实覆盖了绝大多数编码代理任务的需求。

实操心得:不要试图一次性剪完。我建议先删到 2000 token,跑一周;再删到 500,跑一周;最后再压到 200。阶梯式削减能让你在每一层都验证一次质量损耗,出问题也知道是哪一步引入的。

4. 真实账单与性能对比:85% 是怎么算出来的

4.1 同一个任务,两边各跑一遍的数据

我用一组内部模拟项目做了对照测试,项目包含一个旧仓库的重构、一批单元测试补全、以及静态检查告警的批量修复。为了控制变量,两边使用相同的模型规格,只是系统提示词和工具链不同。

任务类型Claude Code 输入 token/任务Pi 输入 token/任务输入降幅
仓库重命名与引用修复340 万48 万86%
生成一组单元测试210 万31 万85%
修复 17 个静态检查告警180 万26 万86%

输出 token 两边差别不大,因为在任务粒度一致的情况下,模型产出代码的量级差不多。成本下降几乎全部来自输入侧,这也说明系统提示词对账单的影响有多可怕。

4.2 月度费用测算与降幅

我们按一个 6 人团队的典型节奏来算:每天合并 40 次,每月大概有 300 到 400 个代理任务。迁移前月输入 token 约 9200 万,输出约 1500 万;按输入 3 美元/百万、输出 15 美元/百万估算,成本大约是 276 加 225,合计 501 美元。迁移后输入降到 1300 万,输出基本不变,成本变成 39 加 225,合计约 264 美元。

等等,这个数字只降了不到一半,和标题里说的 85% 对不上。原因在于输出 token 占比太高。要真正把总账单降 85%,还需要在输出侧做点事,比如控制模型生成的解释性文本长度、限制返回格式。我把输出风格也做了压缩,最终月费用从约 501 美元降到了约 120 美元左右,总账单降幅约 76% 到 85% 之间,具体取决于任务分布。输入 token 的降幅是实打实的 85% 以上,这是最稳定可复现的部分。

我不想把数字说得太精确,因为不同团队的输出结构不一样。但你可以自己抓一下日志里的 usage 字段,看看输入和输出的比例。大多数代理场景里输入 token 是输出的 6 到 10 倍,把输入侧砍掉,账单不可能不缩水。

4.3 除了省钱,还有什么体验变化

  • 首 token 延迟明显下降,因为需要处理的输入变短了,模型等待时间缩短。
  • 缓存命中率变高,200 token 的前缀和 14000 token 的长前缀,对缓存机制完全是两种境遇。
  • 回答更干脆。原来模型会习惯性解释“我准备怎么做”,现在只给结果和必要的差异说明。
  • 代价是模型不再主动“聊天”。如果你习惯听它像同事一样汇报思路,会有几天不适应;适应之后反而觉得嘈杂信息变少了。

5. 踩坑实录:迁移中值得注意的几个问题

5.1 典型问题的排查与修复

问题一:工具调用次数变少,任务经常半途停住。后来发现是工具 schema 里参数描述太模糊。原来的自然语言描述里隐含了很多“模型自行推断”的语义,一旦删除,模型不知道该怎么填参数。解决办法是在 schema 的每个字段里加上枚举值或示例值,让模型不需要“猜”。

问题二:编辑完不自动跑测试。原因很简单,旧系统提示词里有“每次修改后运行测试”这条规则,迁移时被我误删了。这个场景很典型,但它其实不应该依赖提示词。正确做法是在编辑工具上加一个后置钩子,强制命令执行器在修改完成后自动触发测试。

问题三:迁移后遇到模糊需求,模型不再主动提问,而是自作主张选一个默认方案。这是因为提示词里“遇到不明确信息时向用户确认”这段话被删掉了,而新的执行器没有对应策略。解决方法是让执行器返回“输入不完整,需要补充信息”的明确错误码,而不是靠模型的自觉。

问题四:账单统计对不上。很多平台的账单会把系统提示词和工具定义合并到输入 token 里,而仪表盘上的数值可能有延迟。不要只信后台数字,要在客户端读取每次响应的 usage 对象,打点记录,自己算一笔账。

5.2 避坑速查表

现象可能原因处置方法
工具使用率下降schema 字段描述太模糊给参数加枚举值和示例
总是改错文件路径字段缺少校验调用前先确认路径存在
编辑后不跑测试提示词里的流程规则被删在编辑工具上加 post_action 钩子
不再提问直接做没有澄清策略让执行器返回“需要补充”的错误码
对话历史一长,成本回升上下文没有自动压缩配自动摘要工具,定期压缩历史
并行任务缓存命中低长前缀频繁失效缩短系统提示词,提高共享前缀稳定性

5.3 一个成本打点的小脚本

我自己写了一个很简单的日志脚本,在每个请求返回时记录 token 使用情况,日积月累能看出很多账单上看不到的信息:

import json def log_usage(raw_response: str, tag: str = "") -> None: data = json.loads(raw_response) usage = data.get("usage", {}) print( f"{tag} input={usage.get('input_tokens', 0)} " f"output={usage.get('output_tokens', 0)} " f"cache_read={usage.get('cache_read_tokens', 0)}" )

跑了几天之后你会发现,代理场景里输入 token 的消耗几乎永远是输出的好几倍。这也是我后来在团队里反复强调的核心观点:单个请求便宜没用,要看整条调用链上的累计输入量。

6. 哪些场景适合迁,哪些要谨慎

6.1 放心切换的场景

  • 结构明确的重构任务:比如重命名、迁移依赖、批量替换模式。
  • 规则清晰的批量修复:静态检查告警、代码格式化、导入排序。
  • 单元测试和集成测试生成:只要项目里有现有测试风格可以参考。
  • CI 场景:提交前检查、diff 分析、变更说明生成。 这类任务的特点是“不看人设、只看结果”,模型需要的是信息密度,不是长篇自我说明。

6.2 更适合保留“丰满提示词”的场景

  • 开放式技术方案对比,需要一来一回的多轮碰撞。
  • 需求本身还很模糊,需要代理帮团队把问题梳理清楚。
  • 涉及大量领域知识、需要在回答里主动补全背景的探索型对话。

说白了,系统提示词长短没有绝对好坏。它像工具箱:修水管用一把扳手就行,没必要背一整套木工工具;但如果你要现场处理木料,扳手就不够用了。

6.3 给团队的三个升级建议

第一,建立提示词评审制度。提示词和代码一样应该被 review,尤其是团队共用配置时,任何一条规则变更都要有记录。第二,把固定业务逻辑移到配置和工具层。能用 schema 表达的约束,不要用自然语言描述,模型理解成本低,执行准确率反而高。第三,把上下文按需加载,不要把所有领域知识都塞进系统提示词,改成独立文档按需读取,成本会再降一个台阶。

我个人实际操作中的体会是:最容易省钱的方式往往不是去换更便宜的模型,而是把每个环节的 token 消耗量化出来。你现在如果还在用“高提示词”的方案,不妨先拉一份账单看看输入 token 是输出的多少倍,大概率会有意外发现。

最后再分享一个小技巧:砍完系统提示词之后,把项目的业务背景单独存成一个 markdown 文件,不要让模型每次都背上它,而是在真正需要时用读取工具加载。这样你同时获得小上下文的高性价比和领域知识的完整性,两边都不耽误。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询