Memory:让对话拥有记忆
理解对话状态管理:从手动维护消息列表到 ConversationTokenBufferMemory 等策略。
模型本身没有记忆
LLM 是无状态的:所谓"记忆",就是把历史消息再次发给模型。Memory 模块管理的正是"历史消息如何收集、如何裁剪"。
最朴素的方式:手动维护列表
history = []
while True:
q = input("> ")
history.append(HumanMessage(content=q))
resp = llm.invoke(history)
history.append(resp)
print(resp.content)
LangChain 的 Memory 策略
- ChatMessageHistory:最基础的消息存储(内存 / Redis / SQLite 等后端);
- ConversationBufferMemory:原样保留全部历史 —— 简单但 token 增长快;
- ConversationBufferWindowMemory:只保留最近 k 轮 —— 成本可控,丢失远期信息;
- ConversationTokenBufferMemory:按 token 上限裁剪;
- ConversationSummaryMemory:用模型把历史压缩成摘要 —— 长对话首选。
在 LCEL 中接入记忆
from langchain_core.runnables.history import RunnableWithMessageHistory
from langchain_community.chat_message_histories import SQLChatMessageHistory
def get_history(session_id):
return SQLChatMessageHistory(session_id, "sqlite:///chat.db")
chain = prompt | llm
chain_with_history = RunnableWithMessageHistory(
chain, get_history,
input_messages_key="question",
history_messages_key="history",
)
# 调用时通过 config 指定会话
chain_with_history.invoke({"question": "我叫小明"},
config={"configurable": {"session_id": "user-1"}})
📝 课后练习
quiz-1 LLM 应用中"记忆"的本质是?