Hermes Agent 系统架构设计

Hermes Agent 系统架构设计

参考: 官方架构文档

源码版本: b63229016


一、设计理念

原则 实践
进程隔离 Gateway(平台集成)和 Dashboard(Web UI)完全独立进程,各自独立启停重启
协议兼容 API Server 对外暴露 OpenAI 兼容接口,任意 OpenAI 生态工具均可接入
插件化平台 Messaging Platform(TG/Discord/Teams 等)以 adapter 形式接入 Gateway
会话持久化 SQLite WAL 模式保证 ResponseStore 和 SessionDB 重启不丢
平台无关核心 一个 AIAgent 类同时服务于 CLI、Gateway、ACP、Batch 和 API Server
可观测执行 每个 tool call 均通过回调对用户可见
可中断 API 调用和 tool 执行均可被用户输入或信号中途取消

二、整体进程架构

复制代码
┌─────────────────────────────────────────────────────────────────────┐
│                         三大入口                                      │
│                                                                      │
│  hermes dashboard        hermes gateway run         hermes run        │
│  (独立进程 :9119)       (Gateway 进程内 :8642)    (独立进程 TUI)     │
│  FastAPI + React SPA    APIServerAdapter 共用      stdin/stdout      │
│                         Gateway 进程                            │
└──────────────┬─────────────────┬─────────────────┬───────────────────┘
               │                 │                 │
               │ HTTP/REST       │ OpenAI HTTP     │ interactive
               │ Bearer token    │ Bearer token    │ TUI
               │                 │                 │
┌──────────────▼────┐  ┌────────▼────────┐  ┌─────▼──────────────┐
│   Dashboard        │  │  API Server     │  │   TUI              │
│   hermes          │  │  (APIServer     │  │   hermes run       │
│  dashboard        │  │   Adapter)      │  │                    │
│  :9119            │  │  :8642          │  │  hermes_cli/       │
│  FastAPI          │  │  共用 Gateway   │  │  main.py           │
│  web_server.py   │  │  AIAgent 实例   │  │                    │
└───────────────────┘  └───────┬────────┘  └────────────────────┘
                                │
                    ┌───────────▼───────────┐
                    │      Gateway 主进程      │
                    │   gateway/run.py       │
                    │                        │
                    │  PlatformRegistry      │
                    │  AIAgent(共享实例)    │
                    │  SessionDB            │
                    │  CronScheduler         │
                    │  Platform Adapters:    │
                    │   Telegram, Discord,   │
                    │   API Server (:8642),  │
                    │   Dashboard (:9119)... │
                    └───────────────────────┘

关键设计 : API Server 是 Gateway 主进程内的 adapter(APIServerAdapter),与 Telegram/Discord adapter 并列运行,共享同一个 AIAgent 实例。Dashboard 是完全独立进程,不依赖 Gateway。


三、核心组件

3.1 AIAgent(run_agent.py)

核心对话引擎,处理 provider 选择、prompt 构建、tool 执行、重试、回退、回调、压缩和持久化。

复制代码
AIAgent.run_conversation()
  ├── prompt_builder.build_system_prompt()
  │     └── 组装: personality + memory + skills + context files + tool guidance
  ├── runtime_provider.resolve_runtime_provider()
  ├── API call(chat_completions / codex_responses / anthropic_messages)
  ├── tool_calls? → model_tools.handle_function_call() → loop
  └── final response → display → save to SessionDB

