导读: 随着时间推移,大语言模型(LLM)的智能化也越来越惊艳,但从"能聊天"到"能替人类干活",中间隔着极其庞大的工程鸿沟。AI 应用,也出现了越来越多的名词和概念,从最初的 Prompt 提示词,到提示词工程、到上下文工程、到 CoT 思维链、ReAct 模式,再到如今企业级落地不可或缺的Agent、AgentLoop、 Loop Engineering 与 Harness Runtime,Agent 的技术栈究竟经历了怎样的演进?在真正的工程代码和繁杂的概念中,我们到底要做什么?这是我梳理这次文章的一个核心原因。


文章说明
  本文在主线叙事之外,设置了两处 【延伸辨析】,对"Agent Loop 与 Loop Engineering 的边界"以及"Harness 的真实能力边界"做进一步的多维分析。主线帮你建立框架,辨析帮你打破框架。
  为了便于更好的理解演进关系,本文的结构说明与层次关系如下,事先说明,主线逻辑是为了便于理解、建立初识不具备严格意义上的准确性(但也是相对准确的),后面的辨析才是一些思考和打破

  亦即 **主线帮你建立框架,辨析帮你打破框架。先建后破,才是完整的理解。**
层次 内容 作用 建议读法
主线(§1-§6, §8-§11) 8 阶演进 + 5 层架构 + 实例 建立完整框架 通读
延伸辨析一(§3) Agent Loop vs Loop Eng 的边界问题 打破"线性阶段"的思维定式 读完 §2 后读,理解"为什么分 8 阶但又不是严格 8 阶"
延伸辨析二(§7) Harness 的真实能力边界 理解"一层"与"一个范式"的区别 读完 §6 后读,理解"5 层架构是 Harness 的内部结构"
文章的层次关系:

主线叙事:  1 → 2 → [辨析一] → 4 → 5 → 6 → [辨析二] → 8 → 9 → 10 → 11
                  建立框架    打破框架         深化框架    再次打破    收束

辨析一:在"讲完8阶演进区别"之后,会告诉你"区别没那么严格",概念与工程有中间地带
辨析二的位置:在"讲完 5 层"之后,立刻告诉你"概念只是概念,除了模型,其他都可以算是 Harness 和它的内部"

进入正文

一、Agent 的演进简史:大模型如何走向物理世界?

大模型技术的发展,本质上是 “大模型从纯文本概率生成,逐步走向生产级物理世界交接” 的过程。我们可以将这一演进划分为 8 个阶段:

[1. LLM]              ➔ 概率文本生成 (无结构、无推理)
    │
[2. Prompt Engineering] ➔ 引入上下文约束与格式控制 (静态规则)
    │
[3. CoT (思维链)]       ➔ 引入显式推理链 (Think Step-by-Step)
    │
    │  ────── 以上三个阶段:模型始终在"闭门造车" ──────
    │
[4. Agent 抽象]         ➔ 概念提出:定义四要素 (Tools + Memory + Planning + Action)
    │
[5. ReAct Engine]       ➔ Agent 的第一个工程实现 (Thought ➔ Action ➔ Observation)
    │
[6. Agent Loop]         ➔ 动态多轮控制 (Round/Step 重试与状态路由)
    │
[7. Loop Engineering]   ➔ 确定性质量保障 (Context 压缩 + 物理验证)
    │
[8. Harness Runtime]    ➔ 安全基座与资源熔断 (Sandbox + Guardrails + Budget)

1.1 前三个阶段:模型始终在"闭门造车"

这是理解整条演进线的关键分水岭。

LLM、Prompt Engineering、CoT,这三者看起来是三个"阶段",但它们的本质是同一件事

模型基于自己训练时学到的既有知识,进行生成或推理。它没有获取新知识的能力,没有与外部世界交互的通道。

阶段 做了什么 没做什么
LLM 基于训练语料做 Next-Token Prediction 不能查数据库、不能调 API、不能读文件
Prompt Eng 用 System Prompt 约束输出格式和角色 约束是静态的,模型的知识边界没变
CoT 引导模型 “Let’s think step by step”,显式拆解推理 推理链再长,也只是在"已有知识"里打转
# 这三个阶段,代码本质上都是这样:
response = llm.generate(prompt)   # 一进一出,没有外部交互
# 不管 prompt 写得多花哨、推理链拉得多长
# 模型能调用的"知识"永远是训练截止日之前的那些参数
# 它不知道今天的天气、不知道你的数据库里有什么、不知道刚才那条命令跑出了什么

CoT 的局限性尤其值得强调:

用户:2024年Q3,公司A的营收同比增长了多少?

CoT 的"推理":
  Step 1: 我需要找到公司A的2024Q3营收...
  Step 2: 根据我的知识,公司A的营收大约是...  ← 幻觉!它根本不知道!
  Step 3: 同比增长率 = (本期-同期)/同期 × 100%
  Step 4: 所以答案是 15.3%  ← 一本正经地胡说八道

CoT 让模型"看起来在思考",但思考的原材料只有参数里的旧知识。没有外部输入,推理链越长,幻觉越精致。

这就是为什么我们需要 Agent——给模型接上手和脚,让它能真正"获取新知识"。

1.2 Agent:一个概念定义,不是一段代码

2023 年前后,学术界和工业界提出了 Agent(智能体) 的概念,明确了四个核心要素:

Agent = Tools(工具) + Memory(记忆) + Planning(规划) + Action(行动)

但请注意:

Agent 只是一个"接口定义",它告诉你"一个智能体应该有什么",但没有告诉你"物理上怎么跑起来"。

这就像面向对象编程里写了一个 interface

# Agent 只是一个抽象定义
class Agent(ABC):
    tools: List[Tool]          # 能用什么工具?
    memory: Memory             # 怎么记住东西?
    planning: Planner          # 怎么拆解任务?
    
    @abstractmethod
    def act(self, task) -> Result:   # 具体怎么跑?不知道。
        ...

它没有回答:

  • 思考和行动的循环怎么组织?
  • 工具调用的结果怎么喂回去?
  • 失败了怎么重试?
  • 上下文爆了怎么办?
  • 谁来验证结果对不对?

这些问题,需要具体的工程实现来回答。

1.3 ReAct:Agent 的第一个工程实现

