约 33 分钟阅读

OpenCLAW vs Hermes:多智能体框架深度对比

从设计哲学、源码架构到实战场景:两个多智能体框架的系统化对比与选型指南

OpenCLAW vs Hermes:多智能体框架深度对比

引言:为什么需要对比?

1.1 多智能体框架的兴起

2024-2026 年,LLM 应用从单 Agent 向多 Agent 协作演进。早期应用(如 Chatbot)只需一个 LLM 处理用户请求,但复杂场景(如数据分析、工作流自动化)需要多个 Agent 分工协作。

为什么需要框架?

  • 避免重复造轮子:Agent 协作的通用模式(任务分解、状态管理、工具调用)
  • 降低开发成本:框架提供基础设施,开发者专注业务逻辑
  • 最佳实践沉淀:框架封装了多 Agent 协作的经验和教训

1.2 对比的动机

Hermes:我使用数个月,熟悉其能力边界。它是一个个人 AI 助手,擅长即时交互、工具调用、知识管理。

OpenCLAW:新兴的多 Agent 框架,设计哲学与 Hermes 截然不同。它强调自主 Agent 协作,适合复杂任务分解和企业级工作流。

对比价值:帮助读者根据场景选择合适框架,避免”用锤子找钉子”。

1.3 对比维度

  • 设计哲学:以人为本 vs Agent 优先
  • 源码架构:核心类、设计模式、关键实现
  • 能力边界:擅长什么、不擅长什么
  • 适用场景:什么时候选哪个

Hermes 框架深度解析

2.1 设计哲学

以人为本:Hermes 是 AI 助手,而非自主 Agent。人类始终在控制回路中,AI 辅助而非替代。

工具优先:内置丰富工具集(终端、文件、Web 搜索、MCP),Agent 是工具的使用者。

持久化:记忆(memory)、技能(skills)、定时任务(cron),支持长期协作。

2.2 核心架构

会话驱动:基于对话的交互模式,用户输入 → Agent 处理 → 工具调用 → 返回结果。

技能系统:SKILL.md 格式的可插拔能力,YAML frontmatter + Markdown 正文。

记忆机制

  • 短期:会话历史(context window)
  • 长期:memory(事实)+ skills(流程)

工具集

  • 终端:执行 shell 命令
  • 文件:读写、搜索、编辑
  • Web:搜索、访问 API
  • MCP:Model Context Protocol,扩展工具

2.3 能力边界

擅长

  • 个人助理(日程、笔记、邮件)
  • 知识管理(Obsidian、Git、文档)
  • 自动化脚本(定时任务、监控告警)

局限

  • 多 Agent 协作(仅支持 delegate_task,功能有限)
  • 复杂状态管理(无状态机,依赖会话历史)
  • 长期任务(无任务队列,依赖 cron)

2.4 使用场景

个人知识管理:Obsidian 同步、博客写作、知识检索。

自动化运维:定时任务(cron)、监控告警、脚本执行。

技术写作:选题推荐、草稿生成、内容同步。

2.5 Hermes 源码解构

2.5.1 核心类分析

Agent:主循环,处理用户输入和工具调用。

# 简化版 Hermes Agent 核心逻辑
class Agent:
    async def run(self, user_input: str) -> str:
        # 1. 加载上下文(技能 + 记忆)
        context = self.load_context()
        
        # 2. 调用 LLM
        response = await self.llm.chat(
            messages=[{"role": "user", "content": user_input}],
            tools=self.available_tools,
            context=context
        )
        
        # 3. 解析工具调用
        tool_calls = self.parse_tool_calls(response)
        
        # 4. 执行工具(支持并行)
        results = await self.execute_tools(tool_calls)
        
        # 5. 将结果回喂给 LLM
        final_response = await self.llm.chat(
            messages=[
                {"role": "user", "content": user_input},
                {"role": "assistant", "tool_calls": tool_calls},
                {"role": "tool", "content": results}
            ]
        )
        
        return final_response.content

Tool:工具抽象,统一接口。

from abc import ABC, abstractmethod

class Tool(ABC):
    name: str
    description: str
    parameters: Dict  # JSON Schema
    
    @abstractmethod
    async def execute(self, **kwargs) -> str:
        """执行工具,返回结果"""
        pass

