Hermes Agent 是 Nous Research 开源的 AI Agent(智能体)框架,目标是让一个运行在本地设备上的 Agent 能持续学习:对话能沉淀成记忆,重复任务能沉淀成技能,后续执行任务时再把这些经验用起来。
真正长期使用 Agent 时,最难的不是“能不能回答一次问题”,而是“能不能把过去的信息整理好”。如果记忆只是把每轮对话原样存起来,短期看没问题,时间一长就会出现三个麻烦:
| 问题 | 表现 | 后果 |
|---|---|---|
| 重复 | 同一个偏好、身份信息、任务规则被存很多遍 | 检索结果噪声变大 |
| 过期 | 旧状态和新状态同时存在 | Agent 容易采用错误信息 |
| 搜不到 | 只能按关键词匹配,语义相近但词不一样就漏掉 | 明明存了记忆,却用不上 |
MemOS 的 Hermes 本地记忆插件要解决的就是这类长期记忆管理问题。它把 Hermes 原本较简单的“存对话、搜文本”升级成一套本地记忆系统:写入时做摘要、向量化和去重,读取时做全文检索与语义检索融合,并提供可视化管理面板。
开源地址:
https://github.com/MemTensor/MemOS/tree/main/apps/memos-local-plugin
Hermes Agent 与 MemOS 插件各自负责什么
Hermes Agent 本身负责 Agent 的运行:接收用户消息、调用模型、使用工具、生成技能、接入聊天平台。MemOS 插件不是替代 Hermes,而是在 Hermes 旁边加了一层本地记忆管理能力。
可以把二者的关系理解成这样:
flowchart LR
U[用户消息] --> H[Hermes Agent]
H --> M[MemOS 本地记忆插件]
M --> DB[(本地 SQLite)]
M --> V[(向量索引 / 语义检索)]
M --> S[摘要与去重模型]
M --> H
H --> T[工具调用 / 技能执行]
H --> U
Hermes 仍然是任务执行入口,MemOS 负责让“过去发生过什么”变得可维护、可检索、可更新。
| 组件 | 主要职责 |
|---|---|
| Hermes Agent | 对话、任务执行、工具调用、技能运行 |
| MemOS 插件 | 记忆写入、摘要、向量化、去重、检索、注入上下文 |
| SQLite | 本地保存记忆数据和相关元信息 |
| Web 管理面板 | 浏览、搜索、管理记忆和技能 |
整个插件运行在本机,数据不需要上传到云服务。对于包含私人偏好、工作上下文、项目细节的 Agent 记忆来说,本地化是一个很重要的边界。
原生记忆为什么容易变乱
Hermes 原生记忆方式偏直接:把每轮对话保存到 SQLite,检索时主要依赖文本匹配。这种方案实现简单,但对长期记忆不够友好。
假设有这样两段对话:
第 1 周:
用户:我最近在减肥,每天控制在 1800 大卡。
第 2 周:
用户:我不减肥了,恢复正常饮食。
如果系统只是把两段话分别存起来,记忆库里就同时存在两条信息:
用户正在减肥,每天控制 1800 大卡。
用户已经放弃减肥,恢复正常饮食。
当用户后来问:
帮我安排一下周末吃什么。
Agent 检索到第一条旧记忆,就可能继续推荐低卡食谱;检索到第二条新记忆,才会按正常饮食规划。如果两条都被召回,而模型又没有明确判断哪条更新,就容易出现混乱。
原生流程大致如下:
flowchart TD
A[一轮新对话] --> B[直接保存到 SQLite]
B --> C[记忆库条目增加]
D[新问题] --> E[按关键词做文本检索]
E --> F{关键词是否命中}
F -->|命中| G[返回相关文本]
F -->|未命中| H[无法使用历史信息]
这个流程的关键缺陷在于:写入时不理解信息之间的关系,读取时也不理解语义上的相似性。
MemOS 的写入流程:先理解,再存储
MemOS 插件在记忆写入阶段增加了一套处理链路:
flowchart LR
A[新对话内容] --> B[语义分片]
B --> C[LLM 摘要]
C --> D[向量化]
D --> E[召回相似记忆]
E --> F[智能去重与更新判断]
F --> G[(保存到本地记忆库)]
这里的 LLM 指 Large Language Model(大语言模型),Embedding 指把文本转换成向量表示的模型。向量化之后,系统就能判断两段文本在语义上是否接近,而不只看字面关键词是否一致。
语义分片:避免一整段对话混在一起
对话往往包含多个主题。如果把一整轮对话全部当成一条记忆,后续检索会很粗糙。
例如:
我最近不减肥了,恢复正常饮食。
另外周六下午要去上海出差,酒店订在静安寺附近。
这里其实有两类信息:
| 信息 | 类型 |
|---|---|
| 不再减肥,恢复正常饮食 | 个人偏好 / 状态 |
| 周六下午去上海,住静安寺附近 | 行程安排 |
语义分片会尽量把不同主题拆开,后续检索“饮食偏好”和“上海行程”时就不会互相干扰。
摘要:把对话改写成可复用记忆
原始对话通常包含口语、铺垫和无关内容,不适合直接作为长期记忆。摘要模型会把它压缩成更稳定的事实或偏好。
| 原始表达 | 适合保存的记忆 |
|---|---|
| 最近实在扛不住了,不想继续减肥了,还是正常吃吧 | 用户已停止减肥,当前饮食偏好为正常饮食 |
| 以后代码示例尽量用 Python,别用 Java | 用户偏好使用 Python 代码示例,不偏好 Java 示例 |
摘要后的记忆更短,也更容易检索和比较。
智能去重:判断是重复、更新,还是新记忆
MemOS 插件的关键点不只是“存更多”,而是“别乱存”。写入新记忆前,它会先找出已有的相似记忆,再让 LLM 判断二者关系。
常见判断结果有三类:
| 判断结果 | 处理方式 | 示例 |
|---|---|---|
| 重复 | 不新增,或合并引用 | “用户喜欢 Python”重复出现 |
| 更新 | 用新信息更新旧记忆,并记录历史 | “正在减肥”变成“不再减肥” |
| 全新 | 新增一条记忆 | 第一次出现“周六去上海出差” |
减肥例子在 MemOS 中更合理的结果应该是:
当前记忆:
用户已停止减肥,当前饮食偏好为正常饮食。
历史变化:
曾经记录过:用户每天控制在 1800 大卡。
后来更新为:用户不再减肥,恢复正常饮食。
这样既保留了变化过程,又不会让旧状态继续干扰当前决策。
MemOS 的检索流程:全文搜索加语义搜索
只做关键词检索很容易漏掉信息。用户问“上次推荐了什么好吃的地方”,历史记忆里可能写的是“某某餐厅味道不错”。这两句话语义相关,但关键词不完全一致。
MemOS 插件采用混合检索:
flowchart TD
A[用户最新消息] --> B[预检索]
B --> C[全文搜索]
B --> D[向量语义搜索]
C --> E[候选记忆集合]
D --> E
E --> F[融合排序]
F --> G[多样性去重]
G --> H[时间衰减]
H --> I[相关性过滤]
I --> J[注入 Hermes 上下文]
混合检索的几个环节各有作用:
| 环节 | 作用 |
|---|---|
| 全文搜索 | 精确匹配关键词、名称、编号、地点等文本 |
| 向量语义搜索 | 找到表达不同但意思接近的记忆 |
| 融合排序 | 综合两个检索通道的结果,排出更可靠的候选 |
| 多样性去重 | 避免返回一堆意思相同的记忆 |
| 时间衰减 | 新近信息在排序中获得更高权重 |
| 相关性过滤 | 去掉看似相似但对当前问题帮助不大的内容 |
每轮对话开始时,插件会用用户最新消息做一次预检索,把相关记忆放进 Hermes 的上下文。如果没有命中,系统还可以提示 Agent 主动搜索记忆,而不是直接假装不知道。
这个机制让记忆从“被动存档”变成“主动参与推理”。
技能生成:不同任务用不同模型
Hermes 有技能生成能力:当某类任务反复出现时,Agent 可以把做法沉淀成 Skill,之后遇到类似任务就不必重新摸索。
问题在于,技能生成的质量很依赖模型能力。如果生成技能、摘要、Embedding 都使用同一个模型,就会出现两个限制:
- 轻量模型跑得快,但生成复杂技能可能不够稳定。
- 强模型效果好,但让所有环节都用强模型又会增加成本和延迟。
MemOS 插件支持三级独立模型配置:
| 模型类型 | 适合使用的模型 | 负责内容 |
|---|---|---|
| Embedding 模型 | 轻量模型 | 文本向量化、语义召回 |
| 摘要模型 | 中等能力模型 | 对话摘要、记忆整理 |
| 技能模型 | 更强的模型 | 生成和评估可复用 Skill |
技能生成还增加了两层筛选:
flowchart LR
A[任务记录] --> B[规则过滤]
B --> C{是否可重复}
C -->|否| D[不生成 Skill]
C -->|是| E[LLM 评估]
E --> F{是否有复用价值}
F -->|否| D
F -->|是| G[生成 Skill]
这样可以避免把一次性的琐碎请求也变成技能。例如,“今天下午提醒我喝水”没有太多复用价值;“每次整理周报时按固定格式汇总 Git 提交、任务状态和风险项”就更适合沉淀成 Skill。
插件还提供降级机制:如果技能模型不可用,会自动退到摘要模型;摘要模型也不可用时,再退回 Hermes 原生模型。这样即使某个模型服务临时异常,Agent 也不会完全中断。
多 Agent 协同:私有记忆与共享经验分开
单个 Hermes 实例只服务一个人或一个任务时,记忆隔离比较简单。多个 Agent 同时运行时,问题会变复杂。
例如:
| Agent | 任务 |
|---|---|
| Agent A | 处理代码审查 |
| Agent B | 处理产品需求整理 |
| Agent C | 处理部署和运维问题 |
它们会积累不同经验。如果完全隔离,公共规则和可复用技能无法共享;如果全部混在一起,私人上下文和任务边界又会变乱。
MemOS 插件提供两层协同方式。
同一台机器上的多 Agent
同一台机器上可以让不同 Agent 拥有独立记忆空间,同时共享公共记忆和公共 Skill。
flowchart TD
A1[Agent A 私有记忆] --> M[MemOS]
A2[Agent B 私有记忆] --> M
A3[Agent C 私有记忆] --> M
M --> P[(公共记忆)]
M --> S[(共享 Skill)]
这种方式适合本机上按任务拆分多个 Agent,又希望复用一部分通用规则的场景。
跨机器 Hub-Client 架构
团队协作时,可以采用 Hub-Client 架构。私有数据留在本地,只有明确设置为共享的内容才进入团队可见范围。
flowchart LR
C1[成员 A 本地 Client] -->|共享内容| H[Hub]
C2[成员 B 本地 Client] -->|共享内容| H
C3[成员 C 本地 Client] -->|共享内容| H
C1 -. 私有记忆留在本地 .-> L1[(A 本地数据)]
C2 -. 私有记忆留在本地 .-> L2[(B 本地数据)]
C3 -. 私有记忆留在本地 .-> L3[(C 本地数据)]
这里的关键不是“所有记忆都同步”,而是“可共享经验同步,私有上下文隔离”。
Web 管理面板:可视化管理本地记忆
安装插件后,会启动一个本地 Web 管理面板,默认访问地址:
http://127.0.0.1:18901
这个面板用于处理日常记忆管理,不必完全依赖命令行。它覆盖的功能包括:
| 页面 | 用途 |
|---|---|
| 记忆浏览和搜索 | 查看、检索、排查长期记忆 |
| 任务管理 | 查看 Agent 处理过的任务 |
| Skill 管理 | 管理自动生成或已有技能 |
| 分析统计 | 观察记忆和任务使用情况 |
| 工具调用日志 | 排查工具调用过程 |
| 数据导入 | 导入已有数据 |
| 在线配置 | 调整插件运行参数 |
面板带密码保护,并且默认只允许本地访问。对于本地记忆系统来说,这个限制很合理:记忆里可能包含个人偏好、项目资料和工作细节,不应该默认暴露到局域网或公网。
安装与启动
前置条件有三个:
| 依赖 | 要求 |
|---|---|
| Node.js | 18 或以上 |
| Python | Python 3 |
| Hermes Agent | 已安装并能正常运行 |
官方提供了一行安装命令:
curl -fsSL https://raw.githubusercontent.com/MemTensor/MemOS/openclaw-local-plugin-20260408/apps/memos-local-plugin/install.sh | bash
安装器会完成这些工作:
flowchart TD
A[检测本机环境] --> B{Node.js 是否可用}
B -->|不可用| C[安装 Node.js]
B -->|可用| D[下载插件包]
C --> D
D --> E[安装依赖]
E --> F[创建到 Hermes 插件目录的软链接]
F --> G[更新配置文件]
G --> H[验证插件加载]
H --> I[启动 Bridge 守护进程]
I --> J[启动 Memory Viewer]
如果运行环境对安全要求较高,不建议直接把远程脚本管道给 bash,可以先下载检查:
curl -fsSL https://raw.githubusercontent.com/MemTensor/MemOS/openclaw-local-plugin-20260408/apps/memos-local-plugin/install.sh -o install.sh
less install.sh
bash install.sh
安装完成后,正常启动 Hermes:
hermes chat
对话会自动写入本地记忆系统。需要查看或管理记忆时,打开:
http://127.0.0.1:18901
上手文档:
https://memos-docs.openmem.net/cn/openclaw/hermes_local_plugin
适合和不适合的场景
MemOS 插件的收益主要来自长期使用。如果只是偶尔问几个问题,原生记忆已经够用;如果 Agent 每天都参与工作,记忆质量就会越来越重要。
| 场景 | 是否适合 | 原因 |
|---|---|---|
| 长期使用 Hermes 处理日常任务 | 适合 | 记忆会持续积累,去重和更新很重要 |
| Agent 需要记住个人偏好、项目规则、常用流程 | 适合 | 混合检索能把历史上下文重新找出来 |
| 多个 Hermes 实例处理不同任务 | 适合 | 可以隔离私有记忆,同时共享公共 Skill |
| 团队希望沉淀可复用经验 | 适合 | Hub-Client 模式能共享明确开放的内容 |
| 只是临时体验 Hermes | 不太适合 | 记忆规模小,插件收益不明显 |
| 机器资源紧张,无法稳定运行额外模型 | 谨慎使用 | 摘要和向量化会消耗计算资源或 token |
| 对自动记忆完全不可控的场景 | 谨慎使用 | 需要配合面板定期审查和清理 |
使用时需要注意的坑
第一次使用会有额外消耗
插件需要做摘要、向量化和相似记忆判断,这些步骤会调用模型。首次接入或导入大量历史数据时,token 和计算消耗会比普通对话更高。
如果使用云端模型做摘要或技能生成,需要关注调用成本;如果使用本地模型,需要关注机器性能和推理速度。
记忆质量依赖模型质量
Embedding 模型会影响语义召回,摘要模型会影响记忆表达,技能模型会影响 Skill 可用性。模型太弱时,可能出现这些问题:
| 模型环节 | 可能问题 |
|---|---|
| Embedding | 语义相近的记忆召回不到 |
| 摘要 | 把用户意图压缩错,或漏掉关键信息 |
| 去重判断 | 把更新误判为重复,或把重复误判为新记忆 |
| 技能生成 | 生成的 Skill 不够稳定,复用价值低 |
三级模型配置的意义就在这里:便宜、快速的环节用轻量模型,影响决策质量的环节用更强模型。
本地化不等于不用管理权限
数据保存在本机 SQLite,并不代表可以忽略安全边界。需要注意:
- 不要把管理面板暴露到公网。
- 给面板设置足够强的密码。
- 共享记忆前确认不包含私人信息或敏感项目内容。
- 定期备份本地数据库,避免误删或磁盘故障导致记忆丢失。
旧记忆仍然需要人工审查
智能去重能减少混乱,但不能保证每一次判断都完美。长期使用后,仍然应该通过管理面板检查高频记忆、过期记忆和明显错误的 Skill。
Agent 的记忆系统更像一个持续维护的知识库,而不是一次安装后永远不用管的黑盒。
一个更合理的 Agent 记忆形态
Hermes Agent 解决的是“Agent 如何执行任务”,MemOS 本地记忆插件补上的是“Agent 如何管理长期经验”。
原生 SQLite 文本记忆适合轻量使用,结构简单、成本低;MemOS 适合记忆逐渐变多、历史上下文经常被复用的场景。它通过语义分片、摘要、向量化、智能去重和混合检索,让记忆不只是越存越多,而是能被更新、能被找回、能进入后续推理过程。
如果 Hermes 已经承担了日常工作流中的一部分任务,给它接入 MemOS 的价值会比较明显:重复信息更少,过期状态更容易被覆盖,历史偏好和项目规则也更容易在新任务中重新发挥作用。
