( 教学 )Agent 构建 Memory(提示词对话存储)1. ConversationBufferMemory(对话缓存存储, 版本>1.0和<1.0的区别)
ConversationBufferMemory,这是一个用于在缓冲区中存储对话历史的内存类。
通常情况下,不需要额外的处理。但是,当对话历史超出模型的上下文窗口时,可能需要进行额外处理。
学习如何使用 ConversationBufferMemory 来存储和检索对话历史。
目前看这些之前的版本1.0以前的,版本1.0以后的。我会列出两个版本的使用方式和特点。
加载 ConversationBufferMemory 类
python
from langchain_classic.memory import ConversationBufferWindowMemory
memory = ConversationBufferMemory()
可以使用 save_context(inputs, outputs) 方法来保存对话记录。
- 这个方法接受两个参数,
inputs和outputs。 inputs用于存储用户的问题,而outputs用于存储 AI 的回答。- 对话记录会在内部以
history键进行存储。 - 你可以使用
load_memory_variables方法来获取和查看已保存的对话历史。
python
# inputs: dictionary(key: "human" or "ai", value: question)
# outputs: dictionary(key: "ai" or "human", value: answer)
memory.save_context(
inputs={
"human": "你好,我想要远程开设一个银行账户。我该如何开始?",
},
outputs={
"ai": "你好!很高兴你想开设账户。首先,请准备好你的身份证件以供身份验证。"
},
)
内存对象的 load_memory_variables({}) 方法会以字符串形式返回完整的对话历史。
python
# 检查存储在'history'键中的消息历史记录
print(memory.load_memory_variables({})["history"])
塞入数据
python
memory.save_context(
inputs={
"human": "我已经上传了照片。如何进行身份验证?"
},
outputs={
"ai": "我们已确认您上传的照片。请通过手机进行身份验证。请输入通过短信发送的验证码。"
},
)
memory.save_context(
inputs={
"human": "我已输入验证码。现在如何开户?"
},
outputs={
"ai": "身份验证已完成。请选择您想要的账户类型并输入必要信息。您可以选择存款类型、币种等。"
},
)
# Save 2 more conversations.
memory.save_context(
inputs={
"human": "我已经输入了所有信息。下一步是什么?",
},
outputs={
"ai": "我已确认您输入的信息。开户流程即将完成。请同意使用条款并确认开户。"
},
)
memory.save_context(
inputs={
"human": "我已完成所有步骤。账户开通了吗?",
},
outputs={
"ai": "是的,账户已开通。您的账号和相关信息已发送至您注册的邮箱。如果需要其他帮助,请随时联系我们。谢谢!"
},
)
打印一下,查看一下内存中的对话历史。
python
print(memory.load_memory_variables({})["history"])
Human: 你好,我想要远程开设一个银行账户。我该如何开始? AI: 你好!很高兴你想开设账户。首先,请准备好你的身份证件以供身份验证。 Human: 是的,我已经准备好了身份证件用于身份验证。接下来我该怎么做? AI: 谢谢。请清晰地上传您身份证件的正反面照片。接下来我们将继续进行身份验证流程。 Human: 我已经上传了照片。如何进行身份验证? AI: 我们已确认您上传的照片。请通过手机进行身份验证。请输入通过短信发送的验证码。 Human: 我已输入验证码。现在如何开户? AI: 身份验证已完成。请选择您想要的账户类型并输入必要信息。您可以选择存款类型、币种等。 Human: 我已经输入了所有信息。下一步是什么? AI: 我已确认您输入的信息。开户流程即将完成。请同意使用条款并确认开户。 Human: 我已完成所有步骤。账户开通了吗? AI: 是的,账户已开通。您的账号和相关信息已发送至您注册的邮箱。如果需要其他帮助,请随时联系我们。谢谢!
将消息提取为 HumanMessage 和 AIMessage 对象
设置 return_messages=True 将返回 HumanMessage 和 AIMessage 对象。
python
memory = ConversationBufferMemory(return_messages=True)
memory = ConversationBufferMemory(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.load_memory_variables({})["history"]
打印内容
python
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={}), HumanMessage(content='我已经上传了照片。如何进行身份验证?', additional_kwargs={}, response_metadata={}), AIMessage(content='我们已确认收到您上传的照片。请通过手机进行身份验证。请输入通过短信收到的验证码。', additional_kwargs={}, response_metadata={})
使用新版本的存储方式
python
from langgraph.checkpoint.memory import MemorySaver
from langchain_openai import ChatOpenAI
from langgraph.graph import MessagesState, START, StateGraph
from langchain_core.messages import HumanMessage
# 使用 MemorySaver 作为 checkpointer
checkpointer = MemorySaver()
# 定义简单的聊天图
def chat(state: MessagesState):
model = ChatOpenAI(
temperature=0.1, # 控制输出的随机性和创造性,值越低输出越稳定可预测,值越高输出越有创意但可能偏离预期 (范围: 0.0 ~ 2.0)
model_name="Qwen/Qwen2.5-7B-Instruct", # 硅基流动支持的模型名称
openai_api_key=os.getenv("SILICONFLOW_API_KEY"), # 从环境变量获取API密钥
openai_api_base="https://api.siliconflow.cn/v1" # 硅基流动API的基础URL
)
response = model.invoke(state["messages"])
return {"messages": [response]}
builder = StateGraph(state_schema=MessagesState)
builder.add_node("chat", chat)
builder.add_edge(START, "chat")
graph = builder.compile(checkpointer=checkpointer)
# 使用 thread_id 保持对话上下文
config = {"configurable": {"thread_id": "user-1"}}
# 第一轮对话
result1 = graph.invoke(
{"messages": [HumanMessage(content="你好,我叫Bob")]},
config
)
print(result1["messages"][-1].content)
# 第二轮对话 - 记住上文
result2 = graph.invoke(
{"messages": [HumanMessage(content="我的名字是什么?")]},
config
)
print(result2["messages"][-1].content) # 会记住 "Bob"