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 从"会记事"走向"懂上下文"的关键。

相关推荐
大象爱吃西瓜1 小时前
一条IM消息的分布式之旅:从发送到已读
架构
手写码匠1 小时前
手写 AI Prompt Injection 防护系统:从零实现 LLM 安全边界
人工智能·深度学习·算法·aigc
虎子_layor1 小时前
给 Agent 接入新模型的推理模式:从配置开关到协议适配
后端·架构
土星云SaturnCloud1 小时前
边缘计算赋能工业智能化:重大危险源监测+产线控制+视觉分析一体化解决方案
服务器·人工智能·ai·边缘计算
代码柏拉图1 小时前
AI时代如何提问面试者
人工智能·面试·职场和发展
知识浅谈1 小时前
人工智能日报 每日AI新闻(2026年5月16日):OpenAI押注金融入口,YouTube扩展AI深伪检测,Google收紧AI搜索操纵规则
人工智能·chatgpt·金融
hyunbar1 小时前
扣子(coze)高级实战-【今日头条】输入关键词批量采集,循环写入飞书多维表格
人工智能·ai编程
victory04311 小时前
DeepSeek-R1 86页加长版:通过强化学习激励大语言模型的推理能力 技术报告中文翻译
人工智能
郑寿昌1 小时前
2026传感器革命:智能感知新纪元
人工智能