Hermes Agent 架构拆解:ReAct 循环与工具调用机制

目录

  1. 从一个简单的问题开始
  2. ReAct:不是一个新概念
  3. Hermes Agent 的 ReAct 循环实现
    1. 阶段一:输入解析
    2. 阶段二:推理循环
    3. 阶段三:收尾
  4. 一个真实的执行轨迹
  5. 工具系统架构
    1. 工具注册机制
    2. 工具集(Toolset)
    3. 工具调用流程
  6. 推理链的深度控制
  7. 并行工具调用
  8. 错误处理与自纠错
  9. 上下文窗口管理
  10. 与模型层的解耦
  11. 为什么不用 Plan-and-Execute
  12. 你需要理解架构吗
  13. 延伸阅读:OpenClaw 社区资源

从一个简单的问题开始

当你对 Hermes Agent 说「帮我查一下当前服务器的内存使用情况」,从你按下回车到收到回复,中间到底发生了什么?

这个看似简单的过程,背后是一套精心设计的推理-执行循环。理解这套机制,能帮你更好地使用 Hermes Agent,也能在它犯错时知道问题出在哪个环节。

这篇文章从技术角度把 Hermes Agent 的核心架构拆开来讲,但不会钻得太深——你不需要看源码也能看懂。

ReAct:不是一个新概念

Hermes Agent 的推理引擎基于 ReAct 范式。ReAct 是 “Reasoning and Acting” 的缩写,最早由 Yao et al. 2022{rel=”nofollow”} 在论文中提出。

核心思想用一句话概括:让大模型交替进行推理和行动,用推理指导行动,用行动结果更新推理。

这和人类解决问题的过程很像。你去修一台打印机,不会上来就拆——你先看看是什么症状(观察),判断可能是哪里出了问题(推理),然后动手检查(行动),再根据检查结果决定下一步怎么做。

传统的 LLM 调用是「一次性推理」:给一个 prompt,出一个结果。ReAct 把这个过程变成了循环:每一轮推理都基于上一轮行动的真实反馈。

Hermes Agent 的 ReAct 循环实现

具体到 Hermes Agent 的实现,一次完整的任务执行分为以下几个阶段:

阶段一:输入解析

用户的输入先经过预处理:

  • 检索持久记忆,把相关偏好注入上下文
  • 搜索技能库,看有没有匹配的已有技能
  • 构建初始 system prompt,包含可用工具列表

这一步很关键。如果找到了匹配的技能文件,Hermes Agent 会优先按技能走,大幅减少后续的推理轮数。这也是为什么技能系统是整个框架的灵魂。

阶段二:推理循环

这是 ReAct 的主体部分。每一轮循环包含三个步骤:

1. 观察(Observe)

Agent 审视当前掌握的所有信息:

  • 用户原始请求
  • 之前已经执行的操作及其结果
  • 当前可用的工具列表
  • 记忆中相关的上下文信息

2. 推理(Reason)

基于观察到的信息,LLM 进行思考:

  • 当前任务是否已完成?
  • 如果没完成,下一步应该做什么?
  • 应该调用哪个工具?参数是什么?
  • 有没有可能出错?需不需要先做个检查?

这一步的输出是结构化的——它不只是一段文本,而是一个明确的「动作决策」。

3. 行动(Act)

