LangChain Agent 的 Memory(记忆)机制
·
LangChain Agent 的 Memory(记忆)机制 是实现上下文感知、长期交互、个性化服务的核心能力。它不仅记录历史对话,还能通过工作记忆折叠(Working Memory Folding)、会话档案化(Session Archiving)、记忆演化(Memory Evolution) 等高级策略,让 Agent 从“健忘的聊天机器人”升级为“有记忆、能反思、会成长”的智能体。
下面我将从 原理、架构、代码实现、最佳实践 四个维度,深入讲解 LangChain 中的记忆系统。
一、为什么需要 Memory?
❌ 无记忆 Agent 的问题:
- 用户说:“帮我订杨国福麻辣烫”,Agent 问:“要什么口味?”
- 用户答:“少辣,加雪碧”
- 下一句用户说:“再加一份米饭” → Agent 完全忘记前面在点餐!
✅ 有记忆 Agent 的优势:
- 理解上下文(“再加” = 在原订单上追加)
- 避免重复提问
- 支持多轮复杂任务(如规划旅行、写周报)
二、LangChain Memory 的三层架构
graph LR
A[短期:Working Memory<br>(当前会话上下文)] -->|折叠/摘要| B[中期:Session Archive<br>(单次会话完整记录)]
B -->|提炼/索引| C[长期:Memory Store<br>(跨会话知识库)]
| 层级 | 名称 | 作用 | 生命周期 |
|---|---|---|---|
| L1 | Working Memory | 当前对话的即时上下文 | 单次 invoke() |
| L2 | Conversation Buffer / Summary | 整个会话的历史 | 单次会话(session) |
| L3 | VectorStore Memory / Entity Memory | 跨会话的长期记忆 | 永久存储 |
三、核心概念详解
1. 工作记忆折叠(Working Memory Folding)
🎯 目标:
在有限上下文窗口(如 LLM 的 128K token)内,动态压缩历史对话,保留关键信息,丢弃冗余细节。
🔧 实现方式:
- 滑动窗口:只保留最近 N 轮对话
- 摘要压缩:用 LLM 将多轮对话压缩成一段摘要
- 关键信息提取:只保留实体、决策、状态变更
✅ 适用场景:
- 长时间客服对话
- 复杂任务分解(如写论文)
2. 会话档案化(Session Archiving)
🎯 目标:
将一次完整会话结构化存储,用于:
- 审计追踪
- 用户行为分析
- 后续会话冷启动
📁 存储内容:
{
"session_id": "sess_20240320_abc123",
"user_id": "user_789",
"start_time": "2024-03-20T19:00:00Z",
"end_time": "2024-03-20T19:15:00Z",
"turns": [
{"role": "user", "content": "订麻辣烫"},
{"role": "agent", "content": "要什么口味?", "tool_calls": []},
{"role": "user", "content": "少辣,加雪碧"},
{"role": "agent", "content": "已加雪碧", "state": {"order": {...}}}
],
"final_state": {"order_items": ["麻辣烫(微辣)", "雪碧"]}
}
3. 记忆演化(Memory Evolution)
🎯 目标:
让记忆随时间更新、修正、泛化,而非静态存储。
🔄 三种演化机制:
| 类型 | 说明 | 示例 |
|---|---|---|
| 覆盖更新 | 新信息覆盖旧信息 | 用户改地址:“我家搬到朝阳区了” → 更新地址 |
| 冲突检测 | 发现矛盾时主动澄清 | “你上周说喜欢微辣,今天要重辣?” |
| 知识提炼 | 从多次交互中抽象偏好 | “用户总在周五点麻辣烫” → 周五主动推荐 |
四、LangChain 内置 Memory 类型对比
| Memory 类型 | 原理 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| ConversationBufferMemory | 存所有历史消息 | 简单、完整 | 占 token 多 | 短对话 |
| ConversationSummaryMemory | 用 LLM 生成摘要 | 节省 token | 可能丢失细节 | 长对话 |
| ConversationBufferWindowMemory | 只存最近 K 轮 | 轻量 | 忘记早期信息 | 中等长度任务 |
| VectorStoreRetrieverMemory | 向量检索相关历史 | 跨会话、精准召回 | 需嵌入模型 | 个性化服务 |
| EntityMemory | 提取并跟踪实体状态 | 结构化、可更新 | 实现复杂 | 多轮状态管理 |
✅ 推荐组合:
VectorStoreRetrieverMemory(长期) +ConversationSummaryMemory(短期)
五、代码实现:三层记忆系统
步骤 1:安装依赖
pip install langchain langchain-openai langchain-community faiss-cpu
步骤 2:实现工作记忆折叠(摘要压缩)
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-4-turbo", temperature=0)
# 自动将历史对话压缩成摘要
summary_memory = ConversationSummaryMemory(
llm=llm,
memory_key="history",
return_messages=True
)
# 使用示例
summary_memory.save_context(
{"input": "我想订杨国福麻辣烫"},
{"output": "好的,请问要什么口味?"}
)
summary_memory.save_context(
{"input": "少辣,加一瓶雪碧"},
{"output": "已为您添加雪碧,总价31元"}
)
print(summary_memory.load_memory_variables({}))
# 输出: {'history': [SystemMessage(content='The human wants to order Yang Guofu spicy hotpot with mild spice and a Sprite, totaling 31 yuan.')]}
💡 原理:每次新对话后,调用 LLM 将
(旧摘要 + 新对话)压缩成新摘要。
步骤 3:实现长期记忆(向量检索)
from langchain.memory import VectorStoreRetrieverMemory
from langchain_community.vectorstores import FAISS
from langchain_openai import OpenAIEmbeddings
# 初始化向量库
embedding = OpenAIEmbeddings()
vectorstore = FAISS.from_texts([""], embedding) # 初始空库
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})
# 创建记忆
long_term_memory = VectorStoreRetrieverMemory(
retriever=retriever,
memory_key="long_term_info",
input_key="input" # 用于检索的字段
)
# 添加记忆(通常在会话结束时)
long_term_memory.save_context(
{"input": "用户偏好"},
{"output": "喜欢杨国福麻辣烫,口味微辣,常加雪碧,住址:北京市海淀区"}
)
# 在新会话中自动检索
result = long_term_memory.load_memory_variables({"input": "订麻辣烫"})
print(result)
# 输出: {'long_term_info': '喜欢杨国福麻辣烫,口味微辣...'}
🔍 检索机制:
用户新输入 → 嵌入向量 → 检索最相关的 3 条历史记忆 → 注入 prompt
步骤 4:组合记忆到 Agent
from langchain.agents import create_openai_functions_agent, AgentExecutor
from langchain import hub
# 合并短期 + 长期记忆
from langchain.memory import CombinedMemory
memory = CombinedMemory(memories=[summary_memory, long_term_memory])
# 创建带记忆的 Agent
prompt = hub.pull("hwchase17/openai-functions-agent")
prompt = prompt.partial(
history=memory.memories[0].memory_key, # 短期
long_term_info=memory.memories[1].memory_key # 长期
)
agent = create_openai_functions_agent(llm, tools, prompt)
executor = AgentExecutor(
agent=agent,
tools=tools,
memory=memory, # 关键!注入记忆
verbose=True
)
# 运行(自动携带记忆)
response = executor.invoke({"input": "再订一份昨天的麻辣烫"})
✅ 效果:
Agent 会看到:
- 短期摘要:“用户正在点餐”
- 长期记忆:“喜欢微辣+雪碧”
→ 直接回复:“已为您下单杨国福麻辣烫(微辣)+ 雪碧,对吗?”
六、高级:自定义记忆演化逻辑
场景:当用户修改偏好时,自动更新长期记忆
def update_user_preference(new_info: str):
"""用新信息覆盖旧偏好"""
# 1. 检索旧偏好
old_docs = vectorstore.similarity_search("用户偏好", k=1)
if old_docs:
# 2. 让 LLM 合并新旧信息
merge_prompt = f"""
旧偏好: {old_docs[0].page_content}
新信息: {new_info}
请输出更新后的完整偏好(保留未提及的部分):
"""
updated = llm.invoke(merge_prompt).content
# 3. 删除旧记录,添加新记录
vectorstore.delete([old_docs[0].metadata["id"]])
vectorstore.add_texts([updated], metadatas=[{"type": "preference"}])
🔄 演化流程:
用户说“以后不要雪碧了” → 触发update_user_preference("不要雪碧")→ 长期记忆更新
七、会话档案化实现(日志存储)
import json
from datetime import datetime
class SessionArchiver:
def __init__(self, user_id: str):
self.user_id = user_id
self.session_id = f"sess_{datetime.now().strftime('%Y%m%d_%H%M%S')}"
self.turns = []
def add_turn(self, role: str, content: str, metadata: dict = None):
self.turns.append({
"role": role,
"content": content,
"timestamp": datetime.utcnow().isoformat(),
"metadata": metadata or {}
})
def save_to_disk(self):
archive = {
"session_id": self.session_id,
"user_id": self.user_id,
"turns": self.turns,
"end_time": datetime.utcnow().isoformat()
}
with open(f"archives/{self.session_id}.json", "w") as f:
json.dump(archive, f, indent=2, ensure_ascii=False)
# 在 AgentExecutor 中使用
archiver = SessionArchiver("user_789")
# 每次交互后记录
archiver.add_turn("user", "input_text")
archiver.add_turn("agent", "output_text", {"tools_used": [...]})
# 会话结束时保存
archiver.save_to_disk()
八、最佳实践与避坑指南
| 问题 | 解决方案 |
|---|---|
| 记忆污染 | 为每个用户/会话隔离记忆存储 |
| Token 超限 | 优先用 SummaryMemory + VectorStore 组合 |
| 隐私泄露 | 敏感信息(手机号、地址)脱敏后再存记忆 |
| 记忆过时 | 设置 TTL(如 30 天自动清理) |
| 幻觉记忆 | 所有记忆写入前用 LLM 校验一致性 |
九、总结:记忆系统的演进路径
| 阶段 | 能力 | 技术栈 |
|---|---|---|
| V1:无记忆 | 每次对话独立 | Chain |
| V2:短期记忆 | 单次会话连贯 | ConversationBufferMemory |
| V3:长期记忆 | 跨会话个性化 | VectorStoreRetrieverMemory |
| V4:智能记忆 | 自动更新、冲突检测、偏好学习 | 自定义演化逻辑 + LangGraph |
🚀 未来方向:
- 记忆反思:Agent 定期回顾历史,提炼经验
- 多模态记忆:存储图像、语音片段
- 联邦记忆:在保护隐私前提下共享群体知识
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)