ReAct(Reasoning + Acting) 是 Agent 概念落地的第一个、也是最经典的实现范式。它把 Agent 的抽象定义,变成了一段真正能跑的代码:

# ReAct:把 Agent 的"四要素"变成了"一个循环"
def react(task, tools, max_steps=10):
    messages = [{"role": "user", "content": task}]
    
    for step in range(max_steps):
        # Planning + Reasoning(对应 Agent 的 Planning)
        response = llm.chat(messages, tools=tools)
        
        if not response.has_tool_calls():
            return response.text           # LLM 认为做完了
        
        # Action(对应 Agent 的 Action + Tools)
        for call in response.tool_calls:
            result = execute_tool(call)    # ← 真正与外部世界交互!
            
            # Observation → Memory(对应 Agent 的 Memory)
            messages.append(result)        # 结果压回上下文
    
    return "MAX_STEPS_REACHED"

ReAct 的历史意义:它第一次让 LLM 从"闭门造车"走向了"边想边做"。
模型不再只是生成文本,而是真正调用工具、获取外部信息、基于新信息继续推理。

但 ReAct 只是 Agent 的"最小可行实现",它留下了大量工程问题:

ReAct 解决了什么 ReAct 没解决什么
✅ 模型能调用工具了 ❌ 失败了怎么办?(没有重试机制)
✅ 工具结果能喂回去了 ❌ 上下文爆了怎么办?(没有压缩)
✅ 能多步推理了 ❌ 谁来验证结果对不对?(LLM 自己说了算)
❌ 死循环了怎么办?(只有 max_steps 保险丝)
❌ 安全吗?(LLM 可以执行任何命令)

后续所有演进(Agent Loop → Loop Engineering → Harness),都是在填 ReAct 留下的这些坑。

1.4 各阶段核心边界与演进逻辑(完整版)

阶段 核心突破 本质 痛点 / 天花板
LLM Next-Token Prediction 基于既有知识生成 无逻辑约束、幻觉、无外部感知
Prompt Eng System Prompt 约束格式 基于既有知识 + 静态规则 规则脆弱,知识边界没变
CoT 显式分步推理 基于既有知识 + 内部推理链 闭门造车,无外部交互,幻觉更精致
Agent 定义 Tools/Memory/Plan/Action 概念定义,非运行代码 只是接口,没有实现
ReAct Thought → Action → Observation Agent 的第一个工程实现 无重试、无验证、无安全、易死循环
Agent Loop 多轮重试 + 报错塞回 让 ReAct 循环跑得更久 还是 LLM 自己判断成功与否
Loop Eng 上下文压缩 + 物理验证 用代码替代 LLM 做裁判 不管物理安全与硬件资源
Harness 沙箱 + Guardrail + 熔断 物理铁笼 最终防线,LLM 绝不可绕过

二、核心问题:都是"循环",到底有什么区别?

这是全文最关键的一节。 很多人看完演进图会问:ReAct 是循环,Agent Loop 是循环,Loop Engineering 也是循环——它们到底有什么不同?

2.1 先看代码骨架

# ═══ ReAct 循环 ═══
for step in range(max_steps):              # max_steps 只是保险丝
    response = llm.chat(messages, tools)
    if not response.has_tool_calls():      # ← LLM 说"我做完了" → 退出
        return response.text
    messages.append(execute(response))
# 正常情况:LLM 自己决定什么时候停


# ═══ Agent Loop ═══
for round in range(max_rounds):            # 多轮重试
    result = react(messages, tools)        # ← 内部跑一轮 ReAct
    if result.success:                     # ← 还是 LLM 判断成功与否
        return result
    messages.append(f"[Error]: {result.stacktrace}\nPlease fix.")
# 本质:一个"更持久的 ReAct",控制权仍在 LLM


# ═══ Loop Engineering ═══
while True:                                # ← 注意:这里真的用 while
    cont, reason = should_continue(state)  # ← 多维度终止判断(代码决定)
    if not cont:
        return Result(status=reason)
    
    result = react(state, tools)           # ← LLM 只是被调用的一个函数
    passed = run_tests(state)              # ← 代码跑 pytest,客观验证
    if passed:
        return Result(status="SUCCESS")    # ← 代码说"过了"才算完
    
    state = correct(state, strategy)       # ← 代码强制纠偏
# 正常情况:外部验证器决定什么时候停

2.2 五个维度的深层对比

① 谁决定"转不转"?
ReAct Agent Loop Loop Engineering
退出条件 llm.wants_to_continue() llm.judge(success) run_tests().passed
控制权 LLM LLM(加了辅助) 代码
风险 LLM 幻觉 → 提前放弃或死循环 同左,只是能撑更久 代码兜底,不可能被幻觉骗过

ReAct 和 Agent Loop 的退出是"主观的"(LLM "觉得"完了)。
Loop Engineering 的退出是"客观的"(测试跑过了没有、预算超了没有)。

② 循环是"扁平"还是"分层"?
ReAct / Agent Loop:扁平循环(认知循环)
┌───────────────────────────────────────────────────┐
│  think → act → observe → think → act → observe → ... │
│  每一轮结构完全相同,没有层级                           │
│  模拟的是:一个人在"想→做→看→再想"                    │
└───────────────────────────────────────────────────┘

Loop Engineering:分层循环(生产流程)
┌──────────────────────────────────────────────────────────┐
│  外层(代码): check → [内层] → verify → correct → check  │
│  ┌──────────────────────────────────────────────┐        │
│  │  内层(LLM): think → act → observe           │        │
│  └──────────────────────────────────────────────┘        │
│  外层每一轮的结构 ≠ 内层每一轮的结构                      │
│  模拟的是:一条生产线"上料→加工→质检→返工→出厂"          │
└──────────────────────────────────────────────────────────┘

ReAct 的循环是"一个人在想"。Loop Engineering 的循环是"一条线在转"。
人在线里面,不是线在人里面。

③ 每一轮迭代是"同质"还是"异质"?
# ReAct:每一轮结构完全一样(无状态的重复)
for step in range(max_steps):
    thought = llm.think(context)    # 同样的思考
    action  = llm.act(thought)      # 同样的工具集
    result  = execute(action)       # 同样的执行
    # 第 1 轮和第 10 轮,结构上没有任何区别
    # LLM 可能用完全相同的错误方法试 10 次


