跳到主要内容

提示词差异审查作为一种规范:审查者真正需要问的问题

· 阅读需 12 分钟
Tian Pan
Software Engineer

上个季度,一家中型AI初创公司的系统提示词中落地了一个单行变更。这个差异看起来无害:一位工程师收紧了关于响应长度的指令。审查者在两分钟内批准了它,就像批准一个变量重命名一样。48小时内,支持工单激增。模型开始在复杂查询的句子中间截断答案,而旧措辞几个月来默默处理的边界情况现在都失败了。原来的指令不仅控制着长度——它隐式地锚定了模型关于何时一个主题已经完成的判断。没有人捕捉到这一点,没有人去寻找它。

这就是当今提示词审查的核心问题:我们正在将代码审查的直觉应用于一个这些直觉大多数是错误的媒介。代码审查之所以有效,是因为被审查的工件是确定性的,语义可以从语法中恢复。提示词两者都不是。它的含义分布在模型的权重、训练数据以及推理时运行的随机采样中。你在屏幕上看到的差异只是你正在批准的变更的一小部分。

为什么代码审查直觉在提示词层面失效

当工程师审查代码时,他们在寻找逻辑错误、命名一致性、边界情况覆盖和模式遵守。这些直觉假设工件具有确定性语义:给定相同的输入,相同的代码产生相同的输出。这个假设允许你进行局部推理——你可以查看一个函数并知道它做什么。

提示词在每个层面上都违反了这个假设。看起来是表面性的变更——将"简洁"改写为"保持简短的回应"——可能会以直到你运行数千个样本才能看到的方式改变输出分布。即使温度设置为零,LLM在不同模型状态下对等效提示词的输出变化率高达10%。相同的词语,排列不同,会激活不同的注意力模式和模型潜在行为空间的不同部分。

更糟糕的是,提示词行为是非局部的。系统提示词早期的一个句子可能会影响模型对五十行后指令的解释方式。添加用于防止一种失败模式的指令可能会无意中抑制覆盖另一种失败模式的行为。提示词组件之间的依赖关系是隐式的,在差异中不可见,而且通常对作者来说也是未知的。

传统审查者会发现错别字并标记模糊指令。他们会错过结构性失败——被破坏的行为依赖关系、被悄然降低优先级的边界情况、现在相互矛盾的约束。

每个提示词审查者应该问的三个问题

提示词审查最有用的框架不是"这看起来正确吗?"而是一组关于行为编码的问题:

这行在做什么断言? 提示词中的每条指令都是关于模型应该如何行为的声明。审查者的首要工作是明确这个声明。"用简单英语回应"断言了关于词汇和句子结构的某些内容。"不要对用户的意图做假设"断言了关于歧义处理的某些内容。如果你不能用一句话陈述行为断言,那么该指令很可能在模型会不一致地解决的方式上存在歧义。

添加这条指令是为了防止什么失败? 大多数生产提示词是考古文物。每条指令都是针对特定失败或投诉而添加的。原始上下文几乎从不保留。在审查变更时,审查者应该问:如果这行被修改或删除,它最初防止的是什么失败?如果作者和审查者都不知道,这就是检查git历史、与写它的人交谈、或者在一组边界情况下运行没有该指令的提示词的信号。

这个变更可能启用什么新的失败? 这是审查者最一贯跳过的问题。添加防止X的指令可能会为Y打开大门。一个例子:添加"始终用编号列表回应"以提高可扫描性可能会抑制模型在问题不需要结构时给出正确单句答案的能力。添加"不要提出澄清性问题"以加快响应可能会导致模型在应该标记歧义的情况下自信地回答规格不明确的查询。每个约束都创造一个阴影。

构建审查者的检查清单

除了这三个核心问题之外,结构化的检查清单帮助审查者覆盖他们否则会错过的领域。对于提示词变更,审查应该验证:

  • 语气和角色的一致性:新指令是否与提示词其余部分的隐式语域匹配?关于正式性或角色的冲突信号会导致模型在两者之间取平均,产生不连贯的角色。
  • 指令排序效果:是否有任何内容在提示词中改变了位置?早期指令倾向于锚定解释;晚期指令更容易被覆盖。即使没有词语改变,指令顺序的变更也是行为变更。
  • 约束冲突:在某些输入下,现在是否有两条指令相互排斥?"始终用一段话回答"和"包含所有相关细节"在复杂话题上会产生冲突。模型通过加权来解决冲突;加权无法从文本中预测。
  • 输出模式脆弱性:如果提示词编码了结构化输出格式(JSON、markdown表格、编号步骤),变更是否影响格式指令?模式变更会悄然破坏下游解析器。
  • 缺少示例或少样本锚点:如果提示词依靠示例来演示行为,是否有任何示例被添加、删除或重新排序?对于模型具有强先验的任务,示例比指令具有更高的行为权重。

语义差异:哪些工具真正有帮助

文本差异对于捕捉重要失败几乎毫无用处。你想要的是语义差异:比较旧提示词和新提示词在代表性输入集上实际产生的内容。

这个最小版本是免费的:取十个涵盖正常范围的输入,十个触及边界情况的输入,并对它们运行旧提示词和新提示词。阅读输出。这需要三十分钟,可以捕捉大多数回归。跳过这一步的团队会持续发布他们不打算做的行为变更。

