在构建自动化智能体时,规划模块往往负责把模糊目标拆成可执行步骤。但如果没有外部记忆,模型只能依赖当次上下文里的信息。一旦任务跨越多轮交互,或者需要复用之前踩过的坑,单纯扩大上下文窗口会带来延迟与成本,也无法保证关键信息被关注。记忆辅助规划的思路是把历史经验、环境反馈和规则约束持久化,在规划阶段按需检索,形成闭环。

这个闭环通常包含四个环节:观察环境、检索记忆、生成计划、执行后写回。下面从分层存储开始讲起。
一、为什么规划需要外部记忆
规划的核心是根据目标、当前状态和可用动作生成下一步行动。大模型本身具备推理能力,但不具备跨会话状态。假设一个客服智能体要处理退款流程,它需要知道订单状态、用户历史沟通记录、公司最新退款政策。如果这些信息都靠每次拼接,上下文窗口很快被无关历史占满,规划质量会下降。
更隐蔽的问题是反馈丢失。一次规划失败后,模型知道了某个动作在特定条件下不可行;如果没有写回机制,等下一次遇到相同场景,它还会犯同样错误。记忆辅助规划通过显式存储,把这类反馈转化为可检索的经验。记忆不只是日志,更像一个可更新的经验库。
这里的规划不单指静态任务分解,也包括执行中的动态调整。当环境返回异常,智能体需要从记忆中寻找类似情况的处理方式,而不是完全重新推理。这样能降低试错成本,提高多步任务的完成率。
二、分层记忆设计:短期、长期与情景记忆
把记忆分成不同类型,是为了在正确的时间召回正确粒度。短期工作记忆保存当前任务的关键变量,比如目标、已完成步骤、中间结果。它生命周期短,任务结束即可丢弃。长期语义记忆保存稳定的规则和知识,例如某个API的必填参数、某种错误的通用解决方案。情景记忆保存具体经历,包括当时的输入、执行动作、结果和反思。
实际实现中,可以用统一存储接口管理三类记忆。下面是一个简化结构:
class MemoryStore:
def __init__(self):
self.working = {}
self.semantic = []
self.episodic = []
def set_working(self, key, value):
self.working[key] = value
def get_working(self, key):
return self.working.get(key)
def add_semantic(self, rule, source):
self.semantic.append({
"rule": rule,
"source": source
})
def add_episode(self, task, plan, result, reflection):
self.episodic.append({
"task": task,
"plan": plan,
"result": result,
"reflection": reflection
})
短期记忆读写最快,但不适合长期依赖。情景记忆包含大量具体细节,检索时容易引入噪声,因此需要配套相关性评分。语义记忆最稳定,但更新频率较低。例如一个电商智能体,语义记忆保存退换货规则,情景记忆保存某次异常订单的处理过程,短期记忆保存当前订单号与用户诉求。
分层之外还要定义写入策略。不是所有执行结果都值得写进长期记忆。可以设置阈值,只有结果偏差较大或反馈包含新规则时才写入语义记忆,避免记忆库被重复信息淹没。
三、检索增强规划:从相似度召回到提示组装
记忆库再大,如果无法在规划前准确召回,就没有价值。常见做法是把记忆条目向量化,使用余弦相似度或内积计算与当前目标的匹配程度。针对文本记忆,可以先用嵌入模型编码,再建立向量索引。对于规则类记忆,也可以用关键词过滤和倒排索引。
检索时只调用标量过滤还不够,应该结合时间衰减与重要性权重。越是近期且被多次验证的记忆,越应该优先参与规划。下面是一个基于嵌入相似度的召回示例:
import numpy as np
def cosine_sim(a, b):
return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-8))
def recall_memory(query_vec, memory_items, top_k=3):
scored = []
for item in memory_items:
score = cosine_sim(query_vec, item["embedding"])
score += 0.1 * item.get("importance", 0)
scored.append((score, item))
scored.sort(key=lambda x: x[0], reverse=True)
return [item for _, item in scored[:top_k]]
召回后的记忆不能直接堆进提示,否则相关度低的内容会分散模型注意力。可以在提示中分区放置:先给当前目标,再给召回的相似成功案例,最后给相关失败教训。让模型在生成计划时同时参考正面经验与反面约束。
另一个关键点是重排。初筛得到的记忆可能语义接近但场景不同,比如同一关键词在不同业务线代表不同含义。可以用小模型对候选记忆做交叉编码,计算当前目标与记忆的匹配度并重排,只保留最相关的1到2条。这样既控制提示长度,又避免无关记忆干扰规划。
四、动态写入与规划回路:让经验真正沉淀
记忆辅助规划如果只有读取,没有写入,就只是静态知识库。规划执行后需要一个反思步骤,把结果与预期对比,提炼可复用教训。例如计划包含五个步骤,第三步失败,原因是权限不足;反思后写入情景记忆,下一次遇到同用户目标时,规划会直接建议先检查权限。
这个反思可以交给模型完成,提示它输出结构化结果。下面是简化流水线:
def run_planning_loop(store, task, query_vec):
related = recall_memory(query_vec, store.episodic)
plan = generate_plan(task, related)
result = execute(plan)
reflection = reflect(task, plan, result)
store.add_episode(task, plan, result, reflection)
if reflection.get("new_rule"):
store.add_semantic(reflection["new_rule"], source="episode")
return plan, result, reflection
run_planning_loop 把检索、规划、执行、反思写回串成回路。执行结果可以是环境给出的成功失败标志,也可以是用户反馈。反射步骤提取新规则时,建议要求模型给出规则的条件与动作,而不是只给一句总结,这样语义记忆才能被后续检索有效匹配。
需要注意写入频率。每个任务都写入情景记忆会造成大量冗余,可以只写入结果与预期不符或包含新信息的经历。对于语义记忆,最好有人工审核或置信度阈值,避免模型把偶发情况总结成通用规则。
五、工程落地中的权衡与避坑
把记忆辅助规划引入生产系统,首先要权衡检索延迟。向量检索虽然快,但嵌入编码每条记忆也需要时间。可以在写入时离线生成向量,检索时只编码查询向量。对于高频任务,可增加内存缓存,把最近使用的记忆向量常驻。
一致性是第二个难点。短期记忆、情景记忆和语义记忆可能产生冲突。比如语义记忆中的规则已经更新,但情景记忆里还留有旧经验。解决方法是写入时增加来源和版本号,并在检索后做冲突检测。如果发现规则冲突,优先相信版本更新或人工审核过的记忆。
隐私和权限也不能忽略。记忆库会沉淀用户对话内容和业务流程细节,需要脱敏存储、按租户隔离。给记忆条目增加访问标签,规划时根据当前用户权限过滤,避免越权检索。
最后要建立评测机制。记忆辅助规划的效果不能只看单次任务,需要构造多轮任务集,观察记忆写入前后成功率、平均步数和重复错误率。只有指标可量化,才能判断分层策略和检索阈值是否真的有效。