3.2 HermesCLI(cli.py

交互式终端 UI,包含完整的 TUI 实现(多行编辑、斜杠命令自动补全、对话历史、中断重定向、流式 tool 输出)。

3.3 Gateway(gateway/run.py)

消息平台集成中枢,管理 20 个 platform adapters:

平台 路径
Telegram, Discord, Slack, WhatsApp, Signal gateway/platforms/
Matrix, Mattermost, Email, SMS gateway/platforms/
DingTalk, Feishu, WeCom, Weixin, QQBot gateway/platforms/
HomeAssistant, Webhook, API Server, Yuanbao gateway/platforms/

3.4 APIServerAdapter(gateway/platforms/api_server.py)

OpenAI 兼容 HTTP API,通过 aiohttp 实现,监听 :8642。是 Gateway 进程内的协程,与其他 platform adapter 并列。


四、API Server 架构

4.1 源码结构

复制代码
gateway/platforms/api_server.py   2,933 行
    │
    ├── APIServerAdapter         主类
    │     ├── setup_routes()     路由注册(第 2810-2831 行)
    │     ├── _check_auth()       Bearer token 认证
    │     └── start()/stop()      aiohttp AppRunner 生命周期
    │
    ├── IdempotencyCache         10 分钟请求去重
    │
    ├── ResponseStore            SQLite WAL 持久化
    │     ├── get() / put() / delete()
    │     ├── get_conversation()  按 session name 反查
    │     └── 上限 100 条,LRU 淘汰
    │
    └── _RunManager              Runs API 异步任务
          ├── _run_statuses      {run_id: status}
          ├── _run_events        {run_id: asyncio.Queue}
          └── _run_threads       {run_id: Thread}

4.2 路由注册

python 复制代码
# gateway/platforms/api_server.py 第 2810-2831 行
self._app.router.add_get("/health",                       self._handle_health)
self._app.router.add_get("/health/detailed",              self._handle_health_detailed)
self._app.router.add_get("/v1/health",                   self._handle_health)
self._app.router.add_get("/v1/models",                   self._handle_models)
self._app.router.add_get("/v1/capabilities",             self._handle_capabilities)
self._app.router.add_post("/v1/chat/completions",        self._handle_chat_completions)
self._app.router.add_post("/v1/responses",              self._handle_responses)
self._app.router.add_get("/v1/responses/{response_id}", self._handle_get_response)
self._app.router.add_delete("/v1/responses/{response_id}", self._handle_delete_response)
self._app.router.add_get("/api/jobs",                   self._handle_list_jobs)
self._app.router.add_post("/api/jobs",                  self._handle_create_job)
self._app.router.add_get("/api/jobs/{job_id}",          self._handle_get_job)
self._app.router.add_patch("/api/jobs/{job_id}",         self._handle_update_job)
self._app.router.add_delete("/api/jobs/{job_id}",        self._handle_delete_job)
self._app.router.add_post("/api/jobs/{job_id}/pause",    self._handle_pause_job)
self._app.router.add_post("/api/jobs/{job_id}/resume",   self._handle_resume_job)
self._app.router.add_post("/api/jobs/{job_id}/run",      self._handle_run_job)
self._app.router.add_post("/v1/runs",                    self._handle_runs)
self._app.router.add_get("/v1/runs/{run_id}",           self._handle_get_run)
self._app.router.add_get("/v1/runs/{run_id}/events",   self._handle_run_events)
self._app.router.add_post("/v1/runs/{run_id}/stop",     self._handle_stop_run)

4.3 三协议对比

维度 Chat Completions Responses API Runs API
协议 OpenAI 兼容 OpenAI 兼容 OpenAI 兼容
状态 无状态 有状态(previous_response_id 异步任务(queued/running/completed/failed/cancelled
持久化 SQLite ResponseStore 否(内存状态,仅 SSE 可追踪)
流式 SSE 可选 否(一次性返回) SSE(必须)
会话保持 X-Hermes-Session-Id header previous_response_id / conversation input 中带 session
适用场景 简单请求/响应 多轮对话保持上下文 长时间运行,客户端订阅事件

4.4 Runs API 详细流程

复制代码
客户端                      APIServerAdapter
  │                               │
  │──POST /v1/runs─────────────▶│  分配 run_id,状态=queued→running
  │◀──202 {"run_id":"..."}──────│  立即返回(不等 AI 完成)
  │                               │
  │──GET /v1/runs/{id}/events───▶│  建立 SSE 连接
  │◀─event: run.started ─────────│
  │◀─event: tool.started ─────────│
  │◀─event: message.delta ────────│
  │◀─event: tool.completed ──────│
  │◀─event: run.completed ───────│  最终结果
  │                               │
  │──POST /v1/runs/{id}/stop────▶│  中断 run
  │◀─event: run.cancelled ───────│

状态机 : queuedrunningcompleted / failed / cancelled

4.5 认证机制

python 复制代码
def _check_auth(self, request):
    # 1. 未配置 key -> 允许(仅限本地开发)
    if not self._api_key:
        return None

    # 2. Authorization: Bearer <token>
    auth = request.headers.get("Authorization", "")
    if auth.startswith("Bearer "):
        token = auth[7:].strip()
        if hmac.compare_digest(token, self._api_key):
            return None  # OK

    # 3. 返回 401
    return web.json_response({"error": {...}}, status=401)
  • /health 系列端点无需认证
  • 其他所有端点强制认证(已配置 key 时)
  • 使用 hmac.compare_digest 防止时序攻击

五、Dashboard 架构

5.1 组件关系

复制代码
hermes dashboard(独立进程 :9119)
    │
    ├── hermes_cli/web_server.py   FastAPI 后端(4,062 行)
    │     ├── _SESSION_TOKEN       每进程随机(secrets.token_urlsafe(32))
    │     ├── auth_middleware      Bearer token 验证
    │     ├── REST API 端点         /api/*
    │     └── WebSocket            /api/pty(xterm.js PTY bridge)
    │
    └── hermes_cli/web_dist/       React SPA(npm build 产物)
          ├── index.html           内嵌 <script>window.__HERMES_TOKEN__
          └── assets/              JS + CSS bundles

5.2 认证流程

复制代码
SPA 加载
    ├── GET / → HTML 中内嵌 <script>window.__HERMES_TOKEN__="xxx"
    ├── JS 读取 token
    └── 后续所有 /api/* 请求
          Header: Authorization: Bearer <token>
                │
                ▼
          auth_middleware()
            hmac.compare_digest(auth, f"Bearer {_SESSION_TOKEN}")
                ├── 匹配 ──► 处理请求
                └── 不匹配 ─► 401 Unauthorized

注意: Dashboard 的 _SESSION_TOKEN每进程随机 ,与 API Server 的 API_SERVER_KEY.env)完全独立。

5.3 PTY Bridge(嵌入式 TUI)

复制代码
浏览器(xterm.js)
    │
    │ WebSocket /api/pty
    ▼
web_server.py: pty_bridge()
    │
    ├──► Python PTY(subprocess)
    │           └──► hermes run(stdin/stdout)
    │
    └──► WebSocket 回传 PTY 输出到 xterm.js

5.4 前端技术栈

层级 技术
框架 React 19 + TypeScript
构建 Vite
样式 Tailwind CSS v4 + shadcn/ui 风格组件
状态 React Context + Hooks
终端模拟 xterm.js + WebGL 渲染
插件 SDK window.__HERMES_PLUGIN_SDK__(不捆绑 React)

5.5 Dashboard 插件系统

复制代码
~/.hermes/plugins/<name>/
├── plugin.yaml              CLI/Gateway 插件清单
├── __init__.py              CLI/Gateway hooks
└── dashboard/               Dashboard 扩展(可选)
    ├── manifest.json         插件配置(tab、slots、entry)
    ├── dist/
    │   ├── index.js         预编译 JS bundle(IIFE,无构建步骤)
    │   └── style.css        自定义 CSS(可选)
    └── plugin_api.py        后端 FastAPI 路由(可选)

插件通过 window.__HERMES_PLUGINS__.register(name, Component) 注册,不捆绑 React,通过 SDK 访问。

5.6 Shell Slots

Slot 位置
header-left / header-right 顶部栏左右侧
sidebar 驾驶舱侧边栏(仅 layoutVariant: cockpit 时渲染)
sessions:top / sessions:bottom Sessions 页面顶部/底部
analytics:top / analytics:bottom Analytics 页面顶部/底部
cron:top / cron:bottom Cron 页面顶部/底部
config:top / config:bottom Config 页面顶部/底部

六、数据流设计

6.1 配置读取层级

复制代码
hermes config set xxx
    │
    ▼
~/.hermes/config.yaml
    │
    ├──► Dashboard (web_server.py)
    │           └── 直接读取 YAML
    │
    └──► Gateway (gateway/run.py)
                └── 通过 HermesConfig 类读取
                          │
                          └──► AIAgent / PlatformAdapter

6.2 会话持久化

复制代码
~/.hermes/state.db  (SQLite WAL)
    │
    ├──► SessionDB
    │         │
    │         ├──► Gateway(所有 platform adapter 共享)
    │         │
    │         └──► API Server(/v1/responses 等)
    │
    └── ~/.hermes/response_store.db
              │
              └──► ResponseStore(API Server 专属)
                        │
                        └──► /v1/responses 持久化(上限 100 条,LRU)

七、安全模型

7.1 认证矩阵

服务 端点 认证方式 无 key 行为
API Server /health 系列 允许
API Server 其他所有 API_SERVER_KEY.env 拒绝(401)
Dashboard /api/* _SESSION_TOKEN(每进程随机) 不适用(key 必然存在)
Dashboard 静态资源(/ 允许

7.2 密钥存储原则

复制代码
~/.hermes/.env         API Keys、Tokens(敏感)
~/.hermes/config.yaml  平台开关、行为配置(非敏感)

7.3 CORS 策略

  • API Server : 默认不启用 CORS。直接浏览器访问需设置 API_SERVER_CORS_ORIGINS
  • Dashboard : 仅允许 localhost / 127.0.0.1 来源

八、目录结构

复制代码
hermes-agent/
├── run_agent.py              # AIAgent --- 核心对话循环(~13,700 行)
├── cli.py                    # HermesCLI --- 交互终端 UI(~11,500 行)
├── model_tools.py            # Tool 发现、schema 收集、分发
├── toolsets.py               # Tool 分组和平台预设
├── hermes_state.py           # SQLite session/state 数据库 + FTS5
├── hermes_constants.py       # HERMES_HOME、profile 路径
├── batch_runner.py           # 批量轨迹生成
│
├── agent/                    # Agent 内部模块
│   ├── prompt_builder.py     # System prompt 组装
│   ├── context_engine.py     # ContextEngine 抽象类(可插拔)
│   ├── context_compressor.py # 上下文压缩(默认有损摘要)
│   ├── prompt_caching.py     # Anthropic prompt caching
│   ├── auxiliary_client.py   # 辅助 LLM(视觉、摘要)
│   └── model_metadata.py     # 模型上下文长度、token 估算
│
├── hermes_cli/               # CLI 子命令
│   ├── main.py               # 入口 --- 所有 `hermes` 子命令(~10,400 行)
│   ├── config.py             # DEFAULT_CONFIG、OPTIONAL_ENV_VARS、迁移
│   ├── commands.py           # COMMAND_REGISTRY --- 斜杠命令定义
│   ├── auth.py              # PROVIDER_REGISTRY、凭证解析
│   ├── setup.py             # 交互式设置向导(~3,500 行)
│   ├── web_server.py         # Dashboard FastAPI 后端(4,062 行)
│   └── web_dist/            # React SPA 构建产物
│
├── gateway/                  # 消息平台网关
│   ├── run.py               # GatewayRunner --- 消息分发(~12,200 行)
│   ├── session.py            # SessionStore --- 对话持久化
│   └── platforms/            # 20 个 adapter: telegram, discord, api_server 等
│
├── tools/                    # Tool 实现
│   ├── registry.py          # 中心 tool 注册表(61 个 tools)
│   ├── terminal_tool.py      # 终端编排
│   ├── browser_tool.py       # 浏览器自动化
│   ├── mcp_tool.py          # MCP 客户端(~3,100 行)
│   └── environments/         # 终端后端(local、docker、ssh、modal 等 7 种)
│
├── cron/                     # 调度器
├── acp_adapter/              # ACP 服务端(VS Code / Zed / JetBrains)
├── plugins/                  # 插件(memory、context_engine 等)
├── skills/                   # 内置 skills
└── website/docs/             # 官方文档站

九、版本变化要点(v0.12.0)

变化 说明
API Server 三协议 Chat Completions / Responses API / Runs API 完整实现
会话持久化 SQLite WAL 模式,ResponseStore + SessionDB 重启不丢
Runs API 202 即返回 + SSE 事件流 + run_id 轮询 + 并发控制(10)
Dashboard 认证 每进程随机 _SESSION_TOKEN,Bearer token 中间件验证
插件化 Platform 动态 PlatformRegistry,adapter 按需加载
Dashboard 主题 6 种内置主题 + YAML 自定义主题 + 驾驶舱布局
TTS Provider 可插拔 TTS provider registry
冷启动优化 TUI 冷启动削减约 57%
相关推荐
一切皆是因缘际会9 小时前
从概率拟合到内生心智:2026 下一代 AI 架构演进与落地实践
人工智能·深度学习·算法·架构
科研前沿9 小时前
镜像视界 CameraGraph™+多智能体:构建自感知自决策的全域空间认知网络技术方案
大数据·运维·人工智能·数码相机·计算机视觉
爱学习的张大9 小时前
具身智能论文问答(2):Diffusion Policy
人工智能
AI科技星9 小时前
全域数学·72分册·射影原本 无穷维射影几何卷细化子目录【乖乖数学】
人工智能·线性代数·算法·机器学习·数学建模·数据挖掘·量子计算
Chef_Chen9 小时前
论文解读:MemOS首次把记忆变成大模型的一等公民资源,Scaling Law迎来第三条曲线
人工智能·agent·memory
风落无尘9 小时前
《智能重生:从垃圾堆到AI工程师》——第四章 变化的艺术
人工智能·线性代数·算法
发哥来了9 小时前
AI视频生成模型选型指南:五大核心维度对比评测
大数据·人工智能·机器学习·ai·aigc
发哥来了9 小时前
AI驱动生产线的实际落地:一个东莞厂商的技术选型实录
大数据·人工智能·机器学习·ai·aigc
AC赳赳老秦9 小时前
知识产权辅助:用 OpenClaw 批量生成专利交底书 / 软著申请材料,自动校验格式与内容合规性
java·人工智能·python·算法·elasticsearch·deepseek·openclaw