乐于分享
好东西不私藏

号称“OpenClaw + Hermes 完美合体”的 Mercury,我读完了它的每一行代码

号称“OpenClaw + Hermes 完美合体”的 Mercury,我读完了它的每一行代码

一份关于AI Agent记忆系统的真实技术拆解报告

最近,AI Agent圈子里冒出一个叫做Mercury的开源项目。宣传力度不小,官方措辞颇具野心:

“OpenClaw sparked the Idea. Hermes brought the Energy. Mercury now delivers true CONTROL. This is OpenClaw + Hermes, perfected.”

翻译过来就是:OpenClaw只是开了个头,Hermes只是带了点劲,真正的完美形态——是我Mercury。

这个比较对象选得很讲究。OpenClaw,拥有超过34万颗GitHub星标,是2025年以来增长最快的开源Agent项目之一。Hermes,由Nous Research出品,10周内涨到11万颗星,其自学习闭环确实有其独到之处。

Mercury说:我比它们俩加起来还强。

口气不小。于是我做了一件应该做、但可能很多人没做的事:把Mercury的源码从头到尾完整读了一遍。

读完之后,我的感受可以用一句话概括:宣传文案与代码实现之间的距离,大到可以停下一艘航空母舰。

一、Mercury是什么?先承认它有框架

公平地说,Mercury不是一个纯PPT项目。它有可运行的代码,有完整的工程结构。

  • • 技术栈:Node.js + TypeScript
  • • 形态:个人AI Agent框架,MIT开源协议
  • • 运行方式:后台守护进程,支持CLI和Telegram两种交互通道
  • • 核心卖点:一套自称“三层记忆架构”的设计

这套架构在文档中的描述相当漂亮:

记忆层级
实现方式
官方描述
短期记忆
内存中的对话上下文
进程级工作记忆
长期记忆(“第二大脑”)
SQLite数据库
自动提取、多维评分、冲突检测、自动衰减
Soul身份文件
4个Markdown文件
可编辑的Agent人格定义

架子搭起来了。每个功能点都有代码覆盖,文档也写得足够好看。

但真正的问题,从来不在架子上。

魔鬼在细节里。 而Mercury的细节,暴露了从“设计文档”到“可靠工程”之间的巨大鸿沟。

二、记忆评分:让LLM给自己打分

Mercury记忆系统的核心机制是记忆提取:每次对话结束后,系统调用一次LLM,从对话中提取0到3条候选记忆,并由同一个LLM自行评估每条记忆的置信度(confidence)、重要性(importance)和持久性(durability),分值范围0到1。

这是整个记忆系统的根基。如果这一步不靠谱,后面所有的冲突解决、衰减清理、排序检索,都建立在流沙之上。

那么,这一步靠谱吗?

答案:完全不靠谱。

LLM输出“这条记忆的置信度是0.85”——这个数字从何而来?没有任何客观标准,没有任何外部校准机制,没有任何历史数据作为锚点。本质上,这是模型在“感受”一个数字。同一段对话输入两次,可能得到0.7和0.9两个截然不同的结果。

这不是量化评估,这是占卜。

更严重的是,Mercury对这个环节的模型选择几乎没有任何约束。项目默认使用DeepSeek进行推理。用DeepSeek提取的记忆质量和用Claude Opus提取的质量,差距可能是数量级的。但整个代码库中,几乎找不到对这个问题的讨论——仿佛随便换一个LLM,记忆质量都会保持一致。

对比一下Hermes的做法。Hermes的技能学习虽然也依赖LLM的判断,但它至少有一个 “执行→评估→提取→优化→复用”的闭环。一个技能好不好用,下一次任务执行时会得到验证。Mercury的记忆质量呢?提取完之后直接写入数据库,没有任何后续验证机制。存进去,就是“真理”了。

一个建立在占卜之上的记忆系统,你敢把自己的决策依托给它吗?

三、JSON解析失败?没关系,编一个分数存进去

这是我在代码中发现的、最能说明工程态度的一个细节。

LLM返回的记忆提取结果约定为JSON格式。但如果——这在真实使用中极其常见——LLM返回的不是合法JSON(多了一个逗号、少了一个括号、混入了自然语言……),Mercury的处理逻辑如下:

  1. 1. 按行分割文本
  2. 2. 硬编码一个0.75的置信度
  3. 3. 静默写入数据库

我第一次读到这段代码时,以为自己看错了。

一条因为格式错误而无法被正常解析的“记忆”,以一个凭空捏造的“中等置信度”,被悄悄塞进了你的长期记忆库。这条伪造的记忆,会参与后续所有的检索和排序,影响Agent未来每一次决策。

用户完全不知道。 没有警告日志,没有任何提示,没有错误上报。

还有一个更隐蔽的:当剩余token预算不足800时,记忆提取逻辑直接return——不提取、不警告、不记录。你刚刚和Agent进行的那次对话,在记忆系统的视角里,就好像从未发生过。

