请用中文详细讲解 hermes-agent 的核心架构模式——子代理(subagents)、SKILL 体系、记忆管理、网关(gateway)对外接入、以及 MCP 桥接,分别负责什么、如何协同。
No home channel is set for Discourse. A home channel is where Hermes delivers cron job results and cross-platform messages.
Type /sethome to make this chat your home channel, or ignore to skip.
让我先加载相关参考文档,确保架构细节准确。
Hermes Agent 核心架构模式详解
Hermes Agent 的整体设计可以概括为一句话:一个持久化的智能核心(agent loop)+ 一套跨会话的学习系统(SKILL + 记忆)+ 一层把同一核心暴露到所有平台的网关(gateway)+ 一个可无限扩展的工具面(MCP/插件)。下面按五大模块拆开讲。
1. 子代理(Subagents)——进程内并行的工作流引擎
子代理不是独立的 Hermes 进程,而是由主代理通过 delegate_task 工具在同一个进程内孵化出的隔离上下文。
关键机制:
- 完全隔离:每个子代理拥有独立的对话上下文、独立的 terminal 会话、独立的工具集。它不知道父代理的任何历史,所有背景信息都必须通过
goal+context显式传入——这也是"信息显式传递"这一设计原则的体现。 - 批量并行:
delegate_task(tasks=[{goal, ...}, ...])一次可孵化多个子代理并行干活,并发数由delegation.max_concurrent_children限制(默认 3)。 - 两种角色:
leaf(默认):只能执行,不能再孵化自己的子代理——限制递归深度,防止失控的 agent 爆炸。orchestrator:允许再孵化下级 worker,但受delegation.max_spawn_depth深度限制。
- 后台模式:
background=true时立即返回句柄,主循环继续跑,子代理结果完成后以新回合的形式重新进入对话——适合"派活后不等结果"。
设计边界(很重要): 子代理是进程本地、非持久的——父进程退出,子代理即丢失。因此:
| 需求 | 正确工具 |
|---|---|
| 快速并行子任务(几分钟级) | delegate_task |
| 长时自主任务(小时/天级)、要完整工具集 | spawn 独立 hermes 进程(one-shot 或 tmux PTY) |
| 定时、要跨进程存活、要投递结果 | cronjob |
| 多 profile 多 worker 协作分工 | Kanban(SQLite 持久工作队列,gateway 内嵌 dispatcher) |
这个分层是 Hermes 架构里"快路径 vs 持久路径"的典型体现:进程内的归进程内,要活过进程的必须落到磁盘。
2. SKILL 体系——"自改进"的核心,学习的闭环
SKILL 是 Hermes 与其他 agent 框架最本质的区别:它不是一个固定的工具库,而是一个运行时可以自我进化的程序性记忆。
生命周期:
- 创建:完成一次有难度的任务后,代理把"非平凡的、可复用流程"通过
skill_manage固化为SKILL.md(YAML frontmatter + Markdown 正文)。这是显式指令,不是自动行为——"值得沉淀"由代理判断。 - 结构:每个 skill 可以携带
references/(细节文档)、templates/(模板)、scripts/(可执行脚本),SKILL.md 是入口枢纽。 - 加载纪律:会话开始时会扫描技能清单,任务匹配到技能描述就必须
skill_view加载并遵循——技能里编码了用户偏好的工作方式和踩过的坑。 - 维护(Curator):后台进程跟踪每个 skill 的
use_count、view_count、patch_count,把闲置技能标记 stale → 归档。它只处理created_by: "agent"的技能,永远不会删除,最多归档,且每次操作前有 tar.gz 备份可回滚。Pinned 技能豁免一切自动流转。跨技能合并成"伞技能"的 LLM 审查默认关闭,常规清理零 token 成本。 - 开放生态:SKILL 兼容 agentskills.io 开放标准,可从 Skills Hub 安装社区技能,也可分享出去——技能是可移植的资产。
关键设计:上下文压缩时如果技能内容被裁成 [SKILL_PRUNED] 占位符,必须重新 skill_view 加载才能使用——保证代理绝不基于残缺的技能干活。
3. 记忆管理——三层架构,各管各的时间尺度
记忆不是一个大杂烩,而是按持久性梯度分层的:
第一层:项目上下文文件(AGENTS.md / CLAUDE.md / .hermes.md)
作用于当前工作目录下的所有会话,定义项目纪律。比如这台机器上的 CLAUDE.md 就是最高优先级指令。这是"环境/项目级"记忆。
第二层:跨会话持久记忆(两个存储)
user目标:关于用户是谁——身份、角色、偏好、纠正记录。memory目标:关于环境——机器事实、约定、工具怪癖、经验教训。- 写入规范非常讲究:必须写成陈述句事实(“用户偏好简洁回答”)而非祈使句指令(“要简洁回答”)——祈使句在后续会话会被重新读成指令,可能覆盖用户当下的真实请求。存储有硬字符预算,满了就批量合并/淘汰旧条目。
- 路由规则:一周内就过期的信息留在会话历史;可复用流程进 SKILL;只有跨会话稳定的事实才进记忆。
第三层:会话历史 + 全文检索
所有会话存 SQLite(~/.hermes/state.db,带 FTS5 全文索引)。session_search 用关键词就能翻出过去的会话——用户提到"上次我们做过的 X"时,先搜历史而不是让用户复述。FTS5 召回 + LLM 摘要(可选 Honcho 辩证法用户建模)。
三条梯度对应三个问题:这环境里怎么干活?这个用户是谁?我们之前做过什么?——时间尺度从"项目期"到"永久"到"可追溯"。
4. 网关(Gateway)——一个核心,二十个入口
网关解决的是:同一个 agent 实例,同时活在 CLI、TUI、桌面 App、Web Dashboard、以及 20+ 消息平台上——Telegram、Discord、Slack、WhatsApp、Signal、Matrix、Teams、Email、飞书、钉钉、企微、微信、QQ 机器人等。
关键机制:
- 单一核心多表面:平台只是"皮肤",消息进来统一走同一条 agent loop,具备完整工具权限——不是阉割版聊天机器人。
- 路由索引:
~/.hermes/sessions/维护 gateway 路由索引和请求转储;state.db是规范会话存储。 - 凭据池:
~/.hermes/auth.json存 OAuth token 和凭据池,可跨多个 API key 自动轮换;.env只放密钥,config.yaml只放配置——这是硬性不变式。 - Bot Mode:在群聊里通过
@mention组建一支常驻的专家 Bot 团队,机器人之间可以互相协作。 - Profiles:
~/.hermes/profiles/<name>/下是完全隔离的 Hermes 实例——各自独立的会话、技能、记忆、cron、插件。多租户靠 profile 隔离,互不污染。 - 调度投递:cron 任务可以投递到任意平台;webhook 提供事件驱动入口;
hermes proxy甚至暴露一个 OpenAI 兼容的本地代理。
网关的架构意义:agent 能力的边际成本被复用——写一次工具/技能/记忆,所有入口同时升级。
5. MCP 桥接——工具面的标准化扩展
Hermes 内置原生 MCP 客户端(不是调外部 CLI 的壳),让整个 MCP 生态成为它的工具面。
工作机制:
- 配置:
config.yaml的mcp_servers下声明服务器,两种传输:- stdio:
command+args,Hermes 把服务器当子进程拉起(如npx @modelcontextprotocol/server-filesystem)。 - HTTP/StreamableHTTP:
url+headers,连远程共享服务器。
- stdio:
- 启动发现:启动时
discover_mcp_tools()连接每个服务器 →list_tools()发现工具 → 注册进 Hermes 工具注册表 → 自动注入所有hermes-*平台工具集。也就是说 MCP 工具在所有入口(CLI、Telegram、Discord…)开箱即用,零额外配置。 - 命名规范:
mcp_{server}_{tool},连字符/点转下划线(mcp_github_list_issues),天然避免多服务器工具名冲突。 - 生命周期:每个服务器是常驻的 asyncio 后台任务,连接断了自动指数退避重连(5 次封顶,最大 60s);进程退出时优雅关闭;
discover_mcp_tools()幂等,失败服务器下次重试。 - 安全设计(很值得借鉴):
- stdio 子进程不继承完整环境变量——只传
PATH/HOME/USER等基础变量和env里显式声明的内容,防止 API key 泄漏给不可信的 MCP 服务器。 - MCP 工具调用失败的报错信息会自动剥掉凭据模式(
sk-...、ghp_...、token=等)再展示给 LLM。
- stdio 子进程不继承完整环境变量——只传
- 反向能力(sampling):支持 MCP 的
sampling/createMessage——服务器在工具执行期间可以向 agent 请求 LLM 补全,实现"agent-in-the-loop",且带max_tool_rounds、max_rpm防死循环,可对不可信服务器一键关闭。
6. 五大模块如何协同
整个架构是一台"自学习的并行机器",协同关系是:
Telegram / Discord / CLI / Desktop ...(网关层)
│ 消息路由
▼
┌─── 主代理循环(记忆 + 上下文文件加载) ───┐
│ │ │ │
│ skill_view 加载技能 delegate_task │ ← MCP 工具也在工具集里
│ │ 孵化子代理并行 │
│ ▼ │ │
│ SKILL.md 指导执行 子代理独立上下文 │
│ │ │ │
└──── 结果:skill_manage 沉淀 / memory 更新 ─┘
│
▼
cron 定时任务把结果投递回任意平台
具体到一个真实场景:用户在 Telegram 发来"研究 GRPO 并写报告" →
- 网关把消息路由进主代理循环(带用户记忆 + 项目上下文);
- 代理检索 SKILL 列表,加载相关技能(如
arxiv),获得研究流程和工具用法; delegate_task孵化 3 个子代理并行查论文、做实验、写代码,各自可用 MCP 工具(如 GitHub);- 汇总后
skill_manage把"GRPO 研究流程"沉淀为新技能,memory记下用户对该格式的偏好; cronjob定时让报告自动投递回 Telegram。
贯穿始终的设计哲学:
- 快路径 vs 持久路径:子代理是进程内的快路径;SKILL、记忆、cron、kanban 是落到磁盘的持久路径——“经验必须比进程活得久”。
- 信息显式传递:子代理不带历史,全靠显式传参——上下文按需注入,而不是全局共享。
- 单点学习、多点复用:技能和记忆在一个入口学到的,通过网关在 20 个入口复用。
- 安全默认:MCP 环境过滤、凭据剥离、secret/config 分离、子代理递归限深——能力扩张永远配防御。
一句话总结:子代理解决"并行",SKILL 解决"学习",记忆解决"连续性",网关解决"触达",MCP 解决"生态"——五者围绕同一个 agent loop,构成一个越用越强的闭环。