本章目标:彻底理解 Agent Loop——它是 Agent 的”心跳”,也是整个 Agent 领域最核心、也最容易被误解的一段代码。我们会看到它为何如此简单,又为何真正复杂的是它周围的系统。
3.1 最简单的 Agent Loop
如果说 Agent 有一个”最小内核”,那一定是下面这段代码:
while not finished:
response = model(context) # 让模型基于当前上下文做决策
if response.tool_call: # 模型决定调用工具
result = execute_tool(response.tool_call) # 执行工具
context.append(result) # 把结果塞回上下文(连同 tool_call,见下注)
else: # 模型给出最终答案
return response就这么多。一个能“理解任务 → 调用工具 → 观察结果 → 继续推理”的 Agent,其核心循环逻辑,用 Python 写不超过 10 行——但这只是“裸循环”,加上终止条件、错误处理后才会膨胀到几十上百行(本章标题“100 行”即指这个更完整的形态)。这是理解 Agent 的起点,也是理解“Agent 工程”真正的难点在哪里的钥匙。
注:真实实现里,
context.append这一行要把模型的tool_call消息和工具结果一起追加回上下文——只追加结果,模型会“看不到”自己刚才发起的调用;Anthropic 等主流 API 都要求两者成对出现。
Claude Code 源码(2026.03.31泄露版)真实的循环骨架(src/query.ts 的 queryLoop 函数),其核心结构与此几乎完全同构:
async function* queryLoop(params: QueryParams): AsyncGenerator<Message, Terminal> {
let state: State = { messages, toolUseContext, turnCount: 1, transition: undefined };
while (true) {
// 1. 让模型基于当前 messages 生成响应(流式)
const response = yield* streamModelResponse(state.messages);
// 2. 检查是否应该终止
if (response.terminal) {
return response.terminal; // completed / max_turns / hook_stopped ...
}
// 3. 执行模型请求的所有工具
const results = yield* runTools(response.toolCalls);
// 4. 把工具结果追加回 messages
state.messages.push(...results);
state.turnCount++;
}
}注意这个结构里的三个关键点,它们正是本章要展开的核心:
- 循环是无界的(
while (true)),靠内部的终止条件退出——这就是”Agent 会不会跑飞”问题的根源。 - 每一轮只有三件事:生成(Generate)、执行工具(Act)、追加结果(Observe)。
- 所有跨轮次的状态都收敛到一个可变对象里(
state)——这就是”Agent 状态管理”的雏形。
一个重要的观察:这个循环的”简洁”是刻意的。它把”怎么推理”外包给了模型,把”怎么执行”外包给了工具,把”怎么记忆”外包给了上下文。循环本身只做一件事——调度。这个”刻意简洁”是全书最重要的架构认知之一。
3.2 Observe → Think → Act
Agent Loop 的本质,可以抽象为一个三段式的认知循环:Observe(观察)→ Think(思考)→ Act(行动)。
这个框架源自经典人工智能的”感知-思考-行动”模型,也对应着控制论中的”反馈回路”。在 LLM Agent 的语境下,它被具体化为:
Observe(观察) : 读取当前上下文 —— 用户请求、对话历史、工具结果、文件内容
↓
Think(思考) : LLM 推理 —— 我现在知道了什么?下一步该做什么?
↓
Act(行动) : 调用工具或给出答案 —— 读文件、执行命令、返回结果
↓
(工具结果成为新的 Observe,循环继续)
这个循环之所以有效,是因为它把 LLM 的一次性推理,变成了一个带反馈的持续过程。Chatbot 是”一问一答”,Agent 是”边走边看边想边做”。
一个具体的例子——让 Agent “修复一个编译错误”:
Observe: 用户说"编译报错了",错误信息是 "TypeError: foo is not a function"
↓
Think: 这个错误通常是因为 foo 没有被正确定义或导入,我需要先找到 foo 的定义位置
↓
Act: 调用 Grep 工具搜索 "foo" 的定义
↓
Observe: Grep 返回 "src/utils.ts:42 定义了 foo"
↓
Think: 让我看看这段代码,以及调用它的地方
↓
Act: 调用 Read 工具读取 src/utils.ts 和相关调用文件
↓
Observe: 发现 foo 是一个函数,但被错误地当作对象调用了
↓
Think: 需要修改调用方式
↓
Act: 调用 Edit 工具修改代码
↓
Act: 调用 Bash 工具运行测试
↓
Observe: 测试通过
↓
Think: 问题已解决
↓
Act: 返回最终答案
注意,这个过程中模型始终在做”思考”,工具始终在做”行动”,上下文始终在”观察”。三者缺一不可。
这里要强调一个容易误解的点:“Think”不等于“模型有一个独立的思考阶段”。在现代 Tool-use Agent 中,“思考”和“行动”是交织的——模型可能在一次回复里,先输出一段推理文本,紧接着就发起一个工具调用。它们是同一个 token 流里连续的部分,而不是两个分离的阶段。
顺带澄清一个“起点”问题:代码层是先 model(context) 再行动,而认知层把“观察(Observe)”放在最前。这并不矛盾——模型读取上下文这一动作,本身既是“观察”也是“思考”的起点。三段式只是认知抽象,不等于代码里三个先后执行的独立阶段。
3.3 ReAct
ReAct(Reasoning + Acting)是 2022 年 Yao 等人提出的一个里程碑式方法,它的名字就是”推理(Reasoning)”和”行动(Acting)”的缩写。ReAct 的核心洞察是:让 LLM 在推理过程中显式地交替输出”思考”和”行动”,能显著提升它在需要工具的任务上的表现。
ReAct 的典型输出模式是这样的:
Thought: 我需要查询今天的天气才能回答用户。让我调用天气工具。
Action: get_weather[{"city": "北京"}]
Observation: {"weather": "中雨", "temp": 18}
Thought: 北京今天中雨,18 度。用户问是否要带伞,下雨需要带伞。
Action: Finish[今天北京有中雨,建议带伞。]
注意 ReAct 的三个关键要素:
- Thought(思考):模型用自然语言表达它的推理过程,这让它的决策”可解释”。
- Action(行动):模型调用工具,格式是结构化的(工具名 + 参数)。
- Observation(观察):工具的执行结果,作为新信息进入上下文。
ReAct 的历史贡献在于:它证明了把”推理”和”行动”交织在一起,比单纯地”思考完再行动”或”行动完再思考”更有效。这个思想深刻地影响了后续所有的 Agent 框架——包括 Claude Code。
不过,现代 Agent(尤其是 Claude Code)已经不再显式使用 ReAct 的”Thought/Action/Observation”文本格式,而是直接使用原生工具调用(Tool Calling,模型输出结构化的 tool_use,而非文本 Action)。但 ReAct 的”推理-行动交织”精神被完整继承了下来:模型在每一轮都会先”想”(生成推理)再”做”(调用工具)。
为什么从”文本格式”进化到了”原生 Tool Calling”?因为文本格式有一个致命弱点:它依赖”文本解析”。模型输出的 Action: get_weather[{...}] 是一段文本,应用需要用正则/解析器把它提取出来。这个解析过程脆弱且容易出错(模型偶尔会输出格式不对的文本)。而原生 Tool Calling 让模型输出结构化的 tool_use 块,直接就是可解析的数据结构,无需文本解析。可以说,Tool Calling 是 ReAct 的工程化、结构化升级版。
3.4 Plan-and-Execute
Plan-and-Execute(计划-执行)是另一种重要的 Agent 范式。它的核心思想是:先让模型制定一个完整计划,再逐步执行计划。
Plan: 1. 读取项目结构
2. 找到相关代码
3. 分析问题
4. 制定修改方案
5. 执行修改
6. 运行测试验证
Execute: 逐步执行 1-6
Plan-and-Execute 的优势:
- 全局视野:先规划再执行,避免”走一步看一步”导致的短视。
- 可预测性:计划让用户能提前看到 Agent 打算做什么。
- 适合多步骤任务:对于结构清晰、步骤明确的任务尤其有效。
它的劣势也很明显:
- 计划可能过时:执行过程中环境会变化(比如执行第 2 步发现代码结构完全不同),最初的计划就不再适用。
- 额外成本:制定计划本身消耗 token 和时间。
- 不灵活:面对高度不确定的任务(如”排查一个奇怪的 bug”),预先规划往往徒劳,因为根本不知道下一步会面对什么。
Claude Code 的实践是混合式的:它主要使用 Tool-use Agent(边走边决策),但提供了 TodoWrite 工具让模型可以维护一个任务清单,也提供了 Plan Mode(EnterPlanMode)让用户可以先看计划再批准执行。这是一种务实的折中——既保留了 Tool-use 的灵活性,又引入了 Plan-and-Execute 的可预测性。
一个更深的洞见:Plan 本身可以是一等公民,而不只是”执行前的准备”。Claude Code 的 TodoWrite 让”计划”成为一个持久化的、可跟踪的状态——它不只是一次性生成然后丢弃,而是贯穿整个任务,随进展动态更新。这让”计划”从 Plan-and-Execute 的”一次性蓝图”进化成了”活的任务清单”。
3.5 Tool-use Agent
Tool-use Agent 是当前最主流的 Agent 范式,也是 Claude Code 采用的核心模式。它的特点是:模型在每一轮都只决定”下一步做什么”,而不是”全部步骤是什么”。
Tool-use Agent 的循环就是本章开头那个最简单的 loop:
while not finished:
response = model(context)
if response.tool_call:
result = execute_tool(response.tool_call)
context.append(result) # 结果需与 tool_call 成对追加(见 3.1)
else:
return responseTool-use Agent 的优势在于极强的适应性:它不预设路径,完全根据每一步的反馈来动态调整。这正是处理”开放式任务”(比如”帮我重构这个模块”、”帮我查一下线上为什么报错”)所必需的能力。
它的代价是不确定性:模型可能走弯路、可能重复劳动、可能跑偏。这些代价需要靠运行时框架(Harness)层的机制来兜底——这正是后面几章的主题。
为什么 Tool-use Agent 会取代 Plan-and-Execute 成为主流?因为真实世界的任务大多是”开放式”的。你很难在动手前就规划好”排查 bug”的完整步骤——你根本不知道 bug 在哪。Tool-use Agent 的”边走边看”反而更适合这种不确定性的任务。Plan-and-Execute 更适合”流程明确”的任务,但那种任务其实用 Workflow(第 1 章)就够了,未必需要 Agent。
3.6 Reflection
Reflection(反思)是 Agent 能力的重要增强。它的核心思想是:让 Agent 在完成任务后(或执行过程中),回头审视自己的行为和结果,发现问题并改进。
Reflection 的一个典型实现是”生成-批评-修订”循环:
Generate: 生成一个解决方案
↓
Critique: 让模型批评自己的方案(有哪些问题?哪些地方可能出错?)
↓
Revise: 根据批评修订方案
↓
(可以多轮迭代)
Reflection 的价值在于:LLM 的第一次输出往往不是最优的,但给它一个”自我审视”的机会,它常常能发现并修正自己的错误。这在数学推理、代码生成等需要严谨性的任务上尤其明显。
在 Claude Code 的实践中,Reflection 被内化为几种具体机制:
- 错误驱动的自我修正:工具报错 → 模型分析错误 → 修改方案 → 重试(这是最自然的 Reflection)。
- 测试驱动的反思:改完代码 → 运行测试 → 测试失败 → 反思哪里错了 → 继续改。
- 专门的 Review Agent:用子智能体(Subagent)来审查主智能体的工作。
Reflection 和 Self-correction(3.7)密切相关,但有一个微妙的区别:Reflection 更强调”元认知”(审视自己的思考过程),Self-correction 更强调”结果导向”(发现错了就改)。在实践中两者常常混用。
3.7 Self-correction
Self-correction(自我纠正)是 Reflection 的工程化落地,也是 Coding Agent 之所以强大的核心原因。它的完整闭环是:
Read(读代码)
↓
Understand(理解)
↓
Plan(计划修改)
↓
Edit(编辑代码)
↓
Run Test(运行测试)
↓
Observe Error(观察错误)
↓
Analyze(分析原因)
↓
Fix(修复)
↓
Run Test(重新测试)
↓
Pass(通过)
这个闭环的威力在于反馈信号的质量。编码领域有丰富的客观反馈:编译器报错、类型检查失败、测试失败、linter 警告。这些反馈是确定的、即时的、可解析的,让模型能够精准定位问题、精准修复。
对比一下通用 Agent(比如”帮我规划一次旅行”)为什么难以自我纠正:因为”旅行规划得好不好”没有客观标准,模型无从判断自己错没错。而 Coding Agent 有编译器这个”客观裁判”,自我纠正循环才能真正转起来。
这就是为什么 Coding Agent 成了 AI Agent 领域最成功的应用形态——不是因为它最简单,而是因为它有最丰富的反馈信号。后续章节会专门深入这个主题。
3.8 Agent Loop 为什么如此简单
回到本章开头的那个 10 行代码。一个自然的疑问是:Agent Loop 为什么能这么简单?
答案在于一个深刻的架构洞察:复杂度没有被消灭,只是被转移了。
Agent Loop 之所以简单,是因为它做了一个极其聪明的抽象——它把所有”难的部分”都推给了三个外部组件:
model(context)把”怎么推理、调用哪个工具”的复杂度推给了 LLM。模型已经通过海量训练学会了”理解任务、分解步骤、选择工具”,Loop 不需要自己实现这些。execute_tool()把”怎么执行动作”的复杂度推给了工具系统。读文件、执行命令、查数据库,各有各的实现,Loop 只需要一个统一接口。context把”怎么记忆、怎么取舍信息”的复杂度推给了上下文管理。Loop 不需要关心上下文怎么压缩、怎么裁剪,它只负责”追加”。
所以,Agent Loop 简单,不是因为 Agent 简单,而是因为它站在了 LLM、工具系统、上下文管理三个巨人的肩膀上。
这个”复杂度转移”的洞察,是理解”为什么 Loop 周围需要那么多 Harness 机制”的关键。Loop 简单,是因为它把”难的部分”都甩出去了;而”难的部分”并没有消失,它们只是变成了 Harness 的责任。
3.9 为什么真正复杂的是 Loop 周围的系统
这是全书最重要的一个洞察,值得反复强调:
Agent 最核心的代码可能只有几十到几百行,但一个生产级 Agent Harness 可以达到几十万行。
我用实测数据来印证这一点。Claude Code 源码里(2026年3月泄露版),主循环 src/query.ts 只有 1730 行,但整个项目(不含 node_modules)有 约 2000 个 .ts/.tsx 源文件(.ts 1440 个 + .tsx 634 个)。主循环文件只占全部文件的 0.05%,但围绕它构建的:
- 工具系统(
src/tools/40+ 个工具) - 压缩系统(
src/services/compact/多种压缩策略) - 权限系统(
src/utils/permissions/) - 记忆系统(
src/services/SessionMemory/) - MCP 集成(
src/services/mcp/) - 可观测性(OpenTelemetry)
- 终端 UI(React + Ink)
- 状态管理(
src/state/)
……这些加起来,才是那个”50多万行”的 Harness。
为什么 Loop 周围需要这么多东西?因为 Loop 本身只回答了”怎么循环”,而真实世界会抛出一堆它回答不了的问题。让我把这些问题列成一张表,它们就是后面几章(以及整个 Harness 部分)的目录:
| Loop 回答不了的问题 | 对应的 Harness 机制 | 对应章节 |
|---|---|---|
| 模型会不会一直循环不停? | 停止条件、max_turns、收益递减检测 | 本章 3.10 |
| 工具执行失败怎么办? | 工具错误处理 | 本章 3.11、第 7 章 |
| 模型调用失败怎么办? | 模型错误处理、重试 | 本章 3.12、第 2 章 |
| 上下文塞满了怎么办? | 上下文压缩 | 本章 3.13、第 6/14 章 |
| 模型”假装完成”怎么办? | 验证机制、Todo 清单 | 本章 3.14 |
| 任务跑几小时怎么办? | 检查点、持久化、恢复 | 本章 3.15、第 48 章 |
这张表是理解”Harness 为什么复杂”的地图——每一行都是一个真实问题,每一个问题都需要专门的机制来应对。
3.10 无限循环问题
无限循环是 Agent 最经典的故障模式:模型陷入”调用工具 → 结果不理想 → 再调用工具”的循环,永远不停下来。
调用 get_data → 结果不完整 → 再调用 get_data → 结果还是不完整 → ...
或者更糟:
调用 search → 找到 100 个结果 → 调用 read 读第 1 个 → 觉得不对 → 调用 search 换个关键词 → ...
解决方案:设置 max_turns(最大轮次)。这是最简单也最有效的兜底。Claude Code 的 transitions.ts 里,max_turns 正是终止循环的合法理由之一。
但 max_turns 是“最后防线”,更好的做法是在此之前就用更智能的手段识别“收益递减”。Claude Code 的 tokenBudget.ts 就实现了这样一个机制:当 Agent 连续多轮(continuationCount >= 3),且当前增量与前一轮增量都低于 500 token 时,判定为“收益递减”(diminishing returns),主动终止循环。(该机制受 feature('TOKEN_BUDGET') 门控,并非始终启用。)
这是一个非常精巧的设计:它不是简单地数轮次,而是度量”每轮的边际产出”。当 Agent 开始”原地打转”时,边际产出会急剧下降,这个信号比”轮次到了”更早、更准确地捕捉到”该停了”。
让我把这个机制讲得更具体。假设 Agent 在排查一个 bug:
第 1 轮:搜到 50 个相关文件,新增 8000 token → 收益高,继续
第 2 轮:读关键文件,新增 6000 token → 收益高,继续
第 3 轮:改代码,新增 3000 token → 收益中等,继续
第 4 轮:跑测试,新增 400 token → 测试没通过,但信息量小
第 5 轮:重新读同一个文件,新增 200 token → 开始原地打转
第 6 轮:再读,新增 150 token → 收益递减明显
此时 tokenBudget 检测到”连续 3 轮增量 < 500 token”,判定收益递减,主动停止。这比”跑到 max_turns(比如 50 轮)”早得多、省得多。
3.11 Tool Error
工具执行必然会失败:文件不存在、命令报错、网络超时、权限不足。Agent Loop 必须处理工具错误,否则一次失败就会让整个 Agent 卡死。
工具错误的处理策略:
- 把错误作为”结果”返回给模型:这是最优雅的做法。工具失败时,不抛出异常中断循环,而是把错误信息作为一个
tool_result(标记is_error: true)返回给模型,让模型自己决定怎么应对——重试?换策略?还是放弃?
try:
result = execute_tool(tool_call)
except ToolError as e:
result = {"is_error": True, "content": str(e)} <em># 错误作为结果返回</em>
context.append(result)
- 模型基于错误自我修正:模型看到错误信息后,通常会分析原因并调整——这正是 Self-correction 的起点。
- 区分可重试与不可重试错误:网络超时可以重试,文件不存在(可能是路径错了)则模型应该换个路径。
Claude Code 的 yieldMissingToolResultBlocks 函数就体现了这种思想:当流式中断导致工具结果缺失时,它会为每个缺失的工具调用生成一个 is_error: true 的占位结果,让模型知道”这个工具没执行成功”,从而做出正确的后续决策。
一个关键的设计判断:为什么是”错误作为结果返回”而不是”抛出异常”? 因为抛出异常会中断循环,让整个 Agent 崩溃;而”错误作为结果返回”让循环继续,把”如何应对错误”的决策权交给模型。这体现了 Agent 架构的一个基本原则:让模型来处理不确定性,让 Harness 来处理确定性的兜底。
3.12 Model Error
模型本身的调用也可能失败:网络错误、限流(429)、过载(529)、输出格式异常等。这些错误发生在 model(context) 这一环,而不是工具执行这一环。
Model Error 的处理策略与工具错误不同,因为模型错误发生在”决策”环节,此时还没有产生任何副作用:
- 重试:网络错误、限流、过载都是可重试的,用指数退避 + 抖动重试(见第 2 章)。
- 降级:主模型不可用时,切换到备用模型(Model Router 的 Failover 机制)。
- 中断并报告:如果是不可重试的错误(如鉴权失败),则终止循环并向用户报告。
一个关键细节:max_output_tokens 错误(模型输出达到上限被截断)是一种特殊的模型错误。Claude Code 对此有专门的处理——它不会简单地中断,而是会”续写”:记录下已经生成的内容,然后发起新一轮请求,让模型从断点继续。这体现在 transitions.ts 的 max_output_tokens_recovery 和 max_output_tokens_escalate 这两个 Continue 状态上。
max_output_tokens_escalate 尤其值得一提:当”续写”也解决不了时(比如模型反复输出超长内容),它会升级处理——这体现了”多级错误恢复”的思想:先温和处理,处理不了再升级。
3.13 Context Overflow
Context Overflow(上下文溢出)是长任务 Agent 最大的敌人:随着对话历史、工具结果不断累积,上下文窗口终将被填满,模型将无法继续处理。
处理 Context Overflow 的核心手段是 Compaction(压缩)——把冗长的历史对话压缩成一份简洁的摘要,腾出空间继续工作。
Claude Code 的压缩系统包含多种策略,其中 autoCompact、microCompact 等位于 src/services/compact/ 目录,其余通过 feature flag 动态加载:
- autoCompact:当上下文接近上限时,自动触发压缩。
- reactiveCompact:当模型报错“上下文太长”时,被动触发压缩。
- microCompact:轻量级的增量压缩。
- snipCompact:精准裁剪掉最不重要的历史片段。
- contextCollapse:上下文“坍缩”,用摘要替换历史。
注意:泄露版源文件不完整——
reactiveCompact、snipCompact、contextCollapse在query.ts中仅有动态require(...)引用,无对应.ts源文件(待验证),故不能断言它们都位于src/services/compact/目录下。
这些机制将在第 21 章(源码分析)和第 35 章(Mini 实现)中详细展开。这里只需要记住一个核心认知:Compaction 是在”保留足够信息”和”腾出足够空间”之间做权衡,它本身就是一门工程艺术。
压缩的一个微妙难点:压缩本身需要成本。生成摘要也是一次模型调用,也要消耗 token。所以”何时压缩、压缩多少”本身就是一个优化问题——压缩太早浪费成本,压缩太晚有溢出风险。这个权衡在第 21 章会看到 Claude Code 的具体做法(预留摘要输出空间、熔断器等)。
3.14 Agent Premature Stop
Agent Premature Stop(过早停止)是无限循环的反面:模型在任务还没完成时就宣布”我完成了”,给出一个不完整的答案。
这通常发生在:
- 任务太模糊:模型不知道”完成”的标准是什么,就草草收场。
- 模型过于保守:遇到一点小困难就选择放弃。
- 缺少反馈信号:没有测试、没有校验,模型无从判断自己的输出是否正确。
解决过早停止的手段:
- 明确的完成标准:在 Prompt 里清楚定义”什么算完成”(比如”所有测试通过”)。
- 验证机制:要求模型在宣布完成前先运行验证(测试、编译、检查)。
- Todo 清单:用
TodoWrite让模型列出任务清单,只有当所有任务都勾选完成时才算完成。
Claude Code 的做法正是综合性的:它鼓励模型维护 Todo 清单、在改代码后运行测试、用 Self-correction 循环验证结果。这些机制共同作用,把”过早停止”的概率降到最低。
“过早停止”和”无限循环”其实是一体两面的问题:一个 Agent 如果停止得太早,就是”过早停止”;如果停止得太晚,就是”无限循环”。两者的根源都是”模型不知道什么算完成”。所以,解决它们的共同钥匙是:给模型一个清晰的、可验证的”完成标准”。
3.15 Long-running Agent
Long-running Agent(长时运行 Agent)是 Agent 能力的终极考验:让 Agent 连续运行几小时甚至几天,完成一个庞大的任务(如”重构整个代码库”、”迁移整个数据库”)。
长时运行的挑战是前面所有问题的叠加放大:
- 无限循环问题 → 可能浪费几小时的计算。
- 上下文溢出 → 一定会发生,必须处理。
- 过早停止 → 任务巨大,模型更容易”假装完成”。
- 崩溃恢复 → 运行到一半断电/断网怎么办?
长时运行 Agent 需要的额外机制:
- Checkpoint(检查点):定期保存状态,崩溃后能从检查点恢复,而不是从头再来。
- 任务分解与进度跟踪:把大任务拆成小任务,用 Todo 清单跟踪进度。
- Context Compaction:持续压缩上下文,保持”能继续工作”的状态。
- 资源与成本控制:长时间运行意味着大量 token 消耗,必须设置预算上限。
Claude Code 通过 Session 持久化、Checkpoint、Compaction、Token Budget 等机制,支持了相当长时间的任务执行。但”过夜 Agent”(Overnight Agent)仍是前沿挑战,第 48 章会专门讨论。
本章小结
本章完成了对 Agent Loop 的全面拆解,核心要点:
- Agent Loop 的核心代码极其简单——一个
while循环 + 生成 + 执行 + 追加,Python 不超过 10 行,Claude Code 的真实循环queryLoop也遵循同样的结构。 - Loop 的本质是 Observe → Think → Act 的反馈回路,它把 LLM 的一次性推理变成了带反馈的持续过程。
- 五种范式/模式:ReAct(推理-行动交织)、Plan-and-Execute(先规划后执行)、Tool-use Agent(边走边决策)、Reflection(生成-批评-修订)、Self-correction(反馈驱动的自我纠正)。Claude Code 以 Tool-use 为主,混合了 Todo 清单和 Plan Mode。
- Loop 简单,是因为复杂度被转移了——推给了 LLM、工具系统、上下文管理三个巨人。
- Loop 周围才是真正的战场:无限循环、工具错误、模型错误、上下文溢出、过早停止、长时运行,每一个都需要专门的 Harness 机制来应对。
带着这个认知,我们进入 Part II——Agent Harness。如果说 Agent Loop 是”心脏”,那 Harness 就是”整个身体”:它提供了 Loop 赖以生存的全部基础设施。
更多内容:
《AI Agent 架构设计与工程实践指南》——从 LLM、Agent、Harness 到 Mini Claude Code – 编程开物
Comment