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 ───────│

状态机 : queued → running → completed / 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%
相关推荐
2501_938140072 小时前
做内容很省心,2026好用AI笔记,支持抖音小红书视频无水印保存
人工智能
sell-cloud4 小时前
Prompt Engineering要凉了?Fable 5.5能“猜“意图,但银行正在封杀AI Agent——企业AI的真正护城河是什么
人工智能·prompt
Navicat中国6 小时前
Navicat 18 内置 AI 助手让数据库开发从繁琐操作迈向智能协作
大数据·人工智能·数据库开发
4SAPI6 小时前
多模型请求路由怎么设计?成本、速度和能力如何平衡
人工智能·python·gateway·php
魔乐社区6 小时前
翼芯・智算测试与适配优化专区,让国产算力“选得准、跑得通、用得好“
人工智能·开源·大模型
XCDoris8 小时前
郴州logo设计机构
大数据·人工智能·python
Goboy8 小时前
一个人带三个Agent,我用全新TRAE从0到1搭了个资讯周刊站
人工智能·trae
俊哥V9 小时前
每日 AI 研究简报 · 2026-10-19
人工智能·ai
AI_AGENT_DEV_AI9 小时前
AI英语教培智能体的开发
人工智能
物联网软硬件开发-轨物科技9 小时前
【技术白皮书】光伏清检一体化机器人系统解决方案技术白皮书
大数据·运维·网络·人工智能·机器人