HMO分层记忆编排工程思想

HMO 分层记忆编排:Agent 不是记得多,而是想得准

最近看 HMO(Hierarchical Memory Orchestration,分层记忆编排)这个思路时,我觉得它最有价值的地方不是提出了一个多复杂的公式,而是把 Agent 长期记忆这件事讲得更像一个真正的工程问题。

很多人一说 Agent 记忆,第一反应就是"存下来":把用户说过的话做摘要,塞进向量库,下次再检索出来。

这当然是一个起点,但不是终点。

因为长期记忆真正难的地方,从来不是"能不能存",而是"什么时候该想起来"。如果一个 Agent 每次都把一大堆旧历史翻出来,它看起来是记忆力很好,实际上很容易变得又慢又啰嗦,还会把无关信息带进当前判断里。

所以 HMO 给我的启发是:

长期记忆不是仓库,而是一套注意力调度系统。

它关心的不是把所有历史都放进上下文,而是把记忆分层管理,让高价值内容留在前台,让低频内容退到后台,需要时再逐层查找。

先说问题:为什么"全都记住"反而不好

如果只做一个最简单的记忆系统,大概会长这样:

text 复制代码
对话内容 → 摘要 → 向量化 → 存库 → 下次相似度检索

这个方案看起来挺自然,很多 RAG 系统也是这么起步的。

但放到长期陪伴型、协作型 Agent 里,它很快会遇到几个问题。

第一,历史越多,噪声越大。

向量检索找到的是"语义相似",不一定是"行为上重要"。比如用户曾经随口聊过一次某个新闻,后来又问了一个和行业有关的问题,这条新闻可能被召回。但它真的应该影响当前回答吗?不一定。

第二,上下文是有成本的。

每多塞一段记忆,模型就要多读一段内容。短期看只是多一点 token,长期看就是延迟、费用和判断噪声一起上升。Agent 不是资料越多越聪明,有时候是资料越多越犹豫。

第三,用户偏好有轻重。

"我喜欢 TypeScript"是一种偏好,"不要主动暴露内部排程"也是一种偏好,但后者更像边界。忘记前者只是回答没那么贴合,忘记后者可能直接破坏体验。

所以一个好的记忆系统必须回答几个更细的问题:

  • 哪些内容应该每轮都影响 Agent?
  • 哪些内容只是需要时再查?
  • 哪些内容只应该作为历史证据保存?
  • 一条旧记忆被反复用到后,要不要升权?
  • 用户画像变化后,旧记忆要不要重新排序?

HMO 解决的就是这些问题。

用一个类比理解 HMO

我更愿意把 HMO 理解成一张工作台、一个资料柜和一座档案馆。

text 复制代码
Tier 1: 工作台
Tier 2: 资料柜
Tier 3: 档案馆

工作台上放的是现在就要用的东西,资料柜里放的是常用但不必摊开的资料,档案馆里保存完整历史和原始证据。

这套类比比"三级缓存"更容易理解,因为 Agent 的记忆不是纯性能缓存,它还关系到行为、语气、边界和长期协作。

Tier 1:工作台

Tier 1 是最靠近当前对话的记忆层。

这里放的内容应该很少,但很关键。比如用户长期稳定的表达偏好、明确说过的边界、最近正在推进的项目、当前任务必须依赖的上下文。

它的特点是:每轮都可能直接进入上下文。

举个例子:

text 复制代码
用户不喜欢主动消息暴露排程细节。

这类记忆就不应该每次都去向量库里临时搜。它是行为约束,应该长期留在工作台上。

Tier 1 追求的不是完整,而是稳定和准确。它像一个小而精的运行时状态,宁愿少,也不要乱。

Tier 2:资料柜

Tier 2 放的是重要但不必每轮都出现的内容。

比如某个长期项目的背景、用户过去一段时间关注的技术方向、某些被多次召回过但不是强约束的偏好。

它的作用很像二级缓存:大多数查询如果 Tier 1 不够,可以先来 Tier 2 找,而不是直接翻完整历史。

