目录

一. Memory概述

1.1 为什么需要Memory

1.2 什么是Memory

1.3 Memory的设计理念

二、基础Memory模块的使用

2.1 Memory模块的设计思路

2.2 ChatMessageHistory(基础)

2.3 ConversationBufferMemory

2.4 ConversationChain

2.5 ConversationBufferWindowMemory

三、其他Memory模块

3.1 ConversationTokenBufferMemory

3.2 ConversationSummaryMemory

3.3 ConversationSummaryBufferMemory

3.4 ConversationEntityMemory(了解)

3.5 ConversationKGMemory(了解)

3.6 VectorStoreRetrieverMemory(了解)


一. Memory概述

1.1 为什么需要Memory

大多数的大模型应用程序都会有一个会话接口,允许我们进行多轮的对话,并有一定的上下文记忆能力。

但实际上,模型本身是 不会记忆 任何上下文的,只能依靠用户本身的输入去产生输出。

如何实现记忆功能呢?

实现这个记忆功能,就需要 额外的模块 去保存我们和模型对话的上下文信息,然后在下一次请求时,把所有的历史信息都输入给模型,让模型输出最终结果。

而在 LangChain 中,提供这个功能的模块就称为 Memory(记忆),用于存储用户和模型交互的历史信息。

1.2 什么是Memory

Memory,是LangChain中用于多轮对话中保存和管理上下文信息(比如文本、图像、音频等)的组件。它让应用能够记住用户之前说了什么,从而实现对话的上下文感知能力,为构建真正智能和上下文感知的链式对话系统提供了基础。

1.3 Memory的设计理念

问题: 一个链如果接入了 Memory 模块,其会与Memory模块交互几次呢?
链内部会与 Memory 模块进行两次交互:读取和写入:
1、收到用户输入时,从记忆组件中查询相关历史信息,拼接历史信息和用户的输入到提示词中传给
LLM。
2、返回响应之前,自动把LLM返回的内容写入到记忆组件,用于下次查询。

1.4 不使用Memory模块,如何拥有记忆?
不借助LangChain情况下,我们如何实现大模型的记忆能力?
思考:通过 messages 变量,不断地将历史的对话信息追加到对话列表中,以此让大模型具备上下文记 忆能力。
import os
import dotenv
from langchain_openai import ChatOpenAI
dotenv.load_dotenv()
os.environ['OPENAI_API_KEY'] = os.getenv("OPENAI_API_KEY1")
os.environ['OPENAI_BASE_URL'] = os.getenv("OPENAI_BASE_URL")
# 创建大模型实例
llm = ChatOpenAI(model="gpt-4o-mini")
from langchain.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
llm = ChatOpenAI(model="gpt-4o-mini")
def chat_with_model(question):
# 步骤一:初始化消息
chat_prompt_template = ChatPromptTemplate.from_messages([
("system","你是一位人工智能小助手"),
("human","{question}")
])
# 步骤二:定义一个循环体:
while True:
# 步骤三:调用模型
chain = chat_prompt_template | llm
response = chain.invoke({"question": question})
# 步骤四:获取模型回答
print(f"模型回答: {response.content}")
# 询问用户是否还有其他问题
user_input = input("您还有其他问题想问嘛?(输入'退出'结束对话)")
# 设置结束循环的条件
if(user_input == "退出"):
break
# 步骤五:记录用户回答
chat_prompt_template.messages.append(AIMessage(content=response.content))
chat_prompt_template.messages.append(HumanMessage(content=user_input))
chat_with_model("你好")

这种形式是最简单的一种让大模型具备上下文知识的存储方式,任何记忆的基础都是所有聊天交互的历 史记录。即使这些不全部直接使用,也需要以某种形式存储。

二、基础Memory模块的使用

2.1 Memory模块的设计思路

如何设计Memory模块?

  • 层次1(最直接的方式):保留一个聊天消息列表

  • 层次2(简单的新思路):只返回最近交互的k条消息

  • 层次3(稍微复杂一点):返回过去k条消息的简洁摘要

  • 层次4(更复杂):从存储的消息中提取实体,并且仅返回有关当前运行中引用的实体的信息

LangChain的设计:

针对上述情况,LangChain构建了一些可以直接使用的Memory工具,用于存储聊天消息的一系列集成。

2.2 ChatMessageHistory(基础)

