多轮对话如何实现?
未标记
考查重点:会话历史与任务状态更新。按用户/会话读历史和任务状态,加入最新证据构造输入,调用后保存消息与状态;长历史摘要或检索而非全量拼接
本题目录
参考答案
核心回答
多轮对话需要让下一轮拿到相关的对话历史、当前任务状态和最新外部证据,而不是只把所有消息拼起来。基本链路是:识别用户与会话 → 读取状态 → 组装本轮上下文 → 调用模型及工具 → 保存消息与状态 → 返回结果。
会话历史解决“刚才说了什么”,结构化状态解决“现在做到哪一步”,知识检索解决“外部事实是什么”。这三类信息互相配合,也应保留来源和时间,避免把旧回答当成新的事实。
历史与状态怎样保存
消息至少保留角色、内容、顺序和消息ID;工具调用还要保存调用ID、参数与对应结果,恢复时保持配对。当前意图、已确认槽位、待澄清问题和任务进度适合存成结构化状态,避免每一轮都靠模型重新猜。
使用认证身份确定租户和用户,再确定会话ID,不能仅相信客户端随意传来的用户标识。短会话可用关系库或Redis等实现历史存取;需要断点恢复的Agent可用框架checkpointer。单进程内存适合演示,服务重启或多实例运行需要共享的持久存储。
同一会话并发请求要维护顺序或版本,避免两个响应都基于旧状态覆盖对方。用户重发请求和流式连接重连要能去重;中断的工具任务应记录未完成状态,不能把半次调用当完整历史。
多轮RAG的关键处理
改写检索问题时,需要处理历史指代。例如用户先问“介绍A产品退款规则”,再问“那企业版呢”,可以结合历史将后句改写为独立检索问题;用户原问和已经确认的限定条件仍要保留,防止改写改掉意图。
检索结果与历史不是简单谁权重大:用户刚刚更正的产品型号应更新会话条件;政策、生效日期等外部事实应核对最新资料;上一轮模型编出的内容不能因为进了历史就升级成证据。检索后保留文档版本、来源和引用位置。
上下文变长怎么办
近期对话保留原文,较早内容按主题总结;用户明确约束、关键数字、标识符、待办和失败记录单独保存。工具大结果存到外部,传摘要和可回读的引用。摘要不可避免有损,因此遇到冷门技术细节、精确参数或追溯问题时,要能重新读取原始消息或文档。
窗口预算在系统指令、历史、检索、工具与输出之间分配,而不是把历史塞满后才处理。长期偏好只在相关时读取,临时任务内容不应自动成为跨会话永久记忆。
怎么验证
用连续对话检查代词指代、条件补充、用户纠正、话题切换、历史压缩后细节恢复、并发顺序和会话隔离。分别评估上下文是否取对、检索是否命中、最终回答是否跟随最新意图。技术亮点是把多轮对话做成可恢复的状态过程,让对话连续性与事实可靠性都可检查。
对应教程
- 16-记忆与对话历史(含Redis基础):掌握消息历史的保存与恢复。
- 项目实战/电商小二/1-对话系统基础与多轮对话架构:理解多轮对话的状态与会话组织。
参考资料
- 国内:JavaGuide:Agent记忆系统:采用记忆范围、写入和生命周期的划分,区分正文中多轮对话的消息历史、任务状态与长期偏好。
- 国内:WeThinkIn:记忆写入与生命周期:依据偏好作用域、读写与一致性机制,说明正文中会话隔离和并发更新的处理。
- 国内:Datawhale:上下文工程:依据上下文预算与外部引用的设计,解释正文中长对话为何需要摘要及按需回读。
- 国外:LangChain:Memory overview:采用短期线程状态与长期记忆的区分,说明正文中保存位置与读取范围的选择。
- 国外:Anthropic:Effective context engineering for AI agents:借鉴压缩、笔记和子任务上下文的取舍,说明正文中摘要为何应保留原文回查依据。
