跳到主要内容

Prompt 作者身份问题:三个角色同时编辑同一个文件

· 阅读需 14 分钟
Tian Pan
Software Engineer

翻开任何一个运行了一年的生产系统提示词(system prompt)的 git blame,你都会发现一些工程团队不愿承认的事实:这个文件有三个作者,而他们对“变更”的定义各不相同。上个月重构指令块的工程师将提交记录标为“无功能变更,仅为了清晰起见重新排序”。每季度读一次该文件的产品经理会这样描述同样的差异:“你改写了语气——客户会察觉到的”。运行回归测试套件的 ML 工程师会说:“你搞坏了第三个少样本示例(few-shot example),从那以后评估结果(eval)就一直变红了”。

这三者都是正确的。提示词同时具备代码、规范和超参数的属性。任何长期交付 AI 功能的团队都会发现,该文件的提交历史是一场缓慢进行的三方署名权争议,CODEOWNERS 无法捕捉到这一点,diff 查看器也无法体现出来。

通常的反应是增加更多的审核人。但这并不奏效,因为审核人之间并不是在争论变更是否是好的——而是在争论变更“是什么”。在组织从结构上分离这三种创作角色之前,“需要两个批准”仅仅意味着刚好有空的两个人最后走过场式地批准了一项他们都不完全理解的变更。

三种思维模型,一个文本文件

工程团队将提示词视为代码。他们的本能是应用仓库中其他文本工件所遵循的整洁原则:对其进行 lint 检查、版本化、编写测试、在结构腐蚀时进行重构、在两个部分发生漂移时去重。工程师在阅读长系统提示词时,会将冗余措辞视为冗余代码——需要精简的部分。他们会很乐意将三个几乎相同的指令合并为一个,因为这正是优秀工程师所做的。

产品团队将提示词视为规范。对产品而言,提示词是代码库中最接近功能书面描述的东西。措辞很重要,因为措辞就是契约:“be concise”(简洁)和 “be brief”(简短)并不是同一个指令,客户在营销文案中读到的功能描述与生产环境中的功能表现不应产生违和感。语气不是装饰——它是功能的表面。当产品经理读到“无功能变更,仅为了清晰起见重新排序”时,他们听到的是“你没咨询我就改写了规范”。

ML 工程师将提示词视为超参数。措辞是一个旋钮,少样本示例是训练数据,唯一重要的一点是评估套件报告的结果。如果评估显示一句话没有起到作用,ML 工程师会毫不犹豫地删掉一句写得很漂亮的话;而如果评估显示其有效,他会为一句读起来很糟糕的话辩护。对于 ML 团队来说,“搞坏了评估”是这场争论中唯一具有实证意义的话。

这些模型都没有错。它们处理的是同一个工件的不同层级,而文件格式并不能区分它们。

“变更”对各角色的含义

这三个角色对“变更”的定义存在分歧,因为他们各自认为提示词中承担负载(load-bearing)的表面不同:

  • 对于工程团队,负载意味着指令是非冗余的且结构是可解析的。当行为改变时,变更才被称为变更;为了清晰起见而进行的重述是不可见的。
  • 对于产品团队,负载意味着模型输出的词语与客户期望阅读的词语相匹配。当客户可检测到的输出特性发生偏移时——例如正式程度、长度、语体、顺序——变更才被称为变更。
  • 对于 ML 团队,负载意味着评估套件的得分高于当前基准。当指标发生变动时,变更才被称为变更。

这些定义有所重叠但并不一致。工程团队可以发布一个重构,产品团队称之为语气退化,而 ML 团队称之为 1.8 分的评估下降。产品团队可以发布一个措辞调整,工程团队将其归类为“修饰性”变更,而 ML 团队注意到了它,因为评估捕捉到了团队追求了两个迭代(sprints)的 0.4 分提升。ML 团队可以更换一个少样本示例,因为评估得到了改善,而工程团队两个月后才会发现,当时一个无关的变更意外地将该示例改回了之前的形式,导致评估莫名其妙地退化了。

结果就是,“提示词改变了吗?”在不指定针对“谁”的情况下是一个无法回答的问题。要求描述变更的 PR 模板收集到的答案对一个角色来说是真实的,而对另外两个角色来说则是不完整的。

提示词仓库中的公地悲剧

当写权限开放给每个有需要的角色,且没有任何角色的否决权被编码在任何地方时,文件会以一种特定的模式腐败。

