生产环境中的提示工程:真正重要的是什么
大多数工程师学习提示工程都是倒着来的。他们从“发挥创意”和“一步一步思考”开始,反复迭代一个演示直到它奏效,然后在生产环境中发现模型有 15% 的时间在“幻觉”(胡编乱造),他们的 JSON 解析器每隔几小时就会抛出异常。让聊天机器人令人印象深刻的技术,往往不是让生产系统可靠的技术。
在将 LLM 功能部署到真实系统一年后,以下是真正区分有效提示和在负载下仍能保持稳定的提示的关键。
结构化输出问题(以及为什么自由文本在大规模应用中会让你失败)
你在提示工程方面做出的最重要的生产决策不是关于措辞,而是关于输出格式。依赖自由文本 LLM 输出的系统,其错误率大约是强制结构化模式的系统的三倍。
原因很简单:解析自由文本需要你编写脆弱的正则表达式或字符串匹配逻辑,并且模型在分布变化下并不总是遵守格式指令。当你的提示说“用包含 name 和 price 的 JSON 对象响应”时,模型可能会添加引言、将其用 Markdown 代码围栏包围,或者在长字符串上省略引号。这些情况中的任何一种都会导致 json.loads() 失败。
现代 LLM API 已在基础设施层面很大程度上解决了这个问题。在 token 层面(而非生成后验证)强制执行 JSON 模式的结构化输出,极大地降低了格式错误输出的错误率。如果你没有使用此功能,并且你的管道依赖于解析模型输出,那么你正在管理一个已经被解决了的可靠性风险。
实践中有效的方法:
- 在提示中指定模式,使用带有字段描述的 XML 或 JSON 符号
- 在 API 层面强制执行,如果可用则使用约束解码
- 验证并重试作为备用方案——如果模型输出未能通过模式验证,则将错误消息附加到提示中并重试一次
仅第三步——自动验证与自我纠正——就能在无需人工干预的情况下捕获大部分剩余故障。
N-Shot 提示:比你想象的需要更多示例
零样本提示对于定义明确的常见任务很有效。对于任何领域特定或需要一致输出风格的任务,少样本示例是投资回报率最高的技术,但大多数团队都未充分利用它们。
有效阈值比听起来要高:目标是 32-64 个示例,而不是 3-5 个。少量示例通常足以演示格式,但不足以可靠地将模型的行为转向你的目标分布。有了 3 个示例,你基本上只是展示了输出的形状。有了 32 个示例,你是在根据问题空间中的实际方差来训练模型。
少样本示例要做好三件事:
匹配你的生产分布。 示例应反映用户实际发送的完整输入范围,而不仅仅是干净、简单的案例。如果你的实际输入中有 20% 是边缘情况,那么你的示例集也应有相应比例的覆盖。仅选择“良好”示例会创建一个在良好输入上表现出色但在其余输入上崩溃的模型。
匹配标签分布。 如果你的任务是分类,并且 30% 的实际案例应标记为“不确定”,那么你的示例应包含大约 30% 的“不确定”标签。模型从示例中吸收基础比率并将其用作先验知识。
格式一致性比措辞更重要。 示例格式(末尾标点、大小写、空格)的微小变化会导致比你预期更多的输出差异。使所有示例在结构上保持一致。
思维链:草稿板模式
“一步一步思考”有效,但它是思维链提示的最低保真度版本。生产级版本是草稿板模式:你给模型一个明确的推理部分,然后才生成最终答案,最终答案是单独解析的。
<task>
将此客户投诉分类为:账单、技术或一般问题。
首先,在 <reasoning> 标签中推理投诉,然后将你的分类输出到 <category> 标签中。
</task>
<complaint>
我的发票上显示了一笔我未授权的费用,但门户网站也无法访问。
</complaint>
模型随后生成:
<reasoning>
客户提到了未经授权的费用(账单问题)和无法访问的门户网站(技术问题)。
推动此工单的主要投诉似乎是未经授权的费用。
</reasoning>
<category>billing</category>
你只解析 <category>。推理是提高分类质量的内部脚手架——你不会将其暴露或在下游依赖它。
这种模式很重要,因为:
- 在受限部分进行推理可以防止它渗入解析输出
- 你可以提示特定的推理步骤,而不是“一步一步思考”——例如,“首先识别用户在抱怨什么,然后识别他们要求解决什么”
- 验证步骤可以嵌入:“在你的推理之后,检查你的答案是否与上述示例一致”
对于复杂任务,这种结构化的思维链通常能弥合提示与微调之间的大部分性能差距。
提示词漂移:生产环境的隐形杀手
有一个未能得到足够重视的故障模式,那就是提示词漂移(prompt drift):未经协调的修改缓慢累积,逐渐降低性能,直到发生灾难性故障。
一个典型的案例:一个面向客户的团队为了“改善语气”对系统提示词做了一个小改动——仅仅增加了三个词。结果在几小时内,结构化输出错误率飙升。创收工作流程停滞,直到工程师手动回滚了更改。没有人将这次修改标记为高风险,因为它看起来只是表面上的改动。
提示词漂移之所以隐蔽,是因为:
- 更改通常是增量进行的,并且缺乏文档
- 回归通常是渐进的,难以追溯到具体的修改
- 进行更改的人很少监控重要的下游指标
解决方案是将提示词像代码一样对待:
对每个提示词进行版本控制。 提示词应该存在于你的代码库中,而不是配置界面里。每次更改都应该有一个解释原因的提交信息。
在部署提示词更改之前运行回归测试套件。 你应该有一套黄金示例——带有预期输出的输入——以便在每次更新提示词时进行测试。这不需要一个复杂的评估框架;一个电子表格和一个调用 API 的脚本足以捕捉大多数回归。
在生产环境中锁定特定的模型版本。 模型提供商会更新模型,即使 API 签名没有改变,版本之间的行为也可能发生变化。始终为生产工作负载指定明确的模型版本标识符。审慎升级,而非默认升级。
拆解一体化提示词
最可靠的提示词通常不是一个长篇大论的提示词,而是一个由短小、专注的提示词组成的流水线,每个只做一件事。
直觉是:一个被要求同时提取信息、进行推理并格式化输出的模型,在一次调用中就包含了三种不同的故障模式。任何子任务的失败都会影响整体。将其拆分为三个带有中间验证的顺序调用,意味着故障被隔离,重试也更精确。
一个内容审核流水线可能看起来像这样:
- 提取提示词:“从这段文本中提取具体的陈述。返回一个 JSON 字符串列表。”
- 分类提示词:“对于列表中的每项陈述,将其分类为:事实、观点或可验证。返回 JSON。”
- 决策提示词:“根据这些已分类的陈述,此内容是否应该被标记?返回:是、否或需要审查(并附上理由)。”
每个步骤都有清晰的输入、清晰的输出以及特定的故障模式。你可以独立测试每个步骤,单独监控每个步骤,并在不重新启动整个流水线的情况下重试每个步骤。
成本考量是真实存在的——更多的 API 调用意味着更高的延迟和开销。在拆分前进行性能分析:如果一体化提示词已经足够可靠和快速,就不要拆分它。但如果你遇到非确定性故障或难以调试,分解几乎总是有帮助的。
哪些方面没有你想象的那么重要
领域中一些被过度关注的事情:
措辞的巧妙。 精心设计的提示词措辞(如“你是一个拥有 20 年经验的专家系统……”)在现代模型上回报递减。清晰的任务规范、良好的示例和结构化约束比精雕细琢的措辞更有效。
礼貌和威胁。 最近的模型显示,基于礼貌用语或施压语言的行为变化可以忽略不计。为可靠性而设计,而不是为了模型的心理。
温度(Temperature)调整。 温度对于创意任务和采样多样性很重要。对于需要一致输出的结构化生产任务,从 0 开始,只有当你看到有问题的重复时才提高它。
正确的视角
2025 年的提示词工程,与其说是“破解”模型,不如说是为概率系统构建可靠的接口。交付持久 LLM 功能的工程师将提示词视为基础设施:像对待任何其他服务依赖项一样,进行严格的版本控制、测试和监控。
在生产环境中持续运行良好的提示词具有几个共同特点:它们具有明确的结构,包含足够的示例来真正引导模型,其输出经过验证,并且有人负责,其责任与拥有数据库模式(schema)的责任相同。这并不特别——这只是将良好的工程实践应用于一个新的接口。
