LangChain 入门学习第九篇-多轮对话和上下文记忆

💡 原文中文,约2300字,阅读约需6分钟。
📝

内容提要

本文介绍LangChain多轮RAG问答实现。通过MessagesPlaceholder将历史对话插入Prompt,每轮仍检索当前问题上下文,结合历史消息生成回答。用内存list保存HumanMessage和AIMessage,支持追问。限制是程序结束历史丢失、长对话占用上下文,无摘要压缩。核心公式:多轮对话=历史消息+当前问题+当前检索上下文。

🔎

延伸解读

历史消息与检索的职责分工

本文强调多轮对话中历史消息和检索各自承担不同角色:历史消息提供用户上下文,检索提供知识上下文。每一轮都需重新检索当前问题,不能因为有了历史就省略检索。这种设计确保模型既能理解追问的指代,又能获取最新相关知识,是构建多轮RAG系统的关键思路。

内存记忆的局限与演进方向

使用Python list保存对话历史虽然简单直观,但存在明显局限:程序结束即丢失、长对话占用大量上下文、无摘要压缩、无法按用户或会话隔离。文章指出,真实应用需将历史持久化到数据库,并在历史过长时引入摘要机制。这为后续优化指明了方向。

MessagesPlaceholder的作用

MessagesPlaceholder是LangChain中插入历史消息的关键组件,它允许将一组BaseMessage对象动态嵌入Prompt模板。与普通字符串变量不同,它能保留消息的角色(如HumanMessage、AIMessage),使模型能区分对话双方,从而更准确地理解上下文。这是实现多轮对话的基础。

Q&A

LangChain中如何实现多轮对话的上下文记忆?

在LangChain中,可以使用MessagesPlaceholder将历史消息插入Prompt,并用一个list保存HumanMessage和AIMessage。每轮对话时,将历史消息、当前问题和检索到的上下文一起传给模型,从而让模型理解追问的上下文。

多轮RAG中,每一轮都需要检索吗?为什么?

是的,每一轮都需要检索。因为历史消息解决的是用户上下文,而RAG检索解决的是知识上下文。即使有历史,当前问题可能涉及新的知识,所以需要根据当前问题重新检索相关文档片段。

LangChain中MessagesPlaceholder的作用是什么?

MessagesPlaceholder用于在Prompt模板中预留一个位置,用来插入历史消息列表。这样模型在生成回答时可以看到之前的对话内容,从而支持多轮对话。

使用内存list保存对话历史有什么限制?

限制包括:程序结束后历史丢失;长对话会占用越来越多上下文;没有摘要压缩;没有按用户或会话保存。这些限制在真实应用中需要通过数据库或摘要机制来解决。

如何运行LangChain多轮对话的demo?

在code/langchain-demo目录下运行命令:uv run python -m chapter09.memory_rag。也可以传入自定义的第一轮问题,例如:uv run python -m chapter09.memory_rag "FFmpeg 硬解码相关内容有哪些?",程序会自动追加一个第二轮追问。

多轮对话的核心公式是什么?

多轮对话 = 历史消息 + 当前问题 + 当前检索上下文。即结合历史对话、当前问题和检索到的知识片段来生成回答。

🏷️

标签

➡️

继续阅读