# Loop Engineering:不同轮次,结构不同(有状态的演进)
for i in range(max_iterations):
    if i % 5 == 0:
        context = compress(context)                    # 定期压缩
    tools = get_tools_for_strategy(strategy)           # 按策略给工具
    react(context, tools, hint=strategy.hint)          # 按策略给提示
    if same_error_count >= 3:
        strategy = next_strategy()                     # 强制换道
    # 第 1 轮和第 4 轮,结构上完全不同
④ 循环有没有"自我意识"?
能力 ReAct Agent Loop Loop Engineering
知道自己转了几轮? iteration
知道同一个错犯了几次? ❌(LLM 可能"忘了") same_error_count
知道自己花了多少 Token? 模糊 budget_tracker
知道当前用什么策略? strategy 状态机
能主动改变自己的行为? ✅ 代码强制切换

ReAct 循环是"无记忆的金鱼"——每一轮只看上下文窗口里还剩什么。
Loop Engineering 循环是"有笔记本的工程师"——记录错误次数、策略历史、预算消耗。

⑤ 验证是"内省"还是"外检"?(最本质的区别)
# ReAct 的"验证":LLM 自己看结果,自己判断对不对
result = execute(action)
context.append(result)
# 然后 LLM 在下一轮 think() 时"看到"这个结果
# 它自己判断:"嗯,看起来对了" ← 可能是幻觉!
# 没有任何外部机制检验它判断得对不对


# Loop Engineering 的验证:代码跑真实测试
react_result = react(state)
verification = subprocess.run("pytest tests/ -x")   # ← 客观事实
if verification.returncode != 0:
    # 不管 LLM 说"我觉得修好了",测试没过就是没过
    state.record_failure(parse_errors(verification.stderr))

ReAct:LLM 既是运动员又是裁判。
Loop Engineering:LLM 是运动员,代码是裁判,测试用例是规则手册。

2.3 一个类比彻底讲透

ReAct = 一个聪明人在房间里自己修水管
  - 他看看哪里漏水(think)→ 拧一下阀门(act)→ 看看还漏不漏(observe)
  - 他自己觉得不漏了,就走了(终止)
  - 但如果他判断错了呢?没人知道。
  - 如果他一直拧同一个阀门呢?没人拦他。
  - 如果他在里面待了 10 个小时呢?没人管。

Agent Loop = 同一个人,但给了他更大的房间和更好的记忆
  - 他还是自己修、自己判断、自己决定走不走
  - 只是房间更大了(上下文管理),不会忘事(持久化)
  - 本质没变:还是一个人自己搞

Loop Engineering = 一个装修工程管理体系
  - 工人(LLM)负责干活
  - 监理(代码)每干完一步就验收(run_tests)
  - 验收不过?监理说"换个方案"(策略切换)
  - 同一个问题返工 3 次?监理说"换个人来"(升级)
  - 预算超了?监理说"停工"(budget)
  - 要动承重墙?监理说"等业主签字"(审批)
  - 工人不需要知道这些规则,他只管干活

三、【延伸辨析一】Agent Loop 和 Loop Engineering 真的有严格边界吗?

上面的对比看起来非常清晰:Agent Loop 是"LLM 说了算",Loop Engineering 是"代码说了算"。但如果你真的去写代码,你会发现这条线画不出来

3.1 边界是怎么模糊的

# ═══ 这算 Agent Loop 还是 Loop Engineering?═══

class AgentLoop:
    def run(self, task, max_rounds=10):
        messages = [system(prompt), user(task)]
        
        for round in range(max_rounds):
            result = react(messages, tools)
            
            if result.exit_code == 0:        # ← 这算"物理验证"吗?
                return SUCCESS
            
            messages.append(f"[Error]: {result.stderr}")  # ← 这算"报错塞回"吗?
            
            if same_error_3_times(result):   # ← 这算"进展检测"吗?
                return ABORT
        
        return MAX_ROUNDS

你告诉我,上面这段代码:

  • exit_code == 0 是"物理验证"(Loop Eng)还是"工具调用结果判断"(Agent Loop)?
  • same_error_3_times 是"自校正策略"(Loop Eng)还是"提前止损"(Agent Loop)?
  • max_rounds 是"预算控制"(Loop Eng)还是"循环上限"(Agent Loop)?

答案是:都是。同一段代码,你叫它 Agent Loop 也行,叫它 Loop Engineering 也行。

3.2 "加一个功能"边界就消失了

# 版本 A:你叫它 Agent Loop
for round in range(10):
    result = react(messages, tools)
    if result.success:          # LLM 说成功
        return result
    messages.append(error)

# 版本 B:加了一行 pytest,现在叫 Loop Engineering?
for round in range(10):
    result = react(messages, tools)
    if subprocess.run("pytest").returncode == 0:   # ← 就加了这一行
        return result
    messages.append(error)

# 版本 C:加了上下文压缩,现在"更 Loop Engineering"了?
for round in range(10):
    if len(messages) > 50000:
        messages = compress(messages)              # ← 又加了一行
    result = react(messages, tools)
    if subprocess.run("pytest").returncode == 0:
        return result
    messages.append(error)

从 A 到 B 到 C,你加了两行代码,就从"Agent Loop"变成了"Loop Engineering"?

这显然不是工程现实。这是叙事需要

3.3 诚实的结论:它是一个光谱,不是台阶

控制权在 LLM ◄──────────────────────────────────────► 控制权在代码

  ReAct        Agent Loop        "中间地带"        Loop Eng       Harness
  │              │                  │                 │              │
  LLM决定停    LLM决定停         混合决定           代码决定停     代码决定一切
  无验证       简单重试          有验证但LLM可覆盖   代码验证为准   代码完全接管
  无预算       max_rounds        有预算但宽松       多维预算       硬性熔断

中间地带非常大。 大多数生产系统落在中间:

# 真实生产代码(不属于任何"纯"阶段)
for round in range(config.max_rounds):          # 代码设上限
    if budget.exceeded():                        # 代码管预算
        break
    result = react(messages, tools)              # LLM 干活
    if result.exit_code == 0:                    # 代码验证
        return SUCCESS
    if same_error_count >= 3:                    # 代码检测卡死
        strategy = next_strategy()               # 代码换策略
    messages = maybe_compress(messages)          # 代码管上下文
    messages.append(format_error(result))        # 代码格式化

