znlgis 博客

GIS开发与技术分享

第二章:整体架构与核心组件

理解 Hermes Agent 最高效的方式,是先看它的”系统总图”,再逐个拆解。本章用 Hermes 官方架构文档(developer-guide/architecture.mdagent-loop.mdprompt-assembly.mdsession-storage.mdtools-runtime.mdgateway-internals.mdprovider-runtime.md)所揭示的真实代码结构,重新组织出一份对中文读者更友好的全景视图。

2.1 系统总图

Hermes 的整体架构可以抽象为如下分层:

┌─────────────────────────────────────────────────────────────────────┐
│                          入口层(Entry Points)                       │
│                                                                      │
│  CLI (cli.py)       Gateway (gateway/run.py)      ACP (acp_adapter/) │
│  Batch Runner       API Server                    Python Library     │
└──────────┬──────────────┬───────────────────────┬───────────────────┘
           │              │                       │
           ▼              ▼                       ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  Agent 核心(AIAgent,run_agent.py)                  │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐               │
│  │ Prompt       │  │ Provider     │  │ Tool         │               │
│  │ Builder      │  │ Resolution   │  │ Dispatch     │               │
│  │ (prompt_     │  │ (runtime_    │  │ (model_      │               │
│  │  builder.py) │  │  provider.py)│  │  tools.py)   │               │
│  └──────┬───────┘  └──────┬───────┘  └──────┬───────┘               │
│         │                 │                 │                       │
│  ┌──────┴───────┐  ┌──────┴───────┐  ┌──────┴───────┐               │
│  │ Compression  │  │ 3 API Modes  │  │ Tool Registry│               │
│  │ & Caching    │  │ chat_compl.  │  │ (registry.py)│               │
│  │              │  │ codex_resp.  │  │ 68 tools     │               │
│  │              │  │ anthropic    │  │ 52 toolsets  │               │
│  └──────────────┘  └──────────────┘  └──────────────┘               │
└─────────┴─────────────────┴─────────────────┴───────────────────────┘
           │                                    │
           ▼                                    ▼
┌───────────────────┐              ┌──────────────────────┐
│ 会话存储           │              │ 工具后端              │
│ Session Storage   │              │ Tool Backends         │
│ (SQLite + FTS5)   │              │ Terminal (7 backends) │
│ hermes_state.py   │              │ Browser (5 backends)  │
│ gateway/session.py│              │ Web (4 backends)      │
└───────────────────┘              │ MCP (动态)            │
                                   │ File / Vision / ...   │
                                   └──────────────────────┘

可以看到,Hermes 是典型的 “多入口 → 单一 Agent 核心 → 多种后端” 架构:无论你从 CLI、Telegram bot、API Server、ACP IDE 还是 Python 库调用,最终都汇入 AIAgent 这个核心对象,由它统一编排”提示词构建、Provider 选择、工具调度、会话持久化”。

2.2 仓库目录速览

理解架构最好的辅助是熟悉仓库目录。这里给出一份精简版的目录解读:

