Prompt Sprawl:当系统提示词演变成难以维护的遗留代码
你的系统提示词(system prompt)起初只有 200 个 token。一个清晰的角色定义,几条格式规则,一两个约束条件。六个月后,它变成了 4,000 个 token 的指令堆砌,其中一半互相矛盾,团队里也没人能解释为什么会出现关于 JSON 格式化的第三段内容。欢迎来到提示词膨胀(prompt sprawl)—— 这种生产环境中的问题会在每个人都认为提示词“没问题”的情况下,悄悄削弱你的 LLM 应用。
提示词膨胀发生在你把提示词当作“只增不减”(append-only)的配置时。每一个 bug 都会换来一条新指令。每一个边缘案例都会换来一条新规则。每一个利益相关者(stakeholder)都会换来一段新文字。提示词不断增长,却没人删掉任何东西,因为没人知道哪些是起到支撑作用的(load-bearing)。
这就是遗留代码 —— 甚至更糟。没有编译器来捕捉矛盾。没有类型系统来强制执行结构。没有测试套件能验证第 47 条指令是否否定了第 12 条。而且,与乱作一团的代码库不同,你无法安全地进行重构,因为没有依赖图(dependency graph)来引导你。
没人衡量的退化曲线
在你达到宣称的上下文窗口上限之前,LLM 的指令遵循能力就已经开始退化了。研究表明,一旦系统提示词超过大约 2,500–3,000 个 token,准确率就会出现可衡量的下降 —— 这不是一个突然跌落的悬崖,而是一个随着提示词长度增加、准确率逐渐被侵蚀的斜坡。
其机制非常简单。Transformer 的注意力机制表现出首因效应(primacy bias)和近因效应(recency bias),对提示词开头和结尾的权重分配比中间部分更高。超过 3,000 个 token 后,中间部分的指令获得的关注最少。你那些最针对具体任务的规则 —— 那些精心编写的边缘案例处理 —— 恰好落在模型最容易忽略的区域。
这种情况会隐蔽地累积。每增加一条新指令,都会稍微降低对现有指令的遵循程度。新增的指令在隔离状态下“有效” —— 它能通过快速测试。但整体质量会下降一小部分。重复五十次之后,你就积累了可衡量的退化,而这种退化并不是由任何单一变更引起的。
死于千次追加。
还有一个更隐蔽的陷阱。语义相似但存在重叠的指令 —— 这种指令通常是在多人独立添加规则时积累起来的 —— 极具破坏性。模型会以不可预测的方式解决歧义,而且这种解决方式在不同请求之间是不固定的。
膨胀提示词的剖析
提示词膨胀遵循一个可辨识的模式。以下是积累的内容:
矛盾的指令。 “始终以 JSON 响应”出现在“对于错误情况,请以纯文本解释响应”的三段话之上。两位作者都不知道对方的指令。模型会随机选择一个,且选择结果取决于输入。
冗余的护栏(guardrails)。 同一个安全约束被以三种不同的方式陈述,因为三次不同的事件促使不同的人都去“添加一条规则”。模型将每一条都视为独立的指令,在同一个约束上浪费了注意力容量。
作废指令。 针对已不存在的功能的规则。针对几个月前就被重写的下游消费者的格式化要求。针对你已经升级掉的模型版本的约束。没人移除它们,因为没人记得为什么要添加它们。
隐式依赖。 指令 7 只有在指令 3 的背景下才有意义,但它们被 800 个 token 的无关规则隔开了。模型无法可靠地将它们连接起来,因此指令 7 在指令 3 不适用的语境下也会被错误触发。
利益相关者的妥协。 法务加了一段。产品加了语气指南。机器学习团队加了输出格式。支持团队加了错误处理规则。每一次添加在当时都是合理的。加在一起,它们构成了一份 4,000 token 的文档,没有连贯的作者,也没有一个人能理解其全貌。
财务成本也在悄悄累积。系统提示词每增加 500 个 token,就会增加延迟和每个请求的比例成本。在规模化运行下 —— 每天数百万次请求 —— 臃肿的提示词每月可能在浪费的 token 上花费数万美元。多轮对话会放大这一点:系统提示词会随着每次 API 调用发送,因此浪费会随着每一轮对话成倍增加。
为什么“直接清理掉”行不通
显而易见的解决办法 —— 裁剪提示词 —— 遇到了一个根本性问题:没人知道哪些指令是起到支撑作用的。
与代码不同(在代码中你可以通过 grep 搜索调用者并运行测试),提示词指令没有依赖图。删除一句话可能会破坏一个每千次请求才发生一次的边缘案例。你在测试中看不见这种失败,因为你的测试集没有覆盖到它。三周后,当客户针对离奇的回复提交工单时,你才会发现它。
这产生了一种棘轮效应(ratchet effect)。添加指令是低风险且可以立即测试的。移除指令是高风险的,且只能通过生产环境监控来检测。团队理性地选择了增加而不是移除,于是提示词只会不断增长。
版本控制问题放大了这一点。长的提示词在每次变更时都会产生巨大的 diff。审查一段 200 行的提示词 diff 需要理解整个提示词的交互动态,而不仅仅是修改的那几行。大多数审查者只是例行公事地批准(rubber-stamp),原本应该在生产前捕捉矛盾的质量关卡从未真正发挥作用。
- https://mlops.community/the-impact-of-prompt-bloat-on-llm-output-quality/
- https://blog.promptlayer.com/disadvantage-of-long-prompt-for-llm/
- https://blog.promptlayer.com/prompt-routers-and-modular-prompt-architecture-8691d7a57aee/
- https://blog.promptlayer.com/why-llms-get-distracted-and-how-to-write-shorter-prompts/
- https://arxiv.org/html/2510.14842v1
- https://medium.com/data-science-collective/why-long-system-prompts-hurt-context-windows-and-how-to-fix-it-7a3696e1cdf9
- https://langfuse.com/docs/prompt-management/overview
- https://redis.io/blog/context-window-overflow/
