原型可能从一个内联字符串开始。当提示需要负责人、审核、回滚、数据处理、多项功能或多种语言,或需要可测量行为时,生产压力就会出现;这可能发生在发布前,并没有通用时间表。
你会想只修改指令的一部分,而不影响其他部分;想让不同客户等级获得不同的行为;想对不同版本进行A/B测试;出现故障时想要回滚;还想知道提示上次何时更改、为何更改。
生产提示设计会明确这些选择。提示词文本只是受治理的发布和运行系统中的一项制品。
本文用三层编辑架构说明负责人和变更节奏,再展示如何映射到提供商API。它是一种参考设计,并非通用传输格式。对于安全边界,请遵循OWASP提示词注入指南:分离指令和数据有助于审核与评估,但任何提示词模板都无法建立授权或隔离边界。
生产提示工作包含两类独立制品:可复用模板和每次请求的数据。像代码一样对模板进行版本控制。只要渲染后的提示和模型响应包含用户、客户或内部数据,就应将其视为敏感日志。
映射到API的三层编辑架构
这种设计分离三个编辑关注点:
系统层。 相对稳定的行为、身份和约束。由负责跨功能AI行为的团队所有。
开发者层。 特定功能的指令、工具使用政策和输出要求。由功能团队所有。
用户与运行时层。 用户请求加上获授权客户数据、对话历史和检索知识等动态上下文。针对每次请求或对话轮次构建。
将负责人、稳定政策、功能指令和运行时数据混在一起,会让变更更难审核、评估、缓存和回滚。应在有助于控制时分离它们;如果提供商或应用采用不同表示方式,不要强行要求三个API字段。
指令权限和数据位置相互关联,但并不相同。信任层级决定消息冲突时哪条指令优先;数据位置决定应用在哪里携带动态或不可信内容。把检索文本放在用户或上下文字段,不会让它获得授权、变得准确或安全。身份、租户访问、数据最小化、工具权限和输出验证必须在模型之外执行。
分离这些层次是基础:
┌─────────────────────────────────────┐
│ 系统层(相对稳定) │ 身份、行为、政策意图
├─────────────────────────────────────┤
│ 开发者提示(按功能) │ 功能指令、工具、格式
├─────────────────────────────────────┤
│ 用户提示(按调用) │ 用户查询、上下文、对话
└─────────────────────────────────────┘
各模型API表达这些层次的方式并不相同:
- OpenAI:在Responses API中,应用级指令应使用顶层
instructions参数或developer消息,用户输入使用user消息。管理多轮流程时,不要假定上一条响应的指令会自动延续。 - Anthropic:将设计映射到Claude Messages API、其系统指令机制、消息角色和工具定义;不同模型和平台支持的角色位置可能不同。
- Gemini:将设计映射到
system_instruction和请求内容,并使用所选API的独立工具配置。
使用针对提供商的适配器和集成测试。不要照搬API角色名称,并假定其优先级、持续性或工具行为等同。
第1层:系统提示
在这种编辑模式中,系统层定义跨功能角色和行为。目标是让它比功能指令更少变更,但每次变更仍需进行版本管理和评估。
良好的系统提示包括:
身份。 AI是谁。“你是 [公司] 的AI助手,专注于 [领域]。”
语气和风格。 它说话的方式。使用具体特征,而不是含糊的形容词。
必要的行为约束。 模型应拒绝、升级、披露或格式化什么。安全、权限和不可逆操作控制应由应用代码和下游系统执行,而不能只依赖这段文本。
行为模式。 它如何处理常见情况,例如拒绝、升级和不确定性。
安全与合规。 必需的披露、监管规则和内容政策。
不应包含:
- 特定功能的指令(“销售邮件要做X”)。
- 动态上下文(“用户的订单历史是……”)。
- 工具描述(应放在其他位置)。
- 经常变化的内容。
系统提示的长度应以经评估的行为需求为准。短提示可能已经足够,长提示也仍可能遗漏关键规则;不要追求固定字数范围,而应衡量指令冲突、任务质量、延迟和token成本。
一种行之有效的模板:
你是 [name],是 [company / context] 的AI助手。
## 你的职责
[2-3 sentences on what you do]
## 语气和风格
- [Specific trait 1]
- [Specific trait 2]
- [Specific trait 3]
- 不要 [anti-pattern 1]
- 不要 [anti-pattern 2]
## 硬性约束
- 绝不 [hard rule 1]
- 绝不 [hard rule 2]
- 始终 [hard rule 3]
## 如何处理不确定性
- 如果你不知道某项事实:明确说明。
- 如果用户请求超出范围:说明你能提供哪些帮助。
- 如果请求可能造成伤害:拒绝并解释原因。
## 格式要求
- 默认使用纯文本
- 展示代码或结构化数据时使用Markdown
- 保持简洁;不要用空话填充响应
这是整个系统的主干。每次交互都会经过它。对它的更改应审慎且少见。
第2层:开发者提示
开发者提示针对具体功能。不同功能使用不同的开发者提示。
摘要功能的开发者提示:
任务:为下方文档生成摘要。
要求:
- 3-5个要点
- 每个要点都是一个完整句子
- 关注事实和具体主张,不要描述印象
- 如果文档包含数字,请列出最重要的数字
- 不要包含营销用语或推测
- 如果文档在重要事项上含糊不清,请指出
格式:仅使用普通Markdown项目符号,不要前言。
代码审查功能的开发者提示:
任务:审查下方代码差异。
输出一个JSON对象,其中包含:
- summary:用1-2句话概述变更
- concerns:具体问题数组(每项包含:file、line、severity、description)
- suggestions:改进建议数组(每项包含:file、line、suggestion)
- approved:布尔值(没有阻塞性问题时为true)
严重级别:
- "blocker":合并前必须修复
- "warning":应该处理,但不阻塞合并
- "nit":风格问题,可选
重点关注:
- 逻辑错误
- 安全问题
- 性能问题
- 缺少测试覆盖
- 命名或结构不清晰
忽略:
- 格式(由格式化工具处理)
- 主观风格偏好
每项功能都有自己的开发者提示。它们分别存储、分别进行版本控制、分别评估。
第3层:用户提示
用户层是动态的。它通常包含:
用户的实际请求。 “请帮我总结这份文档。”
系统检索到的上下文。 来自RAG的文档、客户历史、对话历史。
每次调用的变量。 用户姓名、时区、语言偏好、账户等级。
这一层在调用时通过程序构建。结构通常如下:
{conversation_history_summary}
{retrieved_context}
用户请求:{user_query}
其他上下文:
- 用户姓名:{name}
- 用户时区:{timezone}
- 用户等级:{tier}
具体结构取决于功能。原则是:数据放在这里,而不是放在系统或开发者提示中。
模板化纪律
生产提示由模板构建。在代码中内联拼接字符串是原型做法,无法扩展。
一个简单的模板系统:
from string import Template
SUMMARIZE_TEMPLATE = Template("""
$conversation_summary
Document to summarize:
$document
User's specific instructions: $user_instructions
""")
prompt = SUMMARIZE_TEMPLATE.substitute(
conversation_summary=summarize_conversation(history),
document=document_text,
user_instructions=user_query,
)
更复杂的方案是使用支持条件和局部模板的模板库(Jinja2、Handlebars)。
{% if user_tier == "enterprise" %}
You have access to advanced analysis features.
{% endif %}
{% if retrieved_context %}
Relevant context from your knowledge base:
{{ retrieved_context }}
{% endif %}
User's request: {{ user_query }}
模板化可以防止通过变量实施提示注入(在适当情况下转义用户输入),支持条件逻辑,并保持提示结构一致。
选择受治理的唯一事实来源
把生产提示词视为有版本记录的发布制品。唯一事实来源可以是存储库、自有注册表或服务,也可以是带编辑界面的托管产品。应根据治理和运行需求选择,而不是假设一种存储方式适合所有团队。
对于以代码管理的提示词,仓库中的prompts/目录加上每个提示词一个文件,是清晰的起始模式:
prompts/
system/
main.txt
customer-support.txt
code-assistant.txt
features/
summarize.txt
classify-ticket.txt
generate-email.txt
templates/
base.j2
每个文件都可以有自己的提交历史和PR审核,而生产部署引用已知的代码版本。
这很重要,原因如下:
- 差异可见。 提示更改时,差异会出现在PR中。审查者能准确看到变更内容。
- 回滚。 变更破坏功能时可以还原。
- 历史记录。 “我们何时更改了提示中的退款政策?”“为什么会有这一段?”——可以通过git blame找到答案。
- 工具集成。 检查工具、验证器和评估套件都能与文件形式的提示集成。
明确比较主要选项:
| 唯一事实来源 | 适用情形 | 必需控制 |
|---|---|---|
| 存储库 | 随应用代码发布、由工程团队拥有的提示词 | 分支保护、代码负责人、脱敏夹具、环境晋级、部署身份、回滚到已知提交 |
| 自有注册表或服务 | 运行时选择、独立提示词发布、多个产品或语言 | 基于角色的访问控制、不可变版本、批准记录、环境隔离、已认证客户端、加密、审计事件、导出和经过测试的回滚 |
| 托管服务或编辑界面 | 非工程人员协作或实验运维 | 基于角色的访问控制、最小权限角色、审核工作流、版本来源、生产访问隔离、数据处理审核、导出和回滚 |
对于小型原型,内联字符串可用,但难以发现和独立发布。如果编辑界面的权限、审核、来源记录、部署和回滚控制符合工作流风险,它也可以是合适选择。从聊天窗口粘贴的提示词应与其他候选条目一样,进入相同的审核、脱敏和评估路径。
不要提交生产对话、客户记录、支持工单、内部文档,或包含敏感变量的渲染后提示。源代码管理系统用于保存可复用模板、测试夹具和经过清理的评估示例。真实跟踪记录应保存在具备保留策略、访问控制和脱敏能力的可观测性存储中。
运行时注册表与服务
对于频繁变化的提示——A/B测试、用户等级变体、特定语言区域的提示——基于文件的源代码管理速度太慢。
可以使用数据库或服务存储提示版本及其元数据。
prompt = prompt_service.get(
name="summarize",
version="v3",
locale="en",
user_tier="enterprise",
)
该服务维护:
- 每个提示的当前版本和历史版本。
- 元数据:何时添加、由谁添加、为何添加。
- 每个版本附带的评估分数。
- 回滚能力。
工具包括PromptLayer、Helicone或内部自建方案。对于大多数团队,使用简单数据库模式自行构建就足够了。
界面至关重要。工程师和非工程人员(产品、内容)都应该能够编辑提示,但变更上线前必须经过审查并通过评估。
以评估作为变更门禁
每次提示变更都要在部署前经过评估。对于严肃的生产系统,这是不可妥协的要求。
流程如下:
- 工程师或非工程人员起草提示变更。
- 使用评估套件运行该变更。
- 在审查变更的同时审查评估结果。
- 如果评估通过(没有回归,最好还有改进),变更就可以获批。
- 部署已批准的变更。
- 部署后监控捕获评估遗漏的问题。
对于重要提示词,应维护有代表性的评估集,并在信号足够可靠、可以充当变更门禁时,把稳定且可自动化的检查放入CI。无法简化为自动评分的验收标准应使用专家或人工审核。记录测试内容、阈值、审核者和剩余不确定性。
这道门禁不能证明正确性。它让发布决定可检查,并为检测部署后的回归提供基线。
实用发布检查清单
提示版本上线前,应要求完成一份简短的检查清单:
| 检查项 | 要求 |
|---|---|
| 归属 | 提示有明确指定的负责人和审查者。 |
| 指令层 | 系统、开发者和用户/上下文数据相互分离。 |
| 模式 | 结构化输出具有模式定义和失败处理路径。 |
| 注入处理 | 用户提供的内容有清晰边界,绝不被视为指令。 |
| 评估 | 候选提示通过回归集和安全用例。 |
| 日志 | 模板版本、模型、延迟、成本及脱敏后的输入/输出均可观测。 |
| 回滚 | 无需大幅修改代码即可恢复之前已知良好的版本。 |
本文所链接的配套检查清单会将这些检查项转化为可重复执行的发布审查。
生产环境中的A/B测试
对于适合在线实验的提示词,与当前版本进行分阶段比较可以增加离线评估之外的真实世界信号。不要把真实流量用作首次安全测试,也不要为了收集数据而让用户接触风险明显更高的处理方式。
以下只是示例模式,并非默认流量比例:
- 95%的流量使用生产提示v3。
- 5%使用新的候选版本v4。
- 模型访问、工具权限和操作限制不得超过获准的生产边界。
- 在符合条件的流量上衡量任务成功、安全与政策错误、用户反馈、下游指标,以及经过审核的评估分数。
- 开始前定义最小样本、停止条件、负责人和一步回滚方法。
- 证据充分后,决定扩大、修订还是停止候选版本。
交付机制可以包括自有功能开关、部署配置、获准的提示词注册表或自定义路由。
注意事项:
- A/B测试只能捕获你所衡量的信号。如果没有用户反馈或下游转化指标,A/B测试提供的信息很少。
- 统计显著性需要足够的流量。对于低流量功能,A/B测试很难实施。
- 并行实验可能相互作用并干扰归因;应有意识地控制重叠。
- 根据产品、人群和司法管辖区考虑通知、同意、排除和审核义务。高影响或不可逆操作通常需要比流量划分更强的批准与可逆性。
提示的可观测性
每次生产大语言模型调用都应记录:
- 使用了哪个提示模板(名称、版本)。
- 替换了哪些变量;变量名称采用白名单,必要时对值进行脱敏。
- 仅在政策允许时记录最终渲染的提示;否则存储脱敏、抽样或哈希后的表示。
- 模型响应;敏感工作流中应进行脱敏或抽样。
- 延迟、令牌、成本。
- 下游信号(用户反馈、成功指标)。
你需要依靠这些数据来调试“为什么模型给这位用户的回答如此奇怪?”没有它们,就只能猜测。
存储位置可以是数据库表或可观测性工具。如果记录所有内容,成本是真实存在的(调用量 × 令牌数 × 存储);隐私风险同样真实存在。应按工作流决定哪些字段可以安全存储,默认对秘密和个人数据进行脱敏,并保持较短的保留期,除非出于合规原因需要保留更长时间。部分团队会进行抽样。
审查方面,可以每周定期阅读一批真实生产提示和响应样本。这能捕获评估遗漏的问题。
提示反模式
以下几种模式应避免:
反模式1:无人负责的多用途提示词。 大型系统提示词如果混合无关功能、政策、示例和运行时假设,可能难以审核、评估和回滚。长度本身不是缺陷,未经衡量的复杂性才是。
修复:在有帮助时按负责人和变更边界分离组件,删除重复或过时指令,并在有代表性的评估上比较修改后的设计。
反模式2:内联字符串拼接。
prompt = "You are helpful. " + (
"The user is a paid customer. " if user.tier == "paid" else ""
) + f"Their name is {user.name}. " + ...
脆弱、难以阅读,而且容易遭受注入。
修复:使用模板系统。
反模式3:过多用例共用同一提示。
一个“通用助手”提示同时用于撰写邮件、代码审查、客户支持和研究。这些任务彼此不同;同一提示无法针对其中任何一项进行优化。
修复:在共享系统提示之上,为每项功能使用专门的开发者提示。
反模式4:硬编码提示。
response = openai.chat.completions.create(
messages=[
{"role": "system", "content": "You are a helpful assistant..."},
{"role": "user", "content": query}
]
)
提示埋在代码中。无法在不部署的情况下编辑,无法进行A/B测试,也无法独立进行版本控制。
修复:提取到提示文件或服务中。
反模式5:没有评估覆盖。
某项功能随从未经过系统测试的提示一起发布。质量完全“凭感觉”,也无法检测漂移。
修复:为重要行为增加与风险相称的评估覆盖,包括失败和升级案例。
反模式6:将数据混入系统提示。
你是John的助手。他是一名premium客户,于2023年加入,居住在Tallinn,有47个未结工单。
现在系统提示每次调用都会变化。缓存失效,混乱随之而来。
修复:动态数据应放在用户/上下文层,而不是系统提示中。
反模式7:指令埋在中间。
帮助用户处理请求。保持礼貌。将输出格式设为JSON。不要使用Markdown。用户正在询问定价,因此引用数字时要谨慎。输出应为1-2句话。现在帮助用户。
重要指令会被淹没,模型可能遗漏。
修复:使用清晰的分节结构,将关键指令放在开头和结尾(近因效应会有所帮助)。
常见功能的具体模式
下面是一些针对特定功能的模式:
分类
任务:将以下文本归入下列类别之一:
- billing:付款、退款、订阅
- technical:缺陷、错误、集成问题
- account:登录、密码、个人资料变更
- feature_request:新功能请求
- complaint:没有具体可执行问题的一般性不满
输出一个JSON对象:{"category": "<one of above>", "confidence": "<high|medium|low>", "reasoning": "<1 sentence>"}
待分类文本:
{text}
模式:带定义的枚举类别、结构化输出、置信度和推理字段。
提取
任务:从下方文档中提取结构化数据。
模式:
- vendor_name:开具发票的公司
- invoice_number:文档上印刷的编号
- date:ISO 8601格式
- line_items:由 {description, quantity, unit_price, total} 组成的数组
- subtotal、tax、total:数字
规则:
- 如果字段不存在,使用null
- 数字应使用数值类型,而不是字符串
- 对于含糊情况,将 "needs_review" 设为true并作出解释
文档:
{document}
模式:明确的模式定义、类型要求、缺失数据处理、含糊情况升级。
带风格要求的生成
任务:围绕 {topic} 主题,面向 {audience} 撰写一篇 {format}。
风格:
- {Specific style trait 1}
- {Specific style trait 2}
- 避免:{anti-pattern 1}、{anti-pattern 2}
约束:
- 长度:{N} 字
- 包含:{required elements}
- 排除:{forbidden elements}
语气参考:
[Provide a sample of the desired voice]
输出:仅输出 {format},不要前言或后记。
模式:具体风格特征(而不是泛泛描述)、明确约束、使用参考样例锚定语气。
代理循环
你可以使用以下工具:
{tool_descriptions}
每轮执行以下步骤:
1. 思考需要做什么。
2. 判断是否需要工具。如果需要,则调用工具。
3. 观察结果后,判断是否还需要更多工具,或是否可以回答。
4. 获得足够信息后,生成最终答案。
约束:
- 每个请求最多调用5次工具。
- 如果5次调用后仍无法完成,请说明缺少什么。
- 绝不编造工具名称或参数。
- 根据工具结果采取行动前先进行验证。
用户请求:
{user_query}
模式:分阶段的工具使用流程、工具预算、明确验证和有边界的失败处理。
团队协作
生产提示通常涉及多类人员:
- 工程师 将提示接入系统、维护模板、管理部署。
- 产品人员 定义提示应实现的目标。
- 内容/营销人员 负责语气和风格指南。
- 领域专家 知道具体用例中的正确做法(法律措辞、医学术语等)。
一种实用模式是建立类似代码审查的“提示审查”流程,并让每个领域的适当人员参与审查。语气变更由内容人员审查,逻辑变更由工程人员审查,特定领域内容由领域专家审查。
对于法律、医疗、金融等敏感用例,提示可能需要正式审查和签字批准。应据此建立流程。
分阶段设门的提示成熟度计划
对于希望从“提示是代码中的字符串”转向“提示是受管理的基础设施”的团队:
阶段1:奠定基础。
- 清点会实质影响行为的提示词和提示词构建代码。
- 定义指令权限模型、运行时数据边界、负责人和提供商映射。
- 选择符合发布工作流的受治理唯一事实来源和模板方式。
- 设置能够识别已部署版本和结果、但不保留不必要敏感内容的隐私安全遥测。
阶段2:评估。
- 优先为风险最高、调用量最大的提示构建评估套件。
- 对重要提示词变更运行有代表性的评估,并在需要时进行领域审核。
- 将稳定的自动检查放入CI,同时让无法自动化的验收决定在审核记录中保持可见。
阶段3:运维。
- 在选定的存储库、注册表或服务中实现提示词版本管理。
- 增加分阶段发布和停止机制;只有符合条件的工作流才使用A/B测试。
- 构建工作流所需的质量、安全、政策、延迟、成本和下游信号监控。
- 建立提示变更审查流程。
不要承诺按日历完成这一结果。只有当测试表明提示发现工作已经完成、关键变更已纳入版本控制并设有门禁、回滚有效、遥测能够识别已部署版本,而且负责人能够演练事件响应时,才结束这一阶段序列。
将提示作为基础设施
生产提示词可以存储为字符串,但运行时是有版本记录的系统组件,周围还有组装、评估、发布、访问和可观察性控制。
指令层级定义权限,但不能保护运行时数据或工具操作。模板化可以减少组装错误,却不能防止提示词注入。受治理的唯一事实来源提供版本历史。与风险相称的评估为发布决定提供信息,遥测则检验预期行为在评估集之外是否持续。
所需严谨程度取决于风险和范围,但任何省略的控制都需要记录理由。发布声明应展示实际实施的版本管理、评估、发布、回滚和遥测证据。
在评估和生产遥测证明所选模型、提示词版本、数据路径、工具和政策在验收阈值内运行之前,可控性只是一个假设。随发布保存这些证据,按版本调查失败,并确保回滚可用。
从最小架构开始,明确负责人、权限、数据处理、评估、部署、回滚和证据。