如果某条 Tier 2 记忆最近频繁被用到,它就可以升到 Tier 1。反过来,如果 Tier 1 里某条记忆长期没被用,也应该退回 Tier 2。

这里开始有了"记忆生命周期"的味道。

记忆不是写入后就固定不动,而是会随着使用频率、时间、用户状态变化而移动。

Tier 3:档案馆

Tier 3 保存的是完整历史、低频信息和原始证据。

它的价值不是快,而是全。

很多内容不适合默认进入上下文,但也不能随便删。因为以后可能需要回溯,尤其是在长期协作里,证据源很重要。

比如用户原话是:

text 复制代码
下次对话时间不要说出来,搞得太有程序感觉了。

如果被摘要成:

text 复制代码
用户不喜欢技术细节。

这就已经偏了。

用户真正表达的是"不喜欢暴露内部排程",不是"不喜欢技术细节"。如果系统只保存摘要,不保存证据,后面就很难纠偏。

所以 Tier 3 不只是冷数据,它还是记忆系统的证据底座。

记忆要带元数据,不只是文本

HMO 最工程化的一点,是它不把记忆当成一段普通文本,而是当成一条有状态的数据。

一条记忆可以长这样:

json 复制代码
{
    "id": "mem_20260515_hide_schedule",
    "content": "用户不喜欢主动消息暴露排程细节。",
    "type": "boundary",
    "tier": 1,
    "importance": 10,
    "personaSimilarity": 0.95,
    "recallCount": 4,
    "createdAt": "2026-05-15T03:30:00.000Z",
    "lastAccessedAt": "2026-05-15T08:00:00.000Z",
    "tags": ["style", "rhythm", "boundary"],
    "sourceIds": ["src_20260515_hide_schedule"]
}

这里面最值得注意的不是字段数量,而是这些字段背后的判断逻辑。

importance 代表这条记忆本身有多重要。核心身份、长期边界、重大目标,肯定比一次寒暄更重要。

personaSimilarity 代表它和当前用户画像有多相关。同样一条记忆,在不同阶段权重可能不同。比如用户最近在研究 Agent 工程,那么 HMO、MCP、Skill、Hook 相关记忆就应该更容易被召回。

recallCount 代表它被用过多少次。经常被用到的记忆,应该更难衰减。这和人类记忆很像:越常想起,越容易再次想起。

lastAccessedAt 用来处理时间衰减。很久没被用到的记忆,可以降级,但不一定删除。

sourceIds 指向原始证据。这个字段我觉得特别重要,因为 AI 总结很容易漂移。长期记忆如果只有"总结后的结论",没有"当时的上下文",后面就容易把用户意思越传越歪。

换句话说,长期记忆不应该只存 content,还要存"这条记忆为什么可信、什么时候用过、从哪里来的、现在还重不重要"。

评分公式真正想表达什么

HMO 里有一个优先级评分,大概可以理解成:

text 复制代码
记忆得分 =
    (初始重要性 + 与用户画像的相关度)
    * 召回次数增益
    * 时间衰减

更形式化一点是:

text 复制代码
S_m =
  (alpha * I_m + beta * Sim(m, P))
  * ln(1 + C_m)
  * exp(-(lambda * (t_now - t_last)) / ln(1 + C_m))

公式看着有点数学味,但它表达的想法并不复杂。

一条记忆越重要,越应该靠前;和当前用户画像越相关,越应该靠前;被反复用过,越应该抗衰减;太久没用,就慢慢往后退。

这里面最妙的是 recallCount 对时间衰减的影响:

text 复制代码
被想起得越多,忘得越慢。

这比单纯的"最近使用优先"更合理。

因为有些记忆不是最近说的,却非常重要。比如用户的长期表达边界、项目协作偏好、对工作方式的稳定要求,这些内容不应该因为一个月没提就消失。

