# Hermes Agent(爱马仕)架构模板 > **代表产品 / 原型**:Hermes Agent(爱马仕,Nous Research,MIT) —— 同类:OpenClaw(龙虾) > **一句话定位**:Nous Research 的自托管常驻智能体「跟你一起成长」——常驻进程 + 跨会话持久记忆 + 自主沉淀可复用技能,接管你的消息账号做长期个人助理,越用越懂你、越用越能干。 --- ## 1. 一句话定位 Hermes = **一个跑在你自己服务器上、永不下线的常驻智能体**:它接管你的消息账号(微信 / Telegram / 邮件……),记得住你过去说过的每件事,还会把「这次怎么把事办成的」沉淀成可复用的技能——**越用越懂你、越用越能干**。 它和 [通用 Agent 平台](../ai-agent-platform/README.md) 的区别在于「常驻 + 成长」:通用 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_run ``` ## 7. 数据模型与存储选择 | 数据 | 放在哪 | 为什么 | |---|---|---| | 会话历史 | **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](https://github.com/NousResearch/hermes-agent/issues/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 让记忆「能跑、好托管」,代价是「语义召回弱」。** 这正是 [向量数据库](../vector-database/README.md) 用 ANN 换来的另一面——向量给你概念级语义召回,代价是内存、运维与一套要单独跑的索引系统。Hermes 先选了「简单可托管」,把「语义召回质量」留给愿意付复杂度的人去升级。延伸理解检索质量的上限,见 [RAG 知识库](../rag-knowledge-base/README.md)。 **决策 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 平台](../ai-agent-platform/README.md) 那句「放飞了就一定要装刹车」。 - 💡 **系统提示稳定性是省钱的架构杠杆。** 让前缀稳定 = 缓存高命中 = 成本骤降;代价是放弃中途热更新——这是一笔在高频长期场景里很划算的交易。 - 💡 **自托管把数据主权换成运维责任。** 数据全在自己手里的另一面,是安全、备份、隔离都得自己扛——默认只信白名单,是这套模型成立的前提。 ## 🎯 随堂检验 --- ## 参考原型与延伸阅读 > 本模板基于以下**官方资料**整理。Hermes Agent 由 Nous Research 开源(MIT),想动手可直接读仓库与官方架构文档。同类常驻智能体可对照看姊妹篇 [OpenClaw(龙虾)](../openclaw/README.md)。 **🔧 官方原型与文档:** - [NousResearch/hermes-agent](https://github.com/NousResearch/hermes-agent) — 官方仓库 README,Hermes Agent 源码入口。 - [官方架构文档(最权威)](https://hermes-agent.nousresearch.com/docs/developer-guide/architecture) — 开发者指南里的架构篇,内核 / 子系统 / 数据流的一手说明。 - [官方文档站首页](https://hermes-agent.nousresearch.com/docs/) — 全部文档导航。 - [官方工具参考](https://github.com/NousResearch/hermes-agent/blob/main/website/docs/reference/tools-reference.md) — 70+ 工具 / 约 28 个 toolset 的权威清单(营销材料常写 40+,以此为准)。 - [官方 Issue #10355](https://github.com/NousResearch/hermes-agent/issues/10355) — FTS5 关键词检索局限 vs 语义检索的一手讨论,第 8 节 ① 的依据。 - [官方落地页:The Agent That Grows With You](https://hermes-agent.nousresearch.com/) — 「跟你一起成长」的产品定位。 **🔗 延伸阅读(本仓库):** - [OpenClaw(龙虾)](../openclaw/README.md) — 同类自托管常驻智能体,姊妹篇对照。 - [向量数据库](../vector-database/README.md) — FTS5 vs 向量检索里「向量 / ANN 那一面」的深入。 - [RAG 知识库](../rag-knowledge-base/README.md) — 检索质量决定上限,理解记忆召回的上限。 - [AI Agent / 工作流平台](../ai-agent-platform/README.md) — 通用 Agent 编排与「给自主性装刹车」。 - [数据与状态](../../tutorial/05-数据与状态.md) — SQLite / 持久化 / 状态管理的基础。 --- > 📌 一句话记住 Hermes:**它不是「更强的一次性 Agent」,而是「一个跑在你自己服务器上、跟你一起长期成长的常驻助理」——常驻进程让它一直在、FTS5 持久记忆让它记得住、自动沉淀技能让它学得会;而它默认用 FTS5 关键词(而非向量语义)、靠白名单 + 审批 + 可中断(而非强沙箱)兜底,全是『简单可托管、自托管单用户』这个定位下的清醒取舍。**