总结一下这套系统的“可靠性”:

场景
Mercury的行为
正常情况
LLM自己给自己打分,可靠性存疑
JSON解析失败
编造假分数,静默写入
Token预算不足
整段对话静默丢弃

这叫“perfected”?

四、“结构化检索”:高级术语包装的朴素关键词匹配

Mercury在宣传材料中反复使用 “Structured Retrieval”(结构化检索) 和 “Selective Injection”(选择性注入) 这类措辞。给人的暗示是:系统具备语义理解、向量检索、知识图谱等高级能力。

实际实现呢?

SQLite FTS5:按空格分词,用OR连接关键词,做全文关键词匹配。

就这些。没有向量嵌入,没有语义相似度,没有任何超越词形的匹配能力。

你问系统:“我上次说的那个关于部署方式的偏好是什么?”系统提取关键词——“上次”“部署”“方式”“偏好”——去数据库里做关键词匹配。数据库中存着一条“User prefers Docker over Kubernetes”。这两段话几乎没有共同的词,系统大概率找不到。

关键词匹配不是“结构化检索”。把WHERE语句包装成学术术语,不会改变它的本质。

FTS5之后倒是有一个后置排序环节,用五个维度打分:

维度
权重
置信度
30%
重要性
25%
新鲜度
20%
持久性
15%
关键词匹配
10%

注意最后一项——“跟你的问题有多相关”这个最核心的因素,权重只有10%,是所有维度里最低的。

这意味着:一条与你当前问题毫不相干、但置信度高、重要性高、比较新的记忆,排名会高于一条真正相关但各项分数一般的记忆。

还有一个更隐蔽的问题:FTS5默认只返回前10条匹配结果。如果第11条才是真正相关的记忆呢?后面的评分系统根本看不到它。

再来看看被对标的两位前辈:

  • • OpenClaw:记忆是简单的文件存储,但用户可以直接看到和编辑每一条记忆,透明度拉满。
  • • Hermes:至少有LLM摘要做二次排序,技能系统本身就是结构化的经验索引。

Mercury呢?既没有OpenClaw的透明,也没有Hermes的闭环,只有一层用高级术语包装过的WHERE语句。

五、冲突解决:三个维度只用了三分之一

数据表结构里明明白白存着三个维度:confidenceimportancedurability

冲突解决只看confidence

importancedurability在冲突解决逻辑中完全不参与计算。它们就静静地躺在数据库里,像两个精心设计但从未启用的摆设。

逻辑极其简单:

  • • 新记忆的confidence更高 → 新记忆胜出
  • • 旧记忆的confidence更高 → 旧记忆胜出
  • • 相等 → 新记忆胜出

一条被反复验证了8次、经受住了多次对话检验的旧记忆(confidence=0.75),会被一条首次出现的LLM单次推断(confidence=0.80)直接覆盖。

别忘了,这个0.80还可能是上一节提到的那种JSON解析失败时硬编码的0.75。

而且是覆盖式更新——旧记忆被直接删除,没有历史版本,没有演进轨迹。你三个月前做了一个重要的技术决策,Mercury覆盖掉了,你永远不会知道它曾经存在过。

Hermes至少有episodic archive,保留完整的会话历史。Mercury号称比Hermes更好,结果连前辈最基本的历史追溯能力都没有。

六、相似度判断:按空格分词,逐词精确匹配

两条记忆是否语义相近、应该合并?Mercury的判断方法极其原始:

按空格分词 → 逐词精确匹配 → 重叠率超过0.74就合并。

举个例子:

  • • “User prefers TypeScript”
  • • “User loves TypeScript”

这两句话不会合并。因为prefers ≠ loves

没有词干还原(stemming),没有词形归并(lemmatization),没有任何语义层面的理解。2026年了。

合并时选哪个版本?选字数更多的那个。不是更准确的,不是更新时间更新的,不是来源更可靠的——是字符串更长的。

“He uses Python.”(16字符)vs “The user has expressed a strong preference for Python in all new projects.”(80字符)——后者胜出。不是因为信息更准确,只是因为字数更多。

这套逻辑在工程领域叫什么?拍脑袋。

七、衰减机制:有Bug,而且方向就有问题

Mercury的衰减逻辑设计如下:

  • • 活跃记忆:21天内未被检索,清除
  • • 持久记忆:120天未被使用,durability衰减;低于0.3则清除

先说Bug。

清理条件中有一个判断:last_seen_at > 0。如果一条记忆从未被检索过,last_seen_at0NULL,这个条件永远不满足——这条记忆永远不会被清理

从未被使用的垃圾记忆,反而获得了永生。经常被使用、有用但暂时过期的记忆,反而可能被过早清理。

这不是边界情况。这是核心逻辑的一个明显缺陷。

再说方向性问题。

