Hermes Agent 架构模式:子代理与 SKILL 体系

请用中文详细讲解 hermes-agent 的核心架构模式——子代理(subagents)、SKILL 体系、记忆管理、网关(gateway)对外接入、以及 MCP 桥接,分别负责什么、如何协同。

:open_mailbox_with_raised_flag: 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 框架最本质的区别:它不是一个固定的工具库,而是一个运行时可以自我进化的程序性记忆

生命周期:

  1. 创建:完成一次有难度的任务后,代理把"非平凡的、可复用流程"通过 skill_manage 固化为 SKILL.md(YAML frontmatter + Markdown 正文)。这是显式指令,不是自动行为——"值得沉淀"由代理判断。
  2. 结构:每个 skill 可以携带 references/(细节文档)、templates/(模板)、scripts/(可执行脚本),SKILL.md 是入口枢纽。
  3. 加载纪律:会话开始时会扫描技能清单,任务匹配到技能描述就必须 skill_view 加载并遵循——技能里编码了用户偏好的工作方式和踩过的坑。
  4. 维护(Curator):后台进程跟踪每个 skill 的 use_countview_countpatch_count,把闲置技能标记 stale → 归档。它只处理 created_by: "agent" 的技能,永远不会删除,最多归档,且每次操作前有 tar.gz 备份可回滚。Pinned 技能豁免一切自动流转。跨技能合并成"伞技能"的 LLM 审查默认关闭,常规清理零 token 成本。
  5. 开放生态: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.yamlmcp_servers 下声明服务器,两种传输:
    • stdio:command + args,Hermes 把服务器当子进程拉起(如 npx @modelcontextprotocol/server-filesystem)。
    • HTTP/StreamableHTTP:url + headers,连远程共享服务器。
  • 启动发现:启动时 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。
  • 反向能力(sampling):支持 MCP 的 sampling/createMessage——服务器在工具执行期间可以向 agent 请求 LLM 补全,实现"agent-in-the-loop",且带 max_tool_roundsmax_rpm 防死循环,可对不可信服务器一键关闭。

6. 五大模块如何协同

整个架构是一台"自学习的并行机器",协同关系是:

        Telegram / Discord / CLI / Desktop ...(网关层)
                        │ 消息路由
                        ▼
        ┌─── 主代理循环(记忆 + 上下文文件加载) ───┐
        │         │                  │            │
        │   skill_view 加载技能    delegate_task  │  ← MCP 工具也在工具集里
        │         │              孵化子代理并行    │
        │         ▼                  │            │
        │  SKILL.md 指导执行       子代理独立上下文  │
        │         │                  │            │
        └──── 结果:skill_manage 沉淀 / memory 更新 ─┘
                        │
                        ▼
                cron 定时任务把结果投递回任意平台

具体到一个真实场景:用户在 Telegram 发来"研究 GRPO 并写报告"

  1. 网关把消息路由进主代理循环(带用户记忆 + 项目上下文);
  2. 代理检索 SKILL 列表,加载相关技能(如 arxiv),获得研究流程和工具用法;
  3. delegate_task 孵化 3 个子代理并行查论文、做实验、写代码,各自可用 MCP 工具(如 GitHub);
  4. 汇总后 skill_manage 把"GRPO 研究流程"沉淀为新技能,memory 记下用户对该格式的偏好;
  5. cronjob 定时让报告自动投递回 Telegram。

贯穿始终的设计哲学:

  • 快路径 vs 持久路径:子代理是进程内的快路径;SKILL、记忆、cron、kanban 是落到磁盘的持久路径——“经验必须比进程活得久”。
  • 信息显式传递:子代理不带历史,全靠显式传参——上下文按需注入,而不是全局共享。
  • 单点学习、多点复用:技能和记忆在一个入口学到的,通过网关在 20 个入口复用。
  • 安全默认:MCP 环境过滤、凭据剥离、secret/config 分离、子代理递归限深——能力扩张永远配防御。

一句话总结:子代理解决"并行",SKILL 解决"学习",记忆解决"连续性",网关解决"触达",MCP 解决"生态"——五者围绕同一个 agent loop,构成一个越用越强的闭环。