从工程角度看,这个评分就是在做一件事:让记忆的位置由"重要性、相关性、使用频率、时间"共同决定,而不是只靠向量相似度。

检索时不要一上来翻全库

普通 RAG 很容易形成一个固定动作:

text 复制代码
问题来了 → 全库向量检索 → 塞 topK → 生成回答

这在知识库问答里可以用,但放到个性化 Agent 里不一定合适。

HMO 的检索更像这样:

text 复制代码
先看 Tier 1
    ↓
不够,再查 Tier 2
    ↓
还不够,再查 Tier 3

也就是先问:工作台上的内容够不够回答?

如果够,就别去翻资料柜。资料柜不够,再去档案馆。

这个顺序的好处很朴素:少查一点,快一点,噪声少一点。

很多时候用户只是问一个当前任务里的问题,Tier 1 已经够了。非要全库检索,反而会把很久以前的旧信息带回来,让模型产生不必要的联想。

这里还有一个值得借鉴的小设计:可以让模型先判断当前上下文是否足够。

不是所有问题都需要深层检索。一个成熟的 Agent 应该知道什么时候查记忆,也应该知道什么时候不要查。

升级、降级和懒更新

如果一条记忆被反复召回,它应该升级。

如果一条记忆长期不用,它应该降级。

如果用户画像明显变化,相关记忆应该重新排序。

这三句话听起来简单,但落地时很重要。因为它们决定了记忆系统是"活的",还是一堆越堆越多的文本。

一个基本流程可以是:

text 复制代码
新交互进入
  ↓
提取候选记忆
  ↓
评估重要性和画像相关度
  ↓
写入对应 Tier
  ↓
检索命中后更新 recallCount 和 lastAccessedAt
  ↓
重新计算得分
  ↓
必要时升降级

不过这里不能走向另一个极端:每次都全量重算。

Tier 3 可能很大,如果用户画像稍微变动一下,就把所有历史都重新评分,成本会非常高。

所以 HMO 里很值得学的一点是懒更新:

  • Tier 1 / Tier 2 经常更新。
  • Tier 3 不频繁全量重排。
  • Tier 3 里的记忆只有被访问时才重新评分。
  • 如果重新评分后很重要,再提升到前面的层级。

这就是典型的工程取舍。

不是追求理论上的全局最优,而是在真实交互里保持够快、够稳、够准。

用户画像不是一段提示词

很多 Agent 系统会维护一段用户画像,然后把它放进系统提示词里。

这有用,但还不够。

在 HMO 里,用户画像不只是"给模型看的自我介绍",而是参与记忆调度的核心变量。

它会影响新记忆的重要性判断,也会影响旧记忆的排序。

比如一个用户过去主要聊前端工程,最近开始频繁研究 Agent、MCP、长期记忆,那么相关记忆就应该上浮。反过来,一些很久不用的前端细节可以暂时后退。

但画像也不能一有变化就触发全量重排,所以可以加一个 Drift Gate

text 复制代码
如果当前画像和上一次重排时的画像差异超过阈值
    才触发 active tiers 重排
否则
    暂时不做昂贵更新

这个设计很现实。

用户画像需要演化,但系统不能因为一点小变化就频繁大动干戈。

如果自己做一版,需要哪些模块

如果我自己实现一个简化版 HMO,不会一开始就上很复杂的图谱结构。我会先拆成这些模块:

text 复制代码
Memory Ingestion
  从对话中提取候选记忆

Importance Evaluator
  评估这条记忆对未来有没有价值

Persona Manager
  维护用户画像,并判断画像是否发生明显漂移

Memory Index
  保存记忆正文、元数据、tier、tags、embedding

Tier Manager
  负责 Tier 1 / Tier 2 / Tier 3 的升降级

Retriever
  按层检索,而不是默认全库搜索

Access Tracker
  记录 recallCount、lastAccessedAt 和召回原因

Source Store
  保存原始证据,避免摘要漂移

Consolidator
  把多条零散记忆合并成更稳定的长期结论

