打开任何一个已经在生产环境中运行了一年的智能体的系统提示词(system prompt)。滚动到底部。你会发现一层读起来像道歉一样的句子沉积层:“绝对不要伪造订单号。”“不要承诺无法确认的退款。”“如果用户在德国,不要提及旧版方案。”每一句都是一块化石。每一句都标志着生产环境中出现问题的确切时刻 —— 有人被传呼了,而当时能找到的最快修复方法就是增加一句话。
没人删除这些句子。不是因为它们还在发挥作用,而是因为删除一句话意味着需要证明一个否定命题 —— 证明模型不会在一个可能已经在三个模型版本前修复的 Bug 上发生回退。没人能证明这一点,所以那行字留了下来。系统提示词变成了一个关于过去事故的“只增不减”(append-only)日志,它让你在每一次调用中都永远支付着 token 费用。
这是 AI 系统中最隐蔽的一种技术债,因为它看起来不像债。它看起来像是在尽职尽责。
提示词如何变成坟墓
这种增生模式与遗留代码(legacy code)的腐烂方式几乎如出一辙,但有一个关键区别:遗留代码在崩溃时至少还懂得抛出一个错误。
一个典型的生命周期是这样的:一个智能体带着干净的 400 token 系统提示词上线。第三周,它言之凿凿地为客户伪造了一个物流单号。发生事故、复盘,修复方案就是增加一行 —— “绝对不要生成物流单号;仅重复查询工具返回的单号。”第七周,它提供了一个并不存在的折扣。又加一行。第十二周,合规审查发现它在讨论一款已停产的产品,于是加入了一段关于哪些 SKU 是禁区的描述。十八个月后,提示词变成了 4,000 token 的防御性规则、few-shot 示例和条件性例外,而修改第二段中的一个句子竟然会离奇地改变结尾总结的语气。
从业者对这种最终状态有一个称呼:提示词坟墓(prompt graveyard) —— 一堆相似但有细微差别的巨型提示词,没人敢删除它们,因为每一个都可能在深处埋藏着一条至关重要的指令。结果就是一场维护噩梦:一个微小的改动就需要数小时的细致编辑和全面的回归测试。
这种情况的发生是结构性的,而非源于懒惰。增加一句话是一个五分钟的修复方案,能立竿见影地证明解决了眼前的事故。而删除一句话是一个开放式的研究项目,没有明确的成功标准。在处理突发事故时,经济效益总是倾向于增量。每一个单独的决定都是理性的,但总和却成了一种负担。
为什么它比遗留代码更糟糕
三个特性使得提示词增生比代码等价物更令人头疼。
它没有测试覆盖。 当你添加一条防御性指令时,你是在添加一个行为需求,却没有任何自动化验证来确保它依然有效 —— 或者它曾经有效过。代码有编译器和测试套件,当假设破裂时会大声报错。而提示词指令只是静静地待在那儿。它可能毫无作用,也可能正在与六个月后添加的另一条指令“打架”。你无法通过阅读来判断,而且大多数团队从不检查。
它失效时是无声的。 存在于提示词而非代码中的业务逻辑很少有版本控制,难以审计,并且在有人将旧提示词复制到新智能体时很容易意外重现。由于模型具有灵活性,一条过时的指令在理应触发警报很久之后仍能“勉强奏效” —— 直到有一天模型的推理逻辑发生了偏移,而没人能解释为什么行为改变了。没有堆栈追踪(stack trace)会指向系统提示词的第 47 行。
它对每一次请求征税。 这是会体现在账单上的部分。智能体每进行一轮对话,都会将整个系统提示词 —— 指令、工具定义、例外情况 —— 重新发送给模型。在一个 50 轮的会话中,一个 2,000 token 的系统提示词意味着 100,000 token 的指令重复处理,而这没有产生任何新价值。乘以你的每日请求量,那些防御性的沉积物就成了一项真实的、经常性的账单支出。提示词缓存(prompt caching)能缓解账单压力,但为一段不再起作用的文字支付折扣价,本质上依然是在为死重(dead weight)买单。
防御性指令即便有效也不是免费的
团队通常用一个令人宽慰的假设来为这种增量辩护:多余的指令或许没必要,但它们是无害的。事实并非如此。
冗长且嘈杂的指令块会导致指令稀释(instruction dilution)。模型的注意力预算(attention budget)是有限的,每一条防御性条款都在与你当前真正关心的指令竞争。针对提示词膨胀的研究发现,推理性能在 3,000 token 左右就会下降 —— 这远低于宣称的上下文窗口 —— 且“迷失在中部”(lost in the middle)效应意味着埋在长提示词中间的规则获得的关注最少。你最重要的指令可能正被模型悄悄忽略,因为它被夹在两块事故化石之间。
更糟糕的是,模型并不擅长忽略那些虽然无关但相关的文本。研究表明,LLM 通常能识别出某个细节是无关的,但在生成过程中仍无法将其排除。关于已停产产品的防御性指令并不是中立的 —— 它在语义上与你正在销售的产品很接近,因此它会主动模糊模型对当前产品目录的认知。你为了修复一个边缘案例而添加的例外条款,现在成了常规案例中的干扰源。
因此,未清理指令的真实成本不仅仅是它的 token 计数。它是被窃取的注意力、被引入的矛盾,以及对模型遵循那些依然重要的规则的能力的缓慢侵蚀。
将 Prompt 视为需要删除的代码
解决方法不是“编写更短的 Prompt”。而是将系统 Prompt 视为一个受维护的工程产物,其生命周期与代码相同——包括删除内容的部分。
为每一行防御性指令标注日期。 当一条指令为了修复事故而加入时,请对其进行标注:日期、事故 ID、以及测试过的模型版本。在该行上方加一个注释块就足够了。这能将无名的化石转化为可审查的记录。六个月后,当你看到这一行时,你会知道它是为了修补一个你已经不再运行的模型上的行为而添加的。
给指令设定半衰期。 借鉴特性标志(feature flags)的想法:防御性指令在被证明是永久性的之前都是临时的。给它打上过期标签——日期或模型版本——届时必须有人明确地重新验证它,否则它就会被修剪。对于未重新验证的事故补丁,默认操作应该是删除,而不是获得永生。这转变了负担:与其需要证据来移除一行,不如需要证据来保留一行。
将消融作为一种真正的实践。 消融(Ablation)——移除一个组件并衡量其效果——在评估中是标准做法,但几乎从未应用于 Prompt 维护。如果你有评估套件,你就可以进行消融实验。移除候选指令,运行套件,观察差异。没有可衡量的变化意味着该行已经废弃,应该移除。性能回退意味着该行是承重的——因此要提升它的地位:编写一个专门的评估案例来固定该行为,现在这条指令就拥有了它一直缺乏的测试覆盖率。无论哪种结果都是共赢。你保留下来的指令是那些你已证明仍然值得消耗 Token 的指令。
将稳定的规则移出 Prompt。 许多防御性指令其实并不适合作为 Prompt 内容。“仅重复工具返回的物流单号”通过在代码中验证工具输出,比客气地要求模型执行效果更好。硬约束属于确定性的护栏(guardrails)——输出验证器、Schema 检查、白名单——而不是模型可能注意也可能不注意的段落。Prompt 应该承载引导;代码应该承载规则。你迁移到代码中的每一个约束,都是你可以信心十足地从 Prompt 中删除的一行。
指定负责人。 没有负责人的 Prompt 默认就是一个“仅追加”的日志,因为追加是唯一不需要授权的操作。必须有人将 Prompt 作为一个产物来负责——审查新增内容、安排修剪周期,并对其总大小负责。将 Token 计数放在仪表盘上。一个只增不减的 Prompt 是没有人负责的 Prompt。
纪律即删除
令人不安的事实是,每起事故在添加相关语句的那一刻,确实都证明了该语句的合理性。失败从来不在于添加。而在于缺失了第二步:有意识地、定期地、基于证据地移除那些比引发它们的事故活得更久的语句。
系统 Prompt 应该“呼吸”。当出现问题时它应该增长,当团队证明过去的修复不再需要时它应该收缩。一个只会“吸气”的 Prompt 不是勤奋的记录。它是一项缓慢累积的税收——体现在延迟、成本以及模型遵循当今真正重要规则的能力上。
去打开那个 Prompt。找到底部最老旧的一行。问一个问题:如果我删掉它,有什么证据证明会出问题?如果你无法回答,你发现的不是一条安全的指令。你发现的是下一个需要消融的对象。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部