hermes-agent/
├── run_agent.py              # AIAgent —— 核心对话循环(约 13,700 行)
├── cli.py                    # HermesCLI —— 交互式终端 UI(约 11,500 行)
├── model_tools.py            # 工具发现、schema 收集、调度
├── toolsets.py               # 工具分组与平台预设
├── hermes_state.py           # SQLite 会话/状态库(带 FTS5)
├── hermes_constants.py       # HERMES_HOME、profile-aware 路径
├── batch_runner.py           # 批量轨迹生成
│
├── agent/                    # Agent 内部
│   ├── prompt_builder.py     # 系统提示拼装
│   ├── context_engine.py     # ContextEngine 抽象(可插拔)
│   ├── context_compressor.py # 默认引擎:有损摘要
│   ├── prompt_caching.py     # Anthropic prompt caching
│   ├── auxiliary_client.py   # 辅助 LLM(视觉、摘要、压缩)
│   ├── model_metadata.py     # 模型上下文长度、token 估算
│   ├── models_dev.py         # models.dev 注册表
│   ├── anthropic_adapter.py  # Anthropic Messages API 适配
│   ├── display.py            # KawaiiSpinner、工具预览渲染
│   ├── skill_commands.py     # 技能斜杠命令
│   ├── memory_manager.py     # 记忆管理编排
│   ├── memory_provider.py    # 记忆 Provider 抽象基类
│   └── trajectory.py         # 轨迹保存
│
├── hermes_cli/               # CLI 子命令与 setup
│   ├── main.py               # 入口:所有 `hermes` 子命令(约 10,400 行)
│   ├── config.py             # DEFAULT_CONFIG、OPTIONAL_ENV_VARS、迁移
│   ├── commands.py           # COMMAND_REGISTRY —— 集中式斜杠命令定义
│   ├── auth.py               # PROVIDER_REGISTRY、凭据解析
│   ├── runtime_provider.py   # Provider → api_mode + credentials
│   ├── models.py             # 模型目录、各家模型列表
│   ├── model_switch.py       # /model 命令逻辑(CLI 与 gateway 共享)
│   ├── setup.py              # 交互式 setup 向导(约 3,500 行)
│   ├── skin_engine.py        # CLI 主题引擎(皮肤)
│   ├── skills_config.py      # hermes skills —— 按平台启用/禁用
│   ├── skills_hub.py         # /skills 斜杠命令
│   ├── tools_config.py       # hermes tools —— 按平台启用/禁用
│   ├── plugins.py            # PluginManager:插件发现、加载、hook
│   ├── callbacks.py          # 终端回调(澄清、sudo、审批)
│   └── gateway.py            # hermes gateway start/stop
│
├── tools/                    # 工具实现(每个工具一个文件)
│   ├── registry.py           # 中央工具注册表
│   ├── approval.py           # 危险命令检测
│   ├── terminal_tool.py      # 终端编排
│   ├── process_registry.py   # 后台进程管理
│   ├── file_tools.py         # read_file、write_file、patch、search_files
│   ├── web_tools.py          # web_search、web_extract
│   ├── browser_tool.py       # 10 个浏览器自动化工具
│   ├── code_execution_tool.py # execute_code 沙箱
│   ├── delegate_tool.py      # 子代理委派
│   ├── mcp_tool.py           # MCP 客户端(约 3,100 行)
│   ├── credential_files.py   # 文件型凭据透传
│   ├── env_passthrough.py    # 环境变量透传到沙箱
│   ├── ansi_strip.py         # ANSI 转义清理
│   └── environments/         # 终端后端(local、docker、ssh、modal、daytona、singularity)
│
├── gateway/                  # 消息网关
│   ├── run.py                # GatewayRunner:消息分发(约 12,200 行)
│   ├── session.py            # SessionStore:对话持久化
│   ├── delivery.py           # 出站消息投递
│   ├── pairing.py            # DM 配对授权
│   ├── hooks.py              # Hook 发现与生命周期事件
│   ├── mirror.py             # 跨会话消息镜像
│   ├── status.py             # token 锁、profile 进程跟踪
│   └── platforms/            # 20 个平台 adapter:telegram、discord、slack、whatsapp 等
│
├── acp_adapter/              # ACP(Agent Client Protocol)适配器,VS Code/Zed/JetBrains
├── acp_registry/             # ACP 注册表
├── plugins/                  # 内置/示例插件(含 memory provider 示例)
├── skills/                   # 内置技能集
├── optional-skills/          # 可选官方技能集
├── cron/                     # cron 调度器实现
├── scripts/                  # 安装、构建、运行测试脚本
├── docker/                   # docker 沙箱镜像与脚本
├── environments/             # Atropos RL 环境
├── gateway-* / web / website # 文档站、Web Dashboard、TUI 等
├── pyproject.toml            # 包定义、可选依赖([all]/[voice]/[messaging]/[mcp]/[tts-premium] 等)
└── setup-hermes.sh           # 一键开发者初始化