你没法说这是"Agent Loop"还是"Loop Engineering"。它两者都是,或者说,这个分类本身就不该是互斥的。

3.4 那这个分类到底有没有用?

有,但不是作为"阶段",而是作为"决策清单"。

真正有意义的不是"我在第几阶段",而是对每一个决策点,谁说了算

决策点 选项 A(信任 LLM) 选项 B(代码接管) 你选哪个?
什么时候停? LLM 说"做完了" pytest exit_code == 0
失败了怎么办? 把错误塞回去让 LLM 自己想办法 代码检测同错 3 次 → 强制换策略
上下文满了怎么办? 不管(等 LLM 自己遗忘) 代码截断/压缩
转了多少轮? LLM 不知道 代码计数 + 多维预算
能执行什么命令? LLM 随便调 白名单 + AST 拦截
花多少钱? 不知道 Token/时间/成本三维预算

所谓"从 Agent Loop 演进到 Loop Engineering",本质上就是:把上面这张表里的选项,从 A 列逐步搬到 B 列。

它不是一个"阶段跃迁",而是一组独立的工程决策,你可以逐个做,也可以只做其中几个。

3.5 那为什么上文要先分成 8 个阶段?

主要是为了让大家现有线性、感性的认知,但实际中,落到工程角度,就发现其实边界并没有那么绝对。

上文的8个阶段(线性):
  1 → 2 → 3 → 4 → 5 → 6 → 7 → 8
  "你必须先有 Agent Loop,才能做 Loop Engineering"

工程现实(网状):
  你可以同时做:
  - 上下文压缩(所谓 L7 的能力)
  - 简单的 max_rounds(所谓 L6 的能力)
  - pytest 验证(所谓 L7 的能力)
  - 但没有策略切换(L7 的另一个能力)
  - 也没有沙箱(L8 的能力)
  
  你不需要"先完成 L6 再做 L7"
  它们是正交的工程决策,不是前置依赖

唯一的真实依赖是:

  • 你得先有 ReAct(L5),才有东西可以"循环"
  • 你得先有循环,才有东西可以"治理"
  • 你得先有代码在跑,才有东西可以"关进沙箱"

除此之外,上下文压缩、物理验证、策略切换、预算控制、沙箱隔离——它们是独立的工程模块,可以任意组合。

3.6 小结:怎么理解"8 阶演进"这个框架

问题 回答
Agent Loop 和 Loop Eng 有严格边界吗? 没有。 是光谱,不是台阶
那为什么文章要分开讲? 教学需要线性叙事,但工程现实是正交决策的组合
真正有意义的区分是什么? 不是"第几阶段",而是每个决策点:LLM 说了算还是代码说了算
实践中怎么选? 按风险等级逐个叠加:先加验证 → 再加预算 → 再加沙箱。不需要"先完成上一阶段"
一句话总结? 所谓"演进",不是从 A 阶段毕业进入 B 阶段,而是围绕同一个 ReAct 循环,逐步把决策权从 LLM 手里收回到代码手里。收多少、收哪些,取决于你的风险容忍度。

如果你的直觉告诉你"这两个概念之间找不到一条’加了这一行代码就从 A 变成 B’的清晰线"——你的直觉是对的。它们就不是两个阶段,而是同一件事的两个程度。


四、实践追问:max_iterations 到底谁定?怎么定?

你可能会问:Loop Engineering 说"代码决定转几圈",但你不能确定一个任务到底是简单还是复杂,设大了浪费,设小了做不完。(实际场景,甚至Agen Loop 、ReAct 可能都会去定义一个max_iterations)

答案是:max_iterations 根本不是主要控制手段。它只是最后一道保险丝。

真正控制循环的是 多维度约束的叠加

def should_continue(state, config) -> tuple[bool, str]:
    
    # ① 正向终止:验证通过(这才是"正常出口")
    if state.last_verification.all_passed():
        return False, "SUCCESS"
    
    # ② 预算约束:Token 花完了
    if state.tokens_used > config.token_budget:
        return False, "BUDGET_EXCEEDED"
    
    # ③ 时间约束:超时了
    if elapsed() > config.time_limit:
        return False, "TIMEOUT"
    
    # ④ 成本约束:钱花完了
    if state.cost > config.cost_limit:
        return False, "COST_EXCEEDED"
    
    # ⑤ 进展检测:还在进步吗?(自适应,不需要预设难度)
    if state.no_progress_count >= config.patience:
        return False, "STUCK"
    
    # ⑥ 轮次上限:最后的保险丝(故意设大,不指望它控制)
    if state.iteration >= config.max_iterations:
        return False, "MAX_ITERATIONS"
    
    return True, "CONTINUE"

真实项目的配置

# loop_config.yaml(生产环境)
max_iterations: 50          # ← 故意设大,纯保险丝
token_budget: 200000        # ← 真正的"预算"
time_limit: 300s            # ← 真正的"deadline"
cost_limit: $2.00           # ← 真正的"钱包"
patience: 5                 # ← 真正的"你卡住了"检测
compress_every: 5           # ← 每 5 轮压缩一次上下文
max_same_errors: 3          # ← 同一错误 3 次 → 换策略

为什么不需要预设任务难度?

约束 特点 适合控制什么
max_iterations 和任务复杂度无关,纯计数 防死循环(保险丝)
token_budget 和任务复杂度正相关 简单任务自然花得少,复杂任务花得多
time_limit 和任务复杂度正相关 同上
patience(进展检测) 自适应 卡死了就停,不管转了几轮

Token / 时间 / 成本是"弹性预算"——简单任务自然提前结束,复杂任务自然多花。
max_iterations 是"刚性保险丝"——不区分简单复杂,纯粹防失控。

通过实际状态进展检测:真正解决"不知道简单还是复杂"的机制

class ProgressDetector:
    """不预设任务难度,而是观察'还在不在进步'"""
    
    def __init__(self, patience=5):
        self.error_history = []
        self.patience = patience
    
    def record(self, errors: list[str]):
        self.error_history.append(set(errors))
    
    def is_making_progress(self) -> bool:
        if len(self.error_history) < 2:
            return True
        recent = self.error_history[-self.patience:]
        # 错误集合在变化 → 在进步(虽然还没对,但在尝试新东西)
        if len(set(frozenset(e) for e in recent)) > 1:
            return True
        # 连续 N 轮错误完全一样 → 卡死了
        return False
    
    def should_change_strategy(self) -> bool:
        if len(self.error_history) < 3:
            return False
        return (self.error_history[-1] == self.error_history[-2] 
                == self.error_history[-3])

这个机制不需要预先知道任务难度:

  • 简单任务:第 2 轮测试就过了,循环自然结束
  • 中等任务:错误在变化(在进步),第 7 轮过了
  • 困难任务:错误在变化但很慢,第 20 轮过了(Token 预算够就行)
  • 不可能的任务:错误不变,patience 触发,停止

五、核心对比:能力与边界矩阵

概念/层级 驱动主体 核心工程职责 决定了系统的什么属性? 绝对能力边界
LLM 深度模型 概率预测、知识生成 智能上限 无确定性、无物理交互
Prompt Eng 静态文本 结构化约束、角色设定 输出规范 无法处理动态长链逻辑
CoT LLM 推理 显式分步逻辑推导 逻辑推理准确度 无法交互外部世界 (No Tools)
Agent 抽象定义 定义 Tools/Memory/Plan/Action 能力抽象 仅是概念接口,非运行代码
ReAct LLM + 代码 Thought → Action → Observation 单步感知与交互 易陷入死循环、无自我验证
Agent Loop 代码状态机 多轮重试路由、报错模板塞回 多轮自校正能力 无法判断代码真正成功与否
Loop Eng 硬编码 上下文截断/压缩、物理验证 结果确定性与 Token 止损 不管物理安全与硬件资源
Harness 硬编码 沙箱隔离、Guardrail 拦截、预算熔断 生产安全性与高可用 绝不允许 LLM 绕过硬编码规则

六、企业级 Agent Runtime 的 5 层工程落地架构

在生产环境中,一个成熟的 Agent 系统通常可以划分为 5 层架构:

┌────────────────────────────────────────────────────────────────────────┐
│ L1: Harness         ➔ 兜底:沙箱隔离、预算监控、Guardrail 强拦截       │
├────────────────────────────────────────────────────────────────────────┤
│ L2: Loop Eng        ➔ 验证:上下文压缩、截断保护、pytest/ExitCode 校验 │
├────────────────────────────────────────────────────────────────────────┤
│ L3: Agent Loop      ➔ 调度:Round 控制、报错拼接重试、自校正路由       │
├────────────────────────────────────────────────────────────────────────┤
│ L4: Agent           ➔ 声明:Prompt 模板、角色人格、Tools 注册/参数声明 │
├────────────────────────────────────────────────────────────────────────┤
│ L5: ReAct Engine    ➔ 执行:Think 推理、Action 生成、Observation 压回  │
└────────────────────────────────────────────────────────────────────────┘

注意:L2 和 L3 之间的边界是模糊的(详见【延伸辨析一】)。 它们不是"先做完 L3 再做 L2"的前置关系,而是围绕同一个循环的正交工程决策。分成两层,是为了关注点分离,不是为了"阶段递进"。

L5: ReAct Engine(推理与决策引擎层)

定位: 单步感知-决策-执行循环 —— “决定这一步思考什么、调什么工具”

class ReActEngine:
    def run(self, messages, tools, max_steps=10):
        for step in range(max_steps):
            response = llm.chat(messages, tools=tools)
            if not response.has_tool_calls():
                return response.text              # LLM 自己说"完了"
            for call in response.tool_calls:
                obs = execute_tool(call)
                messages.append(obs)              # Observation 压回
        return "MAX_STEPS_REACHED"
  • 控制 for step in range(MAX_STEPS) 的单步推理
  • 解析模型返回的 tool_calls,交由 L1 执行后,把 Observation 追加进 Message 列表驱动下一步

L4: Agent(智能体定义与装配层)

定位: 能力与角色的静态声明体 —— “决定我是谁、我能用什么工具”

class AgentDefinition:
    system_prompt = """
    你是一个高级 Python 工程师。
    规范:PEP8、类型注解、docstring 必须。
    SOP:先读代码 → 定位问题 → 最小修改 → 跑测试。
    """
    tools = [
        {"name": "bash", "params": {"cmd": "str"}},
        {"name": "edit_file", "params": {"path": "str", "content": "str"}},
        {"name": "read_file", "params": {"path": "str"}},
    ]
  • 装配包含角色设定、SOP、代码规范的 System Prompt
  • 使用 JSON Schema 标准化声明工具接口

L3: Agent Loop(状态机与多轮控制层)

定位: 多轮生命周期与自校正路由 —— “决定失败后怎么重试、何时停止”

class AgentLoop:
    def run(self, task, agent: AgentDefinition, max_rounds=10):
        messages = [system(agent.system_prompt), user(task)]
        
        for round in range(max_rounds):
            result = react_engine.run(messages, agent.tools)
            
            if result.success:
                return result
            
            # 报错模板拼接:捕获堆栈,打包为 Prompt 重新塞给 LLM
            messages.append(f"[Test Failed]:\n{result.stacktrace}\nPlease fix.")
            
            # 提前止损:连续 3 轮报完全相同的错误 → 切断
            if self.is_same_error_3_times(result):
                return Result(status="ABORT", reason="stuck")
        
        return Result(status="MAX_ROUNDS")
  • 实现 for round in range(MAX_ROUNDS) 状态机
  • 捕获 L2 抛出的 exit_code != 0 堆栈,打包为 Prompt 重新塞给 LLM
  • 识别 LLM 的放弃信号或连续相同错误,自动切断循环打上 ABORT 标记

L2: Loop Engineering(工程治理与客观验证层)

定位: 上下文治理与客观真理裁判 —— “决定记忆爆不爆、做得对不对”

class LoopController:
    def run(self, task, config):
        state = State(task)
        progress = ProgressDetector(patience=config.patience)
        strategy = config.strategies[0]

        while True:
            # ═══ 多维度终止判断 ═══
            cont, reason = self.should_continue(state, config)
            if not cont:
                return Result(status=reason)
            
            # ═══ 进展检测 → 自适应策略切换 ═══
            if progress.should_change_strategy():
                strategy = next_strategy(strategy)
                state.inject_hint(f"之前方法失败3次,换: {strategy.name}")
            
            # ═══ 上下文截断防护 ═══
            if len(state.context) > config.context_limit:
                state.context = self.compress(state.context)
            
            # ═══ LLM 干活(调用 L3)═══
            result = agent_loop.run(state.current_subtask, strategy.tools)
            state.apply(result)
            
            # ═══ 物理断言校验(不信 LLM 的嘴)═══
            verification = subprocess.run("pytest tests/ -x", capture_output=True)
            if verification.returncode == 0:
                return Result(status="SUCCESS", iterations=state.iteration)
            
            # ═══ 记录进展 ═══
            progress.record(parse_errors(verification.stderr))
            state.iteration += 1

核心职责:

  • 上下文截断防护: 监控 Tool 输出,若 Bash 输出 > 2000 字,自动执行"保留头尾 + 中间 ...[truncated]..."
  • 记忆滑动压缩: 维护滑动窗口,保留 System Prompt + Task + 最近 N 轮 Trace,更早的历史自动调用 Summarizer 压缩为摘要
  • 物理断言校验: 调用系统 Shell 执行 pytest / cargo test / eslint,强行提取 exit_code == 0 作为唯一完成指标,拒绝相信 LLM "我搞定了"的嘴硬文本

L1: Harness Runtime(基础设施与安全基座层)

定位: 物理安全防线与资源控制阀门 —— “决定能不能做、能不能继续跑”

class HarnessRuntime:
    def execute(self, task, user_id, config):
        # ═══ 沙箱生命周期 ═══
        sandbox = DockerSandbox(image="python:3.12-slim")
        sandbox.mount(project_dir, read_only=False)
        
        with sandbox:
            # ═══ 越权强拦截(AST / 正则,LLM 绝对无权绕过)═══
            if self.guardrail.detect_dangerous(task):
                return Result(status="BLOCKED", reason="security_violation")
            
            # ═══ 硬性资源熔断 ═══
            with BudgetTracker(token_limit=config.token_budget,
                             time_limit=config.time_limit,
                             cost_limit=config.cost_limit):
                result = loop_controller.run(task, config)
            
            # ═══ 人工审批门(敏感操作)═══
            if touches_sensitive_path(result.changes, ["auth/", "payment/"]):
                if not request_human_approval(result).granted:
                    return Result(status="REJECTED")
        
        sandbox.teardown()
        return result

核心职责:

  • 沙箱生命周期: 封装 Docker / Firecracker 环境,提供 sandbox.mount()sandbox.teardown() 隔离执行
  • 越权强拦截: 在最外层解析 AST 或用正则匹配,强行拦截 rm -rf / 或敏感路径访问,LLM 绝对无权绕过
  • 硬性资源熔断: 主进程挂载 wall-time 定时器(如单次命令 > 60s 直接 SIGKILL),Token 预算耗尽立即 trigger 强制退出

七、【延伸辨析二】Harness 到底"管"到哪里?——从"一层"到"一个范式"

前文把 Harness 定义为 “L1:沙箱 + Guardrail + 预算熔断”——一个很窄的安全层。但 2026 年行业语境里的 Harness Engineering 远不止这些。

7.1 行业定义的 Harness Engineering:五大核心能力

Mitchell Hashimoto 在 2026 年 2 月提出:

“Agent = Model + Harness. The Harness is everything around the model.”

行业共识的 Harness Engineering 包含五大能力:

能力模块 说明
1. 上下文架构(Context Architecture) AGENTS.md 规则文件、分层文档、上下文压缩、渐进式加载
2. 工具能力(Tool Capabilities) Function Calling、Bash、文件系统、MCP 协议、Browser Use、Skills
3. 流程编排(Workflow Orchestration) 多 Agent 协作、任务分解与调度、子 Agent 管理
4. 检查与守护(Guardrails & Validation) 输出约束校验、合规检查、安全审查
5. 记忆与状态(Memory & State) 短期/长期记忆 + 任务/会话状态,跨会话断点续跑

以及五大特点:

特点 说明
结构化上下文驱动 一切信息以统一 schema 流转,非字符串拼接
自我修复(自愈) 区分可重试/不可恢复,指数退避,不因单点崩溃
有状态、跨会话 进度文件、Git 历史、需求清单实现跨 session 传递
安全可控 用户/工具/操作/数据四维权限 + 运行时动态校验
透明可观测 执行链路全记录、质量自动评分、关键指标实时监控

7.2 问题来了:这和前文的 5 层架构是什么关系?

你会发现:Harness Engineering 的五大能力几乎覆盖了我们前文拆出来的所有层。

前文的框架(分层视角):
  L1 Harness ← 只是最外面一层
  L2 工程治理
  L3 循环调度
  L4 Agent 定义
  L5 ReAct

行业语境(范式视角):
  Harness Engineering = 围绕模型的【一切工程】
  ┌─────────────────────────────────────────────┐
  │  上下文架构  ← 对应前文 L2 + L4            │
  │  工具能力    ← 对应前文 L4 + L5            │
  │  流程编排    ← 对应前文 L3                 │
  │  检查守护    ← 对应前文 L1 + L2            │
  │  记忆状态    ← 对应前文 L2 + L3            │
  └─────────────────────────────────────────────┘

前文的"Harness"是一个层。行业的"Harness Engineering"是一个范式——它不是一层,而是"除了模型本身以外的所有工程"。

用一个类比:

说法 含义
“刹车是汽车的一个部件” Harness = L1(一个层)
“汽车工程是围绕发动机的一切” Harness Engineering = 范式(所有层)

7.3 那它和 Loop Engineering 到底怎么区分?

既然 Harness Engineering 包含了所有层,那"Loop Engineering"这个概念还有独立存在的意义吗?

有。区分维度不是"管什么",而是"怎么管"和"管的目的":

维度 Loop Engineering Harness Engineering
关注点 单次任务的循环控制 整个 Agent 系统的工程体系
核心问题 “这一轮循环怎么转、什么时候停” “这个 Agent 系统怎么设计、怎么运维”
时间尺度 一次执行(秒~分钟) 整个生命周期(天~月)
典型产物 should_continue()compress()run_tests() AGENTS.md、工具注册表、权限矩阵、可观测性仪表盘
类比 工厂里一条产线的 PLC 控制程序 整个工厂的管理体系(ISO 流程、安全规范、ERP)
# Loop Engineering 关心的:
while True:
    if budget.exceeded(): break          # 这一次执行,钱够不够?
    if same_error_3_times(): switch()    # 这一次执行,卡没卡住?
    if tests_pass(): return SUCCESS      # 这一次执行,做没做完?

# Harness Engineering 关心的:
# - 这个 Agent 的工具权限矩阵是什么?(跨所有执行)
# - AGENTS.md 里的规范怎么版本管理?(跨所有项目)
# - 执行链路的 trace 怎么存储和查询?(跨所有会话)
# - 多 Agent 之间的通信协议是什么?(跨所有任务)
# - 断点续跑的状态怎么持久化?(跨 session)

7.4 五大能力的进一步拆解:层次与控制权

Harness Engineering 的五大能力之间不是平级的,它们有层次:

┌─────────────────────────────────────────────────────────────┐
│  5. 记忆与状态(Memory & State)                              │
│     → 跨会话、跨任务的"持久层"                                │
│     → 进度文件、Git 历史、需求清单、断点续跑                    │
├─────────────────────────────────────────────────────────────┤
│  3. 流程编排(Workflow Orchestration)                        │
│     → 多 Agent 协作、任务分解、子 Agent 调度                   │
│     → "谁先做、谁后做、谁等谁"                                │
├─────────────────────────────────────────────────────────────┤
│  1. 上下文架构(Context Architecture)                        │
│     → AGENTS.md、分层文档、渐进式加载、压缩                    │
│     → "模型看到什么、看不到什么"                               │
├─────────────────────────────────────────────────────────────┤
│  2. 工具能力(Tool Capabilities)                             │
│     → Function Calling、Bash、MCP、Browser Use               │
│     → "模型能做什么、不能做什么"                               │
├─────────────────────────────────────────────────────────────┤
│  4. 检查与守护(Guardrails & Validation)                     │
│     → 输出校验、安全审查、合规检查、沙箱                       │
│     → "模型做完了,对不对、安不安全"                            │
└─────────────────────────────────────────────────────────────┘

每个能力的控制权归属:

能力 谁在控制? 控制什么? 失败后果
上下文架构 代码(静态配置 + 动态压缩) 模型的"视野" 模型看到错误信息 → 做出错误决策
工具能力 代码(Schema 注册 + 白名单) 模型的"手脚" 模型调了不该调的工具 → 安全事故
流程编排 代码(DAG / 状态机) 多 Agent 的"协作顺序" 死锁、重复执行、遗漏步骤
检查守护 代码(硬编码规则) 模型的"输出" 幻觉上线、越权操作、数据泄露
记忆状态 代码(外部存储) 跨会话的"连续性" 重复劳动、状态丢失、不一致

注意:所有五项的控制权都在代码。这正是 Harness Engineering 的核心哲学——模型是被管理的对象,不是管理者。

7.5 前文框架没覆盖的两个维度

维度 前文覆盖了吗? Harness Engineering 怎么做的?
跨会话状态 ❌ 前文只讲单次执行 进度存在 progress.json / Git commit 里,新 session 启动时自动恢复
可观测性 ❌ 前文未涉及 每次工具调用有 trace,每次推理有 token 计数,结果质量自动评分,异常告警
# 前文框架:单次执行内的循环控制(秒~分钟尺度)
while True:
    react() → verify() → correct()

# Harness Engineering 额外覆盖:
# ① 跨会话状态(天~月尺度)
class SessionState:
    def save(self):
        write_json("progress.json", {
            "task": self.task,
            "iteration": self.iteration,
            "strategy": self.strategy,
            "error_history": self.error_history,
            "git_sha": get_current_sha(),
        })
    
    def restore(self):
        data = read_json("progress.json")
        # 新 session 启动时,从上次断点继续
        self.iteration = data["iteration"]
        self.strategy = data["strategy"]

# ② 可观测性(运维尺度)
class ExecutionTracer:
    def on_tool_call(self, tool, args, result, latency_ms):
        self.traces.append({...})
        self.metrics.record("tool_latency", latency_ms)
    
    def on_llm_call(self, tokens_in, tokens_out, cost):
        self.metrics.record("tokens_total", tokens_in + tokens_out)
        self.metrics.record("cost_total", cost)
    
    def on_iteration_end(self, verification_passed, error_count):
        self.metrics.record("quality_score", compute_score(...))
        if error_count > threshold:
            alert("Agent stuck", severity="warning")

7.6 重新定义:Harness 的完整图景

综合以上分析,给出一个更精确的定义:

┌─────────────────────────────────────────────────────────────────┐
│                                                                 │
│   Model(模型)= 概率推理引擎,不可修改,只能调用               │
│                                                                 │
│   Harness(马具)= 模型以外的一切工程                          │
│   ┌─────────────────────────────────────────────────────────┐   │
│   │                                                         │   │
│   │  静态配置层:                                           │   │
│   │    - AGENTS.md / System Prompt / 角色定义               │   │
│   │    - Tools Schema / 权限矩阵                           │   │
│   │    - 流程 DAG / 多 Agent 拓扑                          │   │
│   │                                                         │   │
│   │  运行时控制层:                                         │   │
│   │    - 循环调度(多轮重试、止损)                          │   │
│   │    - 上下文管理(压缩、截断、渐进加载)                  │   │
│   │    - 验证回路(pytest、exit_code、质量评分)             │   │
│   │    - 策略切换(进展检测、自适应)                        │   │
│   │                                                         │   │
│   │  安全与资源层:                                         │   │
│   │    - 沙箱隔离 / 命令拦截 / AST 分析                    │   │
│   │    - 预算熔断(Token/时间/成本)                        │   │
│   │    - 人工审批门                                        │   │
│   │                                                         │   │
│   │  持久化与可观测层:                                     │   │
│   │    - 跨会话状态(进度文件、Git、断点续跑)              │   │
│   │    - 执行链路 trace / 质量评分 / 告警                   │   │
│   │                                                         │   │
│   └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

7.7 小结:怎么理解"Harness"这个词

问题 回答
Harness 和 Loop Engineering 是同一层吗? 不是。 Loop Eng 是 Harness 的一个子集(运行时控制层)
Harness 和 Agent Loop 是同一层吗? 不是。 Agent Loop 也是 Harness 的一个子集(循环调度)
那前文的 5 层架构还有用吗? 有用,但它是 Harness 内部的"关注点分离",不是 Harness 之外的东西
一句话定义 Harness? 模型以外的一切工程。不是"一层",是"所有层"。
为什么行业要用一个新词? 因为"Agent Engineering"太泛,"Harness"强调的是控制权在代码、模型是被管理的对象这一哲学立场

