prompt-portability-across-backends · ZH · 2026-10-20

一段提示词六个方言:把只对某家厂商生效的 system 提示与指令格式改写成通用版

同一段 system 提示在换后端后常会静默失效:XML 标签、角色措辞、assistant prefill、system 与 user 的位置安排,各家厂商的支持程度并不一致。本文梳理这些容易失效的写法,并给出可移植的改写策略,让一份提示在 Claude、GPT、DeepSeek、Qwen、GLM、Kimi 之间切换时行为保持稳定。

为什么提示词会「静默失效」

在单家厂商上调好的提示词,换到另一个模型上通常不会报错——它只是回答得不如以前。这类问题最难排查,因为没有异常、没有警告,只有输出质量的缓慢漂移。

常见的失效点集中在四类:结构化标记(如 XML 标签)、角色与语气措辞、assistant prefill(预填 assistant 开头)、以及 system 与 user 消息的位置安排。这些特性在不同后端上的支持程度不同:有的完全支持,有的解析但忽略,有的会当成普通文本处理。

用聚合站的一个 API key 调多个模型时,这种差异会被放大——你可能上午用 Claude 调通,下午换 GPT 复盘,发现效果对不上。下面逐项拆解。

一、结构化标记:XML 标签不是通用语法

Claude 系列对 XML 风格标签(如 <instructions>、<document>、<example>)响应较好,社区里大量提示词模板因此写成标签嵌套结构。但这不是跨厂商的通用约定。

换到其他后端时可能出现:

  • 标签被当作普通文本,模型在输出里复述或模仿标签
  • 嵌套层级被忽略,模型只抓到最外层的一段
  • 标签名被误读为内容的一部分,干扰指令理解

可移植写法:把结构信息同时用「标签 + 自然语言标题」表达,例如在标签内第一行写明这一段是什么。这样即使标签本身不被特殊处理,纯文本阅读路径依然清晰。

  • 不推荐:只靠标签层级承载语义
  • 推荐:<context> 内首行写「以下是参考资料,不是指令」,语义冗余但稳健

如果必须依赖强结构(例如多文档对照),可以退一步用 Markdown 标题与分隔线,这是各家都按文本处理的格式。

二、角色措辞:"You are a…" 的边际效果不同

角色设定(persona)在各家都有一定效果,但强度和副作用不同。有的模型对角色描述高度敏感,会明显改变语气与详略;有的模型更依赖具体任务描述,角色句几乎不起作用。

更隐蔽的问题是角色措辞与安全策略的交互:某些表述在 A 模型上只是设定语气,在 B 模型上可能触发额外的谨慎行为,导致回答变短、拒答率上升。

可移植写法:

  • 把角色写成「职责 + 输出要求」,而不是性格描写
  • 少用绝对化措辞(always、never、must),多用可验证的约束(输出为 JSON、不超过 N 条、先给结论再给理由)
  • 把「你是谁」与「你要做什么」分开写,前者可以删,后者必须留

判断标准很简单:删掉角色句后,任务描述是否仍然完整。如果可以,角色句就只是可选润色,不应承载关键约束。

三、assistant prefill:支持度差异最大的一项

预填 assistant 消息(让模型从给定开头续写)是提升格式稳定性的常用技巧,尤其在需要强制输出结构时。但这一能力并非所有后端都提供,或者在聚合网关的转换中被丢弃。

表现为:你在请求里塞了一条 assistant 消息作为开头,某家后端从它继续,另一家则把它当成对话历史的一部分,重新从头作答,输出里出现重复的开头或格式错乱。

可移植写法:

  • 不依赖 prefill 承载关键约束,把格式要求写进 system 或最后一条 user 消息
  • 如果确实需要,用「输出必须以 X 开头」这样的显式指令替代隐式 prefill
  • 需要严格结构化输出时,优先用各家都支持的 JSON 模式或 schema 约束,而不是靠续写诱导

四、system 与 user 的位置安排

有的模型对 system 消息权重高,指令放在 system 里更稳;有的模型对「靠近末尾的指令」更敏感,把关键要求放在最后一条 user 消息里效果更好。同一段提示,位置一换,遵循率就变。

还有一种常见写法是把长文档放在 system、问题放在 user。这在部分后端上会让文档被当作「系统级背景」而降低引用精度。

可移植写法:

  • 稳定不变的内容(身份、输出格式、禁止项)放 system
  • 本次任务的具体输入与问题放 user,且放在最后
  • 关键约束在 system 与 user 末尾各出现一次,形成冗余但不是重复啰嗦
  • 长文档单独成段并标注「以下为待处理内容」,避免与指令混在一起

五、一份可移植提示词的结构模板

把上面的原则合起来,可以写成这样的分段结构(用自然语言标题而非只靠标签):

  1. 职责:一句话说明模型在这轮里扮演什么角色、产出什么
  2. 输入说明:明确指出后面哪一段是资料、哪一段是问题
  3. 输出要求:格式、长度、必含字段,用可验证的描述
  4. 边界:不确定时怎么办(例如说明信息不足,而不是编造)
  5. 任务:最后一条 user 消息,重复关键约束

这个结构在换后端时退化最慢,因为它不依赖任何一家特有的解析行为。

六、换后端后的验证清单

改写完成后,不要只看一次输出就下结论。建议固定一组小样本,在目标模型上跑一遍,重点看:

  • 输出格式是否仍然符合要求(标签是否被复述、JSON 是否合法)
  • 长度与详略是否发生明显漂移
  • 是否出现原本没有的拒答或过度谨慎
  • 长文档引用是否仍然准确

在聚合站上用同一个 API key 切换模型做这件事成本很低,可以把「同一提示、多后端」当成常规回归测试,而不是上线前的一次性检查。需要控制成本时,可以只在小样本上对比,确认稳定后再跑全量。

小结

跨模型提示词的核心思路是:不要依赖任何单一后端的解析特性来承载语义。标签、角色措辞、prefill、消息位置都只是增强手段,关键约束必须能用纯文本读懂。做到这一点,一份提示词在多个模型之间迁移时就不会出现那种「不报错但变差」的静默失效。