
LLM Agent 跑久了最容易出问题的不是单步推理而是记忆。针对这个问题最近值得关注的技术方案是 Hierarchical Graph Memory分层图记忆配合 Path-level Localization路径级定位和 Rewrite重写机制。上下文窗口再大也有边界长对话一拖早期信息要么被截断要么被后来的内容稀释更麻烦的是Agent 执行复杂任务时需要的不只是一条孤立事实而是“上次任务按什么顺序做了哪几步、哪些操作有效、哪个环节失败过”。这种连续性记忆需求普通的 key-value 缓存和向量检索都很难直接满足。如果你在调 LLM Agent 的长期任务、多轮工具调用或者代码库级导航这条技术路线值得仔细拆一遍。先说结论。这套机制最有价值的地方不是“把记忆存进图里”这么简单而是把记忆的检索粒度提升到了“路径”级别并且把记忆更新当成一个需要专门处理的问题。它能解决的是 Agent 的连续性和经验复用问题适合的是任务状态多、步骤之间存在先后依赖、跨会话要延续上下文的场景。至于能不能直接用在你自己的 Agent 里要看你的任务是不是真的需要这种多粒度、多步骤的记忆组织方式。下面按实际落地顺序拆开讲。1. 先分清三种记忆事实记忆、过程记忆、目标记忆1.1 长上下文不等于长期记忆很多团队遇到 Agent 记不住问题第一反应是把对话历史全塞进上下文或者定期做一次摘要压缩。这种做法能做但有两个绕不开的问题。第一个问题是上下文窗口的物理上限。任务一长Token 消耗线性上涨成本先放到一边真正影响的是模型在大上下文里的注意力分布。早期关键信息经常被中段的大段工具调用结果冲散最后模型不是没有信息而是不知道该用哪段信息。第二个问题是摘要会丢过程细节。摘要适合保留结论但 Agent 复用经验靠的是步骤顺序、报错信息、参数调整过程。这些细节一旦被压缩后面只能重踩一遍坑。所以我一直建议把“上下文窗口”和“长期记忆”分开看。上下文窗口是工作台长期记忆是仓库。仓库里的东西必须按结构组织而不是把所有东西都搬到工作台上。1.2 Agent 记忆和普通数据存储不一样普通数据存储存的是事实用户是谁、订单号多少、配置文件在哪。Agent 的记忆里还多一类东西执行过程。这个问题在标题里体现得很清楚它强调的 memory 不只是“记了什么”而是“怎么完成任务”。举一个具体的例子。一个 Agent 负责数据处理任务昨天处理过一张报表先读 CSV发现日期列格式不一致做了清洗再跑聚合最后生成图表。今天用户说“继续处理昨天那张表”。如果只有事实记忆它只能查到“处理过这张表”但不知道当时的清洗规则是什么。如果只存完整对话日志检索成本又太高而且日志里混着大量无关消息。更合理的组织方式是把这次执行记录存成一条路径任务目标、执行步骤、遇到的问题、最终结果节点之间有明确的先后和因果关联。路径的起点是目标中间是动作和反馈终点是结果。下次遇到类似需求直接定位到这条路径就能复用整个处理过程。这是图结构天然适合的表达节点存储信息边表达顺序、因果和归属关系。1.3 分层图记忆要解决的核心矛盾单条路径好存真正难的是 Agent 跑了成百上千条任务之后怎么快速找到“当前问题对应的那几条路径”。如果所有执行记录都平铺在一张巨型图里会同时遇到两个问题。一是节点太多语义噪声大检索结果里总是混着无关路径。二是不同粒度的信息混在一起任务级目标、步骤级操作、结果级反馈全部并列定位效率很低。Hierarchical Graph Memory 的核心做法是把图按粒度分层。高层放任务目标、项目计划、长期偏好中层放子任务、执行阶段、关键决策低层放具体动作、参数变化、错误反馈。节点之间除了同一层的顺序边、因果边还有跨层的归属边。这样做最直接的好处是定位时可以先用高层语义缩小搜索范围再沿着层级往下走。没有分层路径定位就退化成大图里的子图匹配代价高、结果还不稳定。这也是为什么“Hierarchical”和“Path-level Localization”必须放在一起理解分层是路径定位的前提路径定位是分层的价值体现。2. 拆开看三个关键词分层图、路径级定位、重写2.1 图里的节点、边和层级先说图结构本身。按照这个思路一条记忆不是一条文本记录而是一组有结构的节点和边。每个节点是某个粒度的信息单元每条边表达节点之间的语义关系。我给一个便于理解的示意结构。高层节点可以是一条任务目标中层节点是一个可执行步骤低层节点是一次具体操作及其结果Level 3任务层: project-plan-001 - task-001 - task-002 Level 2步骤层: task-001 - step-003 - step-004 Level 1操作层: step-003 - action-007 - result-004跨层边表达归属和被触发关系task-001 --contains-- step-003 step-003 --triggers-- action-007 action-007 --produces-- result-004单看文字可能有点抽象实际对应到刚才数据处理任务的例子就清楚了task-001 是“整理季度销售报表”step-003 是“清洗日期列”action-007 是“把 MM/DD/YYYY 转成 YYYY-MM-DD”result-004 是“清洗后剩余记录数”。节点本身的内容可以用 LLM 生成和总结但图结构的意义是让这些内容之间有了可计算的关系。检索时不只是在文本里找相似而是沿着图结构找一条完整可复用的路径。2.2 为什么要强调“路径级”定位很多记忆方案做的是 node-level retrieval也就是直接找最相似的几个节点。这在单点知识查询里够用但碰到过程型记忆就力不从心。原因是过程中的任何一个片段单独看都可能不完整完整价值在节点串联起来的路径里。比如“清洗日期列”这个节点单独检索出来只能告诉 Agent 有过这么一次操作。但如果把它放到整条路径里Agent 能看到为什么清洗、清洗在哪个阶段发生、清洗完之后聚合结果变成什么样。这才叫可以复用的经验。Path-level Localization 定位的目标是给定当前问题和相关证据返回一条或几条完整的路径。它比单节点检索信息更完整又比全图遍历代价更低。实际落地时定位通常分两步先把查询映射到高层语义节点确定相关子图范围再在范围内走路径匹配选出与当前任务目标一致的候选路径。这个“先粗后细”的顺序正是分层结构带来的效率优势。2.3 Rewrite 不是覆盖是局部一致性维护记忆系统最容易忽略的是更新。路径存进去之后不是固定不变的Agent 执行完新任务后可能发现旧路径里的某个步骤已经过时或者旧路径与当前结论冲突。这时就需要 Rewrite。Rewrite 机制要处理三类问题。第一类是单点修正比如某个参数从 100 改成 200只需更新对应节点。第二类是路径修正比如发现某条路径里第三步顺序错了要重新编排边。第三类是级联修正高层节点的状态变了底层相关节点和路径也要跟着变。最需要注意的是Rewrite 不能每次都在整张图上做全量重写。全量重写既贵又容易造成“记忆漂移”改着改着早期记下来的正确信息被后续噪声覆盖了。合理做法是只在定位到的局部路径范围内做重写改完之后检查路径两端和高层归属节点是否一致。这也是标题里把 Path-level Localization 和 Rewrite 放在一起的原因定位确定了“改哪里”重写负责“怎么改才不影响其它记忆”。3. 一次完整的“写入 — 定位 — 重写”流程3.1 写入阶段节点放哪一层边怎么建写入阶段最容易犯的错是不分层直接塞。建议先设定明确的层级规则让每次写入都有据可依。可以按任务的粒度来定目标类信息进高层步骤类信息进中层操作和结果进低层。规则不一定复杂但必须稳定。如果今天按任务粒度分明天按时间粒度分后面定位和重写都会乱。边的关系也要建立清楚。同层边建议保留两种顺序边表示执行先后因果边表示依赖关系。跨层边表示归属比如某个步骤属于哪个任务。跨层边的重要性经常被低估没有它定位时无法从高层语义顺畅导航到底层操作细节。写入时还有一个实践建议每个节点都保留时间和来源信息方便后面判断是否需要重写。节点更新后保留旧内容或至少保留变更记录这能避免 Agent 改完记忆后发现结果反而变差、却没办回退。注意写阶段最忌讳的是“层级规则不固定”。今天按任务粒度分明天按时间粒度分路径定位和重写都会跟着乱。3.2 定位阶段先粗筛层级再匹配路径检索定位的流程可以拆成四步。第一步用当前用户请求或 Agent 内部状态生成查询向量或关键词。第二步在高层节点里做一次粗匹配找出相关任务领域把搜索范围从整张图缩小到某个子图。第三步在子图内部沿中层节点扩展找出候选步骤路径。第四步对候选路径做排序选出与当前目标最一致的返回。这里要注意两个点。第一查询不一定是完整句子Agent 的中间状态、最近执行的动作、失败的报错信息都可以作为定位输入。第二路径的排序标准要明确不能只按语义相似度。通常要看目标节点重合度、路径长度、最近更新时间、路径中是否有失败标记。失败标记很重要一条曾经失败的路径在相似场景下的参考价值是“避免重犯”而不是照做。3.3 重写阶段成功路径加强失败路径修正任务执行完之后重写阶段才真正开始。这一步我建议按结果分两类处理。如果是成功执行并且现有路径与这次执行结果一致可以做强度更新增加匹配计数、更新最近使用时间、补充新的上下文摘要。这样下次定位时这条路径的排序会更高。如果执行失败或者现有路径与结果冲突就要触发路径级重写。先对比失败步骤和已有路径的差异定位到具体冲突节点再做局部修改要么替换节点的内容要么调整边的顺序要么把失败标记挂到对应节点上。不要一失败就把整条路径删掉。失败路径本身很有价值保留失败标记和原因说明能让 Agent 在下次遇到同样情况时主动避开。重写完成后还要做一次一致性检查重写过的路径所属的高层节点其摘要是否需要同步更新被删除的边所连接的节点是否还有其它路径依赖。这一步不能跳否则图结构会慢慢出现“断边”和“孤立节点”定位质量会越来越差。4. 工程落地时真正要盯的细节4.1 图存储和索引选型先说明一下原始标题没有指定具体实现工具下面只是通用选型经验实际用哪套要看你的环境。最轻量的做法是用 JSON 或关系表维护节点和邻接关系配合内存索引做高层节点粗筛。适合原型验证和小规模任务。如果任务量达到几千条路径以上建议换图数据库或至少把路径索引单独建表。图数据库的好处是遍历边方便坏处是部署和操作成本高只有跨层路径遍历是高频操作时才划算。路径索引是定位性能的关键。建议为每个路径维护一个摘要向量和对应的高层节点 ID这样定位时可以先用向量粗筛路径集合再在集合内做精确匹配。不要每次都全图遍历那样路径一多延迟会线性上涨。4.2 路径匹配的排序标准路径排序是整个系统效果层面的核心。排序不对即使图存得好Agent 也会拿到错误记忆。从我测试的经验看可以优先用下面几个因素加权排序因素说明优先级建议目标重合度候选路径的高层目标和当前目标是否一致最高上次更新时间近期更新的路径更可能反映当前配置较高执行匹配数同一路径被成功复用的次数较高失败标记带失败标记的路径要降权或单独提示中路径长度过长路径可能过度复杂也要看任务需要中这个表不是固定公式具体权重应该根据你的任务类型调。调试期可以把每个因素的分数和最终命中路径一起打进日志看哪条因素没起作用。我遇到最多的现象是更新时间和匹配数权重太高结果把一些低频但目标高度相关的路径压下去了。注意调试期遇到“正确路径已经找到但排在第二位”的情况先查排序权重别急着怀疑图结构。4.3 重写频率、冲突检测和记忆漂移Rewrite 机制最大的隐患是重写过头。每次遇到任务都全量重写过一段时间图的记忆就和最初的真实情况越偏越远这就是记忆漂移。控制办法有几个。一是限定重写范围永远只在定位到的路径内部做修改。二是设置重写触发条件只有在执行结果与现有路径不一致时才触发而不是每次都写。三是对高频更新设置冷却比如同一段路径在短时间内重复更新要等稳定后再确认否则很容易被一次异常结果带偏。冲突检测也要做。新产生的信息和已有路径冲突时不要急着覆盖。可以先把新内容记为候选节点等下一次任务验证后再决定替换还是保留。这个策略看着多一步实际能省掉很多因单次异常执行导致的记忆污染。5. 什么场景适合什么场景别硬上5.1 适合的典型场景根据标题的技术路线这套机制适合的是“过程记忆 长期复用”型任务。我实际验证下来比较典型的有三类。第一类是跨会话任务延续。Agent 不是一次性完成所有事而是每天延续同一个项目需要复用昨天的步骤、结论和待办。第二类是复杂工具链使用例如数据处理、代码库维护、多接口编排任务由多个步骤组成步骤之间有依赖。第三类是长周期个人助理类应用需要同时记住用户偏好、历史对话主题和已执行动作并且能按主题回溯。这三类场景的共同点任务不是单点问答而是多步骤过程需要跨会话复用记忆之间存在明显的归属和依赖关系。5.2 不需要硬上的场景如果任务本身就是单轮问答、短上下文工具调用或者现有 RAG 已经能满足检索质量就没必要引入分层图记忆。图结构会增加存储成本、索引成本和定位复杂度对简单场景是负优化。另外如果 Agent 的任务之间完全没有连续性每次都是从零开始那记忆系统本身就不需要做得多复杂。先用向量存储把事实记下来就够了。判断标准只有一条新增这套机制后任务的连续成功率有没有提升定位延迟有没有控制在可接受范围。如果没有说明场景不匹配不是实现的问题。5.3 怎么判断有没有收益建议做对照实验。同一批任务一组用普通向量记忆或对话摘要一组用分层图记忆加路径定位分别统计任务成功率、失败重试次数、平均轮次和定位延迟。不要只看成功率。定位延迟和存储成本也要看尤其是路径数量超过一万后路径检索的时延可能成为瓶颈。如果成功率提升明显但每次定位多花几秒那就要权衡是定位阶段分层粗筛做得不够还是任务本身不需要这种粒度。6. 最小验证思路和常见排查顺序6.1 最小原型怎么搭我建议不要一开始就做全功能。先拿一个最简单的领域试例如一个模拟的“按步骤完成数据处理”任务。先人工定义一批路径比如 20 条左右覆盖成功案例和失败案例手动写入图结构。然后给一个模糊的查询需求验证定位能否返回最相关的路径。再模拟一次执行结果与旧路径冲突验证重写逻辑是否能正确更新。最后再测一下重写后的一致性。这样三步走每一步都能确定问题出在哪一块比直接写完整方案再调试要快很多。原型阶段可以用内存图和简单 JSON 维护不需要先部署图数据库。跑通再迁移到更重的存储。6.2 核心评估指标建议从四个维度看这套机制是否可用维度指标关注点定位准确性路径命中率、排序 Top-1 / Top-3 命中Top-3 命中率要稳定连续性多轮任务成功率、失败重试次数变化连续任务成功率要高于基线开销路径定位时延、存储量增长速度时延要比全量遍历明显下降稳定性重写后记忆一致性、路径冲突数量冲突和断边数量要随运行收敛指标合格线没有固定值和任务难度相关。但对比基准一定要做至少和“全量塞上下文”“向量检索”这两个基线比一次才能说明这套机制有增量价值。6.3 踩坑时的排查顺序如果系统跑起来效果不好我一般按下面的顺序查。先查路径定位的输入。查询向量、高层节点匹配、子图范围任何一步有偏差返回的路径就不会准。再查路径排序权重。经常是正确路径被排到第二位不是没找到而是排序分数低。然后查重写逻辑。看最新写入的节点和边是否符合预期有没有把失败路径的标记挂错位置。最后查存储层。路径数量增长后索引是否还在生效有没有出现全图遍历。顺序的逻辑是从“信息流”出发先看定位有没有拿到相关信息再看排序有没有把有效信息挑出来再看更新有没有破坏已有结构最后才是存储性能问题。大多数效果问题都出在前三步存储性能问题反而是最容易查的那一类。如果定位总是返回无关路径优先看高层节点的抽象程度。高层摘要写得越空泛路径差异越难区分。如果重写后效果更差先回滚到重写前的节点内容对照判断是哪个局部修改引起的。保留变更记录这个习惯在这种时候能省很多时间。这套机制真正的价值是在 Agent 需要长期连续处理多步骤任务时把“记忆”从简单的文本堆砌变成可定位、可更新、可复用的结构化资产。如果你正准备给自己的 Agent 加长期记忆建议先从最小原型验证路径定位和重写的一致性再考虑全量接入。