不必死记,但建议你在浏览源码或排错时随手对照这份地图。

2.3 入口层:六种调用方式

Hermes 不是单一形态。它通过六种入口对外提供同一个 AIAgent

2.3.1 CLI 与 TUI(cli.py)

最常用的入口。hermes 启动一个交互式终端,特性包括:

  • 多行输入、/ 斜杠命令补全;
  • 流式输出,工具调用实时预览;
  • Ctrl+C 打断;可以”边打断边发新消息”调整方向;
  • KawaiiSpinner 等可换皮肤的视觉元素;
  • /model/personality/new/reset/compress/usage/insights/skills/<skill-name>/rollback/checkpoint/cron/kanban 等几十条斜杠命令。

2.3.2 Gateway(gateway/run.py)

hermes gateway start 启动一个独立进程,把同一个 Agent 暴露给:Telegram、Discord、Slack、WhatsApp、Signal、Matrix、Mattermost、Email、SMS、企业微信、飞书、钉钉、QQ、Yuanbao、Open WebUI、Webhooks、Home Assistant 等。每个平台都是 gateway/platforms/<name>.py,遵循统一 adapter 接口。

2.3.3 ACP Adapter(acp_adapter/)

ACP 是 Agent Client Protocol,被 VS Code、Zed、JetBrains 等编辑器原生支持。Hermes 的 ACP Adapter 让你在 IDE 里通过 ACP 协议跟 Hermes 对话,工具调用、文件 diff、终端命令都渲染在 IDE 内。

2.3.4 API Server

hermes api start 暴露一个 OpenAI-compatible HTTP 端点;任何兼容 OpenAI Chat API 的前端(Open WebUI、LobeChat、LibreChat、ChatBox 等)都能直接接到 Hermes,等于把 Hermes 当成”你的私有 ChatGPT”。

2.3.5 Batch Runner(batch_runner.py)

hermes batch run 在大量 prompt 上并行跑 Agent,输出结构化的 ShareGPT-format 轨迹数据,主要用于训练数据生成与评测。

2.3.6 Python Library

可直接 from run_agent import AIAgent 在 Python 程序里使用 Hermes:

from run_agent import AIAgent

agent = AIAgent(model="anthropic/claude-opus-4.6")
print(agent.chat("帮我把这个 CSV 转成 SQL INSERT 语句"))

详情见 guides/python-library.md

2.4 Agent 核心:AIAgent

run_agent.py 中的 AIAgent 是 Hermes 的”心脏”。它的职责包括:

  • 通过 prompt_builder.py 拼装系统提示与工具 schema;
  • 选择合适的 Provider 与 API 模式(chat_completions / codex_responses / anthropic_messages);
  • 发起 可中断 的模型调用(_interruptible_api_call,支持随时打断);
  • 顺序或并发执行工具调用(带线程池);
  • 维护 OpenAI 格式的对话历史;
  • 执行压缩、重试、Provider 故障切换;
  • 跟踪父子 Agent 的迭代预算;
  • 在上下文耗尽前把记忆持久化。

2.4.1 三种 API 模式

API mode 用于 客户端
chat_completions OpenAI 兼容端点(OpenRouter、自定义、绝大多数供应商) openai.OpenAI
codex_responses OpenAI Codex / Responses API openai.OpenAI(Responses 格式)
anthropic_messages Anthropic 原生 Messages API anthropic.Anthropic(带 adapter)

模式选择优先级:构造参数 > Provider 检测 > base URL 启发式 > 默认 chat_completions。三种模式的消息编码、工具调用结构、流式与缓存机制都不同,但内部统一收敛为 OpenAI 风格的 role/content/tool_calls 字典。

2.4.2 Turn 生命周期