ChatMessageHistory是一个用于存储和管理对话消息的基础类,它直接操作消息对象(如HumanMessage, AIMessage等),是其它记忆组件的底层存储工具。在API文档中,ChatMessageHistory还有一个别名类:InMemoryChatMessageHistory;导包时,需使用:from langchain.memory import ChatMessageHistory

特点:

  • 纯粹是消息对象的“存储器”,与记忆策略(如缓冲、窗口、摘要等)无关。

  • 不涉及消息的格式化(如转成文本字符串)

场景1:记忆存储

#1.导入相关包
from langchain.memory import ChatMessageHistory

#2.实例化ChatMessageHistory对象
history = ChatMessageHistory()

# 3.添加UserMessage
history.add_user_message('hi')

# 4.添加AIMessage
history.add_ai_message('whats up?')

# 5.返回存储的所有消息列表
print(history.messages)

输出:

场景2:对接LLM

from langchain.memory import ChatMessageHistory

history = ChatMessageHistory()

history.add_ai_message('我是一个无所不能的小智')
history.add_user_message('你好,我叫小明,请介绍一下你自己')
history.add_user_message('我是谁呢?')

print(history.messages) #返回List[BaseMessage]类型

2.3 ConversationBufferMemory

ConversationBufferMemory是一个基础的 对话记忆(Memory)组件,专门用于按 原始顺序存储 完整的对话历史。

适用场景:对话轮次较少、依赖完整上下文的场景(如简单的聊天机器人)

特点

  • 完整存储对话历史

  • 简单、无裁剪、无压缩

  • 与 Chains/Models 无缝集成

  • 支持两种返回格式(通过 return_messages 参数控制输出格式)

    • return_messages=True 返回消息对象列表(List[BaseMessage]

    • return_messages=False (默认) 返回拼接的 纯文本字符串

场景1:入门使用

举例1:

# 1.导入相关包
from langchain.memory import ConversationBufferMemory

# 2.实例化ConversationBufferMemory对象
memory = ConversationBufferMemory()
# 3.保存消息到内存中
memory.save_context({"input": "你好,我是人类"}, {"output": "你好,我是AI助手"})
memory.save_context({"input": "很开心认识你"}, {"output": "我也是"})

# 4.读取内存中消息(返回消息内容的纯文本)
print(memory.load_memory_variables({}))

注意

  • 不管inputsoutputs的key用什么名字,都认为inputs的key是humanoutputs的key是AI

  • 打印的结果的json数据的key,默认是“history”。可以通过ConversationBufferMemorymemory_key属性修改。

举例2:

# 1.导入相关包
from langchain.memory import ConversationBufferMemory

# 2.实例化ConversationBufferMemory对象
memory = ConversationBufferMemory(return_messages=True)

# 3.保存消息到内存中
memory.save_context({"input": "hi"}, {"output": "whats up"})

# 4.读取内存中消息(返回消息)
print(memory.load_memory_variables({}))

# 5.读取内存中消息(访问原始消息列表)
print(memory.chat_memory.messages)

场景2:结合chain

举例1:使用PromptTemplate

from langchain_openai import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains.llm import LLMChain
from langchain_core.prompts import PromptTemplate

# 初始化大模型
llm = OpenAI(model="gpt-4o-mini", temperature=0)

# 创建提示
# 有两个输入键:实际输入与来自记忆类的输入 需确保PromptTemplate和ConversationBufferMemory中的键匹配
template = """你可以与人类对话。

当前对话:
{history}

人类问题: {question}

回复:"""

prompt = PromptTemplate.from_template(template)

# 创建ConversationBufferMemory
memory = ConversationBufferMemory()

# 初始化链
chain = LLMChain(llm=llm, prompt=prompt, memory=memory)

# 提问
res1 = chain.invoke({ "question": "我的名字叫Tom"})
print(res1)

举例2:可以通过memory_key修改memory数据的变量名

from langchain_openai import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains.llm import LLMChain
from langchain_core.prompts import PromptTemplate

# 初始化大模型
llm = OpenAI(model="gpt-4o-mini", temperature=0)

# 创建提示
# 有两个输入键:实际输入与来自记忆类的输入 需确保PromptTemplate和ConversationBufferMemory中的键匹配
template = """你可以与人类对话。

当前对话:
{chat_history}

人类问题: {question}

回复:"""

prompt = PromptTemplate.from_template(template)

# 创建ConversationBufferMemory
memory = ConversationBufferMemory(memory_key="chat_history")

# 初始化链
chain = LLMChain(llm=llm, prompt=prompt, memory=memory)

# 提问
res1 = chain.invoke({ "question": "我的名字叫Tom"})
print(str(res1) + "\n")

res = chain.invoke({ "question": "我的名字是什么?"})
print(res)

说明:创建带Memory功能的Chain,并不能使用统一的LCEL语法。同样地,LLMChain也不能使用管道运算符接StrOutputParser。这些设计上的问题,个人推测也是目前Memory模块还是Beta版本的原因之一吧。

举例3:使用ChatPromptTemplatereturn_messages

# 1.导入相关包
from langchain_core.messages import SystemMessage
from langchain.chains.llm import LLMChain
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import MessagesPlaceholder, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain_openai import ChatOpenAI

# 2.创建LLM
llm = ChatOpenAI(model_name='gpt-4o-mini')

# 3.创建Prompt
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个与人类对话的机器人。"),
    MessagesPlaceholder(variable_name='history'),
    ("human", "问题: {question}")
])