首先,每个角色都在自己的思维模型内进行单方面编辑。工程团队在没有产品审查的情况下重构段落,因为“那只是结构”。产品团队在没有 ML 审查的情况下调整措辞,因为“那只是语气”。ML 团队在没有工程审查的情况下添加或删除少样本示例,因为“那只是评估调优”。每次编辑在局部看来都是合理的。

其次,编辑的影响会叠加。重构移动了一个产品团队因为其锚定了某种行为特征而写在特定位置的句子。措辞调整轻微地重新排序了一个 ML 团队针对特定失败模式校准过的子句。评估调优的编辑删除了一个句子,而 ML 团队不知道,该句子的唯一目的是为了保持特定的面向客户的行为一致性。

第三,当六个月后生产环境出现故障时,三个角色中没有一个能完整解释提示词了。工程团队可以描述结构但无法解释评估依据。产品团队可以描述语气但无法解释少样本校准。ML 团队可以描述评估调优历史但无法解释某些措辞为何存在。该工件已演变成一种“公地悲剧”,团队对其集体的理解力低于各部分的总和。

这种失效模式会导致团队宣布“提示词冻结”并尝试从头重写文件——然后惊恐地发现,重写后的文件在评估得分上更低,同时在产品端读起来也更糟,因为现有的提示词积累了比任何人意识到的都要多的约束。

结构化分离是解决之道

摆脱困境的方法是停止将 prompt 视为一个整体文件,而是将其视为具有角色所有权部分的结构化产物。这种格式不需要多么奇特 —— 它可以简单到只是带有明确所有权注释的命名称部分,也可以复杂到是一个模版化的 prompt,其中每个部分都源自独立的文件,并拥有各自的 CODEOWNERS 规则。

一个可行的结构包含三个顶层部分,每个部分由且仅由一个角色负责:

系统指令(system instructions) 部分由工程团队拥有。它定义了模型的运行上下文:有哪些可用工具、输出格式必须是什么样、适用哪些安全护栏、以及哪些故障模式需要被明确处理。这部分 prompt 具有代码的结构。工程团队可以在不咨询其他角色的情况下重构此部分,只要它向其他部分暴露的契约保持不变。

行为规范(behavioral spec) 部分由产品团队拥有。它定义了产品向客户承诺的声音、语调、人格(persona)、语域、品牌一致性以及行为承诺。产品团队可以无需工程团队批准就重写此部分,因为更改规范是产品团队的工作。工程团队和 ML 团队可以提供建议,但他们不能单方面编辑它,就像他们不会单方面编辑营销文案一样。

少样本示例(few-shot examples) 部分由 ML 团队拥有。它包含评估套件(eval suite)所依赖的、经过校准的输入-输出对,并附带关于每个示例防御哪些故障模式的元数据。只要评估套件保持绿色(通过状态),ML 团队可以添加、删除和重新排序示例,而无需咨询其他角色。工程和产品团队可以标记与系统指令或行为规范冲突的示例,但他们不能重写这些示例。

现代 prompt 管理平台原生编码了部分此类分离 —— 生产别名由工程经理掌握,草案版本对产品团队开放,由评估门控的发布流程由 ML 团队控制。这种规范可以转移到普通的代码仓库中,只需几项约定和一个为每个部分指定不同团队的 CODEOWNERS 文件即可。

PR 模板应强制进行变更类型声明

即使有了结构化分离,编辑有时也会跨越边界。产品团队想要添加一项新的行为承诺,这需要一个新的少样本示例来锚定。ML 团队想要针对新的故障模式调整评估,这需要对系统指令进行微调。工程团队想要以一种涉及所有三个部分的方式进行重构。

对于这些跨职能的变更,PR 模板需要一个变更类型分类体系:

  • 行为变更(Behavior change) —— 以客户可感知的方式改变模型的行为。需要产品团队签核。触发完整的评估运行,如果涉及高流量场景,还需触发 A/B 测试框架。
  • 语调变更(Tone change) —— 在不改变模型功能的情况下改变其输出措辞。需要产品团队签核。如果存在风格度量评估(stylometric eval),则触发该评估。
  • 结构化重构(Structural refactor) —— 重新组织 prompt,无意改变行为。需要工程团队签核。触发完整评估以验证重构是否确实保持了行为一致。
  • 评估调优编辑(Eval-tuning edit) —— 调整 prompt 以修复特定的评估退化(regression)。需要 ML 团队签核。触发检查以确保该编辑没有改动行为规范所管辖的客户可感知行为。

