以 Hermes Agent 与 OpenClaw 为案例,深入分析两种主流 Agent 架构范式在工具注册、扩展机制、依赖管理等维度的工程取舍。
一、引言
2026 年,开源 AI Agent 框架进入快速分化期。在"个人 AI 助手"这一细分赛道上,两个代表性项目------Nous Research 的 Hermes Agent (Python)与社区驱动的 OpenClaw(TypeScript)------走出了截然不同的架构路线。前者选择了 Python 单体架构配合自注册工具模式,后者则构建了一套基于 WebSocket 控制面的 TypeScript monorepo 插件体系。
两者解决的核心问题高度一致:连接多个消息平台、调度 LLM 完成工具调用、管理会话与记忆。但在"如何组织代码"这一工程问题上,它们的选择几乎处于光谱的两端。本文将从工具注册机制、扩展模型、依赖管理、贡献门槛四个维度展开对比分析。
二、核心循环:同步单线程 vs 异步事件驱动
2.1 Hermes Agent 的 Agent Loop
Hermes Agent 的核心对话循环位于 run_agent.py 的 AIAgent 类中,采用同步迭代模式:
python
while api_call_count < self.max_iterations and self.iteration_budget.remaining > 0:
response = client.chat.completions.create(
model=model, messages=messages, tools=tool_schemas
)
if response.tool_calls:
for tool_call in response.tool_calls:
result = handle_function_call(tool_call.name, tool_call.args, task_id)
messages.append(tool_result_message(result))
api_call_count += 1
else:
return response.content
这一设计的特点是线性可预测 :每一轮 LLM 调用 → 工具执行 → 结果回传 → 下一轮调用,整个流程在单线程内完成。消息格式遵循 OpenAI 标准(system/user/assistant/tool),reasoning 内容存储在 assistant_msg["reasoning"] 中。
2.2 OpenClaw 的 Gateway 控制面
OpenClaw 采用了不同的架构思路。其核心是一个 WebSocket 控制面(Gateway),所有客户端(CLI、消息平台适配器、macOS/iOS/Android 应用)通过 WebSocket 连接到 Gateway,由 Gateway 统一调度 Agent 运行时(称为 "Pi agent"):
WhatsApp / Telegram / Slack / Discord / ...
│
▼
┌───────────────────────────────┐
│ Gateway │
│ (control plane) │
│ ws://127.0.0.1:18789 │
└──────────────┬────────────────┘
│
├─ Pi agent (RPC)
├─ CLI
├─ WebChat UI
└─ macOS / iOS / Android nodes
Gateway 不仅是消息路由器,还承担了会话管理、工具注册、事件分发、Cron 调度等职责。这种设计天然支持多客户端并发接入,但也引入了更高的架构复杂度。
三、工具注册机制:自注册 vs 插件 SDK
3.1 Hermes Agent 的自注册模式
Hermes Agent 的工具系统围绕一个中央 ToolRegistry 单例构建(tools/registry.py)。每个工具文件在被 import 时自动调用 registry.register() 完成注册:
python
# tools/registry.py 核心注册逻辑
def register(self, name, toolset, schema, handler, check_fn=None,
requires_env=None, is_async=False, emoji="",
max_result_size_chars=None):
"""Register a tool. Called at module-import time by each tool file."""
with self._lock:
self._tools[name] = ToolEntry(
name=name, toolset=toolset, schema=schema,
handler=handler, check_fn=check_fn, ...
)
if check_fn and toolset not in self._toolset_checks:
self._toolset_checks[toolset] = check_fn
一个典型的工具文件结构如下:
python
# tools/my_tool.py
from tools.registry import registry
def my_tool(param1: str, param2: int = 10, **kwargs) -> str:
result = do_work(param1, param2)
return json.dumps(result)
MY_TOOL_SCHEMA = {
"type": "function",
"function": {
"name": "my_tool",
"description": "...",
"parameters": { ... },
},
}
registry.register(
name="my_tool",
toolset="my_toolset",
schema=MY_TOOL_SCHEMA,
handler=lambda args, **kw: my_tool(**args, **kw),
check_fn=_check_requirements,
)
整个依赖链清晰且单向:
tools/registry.py (无依赖 --- 被所有工具文件导入)
↑
tools/*.py (每个文件在 import 时调用 registry.register())
↑
model_tools.py (导入 tools/registry + 触发工具发现)
↑
run_agent.py, cli.py, batch_runner.py
调度同样简洁------dispatch() 方法根据工具名查找 handler 并执行,异步 handler 通过 _run_async() 桥接:
python
def dispatch(self, name, args, **kwargs):
entry = self.get_entry(name)
if not entry:
return json.dumps({"error": f"Unknown tool: {name}"})
try:
if entry.is_async:
from model_tools import _run_async
return _run_async(entry.handler(args, **kwargs))
return entry.handler(args, **kwargs)
except Exception as e:
return json.dumps({"error": f"Tool execution failed: {type(e).__name__}: {e}"})
这种模式的优势在于零配置、零仪式 :新增一个工具只需创建一个 Python 文件,在文件末尾调用 register(),然后在 model_tools.py 的 _modules 列表中添加一行 import。不需要配置文件、不需要注册表、不需要构建步骤。
3.2 OpenClaw 的插件 SDK 体系
OpenClaw 走了一条完全不同的路。其扩展机制基于一套正式的 Plugin SDK,通过 openclaw/plugin-sdk/* 提供超过 150 个子路径导出(从 package.json 的 exports 字段可以看到完整列表)。
一个典型的 Channel 插件注册流程如下:
typescript
// extensions/telegram/index.ts
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/core";
export default defineChannelPluginEntry({
id: "telegram",
name: "Telegram",
description: "Telegram bot integration",
plugin: telegramPlugin,
configSchema: telegramConfigSchema,
setRuntime: (runtime) => { ... },
registerFull: (api) => {
api.registerTool((ctx) => createTelegramTool(ctx), { names: ["telegram_send"] });
},
});
插件通过 api.registerChannel()、api.registerTool()、api.registerMemoryCapability() 等方法向 Gateway 注册能力。每个插件有独立的 openclaw.plugin.json 清单文件,声明元数据、依赖和配置 schema。
OpenClaw 的 extensions/ 目录下有超过 100 个插件目录,涵盖了 LLM 提供商(OpenAI、Anthropic、Google、Mistral 等)、消息平台、记忆后端、媒体生成等各个维度。这种架构的优势在于强隔离和可组合性:每个插件是独立的包,有明确的公共 API 边界,第三方开发者可以通过 npm 分发自己的插件。
3.3 对比小结
| 维度 | Hermes Agent(自注册) | OpenClaw(Plugin SDK) |
|---|---|---|
| 注册方式 | import 时自动注册 | 通过 SDK API 显式注册 |
| 工具定义 | 单文件自包含(schema + handler + register) | 插件包(manifest + entry + runtime) |
| 新增工具成本 | 1 个文件 + 1 行 import | 1 个目录 + manifest + entry + 可能的构建配置 |
| 隔离性 | 弱(共享进程空间) | 强(独立包边界,SDK 契约) |
| 第三方分发 | 通过 Skills Hub(Markdown 指令) | 通过 npm / ClawHub(代码包) |
| 类型安全 | 运行时检查 | 编译时类型检查(TypeScript) |
四、扩展模型:Skills vs Plugins
两个项目对"扩展"的理解存在根本差异。
4.1 Hermes Agent 的 Skills 优先策略
Hermes Agent 的 CONTRIBUTING.md 明确指出:"Should it be a Skill or a Tool? The answer is almost always skill."
Skills 是 Markdown 文件(SKILL.md),包含 YAML 前置元数据和自然语言指令。Agent 在运行时将 Skill 内容注入系统提示词,由 LLM 解释执行:
markdown
---
name: arxiv-search
description: Search and analyze arXiv papers
version: 1.0.0
platforms: [macos, linux]
metadata:
hermes:
requires_toolsets: [terminal, web]
---
# arXiv Search
## When to Use
When the user asks about academic papers or research...
## Procedure
1. Use web_search to query arXiv API...
2. Parse the XML response...
这种设计的哲学是:大多数能力可以通过"指令 + 现有工具"组合实现,不需要写代码。只有当能力需要精确的二进制处理、流式事件或复杂的认证流程时,才应该写成 Tool。
Skills 还支持条件激活(fallback_for_toolsets、requires_toolsets)、平台限制(platforms: [macos])、安全设置(required_environment_variables),以及 Agent 自主创建------这是 Hermes 闭环学习系统的一部分。
4.2 OpenClaw 的代码级插件
OpenClaw 的扩展是真正的代码包。以记忆插件为例,memory-core 插件包含:
extensions/memory-core/
├── src/
│ ├── cli.ts
│ ├── dreaming.ts # 短期记忆提升为长期记忆
│ ├── dreaming-command.ts
│ ├── flush-plan.ts # 记忆刷新策略
│ ├── prompt-section.ts # 系统提示词构建
│ ├── tools.ts # memory_search, memory_get 工具
│ └── memory/
│ └── provider-adapters.ts
├── api.ts
├── index.ts # 插件入口
├── openclaw.plugin.json # 清单文件
├── package.json
└── tsconfig.json
插件通过 definePluginEntry() 注册,可以注册工具、CLI 命令、记忆能力、Gateway 方法等多种能力类型。这种模式的优势在于精确控制:每个插件的行为是确定性的代码逻辑,而非 LLM 对自然语言指令的概率性解释。
4.3 取舍分析
Hermes 的 Skills 模式降低了扩展创建的门槛(不需要写代码),但引入了 LLM 解释的不确定性。OpenClaw 的 Plugin 模式保证了行为的确定性,但提高了开发成本和维护负担。
从实际效果看,Hermes 的 skills/ 目录包含约 30 个 Skill,覆盖研究、生产力、开发等场景;OpenClaw 的 extensions/ 目录包含超过 100 个插件,但其中大部分是 LLM 提供商适配器和消息平台适配器,而非用户可见的"能力扩展"。
五、依赖管理与构建复杂度
5.1 Hermes Agent:pip install 即用
Hermes Agent 使用标准的 pyproject.toml 管理依赖,通过 optional extras 实现按需安装:
toml
[project]
dependencies = [
"openai>=2.21.0,<3",
"anthropic>=0.39.0,<1",
"rich>=14.3.3,<15",
"prompt_toolkit>=3.0.52,<4",
# ...
]
[project.optional-dependencies]
messaging = ["python-telegram-bot[webhooks]>=22.6,<23", "discord.py[voice]>=2.7.1,<3", ...]
voice = ["faster-whisper>=1.0.0,<2", "sounddevice>=0.4.6,<1", ...]
dev = ["pytest>=9.0.2,<10", ...]
安装命令简洁明了:uv pip install -e ".[all]" 或 pip install -e ".[messaging,cron]"。没有构建步骤,没有编译过程,clone 后即可运行。
5.2 OpenClaw:monorepo 构建链
OpenClaw 是一个 pnpm workspace monorepo,包含主包、UI 包、Plugin SDK 包、100+ 个 extension 包。构建流程涉及:
bash
pnpm install
pnpm ui:build # 构建 Web UI
pnpm build # TypeScript 编译,生成 dist/
package.json 中的 exports 字段列出了超过 150 个子路径导出,每个对应一个 Plugin SDK 入口点。这种精细的模块划分为类型安全和树摇优化提供了基础,但也意味着更长的构建时间和更复杂的依赖解析。
从 scripts/ 目录的规模可以窥见这种复杂度:OpenClaw 有超过 200 个构建/检查/测试脚本,涵盖架构边界检查(check-architecture-smells.mjs)、导入边界验证(check-extension-package-tsc-boundary.mjs)、插件 SDK 导出同步(sync-plugin-sdk-exports.mjs)等。这些脚本本身就是一个工程系统。
六、贡献门槛与开发者体验
6.1 新增一个工具的完整流程
Hermes Agent:
- 创建
tools/my_tool.py,编写 handler + schema +registry.register() - 在
model_tools.py的_modules列表添加"tools.my_tool" - 如果是新 toolset,在
toolsets.py添加定义 - 完成
OpenClaw:
- 创建
extensions/my-tool/目录 - 编写
openclaw.plugin.json清单 - 编写
index.ts入口,使用definePluginEntry()注册 - 编写工具实现,遵循 Plugin SDK 类型约束
- 配置
tsconfig.json、package.json - 在构建系统中注册新包
- 运行边界检查确保不违反导入规则
- 完成
6.2 调试体验
Hermes Agent 的调试路径是线性的:cli.py → run_agent.py → model_tools.py → tools/registry.py → 具体工具文件。所有代码在同一进程空间,可以直接设断点。
OpenClaw 的调试需要理解 Gateway WebSocket 协议、插件激活生命周期、RPC 调用链。当问题出现在插件边界时,需要在多个包之间跳转。
七、结论
Hermes Agent 和 OpenClaw 的架构选择反映了两种不同的工程哲学:
Hermes Agent 选择了"简单直接"------Python 单体、自注册工具、Markdown Skills、线性调用链。这种架构的代价是弱隔离和有限的类型安全,但换来了极低的认知负担和贡献门槛。对于一个以"自我进化"为核心卖点的 Agent 框架,这种选择是合理的:当 Agent 自己可以创建 Skills 时,扩展机制的简单性比工程严谨性更重要。
OpenClaw 选择了"工程化治理"------TypeScript monorepo、正式的 Plugin SDK、严格的导入边界、150+ 个类型化子路径导出。这种架构的代价是高复杂度和陡峭的学习曲线,但换来了强类型安全、明确的 API 契约和成熟的第三方生态。对于一个以"平台完备性"为目标的产品,这种选择同样合理。
两种路线没有绝对的优劣。选择哪种架构,取决于项目的核心目标是"让 Agent 更聪明"还是"让平台更完善"。
本文基于 Hermes Agent v0.9.0 和 OpenClaw v2026.4.14-beta.1 的开源代码分析撰写。两个项目均采用 MIT 许可证。