Mercury对“遗忘”的理解是:低于阈值就永久丢弃。数据消失了。设计者说,这是模仿人脑的遗忘机制。

但AI记忆相比人脑记忆的核心价值是什么?恰恰是不像人一样遗忘。

更合理的设计是分层检索:活跃知识优先返回,沉淀知识永远保留但降低检索优先级。你6个月前做过“选择PostgreSQL而不是MongoDB”的技术决策,这条信息不应该被丢弃,而应该安静地待在沉淀层,等到你问“我当初为什么选PG”时再浮现出来。

降低优先级 ≠ 遗忘。 Mercury把这两个概念搞混了。

八、工程质量:24个测试用例撑起的“perfected”

这是整个代码审查中最令人不安的部分。

整个项目的测试覆盖情况:

模块
代码行数
测试用例数
Agent核心循环
1914行
0
权限系统
486行
0
生命周期管理
约200行
0
守护进程/Watchdog
约200行
0
Telegram通道
约800行
3个(仅覆盖用户审批流程)
记忆系统
约700行
13个
Provider模型
约400行
8个
总计 约4700行 24个

核心Agent循环——1914行代码——零测试。
权限安全模块——486行代码——零测试。
崩溃恢复机制——零测试。

OpenClaw拥有超过34万颗星标,经历过数十万用户在实际场景中的实战打磨。Hermes有Nous Research研究团队的学术背书。Mercury有什么?一份设计文档和24个测试用例。

然后它说自己是“perfected”。

更多工程问题,随手列举:

  • • Telegram异步错误被.catch(() => {})静默吞掉——出了问题你永远不会知道
  • • 所有Provider失败时给用户显示“检测到循环”——完全误导性的错误信息
  • • 路径检查不做符号链接解析——/safe/dir/../../etc/passwd可以绕过
  • • 环境变量不展开——rm $SENSITIVE_PATH不会被拦截
  • • Telegram“Allow All”开关不可逆——一旦开启,整个会话进入零权限检查模式
  • • 崩溃重启后短期记忆和待审批请求全部丢失——进程恢复不等于状态恢复

九、宣传与代码,逐条对账

Mercury官方声称
代码实际实现
评判
选择性注入,只注入相关记忆
硬编码5条、900字符上限,不根据上下文动态调整
半真半假
结构化检索
FTS5关键词匹配 + 硬编码权重后置排序
夸大
记忆评分
LLM自评 + JSON解析失败时编造分数
不可靠
冲突解决
只比较confidence一个维度
过度简化
衰减机制
存在逻辑bug,从未检索的记忆永不清理
有缺陷
Token感知
有日预算,但记忆注入不根据剩余预算调整
半真半假
OpenClaw + Hermes, perfected
没有OpenClaw的生态和透明度,没有Hermes的学习闭环
严重夸大

十、Mercury真正的价值是什么?

批判至此,需要说几句公道话。

Mercury不是一个“骗子项目”。

它有真实的设计思考。架构文档(DECISIONS.mdRESEARCH.md)写得相当不错。三层记忆架构、Soul身份系统、权限分层——这些设计方向本身都是正确的,甚至是有启发性的。

Mercury的价值在于:

如果你把它当成一篇用代码写成的设计论文来读——“一个理想的Agent记忆系统应该具备哪些能力”——它确实有学习价值。它提出了正确的问题:记忆需要评分、需要冲突解决、需要衰减、需要身份定义。这些问题,整个行业都还没有完美的答案。

如果你想做一个轻量级原型验证,记忆总量不超过一百条,用户只有你自己,对可靠性要求不高——它也能凑合用。

但是——

如果你被“OpenClaw + Hermes, perfected”这句宣传语打动了,准备把它部署在真实业务场景中,让它在无人值守的情况下长期运行,影响重要决策——

请先完整读一遍它的代码。

写在最后:Agent记忆,是目前最被低估的难题

Agent记忆系统,是整个AI Agent行业目前最被低估的技术难题之一。

  • • 什么信息值得记住?
  • • 记忆的粒度应该多细?
  • • 用户偏好随时间如何演进?
  • • 大规模记忆如何高效检索?
  • • 记忆冲突如何裁决?
  • • 遗忘应该如何建模?

这些问题,确实没有真正令人满意的解决方案。Mercury提出了这些问题——这是它的贡献。

提出好问题和解决好问题之间,隔着一条完整的工程道路。而Mercury目前的位置,还在那条路的起点,而不是终点。

所以,在这个AI Agent赛道日益拥挤的时代,请记住一条朴素但有效的原则:

看到“perfected”这个词,就去读代码。

读它的设计文档,你会觉得它很有想法。
读它的测试用例数量,你会开始产生怀疑。
读它的错误处理逻辑,你会感到不安。
读它的核心循环实现,你会庆幸自己没有把它用在生产环境。

Mercury是一个有野心的实验。但它远未完工。

真正的“perfected”,不需要在宣传语里自己说出来。