跳到主要内容

多轮对话

多轮对话是指 AI 系统能够记住之前的对话内容,在多次交互中保持上下文连贯性的对话方式。

核心概念

什么是多轮对话

与单轮问答不同,多轮对话需要:

  • 记住历史对话
  • 理解指代和省略
  • 保持话题连贯
  • 追踪对话状态

对话示例

用户:北京天气怎么样?
AI:北京今天晴,25°C。

用户:那上海呢? ← 省略了"天气怎么样"
AI:上海今天多云,28°C。

用户:哪个更适合出行? ← 指代"北京和上海"
AI:北京天气更好,更适合出行。

技术实现

1. 消息格式

OpenAI 格式的多轮对话:

messages = [
{"role": "system", "content": "你是一个有帮助的助手。"},
{"role": "user", "content": "我叫小明"},
{"role": "assistant", "content": "你好小明,有什么可以帮助你的?"},
{"role": "user", "content": "我刚才说我叫什么?"},
{"role": "assistant", "content": "你刚才说你叫小明。"}
]

2. 角色说明

角色说明
system系统提示,设定 AI 的行为
user用户的输入
assistantAI 的回复

3. 上下文管理

from openai import OpenAI

client = OpenAI(api_key="your-api-key", base_url="https://api.weelinking.com/v1")

class ChatSession:
def __init__(self, system_prompt="你是一个有帮助的AI助手。"):
self.messages = [{"role": "system", "content": system_prompt}]

def chat(self, user_input):
# 添加用户消息
self.messages.append({"role": "user", "content": user_input})

# 调用 API
response = client.chat.completions.create(
model="gpt-4o",
messages=self.messages
)

assistant_message = response.choices[0].message.content

# 添加助手回复
self.messages.append({"role": "assistant", "content": assistant_message})

return assistant_message

def get_history(self):
return self.messages

# 使用示例
session = ChatSession()
print(session.chat("我叫小明"))
print(session.chat("我刚才说我叫什么?"))

上下文窗口管理

问题:上下文过长

当对话很长时,可能超出模型的上下文窗口限制。

解决方案

1. 截断策略

保留最近的 N 条消息:

def truncate_messages(messages, max_messages=20):
if len(messages) > max_messages:
# 保留 system 消息和最近的对话
return [messages[0]] + messages[-(max_messages-1):]
return messages

2. 摘要策略

定期总结历史对话:

def summarize_history(messages):
summary_prompt = "请总结以下对话的关键信息:\n" + format_messages(messages)
summary = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": summary_prompt}]
).choices[0].message.content

return [
{"role": "system", "content": f"之前对话摘要:{summary}"},
messages[-1] # 保留最后一条
]

3. 滑动窗口

保留固定 Token 数量:

import tiktoken

def sliding_window(messages, max_tokens=4000):
encoder = tiktoken.encoding_for_model("gpt-4o")

total_tokens = 0
result = []

# 从后往前添加消息
for msg in reversed(messages):
msg_tokens = len(encoder.encode(msg["content"]))
if total_tokens + msg_tokens > max_tokens:
break
result.insert(0, msg)
total_tokens += msg_tokens

return result

对话状态追踪

什么是对话状态

对话状态是对当前对话情况的结构化表示:

dialogue_state = {
"user_name": "小明",
"current_topic": "天气查询",
"mentioned_cities": ["北京", "上海"],
"user_preference": "晴天"
}

状态追踪实现

def update_state(messages, current_state):
prompt = f"""
当前对话状态:{json.dumps(current_state, ensure_ascii=False)}

最新对话:
用户:{messages[-1]['content']}

请更新对话状态,返回 JSON 格式。
"""

response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)

return json.loads(response.choices[0].message.content)

多轮对话的挑战

1. 指代消解

理解"它"、"那个"、"这里"等指代词:

  • 显式:通过上下文推断
  • 隐式:模型内部处理

2. 话题切换

用户可能突然改变话题:

  • 检测话题变化
  • 适当保留或清除上下文

3. 长期记忆

跨会话的记忆:

  • 用户偏好
  • 历史交互
  • 个人信息

最佳实践

  1. 明确的 System Prompt: 设定清晰的对话规则
  2. 合理的历史长度: 保留足够但不过多的上下文
  3. 状态持久化: 重要状态单独存储
  4. 错误处理: 处理上下文理解错误
  5. 用户确认: 关键信息主动确认

应用场景

  • 客服机器人: 跨轮次理解用户问题
  • 教育辅导: 持续跟踪学习进度
  • 心理咨询: 记住用户情况和偏好
  • 个人助理: 理解用户习惯和需求