# 示例:终端工具
class TerminalTool(Tool):
    name = "terminal"
    description = "执行 shell 命令"
    
    async def execute(self, command: str, timeout: int = 180) -> str:
        import subprocess
        result = subprocess.run(
            command, shell=True, capture_output=True, 
            text=True, timeout=timeout
        )
        return f"stdout: {result.stdout}\nstderr: {result.stderr}"

Memory:记忆管理。

class Memory:
    def __init__(self):
        self.user_memory = []  # 用户偏好
        self.system_memory = []  # 系统笔记
    
    def add(self, target: str, content: str):
        """添加记忆"""
        if target == "user":
            self.user_memory.append(content)
        else:
            self.system_memory.append(content)
    
    def load_context(self) -> str:
        """加载上下文"""
        return f"User Memory:\n{'\n'.join(self.user_memory)}\n\nSystem Memory:\n{'\n'.join(self.system_memory)}"

SkillLoader:技能加载器。

import yaml
from pathlib import Path

class SkillLoader:
    def load_skill(self, name: str) -> Dict:
        skill_path = Path(f"~/.hermes/skills/{name}/SKILL.md").expanduser()
        content = skill_path.read_text()
        
        # 解析 frontmatter
        if content.startswith("---"):
            end = content.find("---", 3)
            frontmatter = yaml.safe_load(content[3:end])
            body = content[end+3:].strip()
            return {**frontmatter, "content": body}
        
        return {"name": name, "content": content}

2.5.2 关键设计模式

命令模式:工具调用作为命令对象,便于日志记录和重试。

class ToolCommand:
    def __init__(self, tool: Tool, args: Dict):
        self.tool = tool
        self.args = args
    
    async def execute(self) -> str:
        return await self.tool.execute(**self.args)

策略模式:不同的模型提供者(OpenAI/Anthropic/Custom)。

class ModelProvider(ABC):
    @abstractmethod
    async def chat(self, messages: List[Dict], tools: List[Dict]) -> str:
        pass

class OpenAIProvider(ModelProvider):
    async def chat(self, messages, tools):
        # OpenAI API 实现
        pass

class AnthropicProvider(ModelProvider):
    async def chat(self, messages, tools):
        # Anthropic API 实现
        pass

观察者模式:工具调用的事件通知。

class ToolEventBus:
    def __init__(self):
        self.listeners = []
    
    def on_tool_call(self, listener):
        self.listeners.append(listener)
    
    async def notify(self, tool_name: str, args: Dict, result: str):
        for listener in self.listeners:
            await listener(tool_name, args, result)

OpenCLAW 框架深度解析

3.1 设计哲学

Agent 优先:自主 Agent 协作,人类只需定义目标,Agent 自动分解和执行任务。

状态机驱动:明确的状态流转(待处理→执行中→完成),支持复杂任务管理。

可扩展性:插件化设计,支持自定义 Agent 类型和协作策略。

3.2 核心架构

多 Agent 协作

  • 主管 - 工人模式(Orchestrator-Worker)
  • 投票共识(Voting)
  • 流水线协作(Pipeline)

状态管理:基于状态机的任务流转,支持断点续传。

工具调用:类似 LangChain 的工具抽象,需自行实现。

持久化:任务状态、执行历史,支持恢复和审计。

3.3 能力边界

擅长

  • 复杂任务分解(自动拆分为子任务)
  • 多 Agent 协作(主管 - 工人、投票)
  • 长期任务(任务队列、状态持久化)

局限

  • 个人助理场景(缺乏即时交互)
  • 工具丰富度(需自行实现)
  • 学习曲线(需理解状态机、多 Agent 模式)

3.4 使用场景

企业级工作流自动化:需要多角色协作的复杂流程。

复杂数据分析任务:多步骤分析,需要中间状态。

需要多角色协作的场景:如代码审查(作者 + 审查者 + 合并者)。

3.5 OpenCLAW 源码解构

3.5.1 核心类分析

Agent 基类:定义 Agent 的接口。

# 简化版 OpenCLAW Agent 基类
from abc import ABC, abstractmethod
from typing import List, Dict

class Agent(ABC):
    name: str
    role: str
    tools: List[Tool]
    
    @abstractmethod
    def plan(self, task: str) -> Plan:
        """制定计划"""
        pass
    
    @abstractmethod
    def execute(self, plan: Plan) -> Result:
        """执行计划"""
        pass
    
    @abstractmethod
    def communicate(self, message: str, from_agent: str) -> str:
        """与其他 Agent 通信"""
        pass

