Hermes Agent 架构总览:从 Agent Loop 到智能体平台

前言:最近我一直在读 Hermes Agent 的代码。本来只是想看清 Agent Loop 怎么跑,结果越往下翻,越发现它已经不是一个简单的工具调用程序:入口协议、桌面端、模型适配、工具、记忆、压缩、协作和安全都围绕同一套运行时组织起来。这篇先画完整地图,后面的专题再逐层拆开。


系列导航:这组文章按“总览 → 入口 → 运行时 → 扩展 → 状态 → 协作 → 安全”的顺序展开;第一次阅读可以从总览开始,带着具体问题也可以直接跳到专题。

  1. 01|Hermes Agent 架构总览:从 Agent Loop 到智能体平台
  2. 02|Hermes Desktop 架构:Electron 如何连接本地 Python Agent
  3. 03|Hermes Agent 运行时:AIAgent、模型协议与工具执行
  4. 04|Hermes Agent 扩展体系:Skill、Plugin 与 MCP
  5. 05|实战:同一个 Markdown 检查器的 Skill、Plugin 与 MCP 三种实现
  6. 06|Hermes Agent 的持续学习系统:Memory、Review、Skill 与 Curator
  7. 07|Hermes Agent 的长会话架构:Prompt Cache、压缩与 SessionDB
  8. 08|Hermes Agent 的多 Agent 与自动化:从 Goal 到 Kanban
  9. 09|Hermes Agent 安全架构:审批、沙箱、回滚与凭据隔离

我先给它一个定位:窄腰型的智能体运行平台

很多 Agent Demo 的核心只有几步:把消息发给模型,解析工具调用,执行函数,再把结果交回模型。Hermes Agent 当然也有这个循环,但真正让我感兴趣的是循环外面的东西。它需要让同一个 Agent 同时服务 CLI、TUI、桌面界面、消息平台、编辑器协议、API、定时任务和批处理;下面又要接多种模型协议、几十类能力以及可替换的运行后端。

我目前更愿意把它理解为一个多入口、单核心、多协议、可插拔能力、统一状态层的智能体运行平台。中间的 AIAgent 和 Conversation Loop 是“窄腰”:入口怎么变化、工具怎么扩展,最后都要经过这组相对稳定的协议。

flowchart TB
    Entry[CLI / TUI / 桌面 / 网关 / ACP] --> Agent[AIAgent 会话运行时]
    Agent --> Loop[对话循环
Conversation Loop] Loop --> Prompt[Prompt 与 Context Engine] Loop --> Transport[模型提供方传输层
Provider Transport] Loop --> Toolset[Toolset 与 Tool Registry] Agent --> State[SessionDB 与 Memory] Transport --> Models[模型服务] Toolset --> Ext[内置工具 / Plugin / MCP]

上图里最关键的不是模块数量,而是依赖方向:入口层不自己实现一套模型循环,扩展层也不直接侵入每个入口。只要中间这层契约不乱,系统就可以同时向上增加交互方式、向下增加能力。

我的阅读基线:我遍历了官方仓库 website/docs 下 402 个 Markdown/MDX 页面,并以 2026 年 8 月 21 日再次同步到的官方 main 提交 59795c40 为源码锚点。文档用于建立功能地图,默认值、状态机和失败语义则回到对应符号核验;容易变化的工具与平台数量不当作架构结论。

入口层:不同界面,共用同一个 Agent Core

源码里能看到不少入口,但它们的职责其实很一致:接收输入、解析身份与会话、装配回调、调用 AIAgent,最后把结果转换成当前界面能展示的形式。

  • hermes_cli/main.pycli.py 负责命令行、配置和交互式命令;
  • ui-tui/tui_gateway/ 组成终端 UI 及其 JSON-RPC 后端;
  • gateway/run.py 是长驻消息网关,负责鉴权、路由、并发和投递;
  • acp_adapter/ 把 Agent 暴露给支持 ACP 的编辑器;
  • cron/batch_runner.py 和 API 入口复用同一套执行内核。

