( 教学 )Agent 构建 Memory(提示词对话存储)1. ConversationBufferWindowMemory(随时间滑动最近对话交互窗口, 版本>1.0和<1.0的区别)
ConversationBufferWindowMemory,它维护一个随时间滑动的最近对话交互窗口。
与使用所有对话内容不同,ConversationBufferWindowMemory 只保留 最近 K 次 交互内容。
这可以防止内存缓冲区变得过大。
从算法思想上看,就是一个很常见的滑动窗口逻辑。
所以针对,这思想,其实也不要单独一个类来维护,通过编写也可以很好处理。
该类,是之前的版本1.0以前的,版本1.0以后的。我会列出两个版本的使用方式和特点。
在线银行开户会话示例
演示如何使用 ConversationBufferWindowMemory 来模拟虚拟银行助手对话。
流程涵盖了典型的在线银行开户过程,从初始问候到账户创建确认,仅在内存中保留最近的交互记录。
from langchain_classic.memory import ConversationBufferWindowMemory
memory = ConversationBufferWindowMemory(k=2, return_messages=True)
memory.save_context(
inputs={
"human": "你好,我想在线开立一个银行账户。我该如何开始?"
},
outputs={
"ai": "你好!很高兴你想开立账户。首先,请准备好你的身份证件以供验证好吗?"
},
)
memory.save_context(
inputs={"human": "是的,我已经准备好身份证了。下一步该怎么做?"},
outputs={
"ai": "谢谢。请拍摄你的身份证正反面的清晰照片并上传。然后我们将进行身份验证流程。"
},
)
memory.save_context(
inputs={
"human": "我已经上传了照片。身份验证是如何进行的?"
},
outputs={
"ai": "我已确认收到你上传的照片。现在,请进行手机验证。你将收到一条短信验证码 - 请输入该验证码。"
},
)
memory.save_context(
inputs={
"human": "我已经输入了验证码。如何继续开户流程?"
},
outputs={
"ai": "你的身份已验证通过。现在,请选择你想要的账户类型并输入所需信息。你可以选择存款类型、币种和其他选项。"
},
)
memory.save_context(
inputs={"human": "我已经输入了所有信息。下一步是什么?"},
outputs={
"ai": "我已确认你的信息。开户流程即将完成。最后,请同意服务条款并确认开户。"
},
)
memory.save_context(
inputs={"human": "我已完成所有步骤。账户开立成功了吗?"},
outputs={
"ai": "是的,你的账户已成功开立。你的账号和相关信息已发送至你注册的邮箱。如需任何帮助,请随时告诉我们。谢谢!"
},
)
获取对话历史
使用 load_memory_variables() 方法来检查存储的对话历史,以验证我们基于窗口的记忆保留情况。
memory.load_memory_variables({})["history"]
打印结果
[HumanMessage(content='我已经输入了所有信息。下一步是什么?', additional_kwargs={}, response_metadata={}), AIMessage(content='我已确认你的信息。开户流程即将完成。最后,请同意服务条款并确认开户。', additional_kwargs={}, response_metadata={}), HumanMessage(content='我已完成所有步骤。账户开立成功了吗?', additional_kwargs={}, response_metadata={}), AIMessage(content='是的,你的账户已成功开立。你的账号和相关信息已发送至你注册的邮箱。如需任何帮助,请随时告诉我们。谢谢!', additional_kwargs={}, response_metadata={})]
使用最新版本逻辑实现
from langgraph.checkpoint.memory import MemorySaver
from langgraph.graph import MessagesState, START, StateGraph
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, AIMessage
import operator
checkpointer = MemorySaver()
def chat_with_window(state: MessagesState):
"""保留最近 3 条消息的窗口记忆"""
messages = state["messages"]
# 窗口逻辑:只保留最近 3 条消息(1 AI + 2 Human)
window_size = 3
if len(messages) > window_size:
messages = messages[-window_size:]
model = ChatOpenAI(model="gpt-4o-mini")
response = model.invoke(messages)
return {"messages": [response]}
builder = StateGraph(state_schema=MessagesState)
builder.add_node("chat", chat_with_window)
builder.add_edge(START, "chat")
graph = builder.compile(checkpointer=checkpointer)
config = {"configurable": {"thread_id": "user-1"}}
# 模拟多轮对话
inputs = [
HumanMessage(content="你好,我想在线开立一个银行账户。我该如何开始?"),
AIMessage(content="你好!很高兴你想开立账户。首先,请准备好你的身份证件以供验证好吗?"),
HumanMessage(content="是的,我已经准备好身份证了。下一步该怎么做?"),
AIMessage(content="谢谢。请拍摄你的身份证正反面的清晰照片并上传。然后我们将进行身份验证流程。"),
HumanMessage(content= "我已经上传了照片。身份验证是如何进行的?"),
AIMessage(content="我已确认收到你上传的照片。现在,请进行手机验证。你将收到一条短信验证码 - 请输入该验证码。"),
HumanMessage(content="我前面说了什么?") # 窗口内能记住消息3
]
for chunk in graph.stream({"messages": [inputs[0]]}, config, stream_mode="values"):
pass
for msg in inputs[1:]:
for chunk in graph.stream({"messages": [msg]}, config, stream_mode="values"):
print(chunk["messages"][-1].content)