Orchestrator:主管 Agent,负责任务分解和分配。

class Orchestrator(Agent):
    def __init__(self, workers: List[Agent]):
        super().__init__(name="orchestrator", role="task_manager")
        self.workers = workers
    
    def decompose(self, task: str) -> List[SubTask]:
        """将大任务分解为子任务"""
        # 使用 LLM 分解任务
        plan_prompt = f"""
        任务:{task}
        
        请将任务分解为多个子任务,每个子任务应:
        1. 可独立执行
        2. 有明确的输入输出
        3. 可分配给不同 Agent
        
        输出格式:JSON 数组
        """
        subtasks = self.llm.generate(plan_prompt)
        return [SubTask(**st) for st in subtasks]
    
    def assign(self, tasks: List[SubTask]):
        """将子任务分配给工人 Agent"""
        for task in tasks:
            # 根据任务类型选择最合适的 Agent
            worker = self.select_worker(task)
            worker.execute_task(task)

Worker:工人 Agent,负责执行具体子任务。

class Worker(Agent):
    def __init__(self, name: str, specialty: str):
        super().__init__(name=name, role=specialty)
        self.specialty = specialty
    
    def can_handle(self, task: SubTask) -> bool:
        """判断是否能处理该任务"""
        return task.type == self.specialty
    
    def execute_task(self, task: SubTask) -> Result:
        """执行任务"""
        # 1. 制定计划
        plan = self.plan(task.description)
        
        # 2. 执行工具调用
        results = []
        for step in plan.steps:
            if step.requires_tool:
                result = self.execute_tool(step.tool, step.args)
                results.append(result)
        
        # 3. 返回结果
        return Result(
            task_id=task.id,
            status="completed",
            output="\n".join(results)
        )

State:状态管理。

from enum import Enum

class TaskStatus(Enum):
    PENDING = "pending"
    IN_PROGRESS = "in_progress"
    COMPLETED = "completed"
    FAILED = "failed"

class TaskState:
    def __init__(self):
        self.tasks: Dict[str, Dict] = {}
    
    def create_task(self, task_id: str, description: str) -> Dict:
        """创建任务"""
        task = {
            "id": task_id,
            "description": description,
            "status": TaskStatus.PENDING,
            "subtasks": [],
            "history": []
        }
        self.tasks[task_id] = task
        return task
    
    def update_status(self, task_id: str, status: TaskStatus):
        """更新任务状态"""
        task = self.tasks[task_id]
        task["status"] = status
        task["history"].append({
            "timestamp": datetime.now(),
            "status": status.value
        })
    
    def get_task(self, task_id: str) -> Dict:
        """获取任务状态"""
        return self.tasks.get(task_id)

3.5.2 关键设计模式

工厂模式:创建不同类型的 Agent。

class AgentFactory:
    @staticmethod
    def create_agent(agent_type: str, **kwargs) -> Agent:
        if agent_type == "orchestrator":
            return Orchestrator(**kwargs)
        elif agent_type == "worker":
            return Worker(**kwargs)
        elif agent_type == "voter":
            return VoterAgent(**kwargs)
        else:
            raise ValueError(f"Unknown agent type: {agent_type}")

观察者模式:Agent 间的事件通知。

class AgentEventBus:
    def __init__(self):
        self.subscribers: Dict[str, List[Callable]] = {}
    
    def subscribe(self, event_type: str, callback: Callable):
        """订阅事件"""
        if event_type not in self.subscribers:
            self.subscribers[event_type] = []
        self.subscribers[event_type].append(callback)
    
    async def publish(self, event_type: str, data: Dict):
        """发布事件"""
        for callback in self.subscribers.get(event_type, []):
            await callback(data)

# 使用示例
event_bus = AgentEventBus()

async def on_task_completed(data):
    print(f"Task {data['task_id']} completed!")

event_bus.subscribe("task.completed", on_task_completed)

策略模式:不同的协作策略。

class CollaborationStrategy(ABC):
    @abstractmethod
    async def collaborate(self, agents: List[Agent], task: str) -> Result:
        pass

class OrchestratorStrategy(CollaborationStrategy):
    async def collaborate(self, agents, task):
        """主管 - 工人模式"""
        orchestrator = agents[0]
        workers = agents[1:]
        return await orchestrator.execute(task, workers)