# 4.创建Memory
memory = ConversationBufferMemory(return_messages=True)
# 5.创建LLMChain
llm_chain = LLMChain(prompt=prompt, llm=llm, memory=memory)

# 6.调用LLMChain
res1 = llm_chain.invoke({ "question": "中国首都在哪里?"})
print(res1,end="\n\n")

res = llm_chain.invoke({ "question": "我刚刚问了什么"})
print(res)

二者对比

特性 普通 PromptTemplate ChatPromptTemplate
历史存储时机 仅执行后存储 执行前存储用户输入 + 执行后存储输出
首次调用显示 仅显示问题(历史仍为空字符串) 显示完整问答对
内部消息类型 拼接字符串 List[BaseMessage]

注意
我们观察到的现象不是 bug,而是 LangChain 为 保障对话一致性 所做的刻意设计:

  1. 用户提问后,系统应立即“记住”该问题

  2. AI回答后,该响应应即刻加入对话上下文

  3. 返回给客户端的结果应反映最新状态

2.4 ConversationChain

ConversationChain 实际上是就是对 ConversationBufferMemory 和 LLMChain 进行了封装,并且提供一个默认格式的提示词模板(我们也可以不用),从而简化了初始化 ConversationBufferMemory 的步骤。

举例1:使用PromptTemplate

from langchain.chains.conversation.base import ConversationChain
from langchain_core.prompts.prompt import PromptTemplate
from langchain.chains import LLMChain

# 初始化大模型
llm = ChatOpenAI(model='gpt-4o-mini')

template = """以下是人类与AI之间的友好对话描述,AI表现得很健谈,并提供了大量来自其上下文的具体细节。如果AI不知道问题的答案,它会真诚地表示不知道。

当前对话:
{history}
Human: {input}
AI:"""

prompt = PromptTemplate.from_template(template)

chain = ConversationChain(llm=llm, prompt=prompt, verbose=True)

chain.invoke({"input": "你好,你的名字叫小智"}) #注意,chain中的key必须是input,否则会报错

chain.invoke({"input": "你好,你叫什么名字?"})

举例2:使用内置默认格式的提示词模版(内部包含inputhistory变量)

# 1.导入所需的库
from langchain_openai import ChatOpenAI
from langchain.chains.conversation.base import ConversationChain

# 2.初始化大语言模型
llm = ChatOpenAI(model='gpt-4o-mini')

# 3.初始化对话框
conv_chain = ConversationChain(llm=llm)

# 4.进行对话
result = conv_chain.invoke(input='小明有1只猫')
result2 = conv_chain.invoke(input='小明有2只狗')
result3 = conv_chain.invoke(input="小明和小刚一共有几只宠物")
print(result3)

2.5 ConversationBufferWindowMemory

在了解了ConversationBufferMemory记忆类后,我们知道了它能够无限的将历史对话信息填充到History中,从而给大模型提供上下文的背景。但这会导致内存量十分大,并且消耗的token是非常多的,此外,每个大模型都存在最大输入的Token限制。

我们发现,过久远的对话数据往往并不能对当前轮次的问答提供有效的信息,LangChain给出的解决方式是:ConversationBufferWindowMemory模块。该记忆类会保存一段时间内对话交互的列表,仅使用最近K个交互。这样就使缓存区不会变得太大。