为每个 PR 贴上这些标签,可以迫使作者在评审前声明他们对变更的模型认知。看到“结构化重构”标签的评审人员知道要验证评估结果是否没有波动。看到“语调变更”标签的评审人员知道要扫描 diff 中的行为表面变化,而不是寻找清晰度的提升。这种分类体系将“这是否改变了行为?”从一种争论变成了一个可验证的声明。

这种分类体系还捕捉到了一类悄无声息地破坏 prompt 仓库的变更:无意间的跨领域编辑。如果一名工程师将 PR 标记为“结构化重构”,但意外更改了行为承诺的措辞,那么现在评审人员就能发现这种类别不匹配。如果没有这种分类体系,这段 diff 看起来就像是一次普通的重构并直接发布。

共享词汇表,而非共享否决权

解决此问题时一个常见的失败模式是过度修正:要求每个角色对每一项变更都进行签核。这只是用一种悲剧交换了另一种悲剧 —— prompt 变得无法编辑,因为三个角色的日程表永远无法对齐,团队的迭代速度会崩塌,甚至低于底层模型的更新速度。

目标是共享词汇表,而不是共享否决权。这三个角色需要在以下方面达成一致:

  • 存在哪些部分,以及谁拥有每一部分。
  • 存在哪些变更类型,以及哪些类型需要哪些签核。
  • “prompt 的功能”在客户看到的层面、评估衡量的层面以及模型解析的层面分别意味着什么。
  • 哪些分歧属于实现层面(由所属角色解决),哪些属于方向层面(只能通过升级汇报解决)。

当词汇表共享时,分歧发生在设计阶段。产品团队提出一项新的行为承诺,工程团队指出如果没有新工具,系统指令无法强制执行该承诺,而此时双方都还没浪费任何一个冲刺周期。ML 团队建议删除一个评估贡献已经衰减的少样本示例,产品团队提醒该示例是维持规范所依赖的某项面向客户特性的唯一手段,而此时示例尚未被删除,特性也不会悄然消失。

当词汇表不共享时,分歧发生在合并阶段,发生在 PR 的评论区,而那天意见最强烈的人往往会获胜。

工具尚未填补的架构鸿沟

工程团队 PR 工具中的 diff 查看器是为代码设计的,在代码中,“发生了什么变化?”这个问题只有一个答案。而 Prompt 仓库需要的 diff 查看器需要同时回答三个问题:结构改变了吗?行为表现改变了吗?评估测得的行为改变了吗?一些 Prompt 管理平台已经开始发布这类功能——在文本 diff 旁边显示评估增量、跨版本的语义对比、变更类型标记——但这些工具与组织内其余评审界面的集成仍然是碎片化的。

在工具成熟之前,团队必须手动建立规范。在仓库中采用按部分划分所有权的文件,并配置按角色命名的 CODEOWNERS 条目。使用带有“变更类型”字段的 PR 模板,该字段必须是必填的下拉列表,而非可选的注释。设置在每个 PR 上运行的评估门禁(eval gate),并在评审线程中呈现增量,这样无论 PR 是由哪个角色创建的,经评估定义的“变更”都是可见的。在仓库中建立术语表来定义共享词汇,确保这三个团队中任何一个团队的新员工,读到的“行为变更”定义都与其同事一致。

手动构建这些规范的成本是实实在在的。但如果不去构建,成本会更高且更难以察觉,因为它表现为一段没人能完全解释的 Prompt、一次没人能完全归因的评估退化,以及一个以组织无法衡量的速度偏离其规格说明的功能面。

Prompt 是合同,而非配置

领导层需要进行的认知重构是:生产环境中的系统 Prompt(System Prompt)不是 AI 团队拥有的配置文件,不像功能开关(feature flag)或模型温度(model temperature)那样由 AI 团队全权负责。它是三个角色之间的合同,每个角色对其中的不同部分都拥有合法的创作权。组织对其他每一个多利益相关者协作的产物都是这样构造的——面向客户的落地页需要市场、工程、法务的评审;重大的 UX 变更需要设计、工程、PM 的评审;数据处理合同需要法务、安全、工程的评审——Prompt 也不应成为例外。

明白这一点的团队会发布得更快,因为曾经导致合并受阻的分歧在设计阶段就解决了,对单个 PR 的评审变得更聚焦、更迅速。而不明白这一点的团队,则会将每一次 Prompt 编辑视为独立事件,每季度都在重新发现同样的“三方创作权争议”,并且最终得到的 Prompt 在六个月后——当最后触碰它们的工程师、PM 和机器学习工程师都已离职后——没人能完全解释清楚。

下一个对文件执行 git-blame 的人,应该能够通过阅读章节标题就明确该找谁。这就是标准。

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