class VotingStrategy(CollaborationStrategy):
    async def collaborate(self, agents, task):
        """投票共识模式"""
        results = await asyncio.gather(*[
            agent.execute(task) for agent in agents
        ])
        return self.majority_vote(results)

底层逻辑对比

4.1 核心抽象差异

HermesUser ↔ Agent ↔ Tools(单 Agent 多工具)

  • 一个 Agent,多个工具
  • 人类在控制回路中
  • 即时交互,对话式

OpenCLAWOrchestrator ↔ Workers ↔ Tools(多 Agent 协作)

  • 多个 Agent,分工协作
  • 人类只需定义目标
  • 任务队列,异步执行

4.2 状态管理对比

Hermes

  • 会话状态:消息历史(context window)
  • 持久记忆:memory(事实)+ skills(流程)
  • 无状态机,依赖 LLM 理解上下文

OpenCLAW

  • 任务状态:状态机(PENDING → IN_PROGRESS → COMPLETED)
  • 执行历史:任务日志、子任务状态
  • 支持断点续传、任务恢复

4.3 工具系统对比

Hermes

  • 内置工具丰富:terminal/file/web_search/MCP
  • 工具即服务:无需自行实现
  • 扩展方式:MCP 协议、自定义工具

OpenCLAW

  • 工具抽象类似 LangChain
  • 需自行实现工具逻辑
  • 扩展方式:继承 Tool 基类

4.4 扩展机制对比

Hermes:SKILL.md(Markdown + YAML frontmatter)

---
name: git-automation
title: Git 自动化
description: 自动化 Git 工作流
---

# Git 自动化技能

## 能力范围
- 提交代码
- 推送远程
- 创建分支

## 工具调用
- `git_commit(message)`
- `git_push(remote, branch)`

OpenCLAW:Python 类继承(需编码)

class GitAutomationAgent(Worker):
    def __init__(self):
        super().__init__(name="git-automation", specialty="git")
    
    def execute_task(self, task: SubTask) -> Result:
        if task.type == "commit":
            return self.git_commit(task.message)
        elif task.type == "push":
            return self.git_push(task.remote, task.branch)

4.5 设计哲学差异

维度HermesOpenCLAW
核心理念Human-in-the-loopAutonomous
交互模式对话式(即时)任务队列(异步)
状态管理会话历史状态机
工具系统内置丰富需自行实现
扩展方式SKILL.md(无代码)Python 类(需编码)
适用场景个人助理、即时交互企业工作流、复杂任务

能力对比矩阵

5.1 功能对比表

能力HermesOpenCLAW
人机交互✅ 优秀(对话式)⚠️ 有限(任务队列)
多 Agent 协作⚠️ 有限(delegate_task)✅ 优秀(主管 - 工人/投票)
状态管理⚠️ 简单(会话历史)✅ 复杂(状态机)
工具丰富度✅ 丰富(内置 + MCP)⚠️ 中等(需自行实现)
持久化✅ 完善(memory/skills)✅ 完善(任务状态)
自动化✅ 定时任务(cron)⚠️ 需外部触发
学习曲线上手快,精通需时间上手慢,精通后灵活
扩展性SKILL.md(无代码)Python 类(需编码)

5.2 性能对比

响应速度

  • Hermes:即时(对话式,单次 LLM 调用)
  • OpenCLAW:较慢(任务队列,多次 LLM 调用)

资源消耗

  • Hermes:轻量(单 Agent,少状态)
  • OpenCLAW:较重(多 Agent,状态持久化)

扩展性

  • Hermes:技能系统(无代码,易上手)
  • OpenCLAW:插件系统(需编码,灵活)

5.3 学习曲线

Hermes

  • 上手快:对话式交互,无需编程
  • 精通需时间:理解技能系统、记忆机制、工具调用

OpenCLAW

  • 上手慢:需理解状态机、多 Agent 模式、Python 编程
  • 精通后灵活:可自定义 Agent 类型、协作策略、工具系统

实战场景对比

6.1 场景 1:个人知识管理

需求:Obsidian 同步、博客写作、知识检索。

Hermes

  • ✅ 即时交互:随时询问、检索、同步
  • ✅ 工具丰富:文件读写、Git 操作、Web 搜索
  • ✅ 记忆持久:记住用户偏好、写作风格

