AI Agent 对比系列(五):Agent Loop — AI Agent 是怎么「干活」的?
AI Agent 对比系列(五):Agent Loop — AI Agent 是怎么「干活」的?
《AI Agent 对比系列》第五篇 · 整合对比版
本系列通过对比两个真实开源 AI Agent——OpenClaw 和 Hermes Agent——带你深入理解 AI Agent 是什么、能做什么、怎么工作。
上一篇:感知系统篇——AI Agent 怎么看世界、怎么"听见"你、怎么"读取"环境。
本篇:Agent Loop 篇——AI Agent 的"大脑"是怎么转起来的:推理循环、工具选择、上下文管理、中断与恢复。
先来做个实验
对 Hermes 说:
帮我看看 D 盘 workspace 里有哪些目录,然后告诉我最大的一个文件夹叫什么。
注意观察——它不会一口气回答。它会思考 → 调用工具看目录 → 看结果 → 再调用工具查大小 → 输出答案。如果它干到一半,你补一句「等等,改成查 C 盘的」——它会停下来处理你的新消息,再继续。
对 OpenClaw 说(先打开会话输入 /verbose on):
查一下今天的天气,顺便把结果写成一份 Markdown 文件保存到工作区。
你会看到一条条工具调用记录刷出来:先 web_search 搜天气,再 write 写文件,最后才给出回复。
两个实验展示的是同一个东西:你看到的不只是最终答案,而是 Agent 一步步「思考 → 动手 → 看结果 → 再思考」的完整过程。这个循环,就是今天的主角——Agent Loop(Agent 干活循环)。
核心认知:AI Agent 的本质是一个「循环」,不是一次「回答」
这是整篇文章最重要的句子:AI Agent 不是"问一句、答一句"的对话工具——它收到任务后,会进入一个「思考 → 决定 → 动手 → 看结果 → 再思考」的循环,循环里每一步都可能调用工具,直到任务完成、或它认为自己已经尽力。这个循环,就叫 Agent Loop。
传统 AI 和 AI Agent 的区别,用两段对话对比:
传统 AI(你问它答):
你:今天上海天气怎么样?
AI:上海今天多云,24~31℃。(回答完毕,结束)
AI Agent(你派活它干):
你:帮我查上海今天天气,如果下雨就提醒我带伞。
Agent:好的,我来查。
→ 思考:需要天气数据,调用天气工具
→ 调用工具获取天气 → 看到结果:多云,无雨
→ 思考:无雨,不需要提醒带伞
→ 输出:上海今天多云 24~31℃,无雨,不需要带伞。
为什么会有这个区别?因为大模型本身是"一锤子买卖"——你给它一段 prompt,它吐一段文字,完事。它没有"做一件事"的概念,只有"生成一段文字"的概念。当它输出"我要调用 web_search,参数是……"时,那只是一段文字指令——真正去执行这段指令的,是外面的程序。这个"外面的程序"就是 Agent Loop:
思考(模型生成下一步该做什么)
↓
行动(执行工具调用,拿到结果)
↓
观察(把结果喂回给模型)
↓
再思考(根据结果决定下一步)……
大模型负责"想",Agent Loop 负责"动"和"看"。 没有 Loop,大模型只是个只会说话的百科全书;有了 Loop,它才是个能跑腿的实习生。
循环架构对比:一个 9 步,一个六站
Hermes:9 步 Turn Lifecycle
Hermes 的 Agent Loop 由 run_agent.py 的 AIAgent 类驱动,每轮(turn)官方定义 9 步:
run_conversation() 一轮循环:
1. 生成 task_id(如果还没有)
2. 把用户消息追加到对话历史
3. 构建或复用缓存的系统提示词
4. 检查是否需要预压缩(上下文 > 50% 时)
5. 用对话历史组装 API 请求
6. 注入临时提示层(预算警告、上下文压力)
7. (Anthropic 模型时)打缓存标记
8. 发起可中断的模型调用
9. 解析响应:
├── 带工具调用 → 执行工具 → 结果追加回历史 → 回到第 5 步
└── 纯文本 → 保存会话、需要时刷新记忆、返回
OpenClaw:六站旅程
OpenClaw 把一次循环定义为六站:
你发消息:查天气,写成文件
↓
① 入队 —— 消息进入串行队列,等待轮到自己
↓
② 组装上下文 —— 人格 + 技能 + 记忆 + 历史 + 你的消息
↓
③ 模型推理 —— 模型"思考",输出文字回复或工具调用指令
↓
需要调用工具吗?
├── 是 → ④ 执行工具 → 结果回填上下文 → 回到③
└── 否 → ⑤ 流式输出最终回复
↓
⑥ 持久化 —— 写入会话记录,下次还能续上
核心差异哲学:Hermes 把循环做成显式的 9 步生命周期——文档公开、源码可读,每一轮的边界(预算检查、压缩检查、可中断调用)都是明确的一步;OpenClaw 把循环做成六站旅程——从"入队"到"持久化"一镜到底,强调消息在管道里的完整流转。一个像"手术台上的流程清单",一个像"工厂里的流水线"。
逐机制对比
机制一:消息怎么进入循环?
这是两个 Agent 差异最大的地方之一。
Hermes:直接进上下文
你的消息 → 追加到对话历史 → 组装进下一轮 API 请求 → 模型看到
没有队列层。消息进循环的方式简单直接:来了就进。
OpenClaw:串行队列(lane)
每个会话一条专属通道(lane)→ 同一时刻只有一个循环在跑
所有通道汇入全局通道 → 限制总并发数
为什么串行?因为同一场对话里两件事同时干会打架——一个在写文件、另一个在删文件,上下文就撕裂了。OpenClaw 用队列保证「宁可排队,不可乱序」。队列还有四种模式,控制"正在干活时新消息来了怎么办":
| 模式 | 行为 | 适合 |
|---|---|---|
steer(默认) |
新消息注入当前循环,干完当前这步立刻处理 | 日常聊天,感觉最流畅 |
followup |
不打断,排成后续任务 | 长任务进行中 |
collect |
一小段时间内的消息合并成一条再处理 | 群聊刷屏、多平台轰炸 |
interrupt |
中断当前任务,立刻处理新消息 | 紧急插话(“停下!先做这个”) |
Hermes 的对应机制是"可中断调用"(见机制四)——用户新消息可以打断正在进行的模型调用,效果类似 interrupt 模式,但没有显式的队列模式选择。
机制二:上下文组装——Agent 每次"醒来"看到什么
两边思路一致:模型没有记忆,每次推理前都要重新拼一份"眼前的世界"。
| Hermes | OpenClaw | |
|---|---|---|
| 系统提示 | 10 层 Prompt(SOUL.md → 工具指导 → 记忆快照 → Skills 索引 → Context Files → 平台提示) | System Prompt(基础人格 + 技能说明 + 启动文件 + 会话级指令) |
| 历史消息 | 对话历史(OpenAI 兼容格式) | 最近完整消息 + 更早的压缩摘要 |
| 记忆 | MEMORY.md + USER.md 快照 | 记忆召回(相关长期记忆) |
| 本条消息 | 本轮用户输入 | 你刚发的这条消息 |
共同认知:模型每次推理都是"失忆后重新读档案",上下文组装就是"把档案摊到桌上给它看"。摊得越多它越聪明,但桌子(上下文窗口)是有限的。
机制三:思考——模型推理
Hermes:推理内容存进 assistant_msg["reasoning"],可通过 reasoning_callback 显示。模型调用被包在 _interruptible_api_call() 里(见机制四)。消息角色必须严格交替(User → Assistant → Tool → Assistant…),这是模型服务商校验的"交通规则"。
OpenClaw:有一个 Hermes 没有的旋钮——思考级别(Thinking Level):
| 级别 | 含义 |
|---|---|
off |
不思考,直接答(快、省,但容易出错) |
minimal / low |
简单想一下 |
medium |
默认档位 |
high / xhigh / max |
深度思考(慢、贵,但复杂任务更稳) |
可以单条临时指定(/think high 帮我设计这个架构)、设会话默认(/think:high)、或打开思考过程展示(/reasoning on)。思考级别是"深度换质量"的杠杆——简单任务用低档省钱省时,复杂推理用高档求稳。
机制四:工具调用——循环的心脏
这是 Agent Loop 和普通聊天框的分水岭。
Hermes(模型返回带 tool_calls 的响应时):
for each tool_call in response.tool_calls:
1. 从注册表找到工具处理函数
2. 触发 pre_tool_call 插件钩子
3. 检查是否危险命令 → 是则弹批准请求等用户确认
4. 执行工具(传入参数 + task_id)
5. 触发 post_tool_call 插件钩子
6. 把 {"role": "tool", "content": 结果} 追加进历史
- 单个工具调用 → 主线程直接执行;多个 →
ThreadPoolExecutor并发,结果按原调用顺序插回 - 例外:交互式工具(如
clarify)强制串行——要等用户输入 - 部分工具是 Agent 级拦截的(todo/memory/session_search/delegate_task),直接改 Agent 状态,不走注册表
OpenClaw:
模型输出:tool call → web_search({query: "上海 天气"})
↓
OpenClaw 执行工具(真实地访问搜索引擎)
↓
工具返回结果(一大段网页摘要)
↓
结果清洗(截断过长内容、处理图片数据)
↓
回填上下文 → 模型继续思考
- 每一步工具调用都在
tool事件流上广播(start → update → end)——/verbose on看到的就是它 - 回复整形(reply shaping):过滤静默标记
NO_REPLY、合并工具摘要、工具报错时给兜底回复
两边都遵守同一铁律:工具结果不是给用户看的,是给模型看的——它是模型下一步思考的"新事实"。
机制五:防止死循环——钱包保险
模型会卡死循环——反复调同一个工具、拿到同样结果、还不死心。两个 Agent 各有护栏:
| 护栏 | Hermes | OpenClaw |
|---|---|---|
| 迭代预算 | IterationBudget:默认 500(agent.max_turns),子代理独立预算默认 50;预算用尽 → 停止并返回已完成工作的摘要 |
单次循环超时(默认 48 小时 agents.defaults.timeoutSeconds)强制中止 |
| 循环检测 | 无显式工具 | tools.loopDetection.enabled:监控最近的工具调用历史,检测重复模式(默认关闭,小模型建议打开) |
| 压缩后护栏 | 压缩触发按上下文阈值(见机制六) | compaction_loop_persisted:上下文溢出→压缩→重试后仍重复同一 (工具, 参数, 结果) 三元组 → 直接终止 |
| 看门狗 | 可中断调用 + 超时 | 模型长时间不吐字(idle)时看门狗中断请求 |
| 用户取消 | /stop 或新消息打断 |
/stop 或点停止 |
翻译成人话:一个防止"同一个动作做 20 遍还不放弃",一个防止"压缩完记忆还转圈圈烧钱"——这俩都是给钱包上保险的。
机制六:上下文压缩——循环跑久了会"喘气"
循环每转一圈历史就变长,撑爆上下文窗口前必须压缩:
| Hermes | OpenClaw | |
|---|---|---|
| 触发时机 | 预压缩:上下文 > 50%;网关自动压缩:> 85% | 接近上下文上限时自动触发,或手动 /compact |
| 压缩方式 | 提炼关键信息成摘要,继续循环 | 较早的对话总结成摘要,最近的保持原样 |
| 数据安全 | 压缩前需要时刷新记忆 | 压缩前先提醒 Agent"把重要的写进记忆文件"(memory flush)——防止总结把关键细节弄丢 |
| 完整历史 | 保留在会话存储 | 完整历史仍在磁盘上,压缩只改"模型这次看到什么" |
OpenClaw 的比喻:压缩就像期末复习,把整学期的笔记浓缩成一页重点。浓缩完你还能接着学,但细节只能靠记忆文件兜底。
机制七:持久化——干完活,记下来
Hermes:第 9 步返回纯文本时——保存会话、需要时刷新记忆(flush persistent memory before context is lost)。
OpenClaw:第 ⑥ 站把完整记录写回会话文件(transcript),这是 Agent 能"续上"上一轮的原因。写入有细节:会话写锁(session write lock)——任何改写会话记录的操作(正常写入、压缩重写、截断)都要先拿锁,防止多进程同时改坏一个文件。
机制八:子代理——干活循环的"分身术"
一个循环不够用时,两个 Agent 都能派子代理:
| Hermes | OpenClaw | |
|---|---|---|
| 派活工具 | delegate_task |
sessions_spawn |
| 隔离 | 每个子代理独立上下文、独立会话 | 独立会话,默认互相隔离(可开沙箱),不污染主对话 |
| 工具权限 | 子代理有独立工具集 | 默认不继承主代理的会话工具——防止乱动主会话 |
| 完成方式 | 结果回传主代理 | 推送式:主代理派完活结束本轮,子代理干完自动汇报 |
| 预算 | 独立预算,默认 50 次迭代 | 独立 token 开销,批量任务建议配便宜模型 |
| 多智能体雏形 | ✅ | ✅(多个子代理并行干活,最后汇总) |
主 Agent
├─ 派活:去调研选题A ──→ 子代理A(独立会话,并行干活)
├─ 派活:去调研选题B ──→ 子代理B(独立会话,并行干活)
└─ 派活:去调研选题C ──→ 子代理C(独立会话,并行干活)
↓
主 Agent 结束本轮,等子代理们汇报
↓
子代理完成后,结果推送回主会话 → 主 Agent 汇总成最终报告
机制九:可观测与拦截——你能看着它干活
| Hermes | OpenClaw | |
|---|---|---|
| 工具过程 | tool_progress_callback(CLI spinner / 网关进度消息);config display.tool_progress: all |
/verbose on 显示每次工具调用的过程 |
| 思考过程 | reasoning_callback 显示模型推理内容 |
/reasoning on 显示模型思考过程 |
| 状态 | status_callback / step_callback(每轮完成回调) |
/status 看会话状态、压缩次数、模型信息 |
| 干预 | 插件钩子(pre/post tool_call)+ 危险命令审批 | Hook 钩子:循环各节点可插脚本拦截(推理前注入、工具前审批、循环后检查)——自动化/定时任务接进循环的入口 |
/status 里有个隐藏信息:🧹 Compactions: <次数>——压缩次数越多,说明对话越"长寿"。
全景对比
| 能力 | Hermes | OpenClaw |
|---|---|---|
| 思考 → 动手 → 观察 → 再思考 | ✅ 9 步 Turn Lifecycle | ✅ 六站旅程 |
| 消息进入方式 | 直接进上下文 | 串行队列(lane)+ 四模式 |
| 思考级别调节 | ❌ 无显式旋钮 | ✅ /think off~max |
| 多工具并发执行 | ✅ ThreadPoolExecutor | ✅ 工具事件流 |
| 中途打断/改主意 | ✅ 可中断 API 调用 | ✅ steer/interrupt 队列模式 |
| 迭代预算 | ✅ 默认 500(本机 150) | ✅ 循环超时 48h |
| 卡死循环检测 | ❌ 无显式检测 | ✅ loop detection + 压缩后护栏 |
| 上下文压缩 | ✅ 50% / 85% 双阈值 | ✅ 自动 + /compact |
| 压缩前记忆兜底 | ✅ 刷新记忆 | ✅ memory flush |
| 持久化 | ✅ 会话保存 | ✅ transcript + 会话写锁 |
| 子代理 | ✅ delegate_task | ✅ sessions_spawn |
| 可观测 | ✅ 回调 + tool_progress | ✅ /verbose /reasoning /status |
| 循环拦截 | ✅ 插件钩子 + 危险命令审批 | ✅ Hook 钩子 |
能做 / 不能做
| 能做 ✅ | 不能做 ❌ |
|---|---|
| 多步推理:思考→动手→观察→再思考(两边都是) | 无限循环——预算/超时/护栏会收尾 |
| 循环中随时调用工具(搜索/读文件/执行命令) | 不能同时回答和干活——每轮只能选一个 |
| 中途被打断,重新调整方向 | 被打断时已开始的工作会丢弃(不保留半截状态) |
| 多个工具并行执行 | 交互式工具(提问/审批)不能并行 |
| 长时间任务通过压缩机制持续运行 | 上下文超出窗口前必须压缩,压缩会丢细节 |
| 子代理并行干活,最后汇总 | 子代理有独立预算/开销,不是免费分身 |
人类类比
理解 Agent Loop,可以想象一个刚入职、干劲十足的新员工:
| Agent Loop 概念 | 类比 |
|---|---|
| 收到任务 | 老板把你叫到工位,交代一个活儿 |
| 思考 | 你在心里盘算:这活儿该怎么做、分几步 |
| 调用工具 | 你打开电脑查资料、翻文档、打电话问同事 |
| 观察结果 | 你看到查到的资料、同事的回答 |
| 再思考 | 根据新信息调整做法 |
| 输出答案 | 你交活,把结果汇报给老板 |
| 串行队列 | 公司规定一个工位一次只能干一件事,排队处理 |
| 消息打断 | 老板随时能打断你:“先别弄这个了,改做那个” |
| 迭代预算 | 公司规定加班最多到晚上 9 点,到点必须下班汇报 |
| 上下文压缩 | 干了一整天,你翻备忘录把重点记下来,忘掉细节 |
| 子代理 | 忙不过来时叫帮手,各干各的,最后汇总给你 |
关键区别:人类可以一心多用,Agent 一次循环只能专注一件事——但它循环得极快(一轮只需几秒),而且从不觉得重复枯燥。
选择指南
| 场景 | 更推荐 |
|---|---|
| 想要完整的循环架构文档、能读源码研究机制 | Hermes(9 步生命周期完全公开) |
| 群聊刷屏、多平台轰炸时消息不乱套 | OpenClaw(collect 模式合并处理) |
| 想按任务难度调节思考深度(省 token) | OpenClaw(/think 级别旋钮) |
| 用本地小模型(7B-30B),怕卡死循环烧钱 | OpenClaw(loop detection 可开) |
| 需要细粒度控制循环中的每一步 | Hermes(插件钩子 + 危险命令审批) |
| 希望开箱即用、命令简单(/verbose /status) | OpenClaw |
| 子代理批量并行调研 | 两者都可以(delegate_task / sessions_spawn) |
本系列完结
到这里,《AI Agent 对比系列》五篇全部完成:
| # | 主题 | 核心一句话 |
|---|---|---|
| 01 | 入门篇 | AI Agent = 有手有脚有脑子,你派活它干 |
| 02 | 记忆系统篇 | AI 没有真正的记忆,它靠读写文件来模拟 |
| 03 | 工具系统篇 | 手脚 = 工具系统,能力边界由工具决定 |
| 04 | 感知系统篇 | 没有感官,一切感知都是"把世界转成文本塞进上下文" |
| 05 | Agent Loop 篇 | 本质是循环:思考 → 动手 → 观察 → 再思考 |
从"是什么"到"怎么记忆"、“怎么动手”、“怎么感知”、“怎么干活”——五篇合起来,就是 AI Agent 的完整解剖图。理解这些,你就理解了市面上任何 Agent 产品的底层逻辑:它们都是"大模型 + 循环 + 工具 + 记忆"的不同组合,区别只在设计和取舍。
两个 Agent 的完整独立版本可从各自工作区获取,对照阅读,最能体现不同设计哲学。
信息源声明
- Hermes 信息来源:Agent Loop Internals、Tools、本地
config.yaml(agent.max_turns: 150、display.tool_progress: all)、本地工作日志实测 - OpenClaw 信息来源:docs.openclaw.ai/concepts/agent-loop、docs.openclaw.ai/concepts/queue、docs.openclaw.ai/concepts/context-engine、docs.openclaw.ai/concepts/compaction、docs.openclaw.ai/tools/thinking、docs.openclaw.ai/tools/loop-detection、docs.openclaw.ai/tools/subagents、OpenClaw 本地运行时文档
本文以 Hermes 的分析框架为主线组织,融合 OpenClaw 的视角进行对比。两个 Agent 的完整独立版本可从各自工作区获取。
本系列通过对比两个真实运行的开源 AI Agent——OpenClaw 和 Hermes——来解构 AI Agent 的本质,到此全五篇完结。
更多推荐


所有评论(0)