这里先把几个很容易混在一起的名字拆开。ACP 是 Agent Client Protocol,面向“编辑器或其他 Host 如何驱动一个完整 Agent”;TUI Gateway JSON-RPC 是 Hermes 自己为 TUI、Desktop 等富客户端提供的控制协议;MCP 则位于 Agent 的另一侧,用来连接外部 Tool、Resource 和 Prompt。它们都可能使用 JSON-RPC,但消息方法、生命周期和连接对象并不是一回事。

入口或宿主连接协议与传输适配层最终怎样进入 Agent
CLIPython 进程内调用cli.py / hermes_cli/解析命令和 Profile 后直接创建或恢复 AIAgent
Ink TUIHermes JSON-RPC 2.0 over stdio,也可走 WebSockettui_gateway/session.createprompt.submit 等方法映射到会话运行时
Electron DesktopHermes JSON-RPC 2.0 over WebSocket /api/ws;设置和管理功能另走 RESThermes servetui_gateway/ 与 FastAPI BackendReact Renderer 提交 Prompt、接收流式事件;本机窗口和文件能力另走 Preload IPC
VS Code / Zed / JetBrainsACP 的 JSON-RPC over stdioacp_adapter/session/prompt、ToolCall、Diff、取消和 Permission Request 桥接到 AIAgent
OpenAI 兼容 Web UI 或业务客户端HTTP;流式响应和运行事件使用 SSEgateway/platforms/api_server.py把 Chat Completions、Responses 或 Run 请求转换成隔离的 Agent 执行
Telegram / Discord / Slack 等各平台 SDK、Webhook、轮询或长连接gateway/platforms/先做平台鉴权、消息归一化和 Session 路由,再调用同一 Agent Core
Cron / Batch进程内调度,不需要 UI 协议cron/batch_runner.py按 Job 或批任务建立新的执行上下文

所以,Electron Desktop 并不通过 ACP 连接 Hermes:它连接的是 hermes serve 暴露的 TUI Gateway WebSocket。只有当 VS Code、Zed、JetBrains 或其他 ACP Host 启动 hermes acp 时,链路才会经过 acp_adapter。两者最终都汇合到 AIAgent,复用相同的模型、工具、Skill、Memory 和 SessionDB;区别只在入口协议与界面事件如何翻译。

再换一个方向看:ACP 是“Host ↔ Agent”,MCP 是“Agent ↔ 外部能力”,Provider Transport 是“Agent ↔ 模型 API”。一个典型编辑器会话可以同时经过三层:IDE 通过 ACP 驱动 Hermes,Hermes 通过 MCP 查询工程平台,再通过 Provider Transport 请求模型推理。协议是可以叠加的,不是三选一。

平台差异没有被塞进主循环里,而是通过 callback 和 session metadata 向外释放。工具开始、工具完成、模型思考、流式增量、澄清问题、状态变化,都有各自的回调。核心只负责说“发生了什么”,至于显示成终端 Spinner、聊天消息编辑还是编辑器进度条,由入口自己决定。

flowchart LR
    Input[平台原始消息] --> Normalize[统一 SessionSource]
    Normalize --> Auth{鉴权与路由通过?}
    Auth -->|否| Reject[拒绝或配对流程]
    Auth -->|是| Session[恢复 / 创建会话]
    Session --> Runtime[解析模型、工具集和 Profile]
    Runtime --> Agent[智能体运行入口
AIAgent.run_conversation] Agent --> Events[流式文本与状态回调] Events --> Deliver[平台适配器投递]

这里有个很重要的结果:CLI 和消息网关复用的不是几段工具代码,而是完整的 Agent 语义。模型回退、上下文压缩、记忆、审批和持久化都在核心层,因此换一个入口,不应该换一套“大脑”。

运行时到底由哪些组件组成

只看目录很容易把 Hermes Agent 理解成“一堆功能模块”。但真正运行时,它们并不是平铺在一起,而是被装配成一个会话级对象图:入口提供身份和回调,运行时解析模型与工具,Agent 持有当前会话状态,插件和 MCP 则叠加在注册中心与生命周期节点上。