特点

  • 适合长对话场景。

  • 与Chains/Models无缝集成

  • 支持两种返回格式(通过return_messages参数控制输出格式)

    • return_messages=True返回消息对象列表(List[BaseMessage]

    • return_messages=False(默认)返回拼接的纯文本字符串

场景1:入门使用

通过内置在LangChain中的缓存窗口(BufferWindow)可以将memory“记忆”下来。

举例1:

# 1.导入相关包
from langchain.memory import ConversationBufferWindowMemory

# 2.实例化ConversationBufferWindowMemory对象,设定窗口阈值
memory = ConversationBufferWindowMemory(k=2)
# 3.保存消息
memory.save_context({"input":"你好"}, {"output":"怎么了"})
memory.save_context({"input":"你是谁"}, {"output":"我是AI助手"})
memory.save_context({"input":"你的生日是哪天?"}, {"output":"我不清楚"})
# 4.读取内存中消息(返回消息内容的纯文本)
print(memory.load_memory_variables({}))

举例2:
ConversationBufferWindowMemory也支持使用聊天模型(Chat Model)的情况,同样可以通过return_messages=True参数,将对话转化为消息列表形式。

# 1.导入相关包
from langchain.memory import ConversationBufferWindowMemory

# 2.实例化ConversationBufferWindowMemory对象,设定窗口阈值
memory = ConversationBufferWindowMemory(k=2, return_messages=True)
# 3.保存消息
memory.save_context({"input": "你好"}, {"output": "怎么了"})
memory.save_context({"input": "你是谁"}, {"output": "我是AI助手小智"})
memory.save_context({"input": "初次对话,你能介绍一下你自己吗?"}, {"output": "当然可以了。我是一个无所不能的小智。"})
# 4.读取内存中消息(返回消息内容的纯文本)
print(memory.load_memory_variables({}))

场景2:结合Chain

借助提示词模版去构建LangChain

from langchain.memory import ConversationBufferWindowMemory
# 1.导入相关包
from langchain_core.prompts.prompt import PromptTemplate
from langchain.chains.llm import LLMChain

# 2.定义模版
template = """以下是人类与AI之间的友好对话描述,AI表现得很健谈,并提供了大量来自其上下文的具体细节,如果AI不知道问题的答案,它会表示不知道。

当前对话:
{history}
Human: {question}
AI:"""

# 3.定义提示词模版
prompt_template = PromptTemplate.from_template(template)

# 4.创建大模型
llm = ChatOpenAI(model='gpt-4o-mini')

# 5.实例化ConversationBufferWindowMemory对象,设定窗口阈值
memory = ConversationBufferWindowMemory(k=1)

# 6.定义LLMChain
conversation_with_summary = LLMChain(
    llm=llm,
    prompt=prompt_template,
    memory=memory,
    verbose=True,
)

# 7.执行链(第一次提问)
respond = conversation_with_summary.invoke({"question": "你好,我是孙小空"})
# 8.执行链(第二次提问)
respond = conversation_with_summary.invoke({"question": "我还有两个师弟,一个是猪小戒,一个是沙小僧"})
# 9.执行链(第三次提问)
respond = conversation_with_summary.invoke({"question": "我今年高考,竟然考上了1本"})
# 10.执行链(第四次提问)
respond = conversation_with_summary.invoke({"question": "我叫什么?"})
print(respond)

输出(部分日志及最终结果):

思考:将参考 k=1 替换成 k=3,会怎样呢?

三、其他Memory模块

3.1 ConversationTokenBufferMemory

ConversationTokenBufferMemory 是 LangChain 中一种基于 Token 数量控制 的对话记忆机制。如果字符数量超出指定数目,它会切换这个对话的早期部分,以保留与最近的交流相对应的字符数量。

特点

  • Token 精准控制

  • 原始对话保留

原理

举例:情况1:

# 1.导入相关包
from langchain.memory import ConversationTokenBufferMemory
from langchain_openai import ChatOpenAI

# 2.创建大模型
llm = ChatOpenAI(model="gpt-4o-mini")

# 3.定义ConversationTokenBufferMemory对象
memory = ConversationTokenBufferMemory(
    llm=llm,
    max_token_limit=10 # 设置token上限
)

# 添加对话
memory.save_context({"input": "你好吗?"}, {"output": "我很好,谢谢!"})
memory.save_context({"input": "今天天气如何?"}, {"output": "晴天,25度"})

# 查看当前记忆
print(memory.load_memory_variables({}))

输出:

情况2:

# 1.导入相关包
from langchain.memory import ConversationTokenBufferMemory
from langchain_openai import ChatOpenAI

# 2.创建大模型
llm = ChatOpenAI(model="gpt-4o-mini")

# 3.定义ConversationTokenBufferMemory对象
memory = ConversationTokenBufferMemory(
    llm=llm,
    max_token_limit=50  # 设置token上限
)

# 添加对话
memory.save_context({"input": "你好吗?"}, {"output": "我很好,谢谢!"})
memory.save_context({"input": "今天天气如何?"}, {"output": "晴天,25度"})

# 查看当前记忆
print(memory.load_memory_variables({}))

3.2 ConversationSummaryMemory

前面的方式发现,如果全部保存下来太过浪费,截断时无论是按照 对话轮次 还是 token 都是无法保证既节省内存又保证对话质量的,所以推出ConversationSummaryMemoryConversationSummaryBufferMemory

ConversationSummaryMemory是 LangChain 中一种 智能压缩对话历史 的记忆机制,它通过大语言模型(LLM)自动生成对话内容的 精简摘要,而不是存储原始对话文本。这种记忆方式特别适合长对话和需要保留核心信息的场景。

特点

  • 摘要生成

  • 动态更新

  • 上下文优化

原理

场景1:如果实例化ConversationSummaryMemory前,没有历史消息,可以使用构造方法实例化

# 1.导入相关包
from langchain.memory import ConversationSummaryMemory, ChatMessageHistory
from langchain_openai import ChatOpenAI

# 2.创建大模型
llm = ChatOpenAI(model='gpt-4o-mini')

# 3.定义ConversationSummaryMemory对象
memory = ConversationSummaryMemory(llm=llm)

# 4.存储消息
memory.save_context({'input':'你好'}, {'output':'怎么了'})
memory.save_context({'input':'你是谁'}, {'output':'我是AI助手小智'})
memory.save_context({'input':'初次对话,你能介绍一下你自己吗?'}, {'output':'当然可以了。我是一个无所不能的小智。'})

# 5.读取消息(总结后的)
print(memory.load_memory_variables({}))

场景2:如果实例化ConversationSummaryMemory前,已经有历史消息,可以调用from_messages()实例化

# 1.导入相关包
from langchain.memory import ConversationSummaryMemory, ChatMessageHistory
from langchain_openai import ChatOpenAI

# 2.定义ChatMessageHistory对象
llm = ChatOpenAI(model='gpt-4o-mini')

# 3.假设原始消息
history = ChatMessageHistory()
history.add_user_message('你好,你是谁?')
history.add_ai_message('我是AI助手小智')

# 4.初始化ConversationSummaryMemory实例
memory = ConversationSummaryMemory.from_messages(
    llm=llm,
    # 是生成摘要的原材料 保留完整对话快必要时回溯。当新增对话时,LLM需要结合原始历史生成新摘要
    chat_memory=history,
)

print(memory.load_memory_variables({}))

memory.save_context(inputs={"human":"我的名字叫小明"},outputs={"AI":"很高兴认识你"})

print(memory.load_memory_variables({}))

print(memory.chat_memory.messages)

3.3 ConversationSummaryBufferMemory

ConversationSummaryBufferMemory 是 LangChain 中一种混合型记忆机制,它结合了 ConversationBufferMemory(完整对话记录)和 ConversationSummaryMemory(摘要记忆)的优点,在保留最近 对话原始记录 的同时,对较早的对话内容进行 智能摘要

特点

  • 保留最近N条原始对话:确保最新交互的完整上下文

  • 摘要较早历史:对超出缓冲区的旧对话进行压缩,避免信息过载

  • 平衡细节与效率:既不会丢失关键细节,又能处理长对话

原理

场景1:入门使用

情况1:构造方法实例化,并设置max_token_limit

# 1.导入相关的包
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI

# 2.定义模型
llm = ChatOpenAI(model_name='gpt-4o-mini', temperature=0)

# 3.定义ConversationSummaryBufferMemory对象
memory = ConversationSummaryBufferMemory(
    llm=llm, max_token_limit=40, return_messages=True
)

# 4.保存消息
memory.save_context({'input': '你好,我的名字叫小明'}, {'output': '很高兴认识你,小明'})
memory.save_context({'input': '李白是哪个朝代的诗人'}, {'output': '李白是唐朝诗人'})
memory.save_context({'input': '唐宋八大家里有苏轼吗?'}, {'output': '有'})

# 5.读取内容
print(memory.load_memory_variables({}))

print(memory.chat_memory.messages)

情况2:

# 1.导入相关的包
from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI

# 2.定义模型
llm = ChatOpenAI(model_name='gpt-4o-mini', temperature=0)

# 3.定义ConversationSummaryBufferMemory对象
memory = ConversationSummaryBufferMemory(
    llm=llm, max_token_limit=100, return_messages=True
)
# 4.保存消息
memory.save_context({'input': '你好,我的名字叫小明'}, {'output': '很高兴认识你,小明'})
memory.save_context({'input': '李白是哪个朝代的诗人'}, {'output': '李白是唐朝诗人'})
memory.save_context({'input': '唐宋八大家里有苏轼吗?'}, {'output': '有'})
# 5.读取内容
print(memory.load_memory_variables({}))

print(memory.chat_memory.messages)

场景2:客服

from langchain.memory import ConversationSummaryBufferMemory
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.chains.llm import LLMChain

# 1.初始化语言模型
llm = ChatOpenAI(
    model='gpt-4o-mini',
    temperature=0.5,
    max_tokens=500
)

# 2.定义提示模板
prompt = ChatPromptTemplate.from_messages([
    ('system', '你是电商客服助手,用中文友好回复用户问题,保持专业但亲切的语气。'),
    MessagesPlaceholder(variable_name='chat_history'),
    ('human', '{input}')
])

# 3.创建带摘要缓冲的记忆系统
memory = ConversationSummaryBufferMemory(
    llm=llm,
    max_token_limit=400,
    memory_key="chat_history",
    return_messages=True
)

# 4.创建对话链
chain = LLMChain(
    llm=llm,
    prompt=prompt,
    memory=memory,
)

# 5.模拟多轮对话
dialogue = [
    ("你好,我想查询订单12345的状态", None),
    ("这个订单是上周五下的", None),
    ("我现在急着用,能加急处理吗", None),
    ("等等,我可能记错订单号了,应该是12346", None),
    ("对了,你们退货政策是怎样的", None)
]

# 6.执行对话
for user_input, _ in dialogue:
    response = chain.invoke({"input": user_input})
    print(f"用户: {user_input}")
    print(f"客服: {response['text']}\n")

# 7.查看当前记忆状态
print("\n=== 当前记忆内容 ===")
print(memory.load_memory_variables({}))

3.4 ConversationEntityMemory(了解)

ConversationEntityMemory 是一种基于实体的对话记忆机制,它能够智能地识别、存储和利用对话中出现的实体信息(如人名、地点、产品等)及其属性/关系,并结构化存储,使 AI 具备更强的上下文理解和记忆能力。

好处:解决信息过载问题

  • 长对话中大量冗余信息会干扰关键事实记忆

  • 通过对实体摘要,可以压缩非重要细节(如删除策略等,保留价格/时间等硬性事实)

应用场景:在医疗等高风险领域,必须用实体记忆确保关键信息(如过敏史)被100%准确识别和拦截。

{"input": "我头痛,血压140/90,在吃阿司匹林。"}
{"output": "建议监测血压,阿司匹林可继续服用。"}
{"input": "我对青霉素过敏。"}
{"output": "已记录您的青霉素过敏史。"}
{"input": "阿司匹林吃了三天,头痛没缓解。"}
{"output": "建议停用阿司匹林,换布洛芬试试。"}

使用ConversationSummaryMemory:
"患者主诉头痛和高血压(140/90),正在服用阿司匹林。患者对青霉素过敏。三天后头痛未缓解,建议更换止痛药。"

使用ConversationEntityMemory:

{
    "症状": "头痛",
    "血压": "140/90",
    "当前用药": "阿司匹林(无效)",
    "过敏药物": "青霉素"
}

ConversationSummaryMemory 和 ConversationEntityMemory

维度 ConversationSummaryMemory ConversationEntityMemory
存储格式 自然语言文本(一段话) 结构化字典(键值对)
下游如何利用信息 需大模型“读懂”摘要文本,如果 AI 的注意力集中在“头痛”和“换药”上,可能会忽略过敏提示(尤其是摘要较长时) 无需依赖模型的“阅读理解能力”,直接通过字段名(如过敏药物)查询
防错可靠性 低(依赖大模型的注意力) 高(通过代码强制检查)
推荐处理 可以试试阿莫西林(一种青霉素类药) 完全避免推荐过敏药物

举例

from langchain.chains.conversation.base import LLMChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE
from langchain_openai import ChatOpenAI

# 初始化大语言模型
llm = ChatOpenAI(model_name='gpt-4o-mini', temperature=0)
# 使用LangChain为实体记忆设计的预定义模板
prompt = ENTITY_MEMORY_CONVERSATION_TEMPLATE
# 初始化实体记忆
memory = ConversationEntityMemory(llm=llm)
# 提供对话链
chain = LLMChain(
    llm=llm,
    prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
    memory=ConversationEntityMemory(llm=llm),
    verbose=True, # 设置为True可以看到链的详细推理过程
)

# 进行几轮对话,记忆组件会在后台自动提取和存储实体信息
chain.invoke(input="你好,我叫蜘蛛侠。我的好朋友包括钢铁侠、美国队长和绿巨人。")
chain.invoke(input="我住在纽约。")
chain.invoke(input="我使用的装备是由斯塔克工业提供的。")

# 查询记忆体中存储的实体信息
print("\n当前存储的实体信息:")
print(chain.memory.entity_store.store)

# 基于记忆进行提问
answer = chain.invoke(input="你能告诉我蜘蛛侠住在哪里以及他的好朋友有哪些吗?")
print("\nAI的回答:")
print(answer)

3.5 ConversationKGMemory(了解)

ConversationKGMemory是一种基于知识图谱(Knowledge Graph)的对话记忆模块,它比ConversationEntityMemory更进一步,不仅能识别和存储实体,还能捕捉实体之间的复杂关系,形成结构化的知识网络。

特点:

  • 知识图谱结构 将对话内容转化为(头实体, 关系, 尾实体)的三元组形式

  • 动态关系推理

举例:

pip install networkx
#1.导入相关包
from langchain.memory import ConversationKGMemory
from langchain.chat_models import ChatOpenAI

# 2.定义LLM
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 3.定义ConversationKGMemory对象
memory = ConversationKGMemory(llm=llm)

# 4.保存会话
memory.save_context({"input": "向山姆问好"}, {"output": "山姆是谁"})
memory.save_context({"input": "山姆是我的朋友"}, {"output": "好的"})

# 5.查询会话
memory.load_memory_variables({"input": "山姆是谁"})

memory.get_knowledge_triplets('她最喜欢的颜色是红色')

3.6 VectorStoreRetrieverMemory(了解)

VectorStoreRetrieverMemory是一种基于 向量检索 的先进记忆机制,它将对话历史存储在向量数据库中,通过 语义相似度检索 相关信息,而非传统的线性记忆方式。每次调用时,就会查找与该记忆关联最高的K个文档。

适用场景:这种记忆特别适合需要长期记忆和语义理解的复杂对话系统。

原理

举例

import os
import dotenv
from langchain_openai import OpenAIEmbeddings

dotenv.load_dotenv()

os.environ['OPENAI_API_KEY'] = os.getenv('OPENAI_API_KEY')
os.environ['OPENAI_BASE_URL'] = os.getenv('OPENAI_BASE_URL')

embeddings_model = OpenAIEmbeddings(
    model='text-embedding-ada-002'
)

# 1.导入相关包
from langchain_openai import OpenAIEmbeddings
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import FAISS
from langchain.memory import ConversationBufferMemory

# 2.定义ConversationBufferMemory对象
memory = ConversationBufferMemory()
memory.save_context({'input': '我最喜欢的食物是披萨'}, {'output': '很高兴知道'})
memory.save_context({'Human': '我喜欢的运动是跑步'}, {'AI': '好的,我知道了'})
memory.save_context({'Human': '我最喜欢的运动是足球'}, {'AI': '好的,我知道了'})

# 3.定义向量嵌入模型
embeddings_model = OpenAIEmbeddings(
    model='text-embedding-ada-002'
)

# 4.初始化向量数据库
vectorstore = FAISS.from_texts(memory.buffer.split('\n'), embeddings_model) # 空初始化

# 5.定义检索对象
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))

# 6.初始化VectorStoreRetrieverMemory
memory = VectorStoreRetrieverMemory(retriever=retriever)

print(memory.load_memory_variables({'prompt': '我最喜欢的食物是'}))

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