执行推理阶段决定的操作:

  • 调用指定的工具(比如 shell_exec
  • 收集工具返回的结果
  • 把结果追加到上下文中,进入下一轮循环

阶段三:收尾

当 Agent 判断任务已完成(或遇到无法解决的错误),循环结束。这时候会:

  • 生成最终回复给用户
  • 评估是否需要生成技能文件
  • 更新会话记忆

这三个阶段构成了一次完整的任务生命周期。

一个真实的执行轨迹

抽象描述可能不够直观,来看一个具体例子。假设用户说:「帮我在 /opt 下创建一个 Python 虚拟环境,安装 requests 和 flask」

第 1 轮

1
2
3
4
观察: 用户想在 /opt 下创建 Python 虚拟环境并安装两个包
推理: 先检查 /opt 目录是否存在以及 Python 版本
行动: shell_exec("ls -la /opt && python3 --version")
结果: /opt 存在,Python 3.11.2

第 2 轮

1
2
3
4
观察: /opt 存在,Python 版本满足要求
推理: 可以直接创建虚拟环境
行动: shell_exec("python3 -m venv /opt/myenv")
结果: 命令成功执行,无报错

第 3 轮

1
2
3
4
观察: 虚拟环境创建成功
推理: 现在用虚拟环境的 pip 安装依赖
行动: shell_exec("/opt/myenv/bin/pip install requests flask")
结果: Successfully installed requests-2.31.0 flask-3.0.2 ...

第 4 轮

1
2
3
4
观察: 两个包都安装成功了
推理: 任务完成,验证一下安装结果
行动: shell_exec("/opt/myenv/bin/python -c 'import requests, flask; print(requests.__version__, flask.__version__)'")
结果: 2.31.0 3.0.2

收尾:Agent 把执行结果整理好返回给用户,同时评估是否生成技能文件(这次调用了 4 个工具,接近触发阈值但没到 5 个,可能不会生成技能)。

注意看第 1 轮——Agent 没有直接创建虚拟环境,而是先检查了环境。这就是 ReAct 推理的价值:它不是机械地执行命令,而是在每一步都做了判断。

工具系统架构

工具是 ReAct 循环中「行动」阶段的执行者。Hermes Agent 的工具系统设计得相当模块化。

工具注册机制

每个工具在注册时需要提供:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@tool(
name="shell_exec",
description="在终端中执行 shell 命令",
parameters={
"command": {
"type": "string",
"description": "要执行的命令"
},
"timeout": {
"type": "integer",
"description": "超时时间(秒)",
"default": 30
}
}
)
def shell_exec(command: str, timeout: int = 30) -> str:
# 执行逻辑
...

框架会自动把所有已注册工具的名称、描述和参数格式传给 LLM,让模型知道自己「有哪些手可以用」。

工具集(Toolset)

40 多个工具不是散装的,而是按功能分组成 Toolset:

  • core: 基础工具,包括 shell 执行、文件读写
  • web: 网络相关,HTTP 请求、网页抓取
  • dev: 开发工具,Git、代码搜索
  • system: 系统管理,进程管理、资源监控
  • communication: 消息发送相关

你可以在配置文件中控制启用哪些 Toolset:

1
2
3
4
5
6
7
toolsets:
enabled:
- core
- web
- dev
disabled:
- system # 禁用系统管理工具

这在安全场景下很有用——你可以给 Agent 精确的权限边界。详细的安全配置参考 Hermes Agent 安全指南

工具调用流程

当 LLM 决定调用某个工具时,整个流程是:

  1. 参数校验:检查 LLM 输出的参数格式是否正确
  2. 权限检查:确认当前后端是否允许执行该操作
  3. 后端路由:根据配置,把命令发送到对应的执行后端(本地/Docker/SSH等)
  4. 执行:在目标环境中执行
  5. 结果捕获:收集 stdout、stderr、exit code
  6. 结果截断:如果输出太长,自动截断并标注
  7. 返回:把结果回传给推理循环

步骤 6 值得注意——如果一个命令输出了 10MB 的日志,全部塞进上下文会浪费 token 甚至超出限制。Hermes Agent 会智能截断,保留头尾部分,中间用摘要替代。

推理链的深度控制

一个常见问题:如果 Agent 的推理陷入了死循环怎么办?

Hermes Agent 有几层防护:

最大循环次数:默认上限是 25 轮。超过这个次数,Agent 会强制结束并告诉你当前进度。可以在配置中调整:

1
2
agent:
max_iterations: 25

单步超时:每个工具调用有超时限制,默认 30 秒。防止某个命令卡死导致整个任务挂起。

成本预算:你可以设置单次任务的最大 token 消耗。接近预算时,Agent 会尝试收尾而不是继续深入。

自我检测:Agent 的推理 prompt 中包含了循环检测逻辑。如果它发现自己连续两轮在做相同的操作,会主动跳出并换策略。

并行工具调用

Hermes Agent 支持在一轮推理中同时调用多个工具。这在某些场景下能显著提升效率。

比如用户说「查看服务器的 CPU 使用率、内存使用率和磁盘使用率」,Agent 可以一次性发出三条命令而不是串行执行:

1
2
3
4
行动: 
- shell_exec("top -bn1 | head -5")
- shell_exec("free -h")
- shell_exec("df -h")

三条命令并行执行,结果一起返回,用一轮循环就搞定了原本需要三轮的工作。

不过并行调用不是总能用的。如果后一个操作依赖前一个操作的结果(比如先查文件路径再读文件),就只能串行。Agent 会自己判断什么时候可以并行。

错误处理与自纠错

真实环境下命令不可能永远成功。Agent 怎么处理错误?

策略一:重试。如果是网络超时之类的临时性错误,Agent 会自动重试,通常换个姿势(比如加 --timeout 参数)。

策略二:降级。如果某个方案不行,换一种方式达到同样目的。比如 apt install 失败了,试试 yum install;或者源码编译。

策略三:求助。如果 Agent 尝试了多种方式都失败了,它会向用户反馈:「这个操作我搞不定,可能需要你手动介入,具体原因是……」

这种自纠错能力是技能生成的重要信号——如果 Agent 在执行过程中纠错成功了,生成的技能文件会包含纠错路径,让后续任务直接走正确的路线。

上下文窗口管理

大模型的上下文窗口是有限的(通常 8K-128K tokens)。一次复杂任务的执行轨迹可能会很长,怎么管理?

Hermes Agent 的做法是滑动窗口 + 摘要压缩

  1. 最近 3-5 轮的完整轨迹保留在上下文中
  2. 更早的轮次会被 LLM 摘要压缩:原本 500 token 的执行记录可能被压成 50 token 的摘要
  3. 技能文件作为「压缩后的经验」始终在上下文中
  4. 持久记忆始终在上下文中

这个方案在实际使用中效果不错。绝大多数任务在 10 轮以内能完成,上下文压力不大。碰到特别复杂的任务,你也可以让 Agent 把当前进度保存,开新会话继续——它的记忆系统保证了跨会话的信息不丢失。

与模型层的解耦

架构上一个很重要的设计决策:推理引擎和具体的 LLM 是解耦的。

ReAct 循环不关心底层用的是什么模型,它只需要模型能理解指令、输出结构化的工具调用决策。这意味着:

  • 你可以随时切换模型,不需要改任何配置
  • 不同模型的推理风格会影响 Agent 的行为,但基本流程不变
  • 新模型出来后,只要它支持函数调用(function calling),就能接入

实际体验下来,模型选择确实影响很大。用 GPT-4 级别的模型,Agent 的推理更缜密,更少犯错;用小模型虽然快和便宜,但推理质量下降明显,有时候需要更多轮次才能完成任务。

为什么不用 Plan-and-Execute

了解 Agent 领域的读者可能会问:为什么选 ReAct 而不是 Plan-and-Execute?

Plan-and-Execute 是另一种常见范式:先制定完整计划,再按计划执行。优点是全局视角好,缺点是计划一旦制定就比较刚性——遇到预期外的情况不好调整。

ReAct 的优势恰恰在于灵活性。每一轮都能根据实际情况调整策略,更适合和真实环境打交道的 Agent。

但 Hermes Agent 不是纯 ReAct。在技能匹配成功的情况下,它其实走的是一种类似 Plan-and-Execute 的路径——技能文件就是预制的计划。只不过这个「计划」是之前成功经验的沉淀,而不是临时推理出来的。

这种混合策略在 cocoloop 社区的讨论中得到了不少积极反馈。

你需要理解架构吗

坦率讲,你不理解这些也完全能用好 Hermes Agent。它的设计目标就是让用户不需要关心内部实现。

但如果你:

  • 想优化它的执行效率(比如调整 max_iterations)
  • 想排查为什么某个任务表现不好
  • 想自己写工具插件
  • 想理解技能生成的触发逻辑

那么了解这套架构就很有必要了。至少你知道了:问题出在「推理」阶段还是「行动」阶段,是模型能力不够还是工具配置有问题。这能帮你更精确地定位和解决问题。

延伸阅读:OpenClaw 社区资源

本文由 CocoLoop 中文社区出品。如果你在研究 AI Agent 与主流模型的工程化落地,姊妹站 OpenClaw 中文社区 也许会有帮助:

参与讨论

对这篇文章有疑问或想法?cocoloop 社区有不少开发者在讨论 Hermes 相关话题,欢迎加入交流。

前往 cocoloop 社区 →