系统提示词从1.4万字符压缩到200字符的完整复盘

📅 发布时间:2026/10/19 12:57:01
系统提示词从1.4万字符压缩到200字符的完整复盘
1. 从 1.4 万到 200 字符一次系统提示词瘦身的完整复盘第一次看到系统提示词占用 1.4 万字符的时候我的反应和大多数人一样——这玩意儿真的有必要吗直到我把账单拉出来按 token 单价折算了一下才发现每个月花在“系统提示词”上的钱足够再跑好几个实际业务任务。这不是模型贵是我们在用最贵的方式做最廉价的事。这篇文章要聊的是我把一套基于 Claude Code 风格的系统提示词迁移到一套极简 Agent 框架下文统一叫它 Pi的完整过程。核心结果就三个数字系统提示词从约 14000 字符压缩到 200 字符左右单次请求的输入 token 下降约 85%账单同步暴降。但比数字更重要的是我搞清楚了哪些提示词是真正在干活哪些只是心理安慰。适合谁看如果你正在用任何带“系统提示词”的 Agent 工具不管是写代码的、做客服的、还是跑自动化流程的只要你在为 token 付费这篇都值得看完。哪怕你不迁移框架光是“提示词审计”这一节就能帮你省下一笔。先说结论免得你带着疑问往下读系统提示词不是越长越聪明超过某个临界点后它带来的边际收益是负的。原因后面会展开但你可以先记住一句话——模型不是被你“教”会的是被你“约束”对的。2. 为什么 1.4 万字符的系统提示词是个陷阱2.1 系统提示词的真实成本结构很多人算 token 账的时候只盯着“输出多少钱”忽略了输入才是大头。一次请求的成本大致是总成本 系统提示词 token 上下文 token 用户输入 token 输出 token其中系统提示词是每一次请求都要重新计费的。你写 1.4 万字符按英文约 4 字符/token、中文约 1.5 字符/token 粗算保守估计也有 4000 到 6000 token。如果一天跑 500 次请求光系统提示词就是 200 万到 300 万 token 的纯消耗而且它每次内容都一样等于你每天在重复购买同一段文字。我做过一个粗略的对比表用同一套业务任务代码审查 简单重构建议跑 100 次请求项目长提示词方案极简提示词方案系统提示词字符数约 14000约 200单次输入 token含系统约 5200约 780100 次请求输入 token约 52 万约 7.8 万相对成本100%约 15%这个表里最扎眼的不是 85% 的降幅而是极简方案的任务完成质量并没有明显下降。我一开始也不信专门做了盲测把两套方案的输出混在一起让同事判断结果没人能稳定分辨出哪个是长提示词产出的。2.2 长提示词的三个隐性代价第一个代价是注意力稀释。模型的上下文窗口是有限的注意力资源你塞进去 1.4 万字符的规则、示例、边界说明真正和当前任务相关的信息就被淹没了。这就像你给新员工一本 200 页的员工手册然后让他立刻回答一个具体问题——他大概率会翻错页。第二个代价是规则冲突。长提示词往往是多人多次迭代堆出来的前面写着“回答要简洁”后面又要求“每个步骤都要详细解释”模型只能自己猜哪个优先。我见过最离谱的一份提示词里同时存在“不要使用列表”和“用列表组织答案”两条指令模型每次都在掷骰子。第三个代价是维护成本。1.4 万字符的提示词改一个地方要通读全文生怕动了某条隐藏规则导致行为漂移。时间一长没人敢删任何东西只能不断往上加最后变成一座没人敢拆的违章建筑。2.3 什么情况下长提示词反而必要我不是说所有长提示词都该砍。有几类场景确实需要详细约束涉及安全边界的比如必须拒绝某类请求、涉及固定格式输出的比如必须返回特定 JSON 结构、涉及多角色切换的比如客服场景要区分售前售后。但这些内容加起来通常也不会超过 2000 字符。真正让提示词膨胀到 1.4 万的往往是三类“水分”重复强调的通用原则、大段大段的示例对话、以及“以防万一”写进去的边界情况。这三类内容恰恰是压缩空间最大的地方。3. Pi 框架的极简哲学200 字符怎么够用3.1 Pi 的核心设计思路Pi 这套框架的思路和主流 Agent 框架不太一样。大多数框架默认“系统提示词是配置”Pi 默认“系统提示词是接口”。什么意思配置是可以随便写的接口是必须精确的。Pi 把系统提示词压缩到 200 字符左右靠的不是删功能而是把功能从提示词里搬到代码里。举个例子长提示词里常见的“如果用户问的是代码问题请先分析再给建议如果用户问的是概念问题请直接解释”在 Pi 里是通过路由逻辑实现的——先判断意图再决定调用哪个子流程每个子流程有自己的极短提示词。这背后的逻辑是能用代码控制的不要用自然语言控制。自然语言是模糊的、概率的代码是确定的、可测试的。你把规则写进提示词模型可能遵守也可能不遵守你把规则写进代码它一定遵守。3.2 200 字符里到底放了什么我实际用的 Pi 系统提示词核心就三句话翻译成中文大意是你是一个执行具体任务的助手。只做当前任务要求的事不要扩展。不确定时直接说不确定。就这么多。没有角色设定没有语气要求没有输出格式说明没有示例。这些东西全部由调用方在用户消息里按需注入或者由代码层做后处理。你可能会问那模型怎么知道该用什么语气、什么格式答案是它本来就知道。现代模型在预训练阶段已经见过海量的对话、文档、代码你不需要教它“要礼貌”它默认就是礼貌的你不需要教它“用 Markdown”你要求它用 Markdown 它就会用。系统提示词里那些“你是一个专业的、友好的、乐于助人的助手”本质上是在浪费 token 说废话。3.3 迁移前后的架构对比迁移不是简单地把长提示词删短而是整个调用链的重构。我画不了图用文字描述一下两套架构的区别迁移前Claude Code 风格一个巨大的系统提示词 用户输入 → 模型 → 输出。所有规则、格式、边界都在系统提示词里模型一次性接收全部信息。迁移后Pi 风格极短系统提示词 任务路由层 按需注入的上下文 用户输入 → 模型 → 输出后处理。规则被拆散到路由层、上下文组装层、后处理层模型只负责它最擅长的事——理解和生成。这个架构变化带来的直接好处是可调试性。以前模型输出不对你只能改提示词然后祈祷现在你可以定位到是路由错了、上下文缺了、还是后处理漏了每一层都可以单独测试。4. 提示词审计我是怎么把 1.4 万砍到 200 的4.1 第一步给每一段提示词打标签我做的第一件事是把 1.4 万字符的系统提示词按段落拆开逐段打标签。标签只有四类硬约束不写会导致严重错误的比如安全边界、必须遵守的格式。软引导写了更好但不写也能用的比如语气、风格。示例给模型参考的对话样例。冗余重复的、过时的、自相矛盾的。打完标签后统计结果很残酷硬约束只占约 8%软引导约 15%示例约 30%剩下 47% 全是冗余。也就是说将近一半的字符是在自我重复。4.2 第二步硬约束的代码化改造硬约束里真正必须留在提示词的其实很少。我举几个实际例子原来提示词里写“输出必须是合法的 JSON包含 field_a、field_b、field_c 三个字段”。这条我直接搬到代码里用 schema 校验 重试机制实现。模型输出后先校验不合格就自动重试一次重试还不行就报错。这样提示词里只需要说“输出 JSON”剩下的交给代码。原来写“如果用户请求涉及删除操作必须先确认”。这条改成路由层判断检测到删除意图先走确认流程确认后再调用模型。模型根本不需要知道这条规则。改造完之后硬约束里只剩两条真正需要留在提示词的一条是关于不确定时要明说一条是关于不扩展任务范围。这两条加起来不到 100 字符。4.3 第三步示例的按需注入示例是 token 大户。原来系统提示词里塞了 5 组完整对话示例每组 500 到 800 字符。我的做法是把示例从系统提示词里拿出来放到一个示例库里根据当前任务类型动态选取最相关的 1 组注入到用户消息里。这样做的好处是示例和任务的匹配度更高了。以前是 5 组示例硬塞给所有任务现在是根据任务选 1 组模型看到的示例更精准效果反而更好。而且系统提示词里不再有示例每次请求的固定开销大幅下降。4.4 第四步冗余的识别与删除冗余是最难删的因为每一句看起来都“有道理”。我用的方法是删除测试删掉一段跑 20 次任务如果输出质量没有可感知的下降就永久删除。用这个方法我删掉了大量“正确的废话”。比如“请确保你的回答准确、有用、无害”——这句话删掉后模型输出没有任何变化因为模型本来就被训练成准确、有用、无害的。“请用清晰的语言表达”——删掉后输出依然清晰。“请考虑用户的感受”——删掉后该礼貌还是礼貌。这里有个反直觉的发现很多提示词的作用是让写提示词的人安心而不是让模型表现得更好。你写“要准确”不是因为模型不准确而是因为你担心它不准确。这种担心驱动的提示词删掉后往往毫无影响。5. 迁移实操从零搭建 Pi 风格调用链5.1 环境准备与依赖说明我用的技术栈很普通Python 3.10一个 HTTP 客户端库一个 JSON schema 校验库没有引入任何重型框架。核心依赖就三个pip install httpx jsonschema tenacityhttpx负责发请求jsonschema负责输出校验tenacity负责重试。如果你用的是其他语言找对应的等价库就行思路是一样的。提示不要一上来就引入 LangChain 之类的框架。框架会帮你做很多事但也会隐藏很多细节而迁移阶段你最需要的就是看清每一个细节。5.2 极简系统提示词的落地写法我的系统提示词最终版本中文大意如下实际使用时按目标模型的语言习惯调整你是任务执行助手。只完成当前任务不扩展范围。不确定时直接说明。就这一句。你可能觉得太简单了但实测下来配合路由层和上下文注入它的表现比 1.4 万字符的版本更稳定。原因是当提示词足够短模型没有歧义空间行为反而更可预测。这里有个细节要注意极简提示词对“任务描述”的质量要求更高了。以前长提示词里写了很多通用规则现在这些规则没了你必须把任务描述写清楚。这不是缺点是优点——它逼你把每个任务想明白而不是指望提示词兜底。5.3 任务路由层的实现路由层的职责是判断当前请求属于哪类任务然后决定注入什么上下文、走什么后处理。我的实现很朴素先用一个轻量分类器可以是规则匹配也可以是一个小模型调用判断意图然后查表TASK_ROUTES { code_review: { context_template: review_context, postprocess: format_review, max_retry: 2, }, concept_explain: { context_template: explain_context, postprocess: None, max_retry: 1, }, data_extract: { context_template: extract_context, postprocess: validate_json, max_retry: 3, }, }每个任务类型对应一套上下文模板和后处理逻辑。上下文模板负责把该任务需要的背景信息组装进用户消息后处理负责校验和格式化输出。模型本身不感知这些差异它只看到一条清晰的用户消息。5.4 输出校验与重试机制输出校验是保证质量的关键。以 JSON 提取任务为例我的流程是模型输出文本。尝试从文本中提取 JSON 块。用jsonschema校验字段和类型。校验通过则返回失败则把错误信息拼回用户消息让模型重试。重试超过max_retry次则报错并记录日志。这个机制替代了原来提示词里大段的“输出格式说明”。以前你要在提示词里写清楚每个字段的类型、是否必填、取值范围现在这些全部写在 schema 里模型只需要知道“输出 JSON”剩下的由代码保证。注意重试次数不要设太高。我实测下来第一次失败后重试的成功率约 70%第二次重试的成功率降到 30% 以下。超过两次还失败通常是任务描述本身有问题继续重试只是烧钱。6. 账单对比与效果验证6.1 Token 消耗的实测数据迁移完成后我用同一批任务跑了对比测试。任务集包含 50 个代码审查请求、30 个概念解释请求、20 个数据提取请求共 100 次请求。结果如下指标迁移前迁移后变化系统提示词字符数约 14000约 200-98.6%平均单次输入 token约 5200约 780-85%平均单次输出 token约 420约 4507%100 次请求总 token约 56.2 万约 12.3 万-78%任务通过率91%93%2%输出 token 略微上升是因为极简提示词下模型回答稍微详细了一点但输入 token 的降幅远大于输出的增幅总成本依然大幅下降。任务通过率不降反升说明长提示词确实存在注意力稀释的问题。6.2 输出质量的盲测对比为了排除我自己的主观偏差我做了盲测。把迁移前后的输出各取 30 条打乱顺序让三位同事独立评分1 到 5 分。结果迁移前平均分3.8迁移后平均分3.9差异在统计上不显著。有意思的是同事们反馈“迁移后的回答更直接废话更少”。这印证了一个判断长提示词里的很多“引导”实际上是在诱导模型说废话。6.3 什么任务类型受益最大不是所有任务类型的受益程度都一样。我按任务类型拆了一下数据任务类型输入 token 降幅质量变化代码审查-87%基本持平概念解释-82%略好数据提取-79%明显更好多轮对话-71%基本持平数据提取受益最大因为它的规则最明确最适合代码化。多轮对话受益最小因为对话历史本身占用大量 token系统提示词的占比相对较低。7. 常见问题与排查技巧实录7.1 迁移后模型“不听话”怎么办这是最常见的问题。迁移后第一周我发现模型偶尔会跳过某些步骤。排查后发现原因是原来提示词里有一条“必须按步骤执行”迁移时被我当成冗余删掉了。解决办法不是把这条加回去而是在路由层加一个步骤检查如果任务类型是“多步任务”后处理时校验输出是否包含所有步骤缺了就重试。这样规则从提示词搬到了代码更可靠。实操心得迁移后如果发现行为漂移先问自己“这条规则能不能用代码实现”能就用代码不能才考虑加回提示词。加回提示词时用最少的字说清楚不要展开。7.2 极简提示词下如何控制输出格式很多人担心提示词短了模型输出格式会乱。我的经验是格式控制靠后处理不靠提示词。你要求模型输出 Markdown它大概率会输出 Markdown但如果你需要严格的格式比如特定标题层级、特定字段顺序后处理比提示词可靠得多。具体做法是模型输出后用正则或解析器提取内容然后按你的格式重新组装。这样即使模型输出格式有波动最终呈现给用户的格式也是稳定的。7.3 哪些内容绝对不能从提示词里删有三类内容我建议保留在提示词里不要代码化第一类是安全边界。虽然代码也能做安全过滤但提示词层面的安全声明能降低模型主动越界的概率两者叠加更稳妥。第二类是不确定性的表达方式。我保留的那句“不确定时直接说明”是因为它影响的是模型的“态度”代码很难强制。你可以后处理检测“不确定”关键词但模型愿不愿意承认不确定还是提示词影响更大。第三类是任务范围的约束。“只完成当前任务不扩展范围”这句能有效减少模型自作主张的扩展这个用代码很难拦因为扩展的内容看起来也是合理的。7.4 常见问题速查表问题现象可能原因排查方向解决方式输出格式不稳定后处理缺失检查 postprocess 配置补后处理逻辑模型跳过步骤步骤约束被删检查路由层步骤校验加步骤校验或重试回答过于简略任务描述不清检查用户消息组装补充任务上下文重试率偏高schema 过严检查 schema 定义放宽非关键字段成本没降上下文注入过多统计各部分 token 占比精简上下文模板7.5 我踩过的三个坑第一个坑是一次性删太多。我一开始把提示词从 1.4 万直接删到 200结果第一周各种小问题不断。后来改成渐进式删除每次删一批跑测试稳定了再删下一批过程顺利很多。第二个坑是忽略了模型差异。同一套极简提示词在不同模型上的表现不一样。有的模型对极简提示词适应得很好有的模型需要稍微多一点的引导。迁移时一定要针对你实际使用的模型做测试不要照搬别人的提示词。第三个坑是后处理写得太重。我一度把大量逻辑塞进后处理导致响应变慢。后来把能前置的判断前置到路由层后处理只做必要的校验和格式化整体延迟才降下来。8. 迁移后的持续优化与扩展方向迁移完成不是终点。我现在每个月会做一次提示词审计看看有没有新的冗余长出来。极简提示词的好处是一旦有冗余很容易被发现——总共就 200 字符多一句都显眼。扩展方向上我在尝试把路由层做得更细。目前是按任务类型路由下一步想按任务复杂度路由简单任务用更短的上下文复杂任务才注入更多背景。这样能进一步压低平均 token 消耗。另外我在建一个“提示词片段库”把那些确实需要留在提示词里的硬约束片段化管理。每个片段有明确的适用条件组装时按条件拼接。这样既保持了极简又不会在遇到特殊任务时抓瞎。最后分享一个我个人的判断标准如果一条提示词删掉后你需要跑超过 20 次测试才能确认它有没有用那它大概率没用。真正有用的提示词删掉后问题会立刻暴露。那些删了也没事的就是你一直在为它白白付费的部分。