OpenCLAW

  • ❌ 不适合:需要持续的人机交互,而非任务队列
  • ❌ 工具有限:需自行实现文件、Git 工具

推荐:Hermes

6.2 场景 2:自动化运维

需求:定时任务、监控告警、脚本执行。

Hermes

  • ✅ 定时任务:cron 支持,自动执行
  • ✅ 工具丰富:terminal/file/web_search
  • ✅ 即时反馈:执行结果即时返回

OpenCLAW

  • ⚠️ 需外部触发:无内置定时任务
  • ✅ 复杂流程:多步骤任务分解
  • ⚠️ 异步执行:任务队列,非即时

推荐:简单用 Hermes,复杂用 OpenCLAW

6.3 场景 3:数据分析

需求:多步骤分析,需要中间状态。

Hermes

  • ✅ 单次分析:即时查询、简单统计
  • ❌ 多步骤:依赖会话历史,易丢失状态

OpenCLAW

  • ✅ 多步骤:状态机管理,支持中间状态
  • ✅ 任务分解:自动拆分为子任务(数据清洗→分析→可视化)
  • ✅ 持久化:任务状态可恢复

推荐:OpenCLAW

6.4 场景 4:企业工作流

需求:多角色协作(如代码审查:作者→审查者→合并者)。

Hermes

  • ❌ 不适合:缺乏多 Agent 协作能力
  • ❌ 无状态机:无法管理复杂流程

OpenCLAW

  • ✅ 多 Agent:主管 - 工人模式
  • ✅ 状态管理:明确的状态流转
  • ✅ 可扩展:自定义 Agent 类型(作者/审查者/合并者)

推荐:OpenCLAW


选型决策树

7.1 决策流程图

需要多 Agent 协作?
├─ 是 → OpenCLAW
└─ 否 → 需要即时交互?
    ├─ 是 → Hermes
    └─ 否 → 需要复杂状态管理?
        ├─ 是 → OpenCLAW
        └─ 否 → Hermes

7.2 关键问题清单

  1. 是否需要多 Agent 协作?

    • 是 → OpenCLAW
    • 否 → 继续
  2. 是否需要即时交互(而非任务队列)?

    • 是 → Hermes
    • 否 → 继续
  3. 是否需要复杂状态管理(状态机)?

    • 是 → OpenCLAW
    • 否 → 继续
  4. 是否需要丰富的内置工具?

    • 是 → Hermes
    • 否 → 继续
  5. 是否需要定时任务/自动化?

    • 是 → Hermes
    • 否 → 两者皆可

7.3 混合方案

Hermes + OpenCLAW

  • Hermes 做日常助理(即时交互、工具调用)
  • OpenCLAW 处理复杂任务(多 Agent 协作、状态管理)

Hermes + LangGraph

  • Hermes 做交互(对话式、工具调用)
  • LangGraph 做状态管理(状态机、任务流转)

总结与建议

8.1 核心结论

Hermes

  • ✅ 个人助理、即时交互、工具丰富
  • ✅ 上手快、无代码扩展、定时任务
  • ❌ 多 Agent 协作有限、状态管理简单

OpenCLAW

  • ✅ 多 Agent 协作、状态管理、企业级
  • ✅ 灵活扩展、任务持久化、复杂流程
  • ❌ 上手慢、需编程、工具需自行实现

8.2 学习建议

初学者

  • 从 Hermes 开始,理解 Agent 基础
  • 熟悉工具调用、技能系统、记忆机制

进阶者

  • 学习 OpenCLAW,掌握多 Agent 协作
  • 理解状态机、任务分解、协作策略

专家

  • 根据场景选择,甚至混合使用
  • 自定义框架,结合两者优势

8.3 未来展望

Hermes

  • 可能增强多 Agent 协作能力(delegate_task 升级)
  • 可能引入状态机(复杂任务管理)

OpenCLAW

  • 可能增强人机交互体验(对话式接口)
  • 可能内置更多工具(减少自行实现)

融合趋势

  • 两者的设计思想可能互相借鉴
  • 未来可能出现”对话式多 Agent”框架

资源与延伸阅读

9.1 官方文档

9.2 相关博文

9.3 社区与讨论

  • Hermes:Discord 社区、GitHub Issues
  • OpenCLAW:GitHub Discussions、技术论坛

相关文章

💬 评论

主题
字体
密度
语言