很多人调用大模型API只会单轮对话,聊完一句模型就失忆。 核心秘密就在于维护 messages 消息列表, system/user/assistant 三者配合完成上下文记忆。下面完整Demo基于智谱GLM‑4‑Flash,复制修改密钥即可运行。
依赖安装
pip install requests
完整源码
"""messages 三大角色说明- system:系统设定,给 AI 规定身份、回答规则,全程生效- user:用户,人类发出的提问、需求- assistant:助手,AI 之前回复的内容,用于保存聊天上下文"""import requestsclassZhipuAI:def __init__(self):# 替换为你自己的智谱API Key self.api_key ="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" self.url ="https://open.bigmodel.cn/api/paas/v4/chat/completions" self.headers ={"Authorization": f"Bearer {self.api_key}","Content-Type":"application/json"}# 初始化对话列表,预先写入system角色,设定AI身份为小魏 self.messages =[{"role":"system","content":"你是AI小助手小魏,回答简洁友好,分点回答每条单独换行,排版清晰"}]def chat(self, prompt, model="glm-4-flash"):# 打印用户输入print(f"吕浩:{prompt}")# 1.把用户提问追加到消息列表 user self.messages.append({"role":"user","content": prompt})# 组装请求体,把完整历史消息全部传给大模型接口 payload ={"model": model,"messages": self.messages}# http请求调用智谱接口,超时30秒 resp = requests.post(self.url, headers=self.headers, json=payload, timeout=30) res_data = resp.json()# 解析拿到AI返回的回答 ai_answer = res_data["choices"][0]["message"]["content"]print(f"小魏:{ai_answer}\n")# 2.将AI回答存入assistant,保存对话历史,实现记忆 self.messages.append({"role":"assistant","content": ai_answer})return ai_answerif __name__ =="__main__": ai =ZhipuAI() ai.chat("你叫什么名字?") ai.chat("你能做什么?") ai.chat("你喜欢做什么?") ai.chat("我第一次问你的答案是啥?") ai.chat("你那觉得,你爱我或者说,我爱你嘛?我们能一直在一起嘛?") ai.chat("请简洁介绍大模型对话 messages 里 system、user、assistant 三个角色分别是什么作用")
代码逐块解读
1.类初始化 __init__
def __init__(self): self.api_key ="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" self.url ="https://open.bigmodel.cn/api/paas/v4/chat/completions" self.headers ={"Authorization": f"Bearer {self.api_key}","Content-Type":"application/json"} self.messages =[{"role":"system","content":"你是AI小助手小魏,回答简洁友好,分点回答每条单独换行,排版清晰"}]
api_key:平台申请的密钥,用来鉴权,千万不要把真实密钥直接公开发布。url:智谱开放平台接口地址。headers:请求头,携带身份凭证,告诉接口发送的是json数据。messages:对话历史容器,是实现多轮记忆最核心变量。- 数组最开始放一条
system消息,从一开始就定义AI的人设、输出格式,全局生效。
2.chat方法:一次完整对话逻辑
def chat(self, prompt, model="glm-4-flash"):print(f"吕浩:{prompt}") self.messages.append({"role":"user","content": prompt}) payload ={"model": model,"messages": self.messages} resp = requests.post(self.url, headers=self.headers, json=payload, timeout=30) res_data = resp.json() ai_answer = res_data["choices"][0]["message"]["content"]print(f"小魏:{ai_answer}\n") self.messages.append({"role":"assistant","content": ai_answer})return ai_answer
执行流程:
- 将当前用户提问,以
user角色加入消息列表。 - 将完整的全部messages数组打包发送给大模型接口。
✨关键点:大模型本身没有内存,它不知道上一轮聊了什么,全部上下文都是我们程序把历史消息塞过去的。
- 发送http post请求,设置30秒超时防止卡死。
- 解析返回json,取出AI输出文本。
- 把AI返回的回答,以
assistant角色追加进messages。 如果漏掉这一步,下一轮对话AI就会失忆,记不住自己上一轮说过什么。 - 返回回答文本,控制台打印聊天效果。
3.主程序入口
if __name__ =="__main__": ai =ZhipuAI() ai.chat("你叫什么名字?") ai.chat("你能做什么?")...
实例化对象,连续多次调用chat,模拟人持续聊天。 运行之后控制台可以看到一问一答,模型可以记住前面全部对话,比如可以反问“我第一次问你的答案是什么”,模型可以正确回忆。
messages三大角色通俗解释
- system 系统角色 相当于给AI下达初始指令,设定身份、性格、输出规范。写在消息列表最前面,每一轮请求都会读取这条消息。
例子:你是小魏,回答简洁友好。
user 用户角色代表人类的输入,每一次我们说的话,都包装成 role:user放到数组。
assistant 助手角色代表大模型输出的回复。必须把AI输出存进messages,下一次请求一起传给接口,模型才能看见自己之前的回答,实现“记忆”。
消息数组的顺序有意义,严格遵循:system → user → assistant → user → assistant……循环。
常见问题与坑
为什么AI失忆?大概率忘记 append(assistant),只追加user消息,模型看不到自己之前的回复。
密钥泄露风险代码里硬编码密钥,发布到公众号/GitHub会被别人盗用,产生扣费。正式建议使用环境变量读取key。
上下文越来越长多次对话后messages会越来越大,token消耗上涨,长对话需要做消息截断,丢弃最早的历史。
网络异常没有捕获异常示例代码没有try‑except,生产环境需要捕获超时、接口报错、返回异常json。
扩展:增加重置对话方法
def reset_chat(self):"""清空历史,重置会话,保留system人设""" self.messages =[{"role":"system","content":"你是AI小助手小魏,回答简洁友好,分点回答每条单独换行,排版清晰"}]
公众号小提示
- 把示例里的api_key全部替换为占位符
xxxxxxxx,提醒读者填入自己的密钥。 - 可以配一张简单示意图展示消息流转:
system→user请求→模型输出assistant→存入列表,循环。 - 结尾引流话术:
看懂这个小Demo,就搞懂绝大多数大模型应用底层多轮对话原理。复制代码即可本地跑起来,动手试一试。 关注我,持续分享Python、大模型实战小案例。