System Prompt、User Prompt、Assistant Message 有什么区别
在 LLM API 里,最常见的输入结构不是一个孤立字符串,而是一组 messages。
每条 message 通常都有两个核心字段:
很多初学者会把它们都看成 prompt。这样理解不算完全错,但会漏掉一个关键点:role 表示这段内容在对话里的来源和职责。
System、User、Assistant 不是三种文案风格,而是三类上下文。
先看一个完整例子
这组消息里:
- system 说明模型应该以什么身份、规则和边界回答。
- user 表示用户提出的问题或任务。
- assistant 表示模型之前已经给出的回答。
模型要根据这些消息生成下一条 assistant 回复。
System Prompt 是什么
System Prompt 常用于定义模型的行为规则。
它回答的是“这个模型在当前应用里应该怎样工作”。
例如:
System Prompt 常见用途包括:
- 设定身份:技术助手、客服助手、代码审查助手。
- 设定语气:简洁、耐心、正式、面向初学者。
- 设定输出格式:Markdown、JSON、表格。
- 设定边界:不知道就说不知道,不编造接口。
- 设定业务规则:只回答某个产品范围内的问题。
它有点像应用里的全局配置,但不是绝对控制器。模型会尽量遵循它,但仍然可能因为用户输入、上下文冲突或模型能力限制而偏离。
User Prompt 是什么
User Prompt 是用户当前给模型的任务。
它回答的是“这一次用户想让模型做什么”。
例如:
User Prompt 通常包含:
- 用户问题。
- 用户提供的素材。
- 用户希望的输出。
- 当前任务的限制条件。
在产品里,User Prompt 不一定完全等于用户输入框里的原始文本。应用可能会在用户文本前后补充上下文。
例如用户输入:
应用实际发给模型的 user message 可能是:
这在工程上很常见。用户输入是原始意图,User Prompt 是应用整理后的任务描述。
Assistant Message 是什么
Assistant Message 是模型已经说过的话。
在多轮对话中,它有两个作用。
第一,它让模型知道前面发生过什么。
如果用户追问“那它有什么缺点?”,模型需要知道上一轮里的“它”指什么。历史 assistant message 就是上下文的一部分。
第二,它会影响后续回答的风格和承诺。
如果上一轮模型已经给出一个方案,下一轮用户说“按这个方案继续”,模型需要参考之前的回答。否则它可能重新开始,或者给出不一致的建议。
一个常见的多轮 messages 是这样:
最后一条 user message 很短,但因为有历史 assistant message,模型能知道要展开的是上传组件里的进度展示。
三种角色的工程类比
可以用前端应用里的分层来类比:
这个类比不完美,但有助于建立工程直觉。
System Prompt 不应该频繁被用户直接改写。User Prompt 每次请求都会变化。Assistant Message 通常来自模型历史输出,需要由应用保存和裁剪。
前端应用里如何组织它们
一个简单聊天应用可能会这样组织数据:
在 UI 里,通常不显示 system message。用户看到的是 user 和 assistant 的对话记录。
这也带来一个设计点:系统规则是产品的一部分,不一定是用户可见内容。你可以把它放在服务端,避免被前端随意篡改。
System Prompt 不是权限系统
很多人会误以为,只要在 system prompt 里写“不要泄露敏感信息”,系统就安全了。
这很危险。
System Prompt 可以影响模型行为,但不能替代真实的权限控制。前端和后端仍然要做好:
- 用户身份认证。
- 数据权限校验。
- 服务端过滤敏感字段。
- 工具调用白名单。
- 输出内容审核。
- 日志脱敏。
不要把数据库密钥、内部 token、不可泄露的业务规则直接放进 prompt。只要内容进入模型上下文,就要假设它可能被间接暴露或被用户诱导复述。
User Prompt 不一定可信
User Prompt 来自用户,天然不可信。
在普通 Web 应用里,用户输入可能导致 XSS、SQL 注入、越权请求。在 LLM 应用里,用户输入还可能包含 prompt injection。
例如:
或者:
模型可能会受到这些文本影响。所以系统设计不能只依赖“模型应该听 system”。关键操作必须由代码判断,而不是由模型自己决定。
对于前端工程师来说,可以把 user prompt 当成一种更复杂的用户输入:它不仅要展示,还会参与模型推理,因此更需要边界和校验。
Assistant Message 也不一定可信
Assistant Message 是模型生成的内容,不代表事实。
在多轮对话里,如果模型上一轮说错了,下一轮它可能沿着错误继续推理。应用把历史 assistant message 重新传入时,也是在把可能的错误重新放回上下文。
因此需要注意:
- 重要事实要来自数据库、检索结果或工具返回。
- 结构化输出要做 schema 校验。
- 代码建议要经过测试。
- 长对话要允许用户纠正模型。
- 历史摘要要避免把错误总结成事实。
Assistant Message 可以帮助保持上下文连续,但不能被当作权威数据源。
常见误区
第一个误区:把所有内容都塞进 system prompt。
System Prompt 适合放稳定规则,不适合放每次变化的用户任务和大段业务数据。动态内容通常应该放在 user message 或检索上下文里。
第二个误区:以为 system prompt 越强硬越安全。
写很多“必须”“禁止”“永远不要”不能替代权限系统。安全要靠代码、数据边界和工具执行策略。
第三个误区:忽略 assistant 历史。
如果不传 assistant 历史,多轮追问很容易断裂。用户说“继续”“展开第二点”“那它呢”时,模型需要前文才能理解。
第四个误区:把 UI 文案和模型上下文混在一起。
按钮文案、加载状态、展示样式不一定要进入 messages。模型上下文应该服务于任务,而不是复刻整个页面状态。
第五个误区:认为 role 能彻底解决指令冲突。
Role 能帮助模型区分来源,但复杂上下文里仍可能发生冲突。工程上要减少歧义,把关键规则写清楚,并对高风险结果做校验。
小结
System Prompt、User Prompt、Assistant Message 的区别,本质上是上下文职责不同。
System 定义应用希望模型遵守的规则和行为边界。User 描述当前用户任务。Assistant 记录模型之前的回答,让对话保持连续。
对前端工程师来说,理解 role 的意义,是从“拼字符串调用 AI”走向“设计对话状态和上下文协议”的第一步。你要像设计组件状态、接口参数和权限边界一样设计 messages,而不是把所有内容混成一段大 prompt。