run_conversation()
  1. 生成 task_id(若未提供)
  2. 把用户消息追加到历史
  3. 拼装或复用缓存的系统提示(prompt_builder.py)
  4. 检查是否需要预压缩(>50% 上下文)
  5. 把对话历史编码为目标 API 的 messages
  6. 注入 ephemeral 提示层(预算告警、上下文压力)
  7. 给 Anthropic 打 prompt cache 标记
  8. 调用 _interruptible_api_call
  9. 解析响应:
     - 若有 tool_calls → 执行 → 追加结果 → 回到步骤 5
     - 若是文本响应 → 持久化会话 → 必要时 flush 记忆 → 返回

2.4.3 消息交替规则

Hermes 严格执行 OpenAI / Anthropic 都接受的消息交替:

  • 系统消息后:User → Assistant → User → Assistant → ...
  • 工具调用阶段:Assistant(with tool_calls) → Tool → Tool → ... → Assistant
  • 永远不允许两条连续 assistant
  • 永远不允许两条连续 user
  • 只有 tool 角色可以连续(并行工具结果)。

错误的交替会被 Provider 直接拒绝。

2.5 Prompt 构建:prompt_builder.py

系统提示由若干”槽位”组成,按固定顺序拼装。每个槽位都有清晰职责,便于”按需开关”:

  1. Identity(身份):来自 ~/.hermes/SOUL.md(若存在)或内置默认;
  2. Personality(可选):当前 /personality 指定的 preset;
  3. MEMORY(环境/工作约定):来自 ~/.hermes/memories/MEMORY.md,约 800 token;
  4. USER PROFILE(用户画像):来自 ~/.hermes/memories/USER.md,约 500 token;
  5. Context Files:自动发现项目级 .hermes.mdAGENTS.mdCLAUDE.md.cursorrules 等;
  6. Tool Schemas:当前启用 toolset 的工具描述;
  7. Skills Index(progressive disclosure 的 Level 0){name, description, category} 列表,约 3k token;
  8. Ephemeral Layers:上下文预算警告、压缩提示等。

记忆与身份采用 冻结快照(frozen snapshot) 模式:会话开始时一次注入,期间即便 Agent 改了文件也不变更系统提示,以保留 Anthropic prefix cache 的命中率。Tool Response 中始终能看到最新值。

2.6 Provider Runtime:模型选择与故障切换

hermes_cli/runtime_provider.py + agent/auxiliary_client.py 协同决定每次调用走哪家:

  • Provider Routing:你可以把多家 Provider 排序成优先级链;
  • Fallback Providers:主 Provider 报错(限流/网络/5xx)时自动切到下一家;视觉、压缩等辅助任务可以走单独的 fallback;
  • Credential Pool:同一家 Provider 可挂多把 Key,按 round-robin / 限流自动轮换;
  • Auxiliary Client:耗 token 大的”次要任务”(视觉描述、长 chat 摘要、压缩)允许走更便宜/更快的辅助模型,主对话依然用旗舰模型。

第五章会展开这一切的具体配置。

2.7 工具运行时:model_tools.py + tools/registry.py

工具系统由三层组成:

  1. Registrytools/registry.py 集中注册全部工具,每个工具是一个 Python 函数 + JSON Schema;
  2. Toolsetstoolsets.py 把工具按用途分组(webterminalfilebrowsermemorydelegation 等共 52 组);同时维护 平台预设hermes-clihermes-telegramhermes-discordhermes-wecom 等),定义”在某平台默认开哪些组”;
  3. Dispatchmodel_tools.py 在每次推理前把当前启用的工具 schema 收集起来作为可用工具列表,模型返回 tool_calls 后再调度执行。

