同样是给大模型发指令,为什么有的人把要求写在system里效果很好,换成user消息后模型就开始“不听话”?或者反过来,明明在system里写得清清楚楚,模型却在几轮对话之后忘得一干二净。这两个问题的根源都在于没有真正理解System Prompt和User Prompt的区别。本文将从消息结构、优先级、使用场景三个层面详细拆解这两类提示词的差异,并给出实用的组织建议。

一、从消息角色机制看两者的本质区别
无论是OpenAI的Chat Completions接口,还是国内各家大模型的对话API,消息列表中的每一条message都携带一个role字段。常见的取值有三种:system、user、assistant。role并不是一个可有可无的标记,它直接影响模型在推理时对这段文本的“态度”。
System Prompt通常位于消息列表的最前面,用来定义模型的身份、能力边界、输出风格和全局规则。它在训练阶段就被赋予了较高的权重,模型会将其视为“系统级指令”,倾向于在整段对话中持续遵守。而User Prompt则是用户在每一轮对话中发出的具体输入,可能是一个问题、一段待处理文本,或一项任务指令。模型会把user消息当作“当前需要响应的内容”,优先针对它生成回答。
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
model="gpt-4o",
messages=[
{"role": "system", "content": "你是一名专业的数据库工程师,回答简洁准确,涉及SQL时必须给出可执行示例。"},
{"role": "user", "content": "如何给已存在的表加一列并设置默认值?"}
]
)
print(response.choices[0].message.content)从上面的代码可以看到,system消息和user消息在结构上是并列的两条记录,区别只在于role的取值。但正是这个取值,让模型在处理时采取了不同的策略:system内容会被当作长期约束,user内容被当作即时请求。如果把两者的内容互换,模型可能会在回答完第一个问题后,就忘记自己应该扮演数据库工程师的角色。
二、优先级、作用范围与稳定性的差异
理解了两者的定位,还需要搞清楚它们在实际效果上的三处关键差异。
第一是作用范围。System Prompt是全局性的,一旦设定,理论上贯穿整个会话;User Prompt是局部性的,主要影响当前这一轮回答。很多“模型聊着聊着就跑偏”的问题,本质上是把全局规则写在了user消息里,随着上下文变长,早期user消息的影响力被稀释,规则自然失效。
第二是优先级。当system和user的内容发生冲突时,绝大多数模型会优先遵循system中的约定。比如system里写了“回答必须使用中文”,即使用户用英文提问,模型通常仍会用中文回答。这个特性可以用来做输出格式的兜底控制。
第三是token消耗与计费方式。两者在计费上没有区别,都会计入上下文长度,但组织方式会影响总token数量。把不变的规则放进system、只写一次,比在每一轮user消息里重复规则更省token,也更不容易因为重复而让模型产生“这些规则可能是临时的”的误解。
| 对比维度 | System Prompt | User Prompt |
|---|---|---|
| 典型位置 | 消息列表首位,仅出现一次 | 每轮对话中由用户发出 |
| 作用范围 | 整个会话全程生效 | 主要影响当前轮次 |
| 典型内容 | 身份、风格、格式、安全边界 | 具体问题、任务、待处理素材 |
| 冲突优先级 | 较高,通常覆盖user要求 | 较低,可被system约束 |
三、如何正确组织System Prompt与User Prompt
一个实用的划分原则是:把“你是谁、你永远怎么做”写进system,把“这次请你做什么”写进user。具体来说,System Prompt适合承载四类内容:角色定义(你是一名资深前端工程师)、输出规范(回答不超过300字,先给结论再给解释)、行为边界(不讨论与编程无关的话题)、知识背景(项目使用Vue3和TypeScript)。User Prompt则承载具体任务、输入数据、临时性要求。
需要注意一个常见误区:system并不是万能保险箱。当对话轮次很多、上下文接近窗口上限时,部分模型对开头system的遵循度也会下降。工程上的常见做法有两种:一是控制会话长度,及时做摘要压缩;二是在关键轮次的user消息中重申一次最重要的格式要求,形成双保险。
messages = [
{"role": "system", "content": "你是代码审查助手。输出规则:1.只指出问题,不重写全部代码 2.按严重程度排序 3.使用中文"},
{"role": "user", "content": "审查下面这段Python函数,重点看空值处理:\n\ndef get_user(uid):\n return db.query(User).get(uid).name"},
{"role": "assistant", "content": "发现两个问题:\n1. 严重:get(uid)可能返回None,调用.name会抛出AttributeError\n2. 一般:未处理uid非法输入"},
{"role": "user", "content": "第一个问题怎么修?给出最小改动方案。"}
]上面的多轮对话示例展示了一个良好结构:system只写一次且内容稳定,每轮user聚焦当前任务,assistant的历史回答留在消息链中,让模型能准确理解“第一个问题”指的是什么。这种组织方式既保证了规则持续生效,又让对话上下文自然连贯。
最后补充一点,部分模型还支持developer或assistant类型的system替代角色,或者像DeepSeek那样将system内容拼接到对话开头。无论底层实现如何,“稳定约束放前面、易变请求放后面”这条原则都是通用的。掌握System Prompt和User Prompt的分工,是写好提示词的第一步,也是让大模型应用输出稳定可控的基础。
System PromptUser Prompt大模型提示词修改时间:2026-09-13 18:28:48