Python 如何管理 AI 多轮对话上下文:消息窗口、摘要与历史记录

📅 2026/8/2 5:03:27 👁️ 阅读次数 📝 编程学习
Python 如何管理 AI 多轮对话上下文:消息窗口、摘要与历史记录

聊天功能看起来只是不断发送 messages,但真正做成可维护的多轮对话,需要处理历史消息、上下文长度和会话隔离。

为什么要管理上下文?

单轮请求只需要发送当前问题,多轮对话则需要让模型知道之前发生过什么。

如果每次都把所有历史消息完整发送,可能出现:

  • 请求内容越来越长
  • 响应速度变慢
  • 上下文超过限制
  • 无关历史影响当前回答
  • 不同用户的会话互相混淆

因此,多轮对话的核心不是无限保存消息,而是保留当前任务真正需要的信息。


一、用列表保存一段会话

最简单的方式是使用列表:

messages=[{"role":"system","content":"你是一个专业的技术助手。"}]defadd_message(role:str,content:str):messages.append({"role":role,"content":content})

每次用户提问时,先保存用户消息,再调用模型,最后保存模型回答。


二、封装一次完整对话

fromopenaiimportOpenAI client=OpenAI(api_key="your-api-key",base_url="https://your-api-domain.com/v1",)messages=[{"role":"system","content":"你是一个专业的技术助手。"}]defchat(user_input:str)->str:messages.append({"role":"user","content":user_input})response=client.chat.completions.create(model="your-model-name",messages=messages,)answer=response.choices[0].message.content messages.append({"role":"assistant","content":answer})returnanswer

这样可以保留上下文,但消息会不断增长,所以还需要设置窗口大小。


三、只保留最近几轮消息

deftrim_messages(messages:list[dict],max_messages:int=10)->list[dict]:system=[itemforiteminmessagesifitem["role"]=="system"]history=[itemforiteminmessagesifitem["role"]!="system"]returnsystem+history[-max_messages:]

调用前处理:

messages=trim_messages(messages,max_messages=10)

这种方法实现简单,适合短对话和上下文关系不复杂的场景。


四、为什么简单截断有时不够?

如果较早的消息包含重要信息,直接删除可能导致模型忘记:

  • 用户的目标
  • 已经确定的方案
  • 项目约束
  • 已完成的步骤

这时可以把较早内容压缩成摘要,再保留最近几轮原始消息。


五、使用摘要保存长期信息

可以设计一个会话对象:

classConversation:def__init__(self):self.summary=""self.recent_messages=[]defbuild_messages(self):messages=[]ifself.summary:messages.append({"role":"system","content":f"历史摘要:{self.summary}"})messages.extend(self.recent_messages)returnmessages

摘要中建议只保留:

  • 当前目标
  • 已确认事实
  • 关键约束
  • 待处理事项

不要把所有原文重新复制进去,否则摘要就失去了作用。


六、给每个用户单独保存会话

多用户应用不能共用一个全局messages列表。可以使用会话 ID:

sessions={}defget_session(session_id:str)->list[dict]:ifsession_idnotinsessions:sessions[session_id]=[{"role":"system","content":"你是一个专业的技术助手。"}]returnsessions[session_id]

调用时:

messages=get_session("user-001")messages.append({"role":"user","content":"我的问题"})

实际项目中,session ID 应该来自登录用户、会话令牌或业务请求,而不是直接使用用户输入作为唯一标识。


七、会话持久化

如果只保存在内存中,程序重启后历史会丢失。小型项目可以使用 SQLite 保存消息:

CREATETABLEmessages(idINTEGERPRIMARYKEYAUTOINCREMENT,session_idTEXTNOTNULL,roleTEXTNOTNULL,contentTEXTNOTNULL,created_atREALNOTNULL);

查询某个会话时,按created_at排序,再根据窗口策略取最近消息。


八、上下文管理的几个注意点

1. 系统提示词不要重复堆叠

每次构建消息时保持一份清晰的系统提示即可。

2. 不要无限保存原始消息

要设置窗口、摘要或过期策略。

3. 会话之间必须隔离

不要让不同用户共享同一个消息列表。

4. 摘要要定期更新

历史变长后,再生成一次更短的摘要。

5. 注意隐私数据

保存前应考虑脱敏、权限和过期删除。


九、推荐的管理顺序

可以按这个顺序实现:

  1. 列表保存消息
  2. 保留最近几轮
  3. 增加会话 ID
  4. 使用摘要保存长期信息
  5. 用 SQLite 或其他存储持久化
  6. 增加过期和清理机制

先解决会话隔离和长度控制,再考虑复杂的记忆系统。


十、结语

多轮对话上下文管理的核心是:

  • 保存有用的信息
  • 删除无关的历史
  • 控制消息长度
  • 隔离不同会话
  • 必要时使用摘要

对于 Python AI 项目来说,合理的上下文管理可以让聊天功能更稳定,也方便后续接入数据库、缓存和权限控制。

免责声明

本文内容仅用于技术交流与经验分享,具体实现请结合项目实际情况调整。