更复杂的工具存在。基于嵌入的语义差异工具计算提示词表示之间的余弦相似度,以标记意图可能发生重大偏移的情况——约0.80的阈值可以区分表面性变更和实质性变更。像llm-diff这样的工具添加了版本存储和输出沿袭,让你跟踪输出如何随时间跨提示词版本变化。对于使用评估框架(Braintrust、Langfuse、Confident AI)的团队,提示词变更可以在合并前以评估套件通过率为门控。

注意:语义差异工具告诉你某些东西发生了变化,而不是什么发生了变化,或者变化是好是坏。你仍然需要人来解释差异。但工具浮现出信号;没有它,审查者只是在查看源代码并猜测运行时行为。

创建行为契约的审查者-作者对话

提示词审查中最被低估的部分是对话。没有讨论的提示词PR几乎总是一个错失的机会。作者知道一些关于变更意图的事情,这些在差异中是不可见的;审查者看到一些作者已经对其视而不见的东西。他们之间的对话是提示词成为行为契约而不是一堆指令的地方。

作者在这个对话中的工作是预先回答三个核心问题——这个变更断言什么,它在解决什么失败,你检查了哪些新失败——而不是等待审查者提取它。一个说"收紧了长度指令"的PR描述是无用的。一个说"添加了最大句子约束以防止在简单查询上出现冗长答案;检查了评估套件中的15个边界情况;意识到这可能会影响复杂的多步骤响应,我们正在监控这些"的描述给了审查者实际可以验证的东西。

审查者的工作是探测阴影。"你说这防止了X——你能给我看一个旧提示词做X而新提示词不做的案例吗?你说你检查了Y回归——Y的失败案例实际上是什么样子?"这是与"这个变量名是错误的"或"你缺少一个空值检查"根本不同的对话。

做得好,这个对话产生了一个文档化的行为规范:提示词承诺什么,它防止什么失败模式,什么输入可能破坏它,什么监控应该捕捉回归。该规范不需要存在于提示词本身——它属于PR描述或链接的文档。但它需要存在于某处。现在,对于大多数团队来说,它不存在于任何地方。

在提示词变更前后进行测试

在不运行提示词的情况下审查提示词变更就像在不运行EXPLAIN的情况下审查SQL迁移一样。你在阅读意图,而不是行为。

生产中提示词变更的最低标准是与固定输入集进行行为比较。该集合应包括:

  • 标准查询:提示词在生产中将看到的典型输入,如果可用则从日志中提取。
  • 对抗性输入:设计用于对提示词编码的约束施加压力的输入——长输入、模糊输入、推动角色或输出格式的输入。
  • 已知回归案例:任何以前导致失败并且是过去提示词变更动机的输入。这些属于随提示词历史增长的永久评估文件。

对于风险更高的变更,影子测试通过旧提示词和新提示词同时路由实时流量,用户只看到控制组。这捕捉了合成基准测试遗漏的分布效应——你的0.1%用户发送但新提示词灾难性处理的奇怪输入。

输出比较不是二元的。你不仅仅是检查"这是否破坏了?"你在寻找行为漂移:响应长度、语气、结构或置信度的变化,这些不是预期的。这里正确的工具是LLM作为评判的评估,对你关心的维度——正确性、格式遵守、语气、完整性——对两个输出进行评分,并浮现显著的差异。

认真对待时的治理形式

认真对待提示词审查的团队往往会收敛到相似的结构,无论他们如何到达那里。

提示词与代码一起存在于版本控制中。不在Notion文档中,不在没有历史记录的单独工具管理的数据库中,而是在工程师提交和拉取审查的同一个存储库中。这看起来很明显,但即使在拥有严格工程文化的团队中也不是常见做法。

提示词变更在合并前需要通过评估套件。该套件不需要全面;它需要一致。相同的输入集、相同的评分标准、在每次变更时运行。回归会阻止合并。这种规范需要两三次失败的合并才能成为文化。

对生产提示词的访问是有限且受审计的。不是因为提示词泄漏是主要风险(尽管它们是一个风险),而是因为未经审查的变更是失败模式。可以将提示词变更部署到生产的人应该是如果它破坏了某些东西会被呼叫的同一个人——这意味着不是晚上11点有想法的PM。

审查历史是提示词行为文档的一部分。什么改变了,什么时候,为什么,测试了什么。这段历史是对提示词工程中最常见失败模式的唯一防御:有人在添加后三个月读到一个神秘指令,不知道它防止什么失败,并因为它看起来多余而删除它。

前瞻性部分

围绕提示词审查的工具正在快速成熟。提示词行为的正式规范语言(类似于类型系统或API契约)正在从研究进入实践。阻止提示词合并行为回归的评估驱动CI管道在当前工具中可用,并被大规模构建的团队使用。

然而,规范本身仍在形成中。大多数团队将提示词变更视为非正式修改,而不是行为契约修正。使代码审查有价值的习惯——明确断言、文档化意图、回归覆盖、对抗性思考——在今天的提示词审查中大多缺失。建立这些习惯与其说是工具问题,不如说是文化问题。问"添加这条指令是为了防止什么失败?"的审查者正在做任何工具都不会自动做的事情。这个问题必须成为反射。

当一个单行提示词变更导致生产事故时,事后分析几乎总是找到同样的根本原因:审查者看了文本,而不是行为。每次修复都是一样的。看行为。

Let's stay in touch and Follow me for more thoughts and updates