整体链路大概是:

text 复制代码
用户交互
  ↓
候选记忆提取
  ↓
重要性评分 + 用户画像相关度
  ↓
写入 memory-index + source
  ↓
Tier Manager 分层
  ↓
优先读取 Tier 1
  ↓
不足时检索 Tier 2 / Tier 3
  ↓
命中后更新访问元数据
  ↓
周期性重排和画像演化

这里最核心的不是用了哪个数据库,而是职责边界要清楚。

记忆提取、画像维护、检索召回、证据保存、升降级调度,最好不要全写在一个函数里。否则后面你想换评分策略、换向量库、加冲突处理,都会很难改。

落地时我会额外加的几个字段

HMO 的基础思路已经够用了,但如果要做成长期运行的系统,我还会补几个字段。

第一个是可信度:

json 复制代码
{
    "confidence": 0.78,
    "status": "confirmed | inferred | tentative | contradicted"
}

用户偶尔提一次,不代表长期偏好。系统要区分"用户明确确认过"和"模型推断出来的"。

第二个是冲突关系:

json 复制代码
{
    "supersedes": ["mem_old_xxx"],
    "supersededBy": "mem_new_xxx"
}

用户会变化,旧偏好不能永远有效。与其粗暴覆盖,不如保留演化关系。

第三个是场景:

json 复制代码
{
    "contexts": ["coding", "planning", "casual", "thoughts"]
}

同一个人在不同场景下会有不同偏好。写代码时可能要短平快,闲聊时可能希望更自然、更有陪伴感。

第四个是召回理由:

json 复制代码
{
    "memoryId": "mem_hide_schedule",
    "reason": "control_active_message_style",
    "time": "..."
}

这个字段很适合后期调试。你能看到一条记忆到底是不是真的被使用,还是只是躺在 Tier 1 里占位置。

HMO 真正值得学的地方

HMO 值得学的不是"我也要照抄这个公式",而是它背后的工程态度。

它没有把长期记忆当成一个无限扩容的历史仓库,而是把它当成一个会变化、会衰减、会被强化、会被用户画像牵引的运行系统。

这对 Agent 很重要。

因为 Agent 的体验不取决于它保存了多少历史,而取决于它在当前这一刻能不能想起真正有用的东西。

如果只用一句话概括 HMO,我会这么说:

好的长期记忆,不是把过去都带到现在,而是知道哪些过去值得影响现在。

一个普通记忆系统像备忘录,什么都往里记。

一个好的 HMO 系统更像编辑部,每天都在决定什么该上头版、什么放资料库、什么只留档案。

这就是 Agent 从"会记事"走向"懂上下文"的关键。

相关推荐
jimmyleeee2 小时前
大模型安全之十八:AI常见漏洞类别与缓解策略
人工智能·安全
火山引擎开发者社区2 小时前
多行业专家招募|参与线上访谈拿 2000元/h 现金报酬!
人工智能
4SAPI2 小时前
企业大模型API服务商推荐:从多模型接入到AI API Gateway的技术选型分析
人工智能·php
Lynne3092 小时前
工业网络,到底该集中还是自治?
网络·架构·数据
jzshmyt2 小时前
我用 Python 从零“生成“了一个宇宙,然后让它观察自己(v14)
人工智能·pytorch·python·numpy·matplotlib·空间计算·scipy
LuTshoes3 小时前
spring ai 实战 手搓 PlaneExecuteAgent
java·人工智能·spring·ai
火山引擎开发者社区3 小时前
火山引擎 AgentKit 获评中国信通院 2026 智能原生软件“银弹”标杆实践
人工智能
米小虾3 小时前
RSI 走到哪一步了:拆开递归自我改进的三个可写面、五条定律,和那个没人做的对照实验
人工智能·agent
ACP广源盛139246256733 小时前
GSV9001E 国产 4K 视频处理器,AI 多模态可视化大屏多路画面合成方案解析
人工智能·硬件架构·国产芯片·ai服务器