【声明】本博客所有内容均为个人业余时间创作所述技术案例均来自公开开源项目如GithubApache基金会不涉及任何企业机密或未公开技术如有侵权请联系删除背景上篇 blog【AI】【Agent】联网使用大模型DashScopeOpenAI给出了 DashScope 和 OpenAI 两种 SDK 的测试脚本可以在控制台中看到当前的token剩余额度然后对比了两个 SDK 的区别主要是模型区别接着开始分析两种 SDK 都使用的message消息格式这种messages是对话历史的结构化表示模型可以从中知道当前会话已经发生了什么从而让模型能上下文连贯地回复然后解释了下message中的role角色下面继续分析Agent上篇 blog 简单介绍了message中的各个 role 角色message中的 role 字段是大模型理解对话结构的核心机制大模型会根据这条消息判断是谁说的然后决定如何响应虽然 role 看起来只是个字符串比如systemuserassistant但其作用远不止标记身份而会直接影响模型的行为模式输出风格和上下文理解下面再详细分析下这三种角色首先是system属于系统指令可以设定 AI 的角色目标规则输出格式等通常只出现在对话开头也可以中间插入但不推荐对用户不可见理想情况下并且权重最高模型会优化遵守system指令比如发送如下消息{role:system,content:你是一个严谨的 Python 程序员只回答代码相关问题拒绝闲聊。}{role:user,content:我们来闲聊一下如何}模型会拒绝回答比如再换个角色{role:system,content:你是一个贴心的大姐姐。。}{role:user,content:我们来闲聊一下如何}模型会贴心的回答接下来是user属于用户输入是触发 AI 响应的信号代表着人类用户的提问指令或数据每次与大模型的交互都必须以user消息结尾可以包含文本JSON代码甚至多模态提示在支持的模型中而且即使是做 Agent最终给模型的 prompt 也要封装成user消息比如{role:user,content:写一个快速排序函数}可以得到内容总共 2K 个 token有点多后面可以加限制优化下… 目前是免费额度先用着吧最后是assistant这里保存的是 AI 的回复用于多轮记忆记录模型之前的回答形成对话历史其特点有不会触发新的回复只是存档必须与user成对出现比如user→assistant→user→assistant…在流式调用中可以逐步构建assistant比如下面这个例子有两轮对话{role:user,content:你好},{role:assistant,content:你好有什么我可以帮忙的吗},{role:user,content:你能写代码吗}模型会知道这是第二轮提问且上下文是先打招呼后问能力OK下面来看role角色如何影响模型行为的首先是system当没有设定system角色时模型会用默认身份比如直接询问{role:user,content:你是谁}会得到【我是通义千问…】这样的通用回答而当设定角色后system会直接覆盖掉模型的默认身份比如先设定身份{role:system,content:你是孙悟空}然后再询问{role:user,content:你是谁}此时得到模型进行角色扮演的回答【俺老孙乃齐天大圣孙悟空…】OK再来对比是否包含历史assistant首先如果单独提问messages模型理解[user: 11? ]单独问题[user: 11?, assistant: 2, user: 22? ]连续的数学问答回复要保持简洁如果缺少中间的assistant模型可能会认为22?是第一个问题甚至重复解释加法规则浪费tokens另外再列举一些常见的错误写法把system放中间应该放在最开始{role:system,content:你是孙悟空},{role:user,content:你是谁},{role:system,content:你是猪八戒},# ← 模型可能忽略{role:user,content:你是谁},这里模型会忽略掉第二个角色只保留第一个角色扮演孙悟空因为大多数模型只在开头读取system指令连续两个user比如{role:user,content:你好},{role:user,content:在吗}# ← 模型不知道要不要回复第一条中间应该加入assistant比如user→assistant→user用错误的role名称比如{role:human,content:...}# ← 无效必须是 user模型只认systemtuserassistant三个关键字OK本篇先到这里如有疑问欢迎评论区留言讨论祝各位功力大涨技术更上一层楼更多内容见下篇 blog