Skip to content

多轮对话

多轮对话是指 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="http://122.51.35.238:5170/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. 用户确认: 关键信息主动确认

应用场景

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

本页内容来自文档知识库整理,已按 ArmNet 字元服务 服务命名统一更新。