在开发 AI 智能体的过程中,我们常常会遇到这样的困惑:为什么智能体在跨会话交互时总是 "健忘"?为什么相同的用户需求在不同对话中需要反复输入?这些问题的核心,往往在于我们对智能体长期记忆系统的理解和实现存在不足。今天,我们就来系统地探讨 LangGraph 框架下长期记忆的完整解决方案,帮助你构建真正 "有记性" 的智能应用。
长期记忆是智能体技术中最复杂的挑战之一,没有放之四海而皆准的解决方案。但我们可以通过两个核心问题来构建思考框架:记忆的类型是什么?以及何时更新记忆?这两个问题如同指南针,指引我们在复杂的记忆系统设计中找到正确的方向。
人类的记忆系统精妙而复杂,AI 智能体的记忆设计从中汲取了丰富的灵感。根据存储内容的不同,我们可以将长期记忆分为三大类型,每一种都对应着人类记忆的不同方面:
记忆类型 | 存储内容 | 人类示例 | 智能体示例 |
---|---|---|---|
语义记忆 | 事实性知识 | 学校学到的公式 | 用户画像、产品知识库 |
情景记忆 | 经历事件 | 第一次骑自行车 | 历史对话记录、操作日志 |
程序性记忆 | 任务规则 | 骑车的平衡技巧 | 系统提示词、工具调用流程 |
语义记忆是智能体存储事实性知识的核心模块。无论是用户的基本信息,还是产品的规格参数,都可以通过语义记忆来持久化存储。在实现上,语义记忆有两种主要管理模式:
档案模式:将信息整合成单个 JSON 文档,类似电子档案
python
# 构建用户档案
user_profile = {
"language": "English",
"preference": "short_response",
"tech_stack": ["Python", "SQL"]
}
store.put(namespace, "user_profile", user_profile)
这种模式的优势在于整体性强,便于快速检索,但随着档案增大,更新时容易出错。
集合模式:将信息分散存储为多个文档
python
# 存储多条用户偏好
store.put(namespace, "pref_1", {"key": "language", "value": "English"})
store.put(namespace, "pref_2", {"key": "response_style", "value": "short"})
集合模式的优势在于更新灵活,LLM 更容易为新信息生成新对象,但也带来了记忆搜索和上下文整合的复杂性。
情景记忆记录的是智能体的过往经历,这对于需要从历史交互中学习的场景至关重要。在实践中,情景记忆通常通过少样本示例提示来实现:
python
# 存储成功的工具调用案例
example = {
"user_query": "帮我查北京天气",
"tool_called": "weather_api",
"parameters": {"city": "北京"},
"response": "北京今天晴,22-30℃"
}
store.put(namespace, "weather_example_1", example)
# 检索相关示例用于少样本提示
similar_examples = store.search(namespace, query="天气查询")
少样本学习让智能体能够通过 "示例" 来学习,这比单纯的规则描述更有效。LangSmith 提供了强大的动态示例选择器,可以基于关键词相似度检索最相关的历史案例:
python
# 使用LangSmith数据集存储少样本示例
from langsmith import Client
client = Client()
dataset = client.create_dataset("weather_examples")
client.upload_records(
[
{"inputs": {"query": "北京天气"}, "outputs": {"response": "晴"}},
{"inputs": {"query": "上海温度"}, "outputs": {"response": "25℃"}},
],
dataset_id=dataset.id,
)
程序性记忆是智能体执行任务的 "肌肉记忆",它结合了模型权重、智能体代码和提示词,共同决定了智能体的行为模式。在实践中,智能体修改模型权重或代码的情况很少见,更多的是通过 "反思" 机制来优化提示词:
python
def update_system_prompt(state: State, store: BaseStore):
namespace = ("agent_instructions",)
current_prompt = store.get(namespace, "system_prompt")
# 结合用户反馈生成新提示
feedback = state["messages"][-1].content
prompt = f"""
现有系统提示:{current_prompt}
用户最新反馈:{feedback}
请根据反馈优化系统提示:
"""
new_prompt = llm.invoke(prompt).content
store.put(namespace, "system_prompt", {"instructions": new_prompt})
这种元提示(meta-prompting)方法允许智能体从交互中学习并调整自身的指令,特别适合那些难以预先明确指定规则的任务。
记忆更新是长期记忆系统的另一核心问题。我们需要在智能体的运行过程中,选择合适的时机和方式来更新记忆。目前主要有两种更新策略:热路径更新和后台更新。
热路径更新是指在智能体响应用户的主流程中同步更新记忆。这种方式的优势在于记忆的实时性,新记忆可以立即用于后续交互:
python
def save_memory_on_the_fly(state: State, store: BaseStore):
# 从对话中提取关键信息
key_info = extract_key_points(state["messages"])
# 实时存储
store.put(namespace, f"memory_{timestamp}", key_info)
return {"status": "memory saved"}
但热路径更新也带来了明显的挑战:
ChatGPT 使用的 save_memories 工具就是热路径更新的典型案例,它会根据每条用户消息决定是否更新记忆。
将记忆更新作为后台任务是另一种重要策略。这种方式将应用逻辑与记忆管理分离,避免了对主流程的影响:
python
# 后台记忆服务(伪代码)
def background_memory_service():
while True:
# 检查待处理对话
pending_conversations = get_pending_conversations()
for conv in pending_conversations:
# 分析对话并生成记忆
memories = analyze_and_create_memories(conv)
# 批量存储
store.batch_put(memories)
# 定时休眠
sleep(60)
后台更新的优势在于:
但这种方式也需要解决几个关键问题:
不同的应用场景对长期记忆的需求差异很大:
建立完善的记忆评估体系是长期记忆系统成功的关键:
长期记忆是智能体从 "人工" 走向 "智能" 的关键一步。通过理解记忆的类型和更新策略,我们可以构建出更具个性化、更能适应用户需求的智能应用。从语义记忆的精准存储,到情景记忆的经验积累,再到程序性记忆的自主优化,每一个环节都凝聚着人类认知科学与 AI 技术的智慧结晶。
如果本文对你有帮助,别忘了点赞收藏,关注我,一起探索更高效的开发方式~