🎭 大模型对话里的「三角关系」:System、User、Assistant 到底谁是谁?

当你第一次写 messages = [{"role": "user", "content": "..."}] 时,有没有想过:
为啥非要分三个角色?我直接一句话扔给 AI 不行吗?

行,但就像让演员上台不带剧本——能演,但容易演砸。


一、先认识这三位「戏精」

在大模型的对话系统里,每条消息都必须挂一个身份牌。这不是形式主义,而是让 AI 知道"这句话是谁说的"

角色 真实身份 职责 生活类比
🎬 system 导演/编剧 定规则、给背景、设约束 开机前给演员的剧本和指令
🙋 user 观众/甲方 提问题、下指令、给材料 观影时举手提问的人
🤖 assistant 演员/乙方 理解上下文,生成回答 台上表演的主角

二、为什么要分这么清?三个核心原因

原因 1:别把「剧本」当成「台词」

如果你把规则混在 user 里,AI 会懵:

# ❌ 错误示范:规则和问题搅在一起
messages = [
    {"role": "user", "content": "你是一个成本分析专家。请分析这张发票。"}
]
# AI 可能会回答:"好的,我是一个成本分析专家..." 
# 然后就没有然后了——它把规则当成问题回答了!

# ✅ 正确姿势:各司其职
messages = [
    {"role": "system", "content": "你是一位资深成本分析专家,擅长识别发票信息。"},
    {"role": "user", "content": "请分析这张发票。"}
]

system 是"后台指令",user 是"前台交互"。分开,AI 才知道该听谁的。


原因 2:多轮对话不能「串戏」

AI 没有真正的记忆,它靠的是消息列表里的上下文。如果不标记每句话是谁说的,它会把自己上次的回答当成新的指令,逻辑直接崩盘。

# 一段正常的多轮对话
messages = [
    {"role": "user", "content": "北京今天天气怎么样?"},
    {"role": "assistant", "content": "北京今天晴,25度,适合出门。"},
    {"role": "user", "content": "那明天呢?"}  
    # AI 看到"assistant"是自己,知道"那"指代天气,才能连贯回答
]

想象一下,如果不分角色,AI 看到历史记录里有一句"北京今天晴,25度",它可能会想:“这是用户在告诉我天气?还是让我评价天气?”

标记角色,就是给 AI 一个"记忆坐标系"。


原因 3:System 是开发者的「遥控器」

system 是开发者控制 AI 行为的秘密通道:

messages = [
    {
        "role": "system", 
        "content": "你是一位成本分析专家。请严格遵守:
1. 只回答与成本、预算、财务相关的问题
2. 涉及金额必须标注货币单位(如 ¥、$)
3. 不确定的信息要明确说明,禁止编造数据
4. 输出格式必须是 JSON,包含字段:item, cost, currency"
    },
    {"role": "user", "content": "分析这张采购单"}
]

这些规则如果放在 user 里,用户一句话就可能覆盖掉。放在 system 里,AI 会把它当作底层约束,优先级更高


三、实战:成本分析场景怎么搭?

回到你截图里的 CostAnalysisPipeline,一个优雅的对话结构应该是这样的:

class CostAnalysisPipeline:
    def LLM_QA(cls, llm_q):
        qa_template = f"### 待处理问题 ###
{llm_q}"

        messages = [
            # 🎬 导演发话:定调子、立规矩(长期有效)
            {
                "role": "system", 
                "content": "你是一位资深成本分析专家。工作原则:
- 聚焦成本、预算、财务领域,拒绝跑题
- 所有金额必须带货币单位
- 不确定时明确标注'无法确认',绝不编造
- 复杂分析优先用表格呈现"
            },
            # 🙋 用户提问:具体问题(每次不同)
            {"role": "user", "content": qa_template}
        ]

        response = cls.get_completion(messages)
        # 🤖 AI 的回答会自动以 assistant 角色返回
        answer = response.choices[0].message.content.strip()
        return answer

四、一张表看懂所有场景

你在做什么 system 写什么 user 写什么 assistant 是什么
首次提问 设定 AI 身份和专业领域 你的具体问题 AI 的第一次回答
追问/多轮 通常不变,保持连续性 新的问题或补充信息 AI 基于上下文的续答
调整 AI 行为 更新规则或输出格式要求 “请用表格重新整理刚才的回答” AI 按新格式输出
Few-shot 学习 描述任务类型 给 2-3 组「输入→输出」示例 AI 模仿示例回答新问题
角色扮演 “你现在是唐朝诗人李白” “写一首关于月亮的诗” AI 以李白风格创作

五、一句话总结

system 是幕后导演,user 是台下观众,assistant 是台上演员。

区分他们,就是让 AI 知道谁在说啥、该听谁的、该扮演谁

没有 system,演员没剧本;不分 user/assistant,演员会串戏。


附:常见误区

误区 真相
“system 可有可无” 简单对话可以不要,但专业场景必须有,否则 AI 行为不可控
“assistant 消息是我写的” 除非你在做 Few-shot 示例,否则 assistant 内容应该来自 AI 回复
“角色名可以随便改” 标准 API 只认这三个,自定义角色名会被忽略或报错
“消息越多越好” 上下文有长度限制,保留关键 system + 最近几轮 user/assistant 即可

💡 最后的小技巧:如果你发现 AI 总是"不听话",先检查你的规则是不是放在 user 里了。把它移到 system,效果往往立竿见影。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