跳到主要内容

每次事故后你的系统提示词都会增长 —— 而且没人会删掉任何一行

· 阅读需 10 分钟
Tian Pan
Software Engineer

打开任何一个已经在生产环境中运行了一年的智能体的系统提示词(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)买单。

防御性指令即便有效也不是免费的

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates