一场对不上频道的讨论
聊 Agent 架构时,这几个词总是同时出现:
ReAct、Agent Loop、Harness、Loop Engineering、Graph Engineering
大多数人会下意识地把它们排成一个"从小到大"的同心圆:ReAct 最里面,外面套 Agent Loop,再外面套 Harness,最外面是 Loop Engineering。
这个排法是错的。而且错得很隐蔽——它看起来很整齐,但会让两个人在讨论架构时一直对不上频道。
真正的原因是:
这些词根本不在同一个分类轴上。
它们分别是:一个模式、一个程序、一个系统、两个工程方法。
你没法把"菜谱、厨师、餐厅、管理方法"排成大小顺序——它们压根不是同类东西。
先看这张表
| 概念 | 它是什么类型 | 一句话 |
|---|---|---|
| ReAct | 模式 | 推理 → 行动 → 观察,再根据观察继续推理 |
| Agent Loop | 程序 | 真正去调模型、执行工具、回填结果、管生命周期的那段代码 |
| Harness | 系统 | 包含 Agent Loop,再加上模型、工具、状态、权限、沙箱、存储、界面 |
| Loop Engineering | 工程方法 | 怎么把一个循环设计得可靠(触发、目标、验证、重试、预算、停止) |
| Graph Engineering | 工程方法 | 怎么把多个工作单元连成图(节点、边、共享状态) |
看清"类型"这一列,混乱就消失了大半。
用一家餐厅讲清楚
上一篇用"公司"理解 Harness 的部件,这一篇换个更贴切的比喻——餐厅:
ReAct = 菜谱 (做这道菜的思路:先尝味道,再决定加什么) Agent Loop = 厨师 (按菜谱真正动手的那个人) Harness = 整个餐厅 (厨房、仓库、门禁、订单系统、前台,缺一不可) Loop Eng. = 厨师的工作规程 (做失败了重做几次?谁来验菜?超时怎么办?) Graph Eng. = 后厨的流水线设计 (配菜 → 炒制 → 摆盘 → 质检,谁接谁,失败退回哪一步)"菜谱比厨师小吗?"—— 这个问题本身就不成立。它们不是一个维度的东西。
ReAct:一种工作节奏
经典的 ReAct 长这样:
想:得先看看登录代码 做:read(login.ts) 看:文件里 Token 没有设过期时间 想:需要改一下再测 做:edit(login.ts) 看:改好了 做:test 看:测试通过 答:问题已修复有个容易误会的点:现代模型不需要真的输出"想/做/看"这些标签。在 DeepSeek Harness 里,它表现为:
模型请求 → 结构化的 tool-call → 系统执行 → tool-result → 新的模型请求所以准确的说法是"ReAct 风格"——描述的是行为结构,不代表系统里实现了一套独立的 ReAct 协议层。
Agent Loop:把节奏跑起来的那段程序
它回答的是一个很具体的问题:
谁负责真正调用模型、收集工具调用、执行工具、决定要不要再问一次模型?
除了这条主线,它还管:待办队列、轮次和步骤、流式输出、工具并行与结果顺序、取消和错误收敛、事件边界。
DeepSeek Harness 里这个程序的类名就叫ReactLoopAgent——名字本身就说明了它和 ReAct 的关系:它是 ReAct 风格的一个实现,不是 ReAct 的"子模块"。
Harness:让循环能真实、安全、可恢复地跑
Harness 回答的是另一个问题:
要让这个循环在真实世界里跑起来,还缺什么?
缺的东西相当多:模型适配器、工具注册表、提示词组装、会话日志、持久化、审批与沙箱、上下文压缩、子 Agent 与工作流、各种入口(网页 / 终端 / SDK)。
厨师会做菜 ≠ 你有一家餐厅。还得有厨房、进货、门禁、订单和前台。
唯一严格的包含关系
这些概念之间,只有一条是严格的软件结构关系:
Harness ──包含──► Agent Loop(一个插件) Agent Loop ──实现──► ReAct 风格 ← 这是"采用",不是"包含" Loop / Graph Engineering ┄┄分析和设计┄┄► 上面这些 (不是代码里的模块)三条线三种关系,别混:
- 包含:Harness 里真的有 Agent Loop 这个插件,可以在插件清单里找到
- 实现:Agent Loop 采用了 ReAct 这种行为模式,但 ReAct 不是一个能被卸载的服务
- 分析:Loop / Graph Engineering 是你用来设计和评价这套系统的思维工具,代码里没有同名的东西
最后一条特别重要,因为它最容易被当成"系统里的一层":
Loop Engineering 和 Graph Engineering 不是运行时抽象,是行业讨论和教学用的术语。
你在源码里搜不到LoopEngineering这个类,因为它本来就不该在那儿。
Loop Engineering:到底在问什么
既然它不是代码,那它是什么?它是一组你必须回答的设计问题:
| 问题 | 在问什么 |
|---|---|
| Trigger | 什么事件触发一次工作? |
| Goal | 目标是什么、怎么保持不跑偏? |
| Gate | 谁来判断"真的完成了"? |
| State | 跨轮次的进度存在哪? |
| Retry | 失败了退回到哪一步? |
| Budget | 最多几轮、多少 token、多少钱、多长时间? |
| Stop | 什么时候强制停下、或者交给人? |
一句话概括两者分工:
Agent Loop 解决"这一轮里,模型下一步做什么"。
Loop Engineering 解决"这一轮结束后,要不要再来一轮、谁来验收"。
用修 Bug 举例最清楚:
- Agent Loop 负责:让同一个 Agent 读文件、改代码、跑测试
- Loop Engineering 负责:规定"测试必须由独立程序判定、失败最多重启 5 轮、超过 30 分钟就停下报告"
后面那句是部署者的流程设计,不是循环本身自带的保证。
这里有个特别值得注意的现实:DeepSeek Harness 提供了一些搭外循环的积木(连续轮次、子 Agent 轮次、工作流编排、定时触发),但这些积木不自动等于一套好的 Loop Engineering。比如有的多轮工具,"是否完成"主要靠执行者自己上报,缺少独立评估器和完整的费用/时间预算。
积木是系统给的,怎么搭是你的事。这也是为什么它叫"工程方法"而不是"功能"。
Graph Engineering:多个单元怎么连
如果说 Loop 关注"一个单元怎么反复改进",Graph 关注的是"多个单元怎么连"。它只有三个概念:
| 概念 | 是什么 | 餐厅里对应 |
|---|---|---|
| Node(节点) | 干活的单元 | 配菜工、炒锅、质检员 |
| Edge(边) | 干完之后去哪 | 配好菜送去炒,炒糊了退回重来 |
| State(状态) | 大家共享的档案 | 订单、当前进度、返工次数、预算 |
关键一点:节点不一定是 Agent。它可以是普通函数、自动化测试,甚至是"人工审批"这一步。
需求分析 ─┬─► 前端 Agent ─┐ └─► 后端 Agent ─┴─► 合并 ─► 自动测试 ─┬─ 通过 ─► 人工审批 ─► 发布 ▲ │ └── 失败退回 ─┘什么时候用 Loop,什么时候画 Graph
一个很实用的判断标准:
| 情况 | 选什么 | 为什么 |
|---|---|---|
| 下一步取决于探索结果 | 单个 Agent Loop | 比如查一个未知的 Bug——读完才知道下一步查哪,画不出图 |
| 流程能稳定画在白板上 | Graph | 比如"需求 → 两路实现 → 合并 → 测试 → 审批",路线固定,图更可控 |
而且大多数真实系统是混着来的:
外层用 Graph 规定节点之间的路线,每个复杂节点内部跑一个 Loop。
顺便破一个迷思:Graph 不一定比"自由发挥的 Agent"更先进。稳定、可审计的流程适合画成显式图;高度探索性的任务,反而应该让 Agent 自己决定下一步。
顺带澄清:DAG 和那个"DCG"
DAG = Directed Acyclic Graph(有向无环图):箭头有方向,且沿箭头走不回原点。
一个常见误解是"DAG 只能是一条直线"——错的,DAG 完全可以分支和并行:
需求 ─┬─► 前端 ─┐ └─► 后端 ─┴─► 合并 ─► 测试 ─► 发布这依然是 DAG。"无环"限制的是回路,不是分支。
但 Agent 的工作经常需要回路:
编码 ──► 测试 ▲ │ └── 失败 ─┘ 通过 ──► 发布这就是一张有环的有向图。这里有个术语上的坑值得提醒:
"DCG"不是"有向有环图"的通用标准缩写。它在不同领域可能指别的东西。
想表达"图里允许有环",最稳妥的说法就是直说"允许环的有向图",别用未定义的缩写。
还有一点:有环 ≠ 一定死循环。工程上必须补退出规则——测试通过、达到最大尝试次数、超时、预算耗尽、用户取消、或者转人工。这又绕回 Loop Engineering 了。
五个常见误解
| 误解 | 实际 |
|---|---|
| ReAct 就是 React.js | 毫无关系,只是名字像 |
| Agent Loop 就是整个 Harness | Agent Loop 只是 Harness 里的一个插件 |
| Loop / Graph Engineering 是系统里的一层 | 是分析设计方法,代码里没有同名模块 |
| Graph Engineering 是 Loop Engineering 的"下一代" | 不是替代关系,关注轴不同,可以组合 |
| 图一定是 DAG | Agent 的图经常包含受限的重试环 |
下一篇
《DeepSeek Harness 架构拆解(三):Agent Loop》会钻进那个"厨师"内部:Turn 和 Step 到底怎么划分、待办队列怎么工作、历史是怎么每次重新拼出来的、工具并行执行时结果怎么保证不乱序。