深度拆解 HermesAgent(四):多终端后端与 Gateway 网关
系列导读:本文是 HermesAgent 深度拆解系列 的第四篇。HermesAgent 的一个独特设计是支持 6 种终端后端——你的命令不仅能在本地执行,还能在 Docker、SSH 远程服务器、Serverless 平台甚至 HPC 集群上运行。本文将深入分析这套多终端架构和 Gateway 消息网关。
一、为什么需要多终端后端?
大多数 AI Agent 的终端能力是"固定"的——要么只在本地执行,要么只用 Docker 沙箱。但现实场景远比这复杂:
| 场景 | 需要的后端 |
|---|---|
| 个人开发机上的脚本 | 本地终端 |
| 需要隔离环境的测试 | Docker 容器 |
| 操作远程服务器 | SSH 连接 |
| 短暂的计算任务 | Modal Serverless |
| 持久化的开发环境 | Daytona |
| 大规模科学计算 | HPC Singularity |
HermesAgent 的答案是:让 Agent 同时支持所有这些后端,用户可以随时切换。
二、六大终端后端
2.1 总览
┌─────────────────────────────────────────┐
│ Terminal Abstraction │
│ (terminal_tool.py) │
├────────┬────────┬────────┬────────┬─────┤
│ Local │ Docker │ SSH │ Modal │ ... │
│ │ │ │ │ │
└────┬───┴────┬───┴────┬───┴────┬───┴─────┘
│ │ │ │
┌──▼──┐ ┌──▼──┐ ┌──▼──┐ ┌──▼──┐
│你的 │ │容器 │ │远程 │ │云端 │
│电脑 │ │环境 │ │服务器│ │函数 │
└─────┘ └─────┘ └─────┘ └─────┘
所有后端实现位于 tools/environments/ 目录:
tools/environments/
├── base.py # 抽象基类 TerminalBackend
├── local.py # 本地终端
├── docker.py # Docker 容器
├── ssh.py # SSH 远程连接
├── modal.py # Modal Serverless 平台
├── daytona.py # Daytona 开发环境
└── singularity.py # HPC Singularity 容器
2.2 抽象基类设计
# tools/environments/base.py 简化示意
class TerminalBackend(ABC):
"""终端后端抽象基类"""
@abstractmethod
def is_available(self) -> bool:
"""检查该后端是否可用"""
...
@abstractmethod
async def execute(self, command: str, timeout: int = 300) -> TerminalResult:
"""在对应环境中执行命令"""
...
@abstractmethod
async def cleanup(self):
"""清理资源"""
...
2.3 各后端详解
Local(本地终端)
最直接的方式——在用户本机执行命令:
# tools/environments/local.py
class LocalBackend(TerminalBackend):
def is_available(self) -> bool:
return True # 始终可用
async def execute(self, command: str, timeout: int) -> TerminalResult:
process = await asyncio.create_subprocess_shell(
command,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
stdout, stderr = await asyncio.wait_for(
process.communicate(), timeout=timeout
)
return TerminalResult(
exit_code=process.returncode,
stdout=stdout.decode(),
stderr=stderr.decode(),
)
特点:零配置,但安全风险最高(直接操作用户机器)。
Docker(容器隔离)
# tools/environments/docker.py
class DockerBackend(TerminalBackend):
def is_available(self) -> bool:
return check_docker_installed()
async def execute(self, command: str, timeout: int) -> TerminalResult:
# 启动容器 → 执行命令 → 获取输出 → 清理容器
container = self.docker_client.containers.run(
image=self.image,
command=command,
detach=True,
mem_limit=self.memory_limit,
network_disabled=not self.network_enabled,
)
...
特点:沙箱隔离,可控的网络和内存限制,适合执行不可信代码。
SSH(远程执行)
# tools/environments/ssh.py
class SSHBackend(TerminalBackend):
def __init__(self, host: str, user: str, key_path: str = None):
self.host = host
self.user = user
self.key_path = key_path
async def execute(self, command: str, timeout: int) -> TerminalResult:
async with asyncssh.connect(
self.host, username=self.user,
client_keys=[self.key_path]
) as conn:
result = await conn.run(command, check=True)
return TerminalResult(
exit_code=result.exit_status,
stdout=result.stdout,
stderr=result.stderr,
)
特点:Agent 可以操作远程服务器,适合运维自动化场景。
Modal(Serverless)
# tools/environments/modal.py
class ModalBackend(TerminalBackend):
def is_available(self) -> bool:
return check_modal_installed()
async def execute(self, command: str, timeout: int) -> TerminalResult:
# 通过 Modal SDK 提交云端函数执行
# 自动处理容器编排、扩缩容、冷启动
...
特点:无需管理服务器,按使用计费,适合突发性计算任务。
Daytona(持久化开发环境)
# tools/environments/daytona.py
class DaytonaBackend(TerminalBackend):
"""Daytona 提供持久化的云端开发环境"""
# 类似 GitHub Codespaces 的体验
# 环境持久存在,不会因任务结束而销毁
...
特点:Serverless 但持久化,适合需要长期运行的开发环境。
Singularity(HPC 集群)
# tools/environments/singularity.py
class SingularityBackend(TerminalBackend):
"""HPC 集群上的 Singularity 容器"""
# 在超算/集群环境中运行 AI 任务
# 支持 GPU、MPI 等计算资源
...
特点:面向科学计算场景,这是其他 Agent 项目几乎不支持的。
2.4 后端切换
用户可以在运行时切换终端后端:
# 在 AIAgent 中配置
agent = AIAgent(
terminal_backend="docker", # 或 "local", "ssh", "modal", ...
docker_image="python:3.12",
)
或者在 CLI 中通过配置指定:
# ~/.hermes/config.yaml
terminal:
backend: docker
docker:
image: python:3.12-slim
memory_limit: "2g"
network: false
三、Gateway 消息网关
如果说终端后端是 Agent 的"手",那 Gateway 就是 Agent 的"耳朵和嘴巴"。
3.1 架构设计
┌──────────────────────────────────────┐
│ Gateway (run.py) │
│ │
│ ┌──────────┐ ┌──────────────────┐ │
│ │Slash Cmd │ │ Session Store │ │
│ │ Handler │ │ (持久化对话) │ │
│ └────┬─────┘ └────────┬─────────┘ │
│ │ │ │
│ ─────┴─────────────────┴── Core │
│ │ │
│ ┌─────────▼─────────┐ │
│ │ AIAgent Core │ │
│ │ (对话循环) │ │
│ └───────────────────┘ │
│ │
│ ┌──────────────────────────────┐ │
│ │ Platform Adapters │ │
│ │ (Telegram/Discord/Slack/...)│ │
│ └──────────────────────────────┘ │
└──────────────────────────────────────┘
3.2 支持的消息平台
| 平台 | 实现文件 | SDK |
|---|---|---|
| Telegram | gateway/platforms/telegram.py |
python-telegram-bot |
| Discord | gateway/platforms/discord.py |
discord.py |
| Slack | gateway/platforms/slack.py |
slack-bolt |
gateway/platforms/whatsapp.py |
baileys | |
| Signal | gateway/platforms/signal.py |
signal-cli |
| QQ Bot | gateway/platforms/qqbot.py |
QQ SDK |
| Home Assistant | gateway/platforms/homeassistant.py |
aiohttp |
| Matrix | 可选扩展 | mautrix |
| 邮件集成 | - | |
| DingTalk | 钉钉 | 钉钉 SDK |
| Feishu/Lark | 飞书 | 飞书 SDK |
3.3 平台适配器模式
每个平台适配器遵循统一接口:
class PlatformAdapter(ABC):
@abstractmethod
async def start(self):
"""启动平台监听"""
...
@abstractmethod
async def send_message(self, chat_id: str, text: str):
"""发送消息"""
...
@abstractmethod
def register_command_handler(self, handler: Callable):
"""注册消息处理回调"""
...
添加新平台只需实现这个接口并在 Gateway 中注册。
3.4 斜杠命令的统一处理
Gateway 中的斜杠命令与 CLI 共享同一套命令定义:
# hermes_cli/commands.py
COMMAND_REGISTRY = {
"skills": CommandDef("skills", "管理技能", "Skills"),
"model": CommandDef("model", "切换模型", "Model"),
"clear": CommandDef("clear", "清空对话", "Session"),
...
}
一处定义,处处可用:
- CLI 中输入
/skills→ CLI 处理 - Telegram 中发送
/skills→ Bot 菜单 + 消息处理 - Slack 中输入
/hermes skills→ Slack 子命令路由 - 自动补全 →
SlashCommandCompleter共享
3.5 Session 持久化
Gateway 的 session.py 实现了对话持久化:
class SessionStore:
def __init__(self, db_path: str):
self.db = SessionDB(db_path)
async def get_or_create_session(self, chat_id: str) -> Session:
"""获取或创建会话"""
session = await self.db.get_session(chat_id)
if not session:
session = await self.db.create_session(chat_id)
return session
async def append_message(self, chat_id: str, message: dict):
"""追加消息到会话"""
await self.db.add_message(chat_id, message)
这意味着用户在 Telegram 上开始一段对话,切换到 Discord 后可以继续(如果使用同一个 session_id)。
四、ACP 适配器 —— IDE 集成
HermesAgent 通过 acp_adapter/ 实现了 Agent Client Protocol(ACP) 服务器,支持直接在 IDE 中使用 Agent:
| IDE | 支持方式 |
|---|---|
| VS Code | ACP 插件 |
| Zed | 原生 ACP 支持 |
| JetBrains | ACP 插件(IDEA/PyCharm/…) |
# acp_adapter/entry.py
class ACPServer:
"""ACP 协议服务器"""
async def handle_request(self, request: ACPRequest) -> ACPResponse:
if request.type == "initialize":
return self.initialize()
elif request.type == "conversation":
return await self.run_conversation(request)
...
ACP 让 HermesAgent 可以作为 JetBrains 或 VS Code 的"AI 编程助手"运行,类似于 Cursor 或 Copilot,但使用的是你自己的 LLM Provider 和配置。
五、与 OpenClaw 的 Gateway 对比
| 维度 | OpenClaw Gateway | HermesAgent Gateway |
|---|---|---|
| 架构 | WebSocket 多节点分布式 | 单进程 + 事件循环 |
| 通道数 | 20+ 原生集成 | ~10 个平台 |
| 分布式 | 支持多节点部署 | 单实例 |
| 协议层 | 自定义类型化协议 | 简单回调 |
| 终端后端 | Docker sandbox | 6 种后端 |
| IDE 集成 | 无 | ACP (VS Code/Zed/JetBrains) |
| 原生应用 | iOS/macOS/Android | 无 |
| 复杂度 | 高 | 中 |
OpenClaw 的 Gateway 更"企业级"(分布式、多协议、多端原生),HermesAgent 的 Gateway 更"开发者友好"(简洁、统一、IDE 集成)。
六、对 Avagent 的启示
1. 终端后端抽象是刚需
Avagent 如果要"控制本地计算机",就必须有终端后端抽象。建议初期至少支持:
- Local(基础能力)
- Docker(安全隔离)
后续再扩展 SSH 和 Serverless。
2. Gateway 设计从简到繁
初期不需要 OpenClaw 那样的分布式 Gateway。一个简单的平台适配器层就够了,先把核心流程跑通。
3. ACP 协议值得关注
IDE 集成是开发者场景的刚需。ACP 协议正在成为 Agent 与 IDE 通信的标准,Avagent 应该尽早支持。
4. 斜杠命令统一是用户体验的关键
CLI、Telegram、Discord、Slack 共享同一套命令定义,用户不需要为每个平台重新学习。
七、小结
HermesAgent 的多终端后端和 Gateway 网关体现了**“以开发者为中心”**的设计理念:
- 6 种终端后端覆盖了从个人开发到科学计算的完整场景
- Gateway 网关支持主流消息平台,且命令系统统一
- ACP 适配器让 Agent 直接嵌入开发者日常工作环境
这种设计让 HermesAgent 不只是一个"聊天机器人",而是一个真正的开发助手——能在任何地方、任何环境中帮你干活。
系列导航:
本文基于 HermesAgent v0.10.0 源码分析,项目持续迭代中。
更多推荐




所有评论(0)