Hermes Agent(爱马仕)架构模板
代表产品 / 原型:Hermes Agent(爱马仕,Nous Research,MIT) —— 同类:OpenClaw(龙虾) 一句话定位:Nous Research 的自托管常驻智能体「跟你一起成长」——常驻进程 + 跨会话持久记忆 + 自主沉淀可复用技能,接管你的消息账号做长期个人助理,越用越懂你、越用越能干。
1. 一句话定位
Hermes = 一个跑在你自己服务器上、永不下线的常驻智能体:它接管你的消息账号(微信 / Telegram / 邮件……),记得住你过去说过的每件事,还会把「这次怎么把事办成的」沉淀成可复用的技能——越用越懂你、越用越能干。
它和 通用 Agent 平台 的区别在于「常驻 + 成长」:通用 Agent 多是「一次任务、用完即弃」,每次从零开始;Hermes 是一个长期活着的进程,有跨会话的持久记忆,有不断自我积累的技能库。它要回答的不是「这一个任务怎么自动化」,而是「一个智能体怎么陪你长期成长,而不是每次都失忆」。
2. 业务本质:它在解决什么问题
通用聊天 Agent 有三个根本痛点:跨会话失忆(关掉窗口,它就忘了你是谁)、每次从零(同样的偏好、同样的背景,你得反复交代)、知识无法复利(上周教会它的解法,这周它又不会了)。
Hermes 卖的就是「让 agent 越用越懂你、越用越能干」。它用三件事打破上面三个痛点:
- 持久记忆:把每次会话写进数据库,下次能检索回过去说过的话——它「记得住」。
- 自动技能:复杂任务办成后,把解决路径抽象成可复用的技能存起来——它「学得会」。
- 常驻进程:一个永远在线的 daemon,接管你的消息账号——它「一直在」。
一句话:它不是「更强的一次性 Agent」,而是「一个跟你一起长期成长的私人助理」。价值不在单次任务多惊艳,而在时间维度上的知识复利——用得越久,它对你的理解和能力越厚。
3. 核心需求与约束
功能性需求:
- [ ] 常驻进程接管消息账号:多平台(微信 / Telegram / 邮件 / SMS……)统一入口
- [ ] 跨会话持久记忆:能检索「过去说过的话」,按用户 / 平台隔离
- [ ] 自动技能:复杂任务后自主沉淀可复用技能,后续相似任务自动命中
- [ ] 工具调用循环:70+ 工具(跨约 28 个 toolset),含终端 / 代码执行,危险命令经审批
- [ ] 多入口:CLI / 常驻 Gateway / IDE(经 ACP)/ cron 定时
- [ ] cron 定时任务:作为 first-class agent 任务(而非裸 shell 脚本)无人值守执行
非功能性需求 / 质量属性:
| 质量属性 | 目标 | 为什么对这类系统重要 |
|---|---|---|
| 持久常驻 | 永远在线 | 「长期助理」的前提,断了就回到失忆 |
| 可移植 | $5 VPS 能跑 | 自托管才有「数据在自己手里」;门槛越低越普及 |
| 可观测可中断 | 每次工具调用对用户可见、可中途取消 | 它能跑终端 / 自创技能,必须能踩刹车 |
| 松耦合 | 子系统可选、可插拔 | 用 registry + check_fn gating,$5 VPS 上能砍掉重组件 |
| 无厂商锁定 | 多 provider、数据自存 | 换模型、换机器不被绑死 |
关键约束(不可逾越的边界):
- 🔴 单机优先:面向单用户单部署,不是多租户 SaaS 集群。
- 🔴 SQLite 单写者、无 sharding:会话与记忆默认存 SQLite,写入串行、不分片。
- 🔴 系统提示对话中途不可变:为最大化 prompt 前缀缓存命中,系统提示在一次对话里不热更新。
- 🔴 每 profile 隔离一套
HERMES_HOME:多开靠多 profile,各自一套配置 / 凭据 / 数据目录。 - 🔴 能跑终端 + 自创技能 + cron 无人值守:威力即风险面,必须靠审批 + 隔离 + 可中断兜底。
4. 架构全景图
┌──────────── 多入口(谁来触发 Agent) ────────────┐
│ CLI 常驻 Gateway IDE(经 ACP) cron │
│ (交互) (接管消息账号) (编辑器内) (定时) │
└───────┬────────┬──────────────┬───────────┬──────┘
│ │ │ │
▼ ▼ ▼ ▼
╔════════════════════════════════════════════════════════╗
║ 平台无关 AIAgent 编排内核(唯一的「大脑」) ║
║ prompt_builder 装配 → provider 调用 → 工具循环 → 回复 ║
║ (所有入口共用同一个内核,行为一致、零重复实现) ║
╚════════════════════════════════════════════════════════╝
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲ (一圈可插拔子系统)
┌────────┘ │ │ │ │ │ │ └────────┐
▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│记忆 │ │技能 │ │工具 │ │provider│ │ cron │ │终端 │ │插件 │
│FTS5 │ │系统 │ │注册表 │ │解析层 │ │调度器 │ │后端 │ │hook/ │
│检索 │ │(自创+ │ │70+ │ │(18+ → │ │ │ │(7 种) │ │子agent│
│ │ │自改进)│ │工具 │ │ 3 mode)│ │ │ │ │ │ │
└──────┘ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘ └──────┘
│ │
└──── 会话存储 SQLite + FTS5(按平台隔离,含 lineage)────┘
记忆: MEMORY.md(agent级) / USER.md(被蒸馏的你)
数据流:消息 ─▶ 鉴权 ─▶ 取会话历史 ─▶ prompt_builder(注入 SOUL/MEMORY/
USER + FTS5 检索相关技能与过往会话)─▶ provider ─▶ 工具循环
(危险命令→审批)─▶ 回复 ─▶ 写回会话 DB(+ 可固化记忆 / 沉淀技能)灵魂是中间那个平台无关的 AIAgent 内核——它是唯一的大脑,所有入口(CLI / Gateway / IDE / cron)都复用它,所以「在微信里」和「在命令行里」行为完全一致。围在它周围的一圈子系统全部可插拔:$5 VPS 上跑不动的(向量库、隔离终端)可以砍掉,用 registry + check_fn 决定哪些子系统挂载。「一个内核 + 多入口 + 可插拔子系统」是它能既统一又轻量的根本。
5. 组件职责
- AIAgent 编排内核:驱动「装配提示 → 调用模型 → 工具循环 → 回复」的核心循环,平台无关。为什么需要:它是唯一大脑,把「多入口」收敛成「一套行为」,避免每个平台各写一套逻辑。
- 常驻消息 Gateway + 约 20 个平台 adapter:一个常驻 daemon 接管你的消息账号,adapter 把各平台(Telegram / Discord / Slack / WhatsApp / Signal / Matrix / Email / SMS,以及国内 DingTalk / Feishu / WeCom / 原生微信 Weixin / QQ / Yuanbao 等)归一成内核能懂的消息。为什么需要:让「用户在哪,agent 就在哪」,省掉自建前端。
- 会话存储(SQLite + FTS5):存所有会话历史,带全文检索,按平台隔离,记录会话 lineage(派生关系)。为什么需要:跨会话记忆的物理底座,单文件零运维。
- 记忆系统(可插拔 provider):短期=会话历史;长期 artifact =
MEMORY.md(agent 级长期记忆)与USER.md(用户画像 / 「被蒸馏的你」);默认检索走会话 DB 的 FTS5,可换外置 provider(知识图谱 / 向量)。为什么需要:让它「记得住你」,且记忆策略可按需升级。 - 技能系统(程序化记忆):技能是文件形式的「怎么把某类事办成」,自动创建 + 在使用中自我改进。为什么需要:把一次性的解题过程变成可复用资产——这是「越用越能干」的引擎。
- 工具注册表:登记 70+ 工具(跨约 28 个 toolset),含终端 / 代码执行 / 文件 / 网络等。为什么需要:工具是 agent 的「手脚」;注册表让工具可枚举、可 gating(早期 / 营销材料常写 40+,以开发者文档 70+ 为准)。
- provider 解析层:把 18+ 模型供应商(Anthropic / Gemini / MiniMax / Kimi / GLM……)归一到三种 API mode。为什么需要:用三种交互范式吸收 N 家差异,换模型不改内核——无厂商锁定的关键。
- cron 调度器:定时任务调度,且每个 job 是 first-class agent 任务(不是裸 shell)。为什么需要:让 agent 能「自己定时干活」——发周报、查日程,无人值守。
- 终端后端(7 种):工具里的命令在某个终端后端执行,从本机直跑到隔离沙箱(Docker / Singularity / Vercel Sandbox)。为什么需要:在「能干活」和「别闯祸」之间提供可调的隔离档位。
- 插件 / hook / 子 agent:用 hook 在生命周期切点扩展;复杂任务可派生子 agent 并行。为什么需要:在不动内核的前提下扩展能力、做有限并行。
6. 关键数据流
① 一条消息从进来到回复(主链路)
消息(微信/Telegram…) ─▶ Gateway adapter 归一
└▶ 鉴权:allowlist + DM pairing + token lock(不在白名单直接拒)
└▶ 取会话历史(按 平台+用户 隔离)
└▶ prompt_builder 装配上下文:
· 注入 SOUL.md(人格)/ MEMORY.md(长期记忆)/ USER.md(用户画像)
· FTS5 检索:从过去会话 + 技能库里捞「关键词相关」的内容塞进上下文
└▶ provider 调用(经解析层归一到某 API mode)
└▶ 工具循环:模型要调工具 → 危险命令先走审批 → 在终端后端执行 → 结果喂回
└▶ 生成回复 ─▶ 投递回原平台
└▶ 写回会话 DB(+ 可调 memory 工具把要点固化进 MEMORY.md / USER.md)② 自主沉淀技能闭环(「越用越能干」的引擎)
复杂任务办成
└▶ 把这次的解决路径「抽象」成一个可复用技能(文件)→ 写入技能库
↓ (时间流逝,来了相似任务)
└▶ prompt 装配时 FTS5 命中这个技能 → 加载进上下文
└▶ 执行中发现技能有缺陷 / 可优化 → 就地自我改进、回写技能库
↺ 经验复利:同类任务一次比一次顺③ cron 定时任务(first-class agent 任务)
调度器 tick(到点)
└▶ 新建一个全新、无历史的 AIAgent 实例(干净上下文)
└▶ 注入这个 job 的指令 + 它附带的技能
└▶ agent 自主执行(可调工具、可跑终端)
└▶ 投递结果(发到指定渠道)+ 更新 next_run7. 数据模型与存储选择
| 数据 | 放在哪 | 为什么 |
|---|---|---|
| 会话历史 | SQLite + FTS5,按平台隔离,含 lineage | 单文件零运维;FTS5 给全文检索;lineage 记派生关系 |
| 长期记忆(agent) | MEMORY.md 文件 | 人类可读可编辑的长期事实,跨会话稳定存在 |
| 用户画像 | USER.md 文件(「被蒸馏的你」) | 把对你的理解沉淀成一份可读档案 |
| 记忆检索 | 默认走会话 DB 的 FTS5;可换外置 provider | 默认零依赖;需要语义召回时再换知识图谱 / 向量 |
| 技能 | 文件(agentskills.io 兼容) | 可移植、可分享、可版本化——技能即资产 |
| 人格 | SOUL.md | 把「它是谁、怎么说话」固化下来 |
| 配置 / 凭据 | profile 感知的 HERMES_HOME | 多开隔离:每 profile 一套环境与密钥 |
| cron jobs | JSON | 简单可读的任务定义 |
教学点:它的记忆默认不是向量 RAG,而是「会话存进 SQLite + FTS5 关键词检索」。长期事实落到人类可读的
MEMORY.md/USER.md。这套选择的全部理由,见下一节第 ① 条——这是本篇最值钱的一节。
8. 关键架构决策与权衡 ⭐
决策 1:记忆检索用 FTS5 关键词,还是向量语义?(本篇最核心,务必读透)⭐⭐⭐
这是 Hermes 整个记忆设计的命门,也是「简单可托管」对「语义召回质量」的一次明确取舍。
选 FTS5 关键词检索的收益:
- 零外部依赖:SQLite 自带 FTS5,不用额外跑一个向量库 / embedding 服务。
- 部署极简、CPU 友好:没有 embedding 推理、没有 ANN 索引常驻内存,$5 VPS 就能跑。
- 精确词匹配快:你说过的原词,关键词检索能快速、精确地捞回来。
- 辅以 LLM 摘要做检索后处理:召回的原始片段先让模型压缩 / 提炼,缓解关键词检索「捞回一堆但不精」的问题。
代价(官方 Issue #10355 直承):
- 只能关键词召回,没有概念级检索:经典反例——你记过一条标题
Fixed N+1 query的记录,下次问database performance optimization,FTS5 找不到它,因为字面没有共同词,但语义高度等价。 - 跨会话语义不连续:换种说法描述同一件事,就可能检索不到上次的相关记忆。
- 记忆等权、无差别:FTS5 按词频相关性排,不区分「这条记忆对你有多重要 / 多近期」,重要的旧记忆和琐碎的新记忆被同等对待。
- 只能关键词召回,没有概念级检索:经典反例——你记过一条标题
演进方向(但默认仍坚持 FTS5):
- RRF 混合检索:把 BM25(关键词)与 cosine(向量语义)两路结果用 Reciprocal Rank Fusion 融合,兼得精确与语义。
sqlite-vec+ FTS5 hybrid:在同一个 SQLite 里同时上关键词与向量,保持「单文件」优势的同时补语义召回。- 知识图谱 provider:把记忆结构化成实体 / 关系,支持概念级查询。
- 但 embedding 会带来复杂度 / 延迟 / 磁盘占用 / 迁移风险(模型一换,历史向量全要重算)。对一个要在 $5 VPS 上常驻、面向单用户的助理,这些成本未必划算——所以默认坚持 FTS5,把语义升级留作可选 provider。
一句话记住这个取舍:FTS5 让记忆「能跑、好托管」,代价是「语义召回弱」。 这正是 向量数据库 用 ANN 换来的另一面——向量给你概念级语义召回,代价是内存、运维与一套要单独跑的索引系统。Hermes 先选了「简单可托管」,把「语义召回质量」留给愿意付复杂度的人去升级。延伸理解检索质量的上限,见 RAG 知识库。
决策 2:自我成长 / 自动写技能——要不要让它自己造能执行的技能?⭐
- 收益:经验复利,越用越强;复杂任务的解法不再一次性蒸发,而是变成可被
terminal/execute_code复用的可执行技能。 - 代价:一个错误或被污染的技能会被反复执行、自我放大;缺强制人工评审时,技能库会悄悄漂移(越改越偏却没人发现)。
- 取向:不上「强沙箱关死」那条路,而是靠命令审批 + 全程可观测可中断兜底——让危险动作在执行前被你看到、可叫停。刹车装在「执行关口」,不是装在「能力本身」。
决策 3:常驻 daemon + 平台无关内核——一个服务服务所有入口?⭐
- 收益:一个 AIAgent 内核服务 CLI / Gateway / IDE / cron,行为一致、零重复实现;改一处,所有入口同步受益。
- 代价:这个 daemon 成了并发与可用性的集中点——它挂了,所有入口都哑。
- 取向:面向单用户单部署,集中带来的「一致」远大于「单点」的代价;真要扩展,用多 profile 在单机并行,而非做成集群。
决策 4:消息平台即 UI——直接接管你的微信 / Telegram?⭐
- 收益:零前端成本,用户在哪 agent 就在哪,天然多端。
- 代价:受各平台 API / 限流 / 内容审核约束;鉴权得自己扛——靠 allowlist + DM pairing,而非平台给的账号体系。
- 取向:个人助理场景下值得——省掉一整个前端工程,换来「在你本来就用的 App 里」。
决策 5:Prompt 稳定性优先(缓存友好)——系统提示中途不变?⭐
- 收益:系统提示在一次对话里不变,换来前缀缓存高命中、显著降成本 / 降延迟。
- 代价:对话中途无法把新记忆 / 新技能热更新进当前系统提示——只能等下一轮对话生效。
- 取向:对一个高频、长期、自掏腰包跑的助理,省钱的杠杆压倒「即时热更新」的便利。
9. 规模化与瓶颈
- 第一个瓶颈:SQLite 单写者 + FTS5 检索。 语料涨大后,单写争用(写入串行)和全文检索延迟会先到顶;更隐蔽的是,FTS5 的语义鸿沟随语料放大——库越大,关键词召回「捞不到语义等价记录」的痛感越强。→ 破解:迁外置 DB / 上混合或语义检索 provider。
- 第二个瓶颈:单 daemon 无 sharding。 面向单用户单部署,多开靠 profile 隔离在单机并行,而非集群。→ 破解:接受定位,真要多用户就开多实例。
- 第三个瓶颈:记忆无自动 GC。 记忆只增不减,靠 agent / 用户主动裁剪。→ 破解:定期人工审视
MEMORY.md/USER.md与技能库。 - 第四个瓶颈:并行能力有限 + 长会话受窗口约束。 并行靠子 agent 但单机派生;长会话靠 context 压缩,仍受上下文窗口上限约束。→ 破解:把大任务拆小、及时归档老会话。
10. 安全与合规要点
- 数据全在自己手里:自托管意味着会话 / 凭据 / 记忆全在你自己的服务器,不经第三方——这是自托管的根本卖点。
- 密钥处理:密钥分散存储、不写日志,经透传机制注入到(隔离)终端,而非散落在命令行 / 日志里。
- 渠道鉴权:allowlist(白名单)+ DM pairing(私聊配对)+ token lock(令牌锁) 三件套防串扰、防陌生人触发——它默认只听白名单里的人。
- 🔴 最大风险面:它能跑
terminal/execute_code,且会自创技能,还有 cron 无人值守执行——这是威力最大、也最危险的组合。主要靠隔离终端后端(Docker / Singularity / Vercel Sandbox)+ 命令审批 + 全程可观测可中断来兜,而非默认就开强沙箱。 - 🔴 提示注入:靠用户白名单 + 命令审批防,而非靠内容检测扫描——所以「默认只信任白名单用户」是整套安全模型的关键前提。一旦把不可信用户 / 内容喂给它,等于把 shell 交给了注入者。
11. 常见误区 / 反模式
- ❌ 当它是「带向量 RAG 的记忆」 → ✅ 它默认是 FTS5 关键词检索,语义召回弱;要语义得换 provider。
- ❌ 把不可信用户 / 内容直接喂给它 → ✅ 它能自动执行 + 自写技能,这等于把 shell 暴露给提示注入;默认只对白名单开放。
- ❌ 当多租户 SaaS 横向扩容 → ✅ 它是单用户单部署;要服务多人用多 profile / 多实例,不是做成集群。
- ❌ 以为 cron 是跑 shell 脚本 → ✅ cron job 是 first-class agent 任务(有上下文、能调工具、能用技能)。
- ❌ 放任记忆与自创技能无人监管 → ✅ 无自动 GC、技能会漂移,要定期人工审视裁剪。
- ❌ 指望对话中途热更新系统提示 → ✅ 为缓存友好,系统提示一次对话内不变,新记忆 / 技能下轮才生效。
12. 演进路线:MVP → 成长期 → 成熟期(不同阶段怎么设置)
| 阶段 | 规模 / 场景 | 怎么设置(具体) | 此时该操心什么 |
|---|---|---|---|
| MVP | 自己一人用 | 单机部署;记忆用默认 FTS5;渠道白名单只放自己;终端先用本机后端 | 先跑起来,验证「常驻 + 记忆 + 技能」对你到底有没有用 |
| 成长期 | 多渠道 + 攒经验 | 接更多渠道(微信 / Telegram…);积累技能与记忆;收紧命令审批 + 切隔离终端后端 | 召回质量、技能漂移、危险命令的可控性 |
| 成熟期 | 重度长期助理 | 换语义 / 混合检索 provider(RRF / sqlite-vec / 知识图谱);终端全程隔离(Docker 等);定期人工审视记忆与技能库 | 语义召回、隔离强度、记忆与技能的长期卫生 |
13. 可复用要点
- 💡 持久记忆 + 自动技能 = 让 agent 知识复利。 「记得住」+「学得会」是把一次性智能体变成「长期资产」的两根支柱——价值在时间维度上累积。
- 💡 先用最简检索能跑起来,再按召回质量升级。 FTS5 让记忆零依赖上线;等语义鸿沟真的痛了,再上混合 / 向量 / 图谱——和「能用单机就别上集群」是同一种克制。
- 💡 自我成长必须配可观测 / 可中断 / 审批的刹车。 任何「能自己造能力、还自己执行」的系统,刹车不是可选项;呼应 Agent 平台 那句「放飞了就一定要装刹车」。
- 💡 系统提示稳定性是省钱的架构杠杆。 让前缀稳定 = 缓存高命中 = 成本骤降;代价是放弃中途热更新——这是一笔在高频长期场景里很划算的交易。
- 💡 自托管把数据主权换成运维责任。 数据全在自己手里的另一面,是安全、备份、隔离都得自己扛——默认只信白名单,是这套模型成立的前提。
🎯 随堂检验
- A检索太慢跑不动
- B只能关键词匹配,没有概念级语义召回,换种说法就找不到等价记录
- C必须联网才能用
参考原型与延伸阅读
本模板基于以下官方资料整理。Hermes Agent 由 Nous Research 开源(MIT),想动手可直接读仓库与官方架构文档。同类常驻智能体可对照看姊妹篇 OpenClaw(龙虾)。
🔧 官方原型与文档:
- NousResearch/hermes-agent — 官方仓库 README,Hermes Agent 源码入口。
- 官方架构文档(最权威) — 开发者指南里的架构篇,内核 / 子系统 / 数据流的一手说明。
- 官方文档站首页 — 全部文档导航。
- 官方工具参考 — 70+ 工具 / 约 28 个 toolset 的权威清单(营销材料常写 40+,以此为准)。
- 官方 Issue #10355 — FTS5 关键词检索局限 vs 语义检索的一手讨论,第 8 节 ① 的依据。
- 官方落地页:The Agent That Grows With You — 「跟你一起成长」的产品定位。
🔗 延伸阅读(本仓库):
- OpenClaw(龙虾) — 同类自托管常驻智能体,姊妹篇对照。
- 向量数据库 — FTS5 vs 向量检索里「向量 / ANN 那一面」的深入。
- RAG 知识库 — 检索质量决定上限,理解记忆召回的上限。
- AI Agent / 工作流平台 — 通用 Agent 编排与「给自主性装刹车」。
- 数据与状态 — SQLite / 持久化 / 状态管理的基础。
📌 一句话记住 Hermes:它不是「更强的一次性 Agent」,而是「一个跑在你自己服务器上、跟你一起长期成长的常驻助理」——常驻进程让它一直在、FTS5 持久记忆让它记得住、自动沉淀技能让它学得会;而它默认用 FTS5 关键词(而非向量语义)、靠白名单 + 审批 + 可中断(而非强沙箱)兜底,全是『简单可托管、自托管单用户』这个定位下的清醒取舍。
💬 评论