学习目标
- 学会多轮对话,跟 AI 来回聊,不是问一句就跑(搞定!✅)
- 理解 messages 数组是怎么累积对话历史的(搞定!✅)
- 做一个能持续聊天的简单程序(搞定!✅)
一、单轮 vs 多轮,有啥区别?
单轮对话(昨天干的)
你问一句,AI 回一句,完事。每次都是新开局,AI 不记得你之前说过啥。
你:你好
AI:你好呀!
你:我叫小明
AI:你好小明!(它其实不知道你之前说过啥,只是顺着你说)
多轮对话(今天要学的)
你问一句,AI 回一句,你再问,AI 记得之前聊的内容,能接着话题聊。
你:你好
AI:你好呀!
你:我叫小明
AI:你好小明!有什么可以帮你的吗?
你:帮我写个函数
AI:好的小明,你想写什么函数?
区别在哪? 多轮对话每次都要把之前的聊天记录一起发给 AI,这样它才知道上下文。
二、核心原理:messages 数组
昨天的代码
messages = [
{"role": "user", "content": "你好"} # 只有这一句
]
每次发请求只带当前这一句,AI 没有历史记忆。
今天的关键
messages = [] # 先建个空数组
# 第一轮
messages.append({"role": "user", "content": "你好"})
# 发请求,AI 回复 "你好呀"
messages.append({"role": "assistant", "content": "你好呀"}) # 把 AI 回复也存下来
# 第二轮(此时 messages 里已经有两句话了)
messages.append({"role": "user", "content": "我叫小明"})
# 发请求时,messages = ["你好", "你好呀", "我叫小明"]
# AI 知道前面聊过啥,所以能说 "你好小明"
重点:每次发请求,都要带上完整的 messages 数组!
三、代码示例
3.1 多轮对话完整代码
# -*- coding: utf-8 -*-
import requests
import sys
sys.stdout.reconfigure(encoding='utf-8')
url = "http://xxx:port/v1-openai/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": "Bearer your-api-key"
}
# 对话历史,一开始是空的
messages = []
print("多轮对话开始!输入 'quit' 退出")
while True:
# 用户输入
user_input = input("\n你说:")
if user_input.lower() in ['quit', '退出']:
print("拜拜!")
break
# 用户消息加入历史
messages.append({"role": "user", "content": user_input})
# 发请求(带上完整历史)
data = {
"model": "deepseek-ai-qwen-32b",
"messages": messages # 整个历史都发过去
}
response = requests.post(url, headers=headers, json=data, timeout=60)
if response.status_code == 200:
result = response.json()
ai_reply = result["choices"][0]["message"]["content"]
# AI 回复也加入历史(关键!)
messages.append({"role": "assistant", "content": ai_reply})
print(f"\nAI:{ai_reply}")
else:
print(f"出错:{response.status_code}")
messages.pop() # 出错就把刚才加的用户消息删掉
四、代码拆解
4.1 while True 循环
while True:
user_input = input("你说:")
这是个死循环,一直等着你输入,输一句,AI 回一句,再等着你输入。
直到你输入 quit 才会 break 跳出循环。
4.2 messages 的累积过程
| 轮次 | messages 内容 |
|---|---|
| 第1轮后 | [user:你好, assistant:你好呀] |
| 第2轮后 | [user:你好, assistant:你好呀, user:我叫小明, assistant:你好小明] |
| 第3轮后 | [user:你好, assistant:你好呀, user:我叫小明, assistant:你好小明, user:帮我写代码, assistant:...] |
每次发请求,AI 都能看到完整的历史,所以它知道你叫小明。
4.3 role 的两种值
| role | 代表谁 |
|---|---|
user | 你说的话 |
assistant | AI 说的话 |
对话历史就是 user 和 assistant 交替出现。
4.4 出错了为啥要 pop()
if response.status_code != 200:
messages.pop() # 删掉最后一条(刚才加的用户消息)
因为用户消息已经在出错前加入了 messages,但请求失败了,AI 没回复。
如果不删掉,下次再发请求,messages 里会有一条没回复的用户消息,顺序就乱了。
五、跑起来试试
python week1/02_multi_turn_chat.py
多轮对话开始!输入 'quit' 退出
你说:你好
AI:你好呀!有什么可以帮你吗?
你说:我叫小明
AI:你好小明!很高兴认识你~
你说:帮我写个 hello world
AI:好的小明,这是一个 Python 的 hello world:
print("Hello, World!")
你说:quit
拜拜!
试试连续聊,看看 AI 能不能记住你之前说的内容!
六、知识点总结
| 知识点 | 记住啥 |
|---|---|
| messages 数组 | 存对话历史,每次请求都要带上 |
| role | user 是你,assistant 是 AI |
| append | 每次对话都要把双方消息都加进去 |
| while True | 死循环,持续等待用户输入 |
七、踩坑记录
Q1: AI 还是记不住之前说的话
咋回事:messages 没正确累积,可能每次都重新初始化了
咋办:检查 messages 是不是在循环外面初始化的,别在循环里每次清空
Q2: 越聊越慢,甚至报错
咋回事:messages 太长了,token 超限
咋办:对话太多时,可以删掉最早的部分历史,只保留最近几轮
# 只保留最近 10 条消息
if len(messages) > 10:
messages = messages[-10:]
Q3: 输入中文乱码
咋回事:跟昨天一样,Windows 控制台的问题
咋办:记得加 sys.stdout.reconfigure(encoding='utf-8')
八、今日总结
今天干了啥:
✅ 学会了多轮对话,能跟 AI 连续聊了
✅ 理解了 messages 数组的累积机制
✅ 做了一个能持续对话的小程序
明天干嘛:试试流式输出,让 AI 边思考边说话,不用等它憋完一大段才显示。
九、参考学习网站
想深入理解对话原理?看看这些:
- OpenAI Chat Completions API - 官方文档,讲得很清楚
- DeepSeek API 文档 - 国产的,中文友好
- 大模型核心概念科普:Token、上下文长度、最大输出,一次讲透 - 知乎 - 知乎上有人讲 token 和 context window
记于 2026-04-04,AI 学习第二天,能聊起来了!