验证器陷阱:事后防御如何从内部腐蚀你的提示词
第一次验证器捕捉到糟糕的 LLM 输出时,感觉像是一场胜利。第二次,你会调整提示词以降低失败的可能性。到第二十次时,团队中没人能解释为什么提示词中存在那三个段落 —— 它们是早已被遗忘的事故留下的瘢痕组织,而模型在阅读警告上花费的 Token 比推理实际任务还要多。
这就是验证器陷阱。你添加的每一个事后防护(post-hoc guard)—— JSON 模式检查、正则表达式、内容分类器、第二个作为裁判的 LLM —— 都会对上游提示词施加反馈压力。提示词会增加防御性指令来安抚验证器,验证器反过来又会捕捉到一类新的失败,接着你又会添加更多指令。每一次迭代在局部看来都是合理且明智的。但总体而言,系统变得越来越慢、越来越贵,而且在原本设计的任务上的表现也明显变差了。
陷阱是如何触发的
验证器很少作为设计的一部分出现。它们通常是在事故发生后才出现的。一个空字段破坏了下游仪表盘。一个未转义的引号污染了 SQL 查询。本应是三个枚举值之一的字段却出现了一长串解释。于是有人添加了模式检查或重试循环,眼前的问题消失了。
接下来发生的事情是悄无声息的。为了在不消耗五次调用的情况下让重试成功,工程师会在提示词中添加引导:“仅返回有效的 JSON。不要包含 Markdown 代码块。每个字段都是必填的。不要解释你的答案。status 字段必须是 pending、active 或 closed 中的一个。”每一行看起来都无伤大雅。每一行都是为了防止已经发生过一次的失败再次发生。
下一次事故暴露了一个语义错误 —— 模型尽职地生成了有效的 JSON,但在一段乱码输入上,confidence 字段却是 0.99。显而易见的解决办法是增加另一条指令:“仅在证据确凿时才返回高置信度分数。”提示词的表面积变大了,需要解析的指令增多了,模型在开始处理实际任务之前必须权衡的竞争目标也更多了。
一年之后,提示词看起来不再像是一份规范说明,而更像是一份和解协议。它用了 60 行来描述模型“不准做”什么,而描述模型“应该做”什么却只用了 3 行。逐月测量提示词长度的团队会发现它增长了 5% 到 10%。这个增长率就是确凿的证据 —— 熵正在累积,却没有人为此预留预算。
为什么指令会剥夺推理能力
臃肿的提示词会导致输出质量下降,这并非 玄学,而是有原因的。Transformer 会关注上下文窗口中的每一个 Token,模型的有效推理能力取决于有多少注意力可以分配给问题,而不是分配给指令。当提示词长度翻倍时,大部分新增的 Token 并不是新信息 —— 它们是冗余的约束,是不同工程师在不同事故中用略有不同的措辞重复陈述的要求。
模型会阅读所有内容。在较长的上下文中,研究人员反复证明,对于埋在提示词中间的任务,准确率会下降;而且随着指令被额外文本稀释,经过安全调优的模型变得更容易受到越狱攻击。一个最初简洁的任务描述提示词变成了一个草堆,实际的任务成了众多警告中的一根针。
一个有用的启发式方法:计算提示词要求模型同时执行多少个不同的认知任务。格式监管、内容过滤、人设维持、思维链塑形、工具选择以及实际任务。如果答案大于一,那么偏移是必然的,这种偏移会表现为看似随机的性能退化,因为没有哪个单一的提交(commit)导致了这一切。
验证器-提示词耦合审计
摆脱陷阱的第一步是让这种耦合变得可见。挑选出流水线中的每一个验证器和防护措施 —— 模式检查、正则过滤器、LLM 裁判、输出解析器、修复循环 —— 对于每一个,找出是因为它才存在的提示词指令。大多数团队会发现他们做不到。
这本身就是一个发现。当验证器捕获到一个失败时,随后的提示词修改很少会被标记上验证器的名字。六个月后,这条指令读起来就像是一直存在的一样。要显式地对这种耦合进行编码:通过注 释、提示词片段注册表或 YAML 文件,列出每个防御性条款以及催生它的事故或验证器。例如:# 2025-11 添加:在长输出中 retry-loop-v2 持续产生 Markdown 代码块。
- https://collinwilkins.com/articles/structured-output
- https://blog.promptlayer.com/how-json-schema-works-for-structured-outputs-and-tool-integration/
- https://www.ml6.eu/en/blog/the-landscape-of-llm-guardrails-intervention-levels-and-techniques
- https://blog.budecosystem.com/a-survey-on-llm-guardrails-methods-best-practices-and-optimisations/
- https://deepchecks.com/llm-production-challenges-prompt-update-incidents/
- https://snippets.ltd/blog/structured-outputs-with-claude-json-schemas-validation-retry-loops
- https://machinelearningmastery.com/the-complete-guide-to-using-pydantic-for-validating-llm-outputs/
- https://www.news.aakashg.com/p/prompt-engineering
- https://developers.openai.com/cookbook/examples/how_to_use_guardrails
- https://dev.to/lovanaut55/openrouter-structured-output-broke-before-translation-quality-did-3-layers-of-defense-for-1cdb