工具执行支持 并发(tool_concurrency审批回调(approval:危险命令(rm -rf /、改 /etc 等)会触发 tools/approval.py 的检测,CLI 用户会看到一个”是否允许”的 prompt;Gateway 用户可以接到 DM 配对授权流程。

终端工具特别值得一提:它支持 7 种后端

Backend 描述 典型场景
local 本地 shell 个人开发机
docker 本地 / 远程 docker 容器 沙箱、隔离
ssh 远端 SSH 操控生产/服务器
daytona Daytona Serverless 工作空间 空闲 0 成本
modal Modal serverless 同上,且自动 scale
singularity HPC Singularity 容器 大学/超算
tmux* 内嵌 tmux 会话视图 长进程观察

切换只需 hermes config set terminal.backend docker 这一条命令,第六章会详细介绍。

2.8 会话存储:hermes_state.py + gateway/session.py

Hermes 使用单一 SQLite 数据库 ~/.hermes/hermes.db 存储:

  • 每条对话历史(与 OpenAI 格式 1:1 对应,便于恢复);
  • 任务(task_id)、迭代、token usage、cost;
  • 工具调用日志、轨迹;
  • Skills 元数据;
  • Cron 任务与执行历史;
  • Kanban 任务(独立 DB kanban.db)。

并启用 FTS5 全文索引,让 session_search 工具可以快速检索”上次我修过哪个 bug”。Gateway 自己也维护一份 gateway/session.py 中的 SessionStore,多平台对话与 Profile 相互隔离。

2.9 学习闭环:Memory + Skills + Curator + Honcho

这套 Hermes 引以为傲的”自我提升”机制由 4 个协作模块构成:

  • Memory Manager(agent/memory_manager.py:编排记忆读写,向 Agent 暴露 memory(action=add|replace|remove, target=memory|user, content=...) 工具;
  • Skills Manager(hermes_cli/skills_config.py + skills/:管理 ~/.hermes/skills/ 下的所有技能;自动把每个技能注册成 /<skill-name> 斜杠命令;进度披露式加载(Level 0 索引 → Level 1 全文 → Level 2 引用文件);
  • Curator(user-guide/features/curator.md:周期性”提示” Agent 整理记忆、搬运重要事实、识别可技能化的步骤;
  • Honcho Memory Provider(plugins/memory/honcho/:可选的辩证用户建模后端,把零散的”用户偏好”整合成更紧凑的 USER.md

第七章我们会详细讲怎么让 Agent 在你的工作流里”越用越聪明”。

2.10 Gateway 内部:多平台分发

Gateway 把消息平台和 Agent 解耦:

Telegram / Discord / Slack / WeCom / Feishu / DingTalk / ...
                ↓ Adapter 把平台事件统一为 GatewayMessage
        gateway/run.py 的 GatewayRunner(消息泵)
                ↓ 根据 conversation_id 找对应 SessionStore 的会话
              AIAgent.run_conversation(...)
                ↓ 文本/语音/图片附件 → 转成 OpenAI 格式
              gateway/delivery.py 出站投递
                ↓ 按平台 adapter 还原成 Telegram/Discord/Slack 的消息

关键能力:

  • DM Pairing:陌生人发起对话需要先经过授权(gateway/pairing.py),避免被滥用;
  • Cross-Session Mirrorgateway/mirror.py):在不同平台的对话之间镜像消息,实现”在 Telegram 跟它说话,在 Slack 也能看到上下文”;
  • Status / Token Lockgateway/status.py):避免同一个 Profile 被多个进程同时启动;
  • Hooks(gateway/hooks.py:基于 ~/.hermes/hooks/ 下的 HOOK.yaml + handler.py 监听 agent:start / agent:end / command:* 等生命周期事件。

第九章会逐条讲国内/国外平台的接入步骤。

2.11 自动化层:Cron、Kanban、Webhook

  • Croncron/ 模块独立维护一份调度表,每个 job 都跑在新 Agent 会话里;可以挂 0/1/N 个技能,可以指定结果投递目标(telegram://chat_id、wecom、邮件、文件等)。
  • Kanbanhermes kanban + kanban_* 工具组。多个命名 Profile 通过 SQLite 任务板协作,是 delegate_task 之外针对”持久化、可恢复、需要人介入”工作流的更重一档解法。
  • Webhook:Gateway 的 webhook 平台 adapter 可以接收外部事件(GitHub PR、Stripe、Slack action)并 trigger Hermes 任务,配合”PR Review Agent”等典型 guide 即可上手。

2.12 安全与隔离

Hermes 把”安全”作为一等公民:

  • 危险命令检测tools/approval.py 内置正则与模式集;用户可在 ~/.hermes/config.yaml 加白名单。
  • Container Isolation:Docker 后端默认运行用户级容器,--read-only--cap-drop=ALL 等可选。
  • DM Pairing:所有 IM 平台默认拒绝未授权 DM,只有显式配对的用户才能让 Agent 干活。
  • Credential Files:API Key、SSH key 通过 tools/credential_files.py 透传到沙箱,避免直接 export 到环境变量。

详细安全机制见 user-guide/security.md,本教程第十二章会做一份操作手册。

2.13 研究与训练:Atropos / Trajectory / Tinker

Hermes 把日常 Agent 跑出来的对话/工具调用直接当成 RL 训练数据:

  • batch_runner.py 跑大量 prompt,输出 ShareGPT/Trajectory;
  • environments/ 里实现了若干 Atropos 兼容的 RL 环境;
  • trajectory_compressor.py 提供轨迹压缩,便于训练;
  • tinker-atroposmini_swe_runner.py 等脚手架让研究者能直接基于 Hermes 训练新一代工具调用模型。

这一面对绝大多数最终用户不可见,但对模型团队/学术机构非常有价值;第十二章会简要介绍。

2.14 关键概念词典(Cheat Sheet)

最后给出几个高频概念的中文对照,本教程后续都会反复使用:

英文 中文 含义
AIAgent 智能体核心 run_agent.py 中那个对话循环对象
Provider 模型供应商 OpenRouter / Anthropic / OpenAI 等
API Mode API 模式 chat_completions / codex_responses / anthropic_messages
Toolset 工具集 工具的逻辑分组
Skill 技能 一段可复用步骤说明(SKILL.md
Memory / USER 记忆 / 用户画像 MEMORY.md / USER.md
Profile 配置剖面 一份完整的”身份 + 配置 + 数据”,可以并存多个
Backend 终端后端 local / docker / ssh / modal 等
Gateway 网关 多平台消息分发进程
Adapter 适配器 某个具体平台的接入实现
Hook 钩子 在生命周期事件上跑用户代码
Plugin 插件 给 Hermes 加工具/记忆 provider/上下文引擎
MCP Model Context Protocol 外部工具服务标准
ACP Agent Client Protocol IDE 与 Agent 协议
Curator 策展子系统 提醒 Agent 整理记忆与提炼技能
Trajectory 轨迹 一次会话的结构化日志
Kanban 看板 多 Profile 协作的 SQLite 任务板

2.15 本章小结

本章我们建立了 Hermes 架构的”心理模型”:

  1. 多入口、单核心、多后端的分层结构;
  2. AIAgent 是心脏,负责 Prompt、Provider、工具调度、会话;
  3. 三种 API 模式让它能跨 OpenAI/Codex/Anthropic 不变形使用工具;
  4. Prompt 由若干槽位拼成,记忆与技能通过 冻结快照进度披露 平衡 token 与新鲜度;
  5. Provider Runtime + Fallback + Credential Pool 解决”模型自由度”;
  6. 7 种 terminal backend 解决”运行环境自由度”;
  7. SQLite + FTS5 是会话与任务的统一存储;
  8. Memory + Skills + Curator + Honcho 形成 学习闭环
  9. Gateway 让 Hermes 同时在 15+ 平台上活着;
  10. Cron + Kanban + Webhook 把它升级成 自动化操作系统

下一章我们正式动手:在自己的机器上跑通 Hermes 的第一个会话。