📌 前文说"Harness 是 L1 安全层"——这是窄义。
行业说"Harness Engineering 是围绕模型的一切工程"——这是广义。
两者不矛盾:窄义的 Harness(安全层)是广义 Harness(范式)里最不可妥协的那一部分。


八、 完整实例:自动修复 GitHub Issue

这是最能体现 5 层架构协同工作的场景。

配置

# loop_config.yaml
max_iterations: 50            # 保险丝,不指望它控制
token_budget: 200000
time_limit: 300s
cost_limit: $2.00
patience: 5
compress_every: 5
max_same_errors: 3
sensitive_dirs: ["auth/", "payment/"]
verification_cmd: "pytest tests/ -x"
strategies:
  - direct_fix       # 直接改出错的行
  - refactor         # 重构整个函数
  - rewrite          # 推倒重写

实际执行轨迹

Iteration 1:
  [L1-前置] 不涉及敏感目录 ✓  Token: 12k/200k ✓  时间: 8s/300s ✓
  [L5-ReAct] LLM 读代码 → 改第42行 → write_file
  [L2-验证] pytest → ❌ FAILED: test_create_user (AssertionError)
  [L2-记录] 错误#1: AssertionError@line87

Iteration 2:
  [L5-ReAct] LLM 看到错误 → 又改第42行(换个写法)
  [L2-验证] pytest → ❌ 同一个 AssertionError
  [L2-记录] 错误#2(同一错误)

Iteration 3:
  [L5-ReAct] LLM 第三次改第42行
  [L2-验证] pytest → ❌ 同一个 AssertionError
  [L2-记录] 错误#3 → ⚡ 触发规则!same_error_count >= 3
  [L2-自校正] 策略切换: direct_fix → refactor
  [L2-注入] "直接修改已失败3次,请重构整个函数"

Iteration 4:
  [L5-ReAct] LLM 收到策略提示 → 重构函数结构
  [L2-验证] pytest → ❌ 但错误变了!ImportError
  [L2-记录] 新错误#1(计数器重置 → 说明在进步)

Iteration 5:
  [L2-压缩] ⚡ 触发!前4轮压缩为200字摘要(Token 从 45k → 8k)
  [L5-ReAct] LLM 修复 import
  [L2-验证] pytest → ✅ ALL PASSED (exit_code == 0)
  [L1-终止] 返回 SUCCESS, iterations=5, tokens_used=67k, cost=$0.34

🔑 关键洞察:LLM 从头到尾不知道"最多50轮"“3次换策略”“5轮压缩”“200k Token 预算"这些规则。它只是在每一轮里被调用,做好"思考→行动→观察”。所有控制逻辑都在代码层。


九、代码架构对比:一个文件 vs 分层系统

═══ ReAct:一个文件搞定 ═══

agent.py
  └── class ReActAgent:
        └── def run(task, tools): ...


═══ 5 层架构:分层系统 ═══

harness_runtime.py        ← L1: 沙箱、Guardrail、预算熔断
loop_controller.py        ← L2: 外层循环、验证器、策略机、压缩器
progress_detector.py      ← L2: 进展检测(自适应终止)
agent_loop.py             ← L3: 多轮重试、报错拼接、止损路由
agent_definition.py       ← L4: Prompt 模板、Tools Schema
react_engine.py           ← L5: 单步 Think→Act→Observe
loop_config.yaml          ← 规则配置(非 Prompt!)

十、什么时候该用哪个?

场景 选择 理由
一次性问答 / 简单工具调用 ReAct 就够 不需要复杂控制
生产环境单任务(客服、搜索) ReAct + Agent Loop 需要多轮重试、上下文管理
自动修 Bug / 自动写代码 Loop Engineering 需要验证回路、自校正、预算
多步骤复杂工作流 Loop Engineering + 多 Agent 拓扑 需要子循环嵌套
涉及资金/权限的操作 Loop Engineering + Harness 必须沙箱 + 人工兜底

** 再次强调 **(呼应【延伸辨析一】):这不是"先做第一行再做第二行"的线性路径,而是"根据你的风险等级,勾选你需要的工程决策"。


十一、总结与工程哲学

11.1 整条演进线只有两个真正的分水岭

LLM → Prompt → CoT          "闭门造车"(无外部交互)
         │
         │  ← 分水岭 1:模型第一次获得"手和脚"
         ▼
Agent(概念)→ ReAct(实现)  "边想边做"(有外部交互)
         │
         │  ← 分水岭 2:从"信任模型"到"不信任模型"
         ▼
围绕 ReAct 叠加工程决策      "用代码兜住模型的不确定性"
(验证/预算/压缩/策略/沙箱/审批...按需组合)

11.2 三句话总结三种循环

一句话本质 类比
ReAct Agent 的第一个实现,循环就是认知过程,LLM 既是执行者也是裁判 一个人在房间里自己修水管
Agent Loop 让认知循环跑得更久、记得更多,但控制权仍在 LLM 同一个人,给了更大的房间和更好的记忆
Loop Engineering 循环不再是认知过程,而是包含 Agent 的生产流程 一条生产线:工人干活,监理验收,预算官管钱

11.3 两个"延伸辨析"的核心结论

辨析 核心结论
Agent Loop vs Loop Eng 没有严格边界,是光谱不是台阶。真正有意义的不是"第几阶段",而是"每个决策点谁说了算"。按风险等级逐个叠加,无强制顺序。
Harness 的能力边界 窄义 Harness = L1 安全层;广义 Harness Engineering = 模型以外的一切工程(范式)。前文 5 层架构是 Harness 内部的关注点分离,不是 Harness 之外的东西。

11.4 最终结论

模型决定了上限,而 Harness 与 Loop Engineering 决定了底线。

所谓"Agent 工程化",不是从第 1 阶段毕业进入第 8 阶段。而是围绕同一个 ReAct 循环,逐步把决策权从 LLM 手里收回到代码手里。收多少、收哪些,取决于你的风险容忍度。

这不是对 AI 的悲观,而是工程的基本纪律——就像你信任一个优秀员工的能力,但仍然需要流程、审批、验收标准。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