组件主要实现位置运行时职责生命周期
入口适配器cli.pygateway/acp_adapter/接收输入、鉴权、建立平台回调、投递输出进程级或连接级
AIAgentrun_agent.py保存一个会话所需的模型、工具、记忆、预算和中断状态会话级
Agent Initagent/agent_init.py解析配置并装配 Agent 对象图创建或重建 Agent 时
Conversation Loopagent/conversation_loop.py组织模型调用、工具结果和最终答案每个用户 Turn
Prompt Systemagent/system_prompt.pyagent/prompt_builder.py构建冻结 Prompt 和本轮临时上下文新会话、恢复与请求级
Provider Runtimeplugins/model-providers/agent/transports/选择凭据、模型协议并归一化响应Agent 创建与每次 API 调用
Tool Registrytools/registry.pymodel_tools.py保存 Schema、handler、可用性与作用域进程级注册,会话级快照
Tool Executoragent/tool_executor.py审批、分段并发、执行并回填工具结果每个工具批次
Skill Systemtools/skills_tool.pyagent/skill_commands.py提供紧凑索引与按需加载的操作知识会话级索引、按调用加载
Plugin Managerhermes_cli/plugins.py发现插件并注册工具、Hook、Provider 和中间件Profile / 进程级
MCP Clienttools/mcp_tool.py连接外部工具服务并动态注册 Schema服务连接级
Memory / Contexttools/memory_tool.pyagent/memory_manager.pyagent/context_engine.py文件记忆、外部召回、上下文选择与压缩会话级与 Turn 级
SessionDBhermes_state.py消息、Prompt、用量、搜索、租约与并发协调持久化
flowchart TB
    Config[Profile 配置与凭据] --> Init[agent_init 装配]
    Plugins[Plugin Manager 注册覆盖层] --> Init
    MCP[MCP 动态工具] --> Registry[工具注册表
Tool Registry] Init --> Agent[AIAgent 会话对象] Init --> Transport[模型提供方传输层
Provider Transport] Init --> Registry Init --> Memory[记忆管理器
Memory Manager] Init --> Context[上下文引擎
Context Engine] Agent --> Loop[对话循环
Conversation Loop] Loop --> Transport Loop --> Registry Loop --> Memory Loop --> Context

启动时和每轮请求时,不是同一套工作

我读代码时比较容易混淆“注册时发生什么”和“对话时发生什么”。把它们分开后就清楚了:

  • 进程启动或 Profile 首次使用:发现内置工具和插件,注册 Provider、平台、Hook 与工具元数据;MCP 连接后也会把远端工具加入 Registry。
  • 创建 AIAgent:解析模型、API mode、凭据、Toolset、Memory Provider 和 Context Engine,取得当前 Registry 的会话快照。
  • 开始一个 Turn:获取会话租约、加载历史、组装本轮上下文、调用模型、执行工具并最终提交。
  • Turn 结束:持久化消息与用量,触发观察 Hook、记忆异步同步和 Context Engine 的完成回调,再释放租约。

因此 Plugin 和 MCP 并不是每轮临时“插进来”的独立旁路。多数情况下,它们在更早阶段把能力注册到现有边界,到了 Conversation Loop 里看起来就和内置能力差不多,只是多了来源、作用域和授权信息。

从全站功能回看它的亮点

通读文档站后,我觉得项目亮点并不是“内置了很多工具”。更有意思的是,它把个人 Agent 运行几年后一定会遇到的六类问题都做成了明确边界:入口、学习、持续执行、扩展、安全和模型运营。很多功能看起来相距很远,源码里却共享同一套 Session、Profile、Toolset 与生命周期契约。

亮点用户能看到的功能源码中的共同机制
闭环学习Memory、Session Search、Agent-created Skills、Curator、Learning JourneyMemoryStorebackground_review.pyskill_manage、FTS5 与写入审批
多入口同语义CLI、TUI、Desktop、20+ 消息入口、API Server、ACPAIAgent、Gateway Session、JSON-RPC、Platform Registry 与统一回调
持续执行梯度Loops、Heartbeat、Goals、Cron、Delegation、Kanban、Bot Mode从会话内定时器、Goal contract,到持久 Job/Board 与 Profile Worker,不拿一种机制硬撑所有生命周期
扩展不撑大核心Skills、Plugin、MCP、Provider、Memory Provider、Context EngineTool Registry 窄腰、配置选择、动态 Toolset 与显式兼容契约
副作用有多层安全网危险命令审批、文件检查点与 rollback、Worktree、Sandbox、Secrets、Managed Scope、Egress Proxy审批管线、shadow Git snapshot、Environment Backend、Secret Source 与出站凭据注入
模型运营不是硬编码Provider Routing、Fallback、Credential Pool、Auxiliary Models、MoAProvider Profile、Transport、运行时凭据解析、任务级路由与统一 usage 记录

尤其值得注意的是“持续执行梯度”。/loop 适合在当前会话重复一个 Prompt,Heartbeat 在会话空闲时重新进入,Goal 用完成条件推动跨 Turn 工作,顶层 Delegation 并行但仍是进程内临时任务,Cron 把计划持久化为定时 Job,Kanban 再增加依赖、认领、Review 和崩溃恢复。架构上先问生命周期,再选机制,比笼统地说“支持 Autonomous Agent”更有解释力。

做得好的地方

  • 多入口复用的是语义。不同界面天然得到同一套模型、工具、记忆、压缩和持久化行为。
  • 供应商差异被限制在协议边界。上层面对统一消息模型,不需要跟每一家 API 一起变化。
  • 扩展方式有重量级。Skill、Plugin、MCP、Provider 和核心工具各有位置。
  • 长会话不是事后补丁。Prompt Cache、sidecar、Context Engine 和 lease 从不同角度保护连续性。
  • Profile 作用域进入了注册中心。一个进程可以同时服务相互隔离的配置与扩展。

它付出的代价

  • run_agent.pyconversation_loop.pygateway/run.py 仍然很大,历史兼容逻辑的阅读成本不低;
  • 动态注册让最终能力集依赖配置、Profile、加载顺序和外部探测,静态分析更难;
  • Prompt Cache 的不变量限制了会话中途随意修改系统提示和工具集;
  • Agent Cache、SQLite、路由状态、压缩锁和 turn lease 共同工作,多进程一致性本身已经是一个子系统;
  • Hook 和 Provider 一旦开放,就会产生长期兼容与安全治理成本。

所以它不是那种“代码很少、边界特别漂亮”的教学框架。它更像一套高速演进、已经承受真实入口和真实状态压力的系统。架构上的价值,恰恰在于这些复杂性大多有明确归属,而不是完全散落在每条调用链里。

如果只记五件事

  1. 把 Prompt Cache 当成架构不变量。明确哪些内容会话内冻结,哪些只按轮注入。
  2. 控制模型可见接口的面积。能用现有工具、Skill、Plugin 或 MCP 解决,就不要急着加核心工具。
  3. 能力属于 Session,不属于 Process。权限和工具可用性必须根据当前会话来源解析。
  4. 分开历史、记忆和上下文选择。它们解决的问题不同,也应该有不同生命周期。
  5. 为一轮执行建立所有权。成熟 Agent Turn 需要预算、租约、中断、审批和 Finalizer,不能只依赖同步调用栈。

一开始我以为 Hermes Agent 最值得看的会是某个 Prompt 或某个工具。代码翻完后,我反而觉得它最有价值的地方是:当 Agent 从 Demo 变成长时间运行的软件,重点会从“怎么让模型行动”变成“怎么约束行动、保存状态、控制成本,并让系统继续扩展而不把核心撑爆”。

参考资料与源码入口

题图来源:《山、鸟类与轮廓》,创作者 giani,来自 Pixabay;依据 Pixabay Content License(Pixabay 内容许可)使用。

下一篇:Hermes Desktop 架构:Electron 如何连接本地 Python Agent

AI混合云架构设计 实战:同一个 Markdown 检查器的 Skill、Plugin 与 MCP 三种实现 Hermes Agent 安全架构:审批、沙箱、回滚与凭据隔离
View Comments