跳到主要内容

系统提示词是软件接口,而非配置字符串

· 阅读需 10 分钟
Tian Pan
Software Engineer

大多数团队对待系统提示词的方式,就像早期 Web 开发者对待 CSS:粘贴一段能跑的代码,小心翼翼地修改以免破坏什么,提交到配置文件,然后祈祷没人动它。接着某位新成员"顺手整理"了一下,模型升级后行为悄然改变,三周后用户提了一个 bug,而没人能复现——因为没人知道上周二那个提示词究竟写的是什么。

这不是工作流问题,而是概念分类的错误。系统提示词不是配置,而是软件接口。只要工程团队还没有如此对待它们,他们构建的 LLM 功能就将持续脆弱、难以调试、无从扩展。

上下文窗口是一个编程界面

概念转变从这里开始。传统软件中,你编写函数读取寄存器、处理数据、输出结果。在基于 LLM 的系统中,你把指令、数据、示例和工具描述加载到上下文窗口,由模型的权重对这些结构化输入进行计算。上下文窗口是内存,模型权重是 CPU,系统提示词就是程序。

这一框架在近期研究中被正式命名为"Software 3.0",它带来的实践影响远超大多数团队的认知。如果系统提示词是程序,那么:

  • 不经评审流程就随意修改,等同于在没有 PR 的情况下改动生产代码。
  • 不写回归测试就上线,等同于部署未经测试的逻辑。
  • 把它硬编码为源码中的字符串常量,等同于把业务逻辑嵌入模板文件。

从"提示词工程"到"上下文工程"的术语演变,正是这种成熟化的标志。提示词工程是一门手艺——巧妙的措辞、零样本技巧、思维链咒语。上下文工程则是架构:决定什么信息进入上下文窗口、以何种结构、何种顺序,以及如何与检索、工具和记忆交互。系统提示词是这一架构的组成部分,理应按架构的标准来工程化。

软件接口的必要条件

如果你认同系统提示词定义了应用程序与模型之间的行为契约,那么所有关于 API 设计的经验都可以直接套用。

携带变更说明的版本控制。 良好的 API 版本控制不只告诉你变了什么,还告诉你影响是什么。主版本号升级意味着"使用方必须认真审查";补丁版本意味着"小范围修复,旧集成仍可工作"。系统提示词需要同样的规范:每个版本都应包含语义化版本号、变更描述、变更原因,以及验证该变更的评估结果。没有这些元数据,存放在配置文件里的提示词不过是一个无版本的 blob,在模型更新后产生不同的结果,而没有任何审计记录能解释原因。

向后兼容性作为设计约束。 API 团队很快就会意识到,改变一个响应字段会破坏所有下游消费者。提示词的逻辑完全相同。如果你的系统提示词一直在生产特定 schema 的 JSON,某次"整理" PR 删掉了一个字段,那么所有消费该输出的地方都会出错。规律可以直接映射:尽量只做加法式变更;先废弃再删除;不要以破坏现有消费者的方式收紧验证。唯一的区别是,API 的破坏通常是显性的(反序列化报错),而提示词的破坏往往是静默的(模型悄悄停止输出某个字段,输出仍能解析,下游逻辑只是拿到了空值)。

模块化与组合。 没有人把大型应用写成一个单体函数,但大多数团队确实把系统提示词写成了一个单体字符串。先进的团队正在向提示词模块迁移:基础推理模块、任务专属模块、工具描述模块,在运行时组合为最终的系统提示词。这与传统软件的库和继承模式如出一辙。共享模块可以独立版本控制并跨功能复用,从而消除痛苦的"指令复制粘贴"问题——同一行为要求被拷贝进十几个提示词,然后各自漂移成不一致的状态。

已经无处不在的失效模式

团队陷入的模式是可以预见的。工程师写了一个在测试中表现良好的系统提示词,它被硬编码为字符串常量提交到主干,然后立刻变成了不可见的基础设施。随着时间推移,几件事会依次发生:

提示词积累了来自多个贡献者的无序编辑。有人为了处理用户投诉加了一句话,有人调整了语气,第三个人删掉了他认为多余的约束。没有人知道当前提示词整体上到底在做什么——因为没有人把它当成一个整体来读,每次阅读都只聚焦于即将修改的部分。

模型升级发生了。GPT-4o 被 GPT-5 或某个微调变体替换。为一个模型的指令遵循模式精心编写的提示词,现在在具有不同敏感性的新模型上运行。没有人重新评估。行为漂移缓慢而静默。

提示词中的安全或合规要求逐渐松弛。"绝对不得讨论竞品"变成了经过多次渐进式软化后的"一般避免讨论竞品"。没有哪次单独的编辑看起来有问题,但经过二十次编辑,约束消失了。

质量回归数周内未被检测到。与代码不同——代码提交时测试会立即失败——提示词回归通过用户投诉或缓慢积累的指标衰减才浮出水面,速度之慢足以被误判为噪声。

核心问题:依赖试错、缺乏系统性工程规范的提示词开发,正是研究者所说的"提示词软件危机"——提示词对生产系统的重要性与其糟糕的管理状态之间的鸿沟。

弥合差距的工程实践

回归测试套件是投资回报率最高的举措。 团队能做的最有效的单一改变,就是为每个系统提示词维护一套测试数据集,并在每次变更前运行它。数据集应包含:预期行为的黄金样本、暴露失效模式的对抗性输入、来自真实用户会话的边缘案例,以及来自过往故障的回归案例。并非一切都需要用 LLM 作为裁判——对输出格式、必填字段存在性和延迟的确定性检查,能够捕获大多数机械性回归。将概率性评估留给主观质量维度。

评估驱动的迭代,而非直觉驱动的迭代。 诱人的工作流是:写一个看起来对的提示词,在几个例子上手工测试一下,上线。稳健的工作流是:先定义行为规范,建立针对规范的评估数据集,然后基于数据集迭代提示词。这种反转——测试先行的提示词工程——能够捕获常见的失效:某次变更改善了你测试过的五个例子,却悄悄破坏了你没想到要检查的三十个其他例子。

环境晋升,而非直接生产编辑。 提示词应该像代码一样经历环境晋升:开发环境中的草稿版本,经过回归测试验证后,晋升到 staging 进行集成测试,再在评估阈值满足后晋升到生产。这并不复杂——大多数提示词版本控制平台都直接支持——但它要求将提示词部署视为可部署的制品,而非文本文件的提交。

合并前的同伴评审。 改变模型行为的提示词变更,与改变业务逻辑的代码变更同等重要,值得同等的审查:第二位工程师检查变更的正确性、意外的副作用,以及与系统其他部分的交互。评审还会迫使作者阐明变更的理由,这本身就是有价值的文档。

可组合提示词与新兴基础设施

工具生态已大幅成熟。提示词注册中心现在为提示词制品提供类似 git 的版本控制,具备集中存储、环境专属部署、A/B 测试支持,以及跨版本的性能追踪。Promptfoo 和 DeepEval 等评估框架可以插入 CI/CD 流水线,并能在评估失败时阻断部署——与类型错误阻断编译的方式相同。

在协议层面,Anthropic 的 Model Context Protocol 将提示词定义为服务端发布、客户端发现的一等资源,从而实现跨团队和跨应用的提示词复用。在 MCP 下,提示词不再是嵌入代码库的字符串,而是任何合规客户端都能消费的有类型、有版本的制品。这是规模化提示词组合的基础设施。

用于提示词定义的领域特定语言还处于早期阶段,但已展示出方向:Impromptu 等工具允许以内置参数继承、版本追踪和平台无关性来定义提示词。发展轨迹是:提示词将越来越像带有正式规范的有类型接口,而非文档。

团队在这一转型中常犯的错误

对于将系统提示词视为软件的最常见反对意见是:它们感觉与代码不同——更模糊、更不确定、更难规范。这是事实。但模糊性并不能免除制品接受工程规范的义务,反而使这种规范更加重要。容忍模糊的系统需要更多的回归测试,而非更少,因为可能的失效空间更大、更难预测。

第二个反对意见是开销:如果工程师必须对每次提示词变更进行版本控制、测试和评审,迭代速度会变慢。这混淆了规范的成本与破坏的成本。没有回归测试套件就上线提示词的团队并不会更快——他们会快,直到第一次静默回归,然后花数周调试一个无法复现其状态的系统。规范比事故便宜。

第三个错误是把这当成工具问题,期待工具自己解决。采用提示词版本控制平台有帮助,但根本的转变是组织层面的:提示词变更需要被视为部署,而非编辑。这要求改变团队审查工作的方式、定义"完成"的标准,以及对"生产就绪"的判断。

前瞻性结论

那些能构建出最可维护的 AI 系统的团队,已经在将系统提示词视为一等软件制品——有版本控制、有测试、有评审,部署时与其他生产代码同等严格。那些仍在把提示词从聊天记录复制粘贴进配置文件的团队,正在积累 AI 版本的无文档数据库 schema:不透明的基础设施,能用直到不能用,而出了问题没人能解释。

好消息是这些实践并不新奇。版本控制、回归测试、同伴评审、环境晋升——这些都是软件工程中已经解决的问题。将它们应用于系统提示词,需要的是纪律,而非发明。上下文窗口是一个编程接口,请按此构建它。

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