深入理解 Agent Loop(二):执行流程与内部实现
深入理解 Agent Loop(二):执行流程与内部实现
系列第二篇。本篇深入 Agent Loop 的执行流程与内部代码实现。
第四章:什么是 Agent Loop?
4.1 Agent Loop 的定义
终于来到本文的核心概念。Agent Loop(智能体循环),本质上是一种 让 LLM 持续地「思考→行动→观察→再思考」的运行模式,直到任务完成。
用一句话定义:
Agent Loop = 一个由 LLM 驱动的、能够自主决定下一步动作、执行动作、观察结果、并根据结果迭代决策的闭环控制结构。
注意这个定义里的几个关键词:
- 自主决定:不是人告诉它下一步做什么,而是它自己判断
- 执行动作:它有「手」,能调用工具(读文件、跑命令等)
- 观察结果:它会看动作执行后的反馈
- 迭代决策:它会根据反馈调整策略
- 闭环 / 循环:这个过程会一直持续,直到任务完成
4.2 为什么叫「Loop」?
「Loop」这个词是整个概念的核心。我们对比一下传统 LLM 和 Agent Loop:
传统 LLM 是一条直线:Prompt → LLM → 回复 → 结束。
Agent Loop 是一个圆环:Reason → Act → Observe → Update Memory → 回到 Reason,如此循环,直到某个终止条件触发(任务完成、达到最大步数等)。
这个「圆环」结构意味着:Agent 不会在一次回复后就停下来,它会持续工作。就像人类解决复杂问题时的思维过程——想一想、做一做、看看结果、再想一想。
4.3 Agent Loop 的四要素:Reason → Act → Observe → Memory
我们来逐一拆解 Agent Loop 循环中的四个核心环节:
① Reason(推理/思考)
这是 Agent 的「大脑」环节。LLM 在这一步要做三件事:
- 理解当前任务的最终目标
- 回顾之前做了什么(从 Memory 中读取)
- 决定下一步应该做什么
// Reason 阶段的伪代码
interface ReasonResult {
thought: string; // "我需要先读取 package.json 了解项目依赖"
action: Action; // 决定执行的动作
isFinished: boolean; // 是否认为任务已完成
}
② Act(行动)
这是 Agent 的「手脚」环节。Agent 调用具体的 工具(Tool) 来执行动作。比如:
- 调用
read_file工具读取文件 - 调用
run_command工具执行命令 - 调用
search工具搜索代码
// Act 阶段的伪代码
async function act(action: Action): Promise<Observation> {
const tool = tools[action.toolName];
const result = await tool.execute(action.parameters);
return { result, timestamp: Date.now() };
}
③ Observe(观察)
这是 Agent 的「眼睛」环节。工具执行完会有一个返回结果(成功/失败、输出内容、错误信息等),Agent 必须把这个结果读进来,作为下一步推理的依据。
// Observe 阶段
function observe(result: ToolResult): Observation {
// 把工具执行结果转化为模型可理解的文本
return {
success: result.exitCode === 0,
output: result.stdout + result.stderr,
// 这些信息会被拼入下一轮的 Context
};
}
④ Memory(记忆更新)
这是 Agent 的「记忆」环节。每一轮的 Thought、Action、Observation 都会被追加到上下文中,供下一轮 Reason 时参考。没有 Memory,Agent 就像失忆症患者,每次推理都从零开始。
// Memory 更新
function updateMemory(memory: Memory, round: RoundResult): Memory {
memory.messages.push(
{ role: 'assistant', content: round.thought },
{ role: 'tool', content: round.observation }
);
return memory;
}
4.4 一个具体例子:Agent Loop 如何「读 README 并总结」
让我们用一个最简单的例子来感受 Agent Loop 的运转。任务是:「读取项目的 README.md 并总结它用到了哪些技术」。
看到了吗?短短一个任务,Agent Loop 完整地走了一遍 Reason → Act → Observe → Memory 的循环。虽然这个例子只循环了 1 次,但它已经展示了与传统 LLM 的本质区别:Agent 自己决定要读文件,自己去读,读到内容后自己总结——而不是你把 README 贴给它让它总结。
💡 核心认知:Agent Loop 的本质,就是把「人类驱动 AI」变成「AI 自我驱动」。你只需给出目标,Agent 会在循环中自主完成所有中间步骤。这正是「回答问题」和「完成任务」的根本分水岭。
第五章:Agent Loop 的完整执行流程
5.1 一个真实的 Coding Agent 任务
上一章我们用了一个极简例子。现在我们来看一个真实的、完整的 Coding Agent 任务,观察 Agent Loop 是如何在多轮循环中持续推进任务的。
任务:给一个电商项目新增支付模块。
这个任务对一个人类开发者来说,大概需要:看项目结构、了解数据库 Schema、写支付相关代码、跑构建、修构建错误、测试。一个 AI Agent 干这件事的过程完全一样,只不过每一步都对应 Agent Loop 的一轮循环:
5.2 逐轮拆解:注意第 5 轮的「失败 → 修复」循环
请特别关注上图的第 5~7 轮。这是 Agent Loop 最有价值的地方:
- 第 5 轮:Agent 决定跑
npm run build验证,结果构建失败了(类型错误)。 - 第 6 轮:Agent 观察到失败信息,推理出「缺少 import」,于是修改代码。
- 第 7 轮:Agent 再次跑 build,这次成功了。
这就是 Agent Loop 的精髓——它能像人类开发者一样,遇到错误不放弃,而是分析错误、修复、再验证,直到成功。传统 LLM 在第 5 轮就「结束」了,它无法自己进入第 6、7 轮。
5.3 用 TypeScript 代码模拟这个完整流程
让我们用代码把上面这个 8 轮循环的过程模拟出来,让你从「代码层」直观感受 Agent Loop:
// 模拟「新增支付模块」任务的 Agent Loop 执行过程
type ToolName = 'read_file' | 'write_file' | 'edit_file' | 'run_command';
interface AgentAction {
thought: string; // Reason: 这一步在想什么
tool: ToolName; // Act: 用什么工具
args: string[]; // 工具参数
}
interface ToolResult {
success: boolean;
output: string;
}
// 模拟工具执行器(实际中每个工具都有真实实现)
const toolExecutors: Record<ToolName, (args: string[]) => ToolResult> = {
read_file: ([path]) => {
const mockFiles: Record<string, string> = {
'package.json': '{"name":"ecommerce","dependencies":{"vue":"^3.4","vite":"^5.0","@prisma/client":"^5.0"}}',
'prisma/schema.prisma': 'model Order { id Int @id \n model User { id Int @id }'
};
const content = mockFiles[path];
return content !== undefined
? { success: true, output: content }
: { success: false, output: `Error: 文件 ${path} 不存在` };
},
write_file: ([path, content]) => ({ success: true, output: `已创建 ${path}` }),
edit_file: ([path]) => ({ success: true, output: `已修改 ${path}` }),
run_command: ([cmd]) => {
// 模拟第一次 build 失败,第二次成功
if (cmd === 'npm run build') {
return buildAttempts++ < 1
? { success: false, output: 'error TS2307: Cannot find module ./types (payment.service.ts:3)' }
: { success: true, output: '✓ built in 2.4s' };
}
return { success: true, output: 'done' };
}
};
let buildAttempts = 0;
// 完整的 Agent Loop 执行轨迹(模拟)
const executionTrace: AgentAction[] = [
{ thought: '我需要先了解项目结构和依赖', tool: 'read_file', args: ['package.json'] },
{ thought: '需要看数据库结构,确认有没有支付相关表', tool: 'read_file', args: ['prisma/schema.prisma'] },
{ thought: '数据库缺少 Payment 表,需要新增模型', tool: 'edit_file', args: ['prisma/schema.prisma'] },
{ thought: '需要编写支付服务代码', tool: 'write_file', args: ['src/services/payment.service.ts', 'export class PaymentService {}'] },
{ thought: '验证构建是否通过', tool: 'run_command', args: ['npm run build'] },
{ thought: '构建失败,缺少类型 import,需要修复', tool: 'edit_file', args: ['src/services/payment.service.ts'] },
{ thought: '修复后再次验证构建', tool: 'run_command', args: ['npm run build'] },
];
// 运行 Agent Loop
async function runAgentLoop() {
console.log('🚀 启动 Agent Loop:新增支付模块\n');
for (let i = 0; i < executionTrace.length; i++) {
const action = executionTrace[i];
console.log(`\n===== 第 ${i + 1} 轮 ===`);
console.log(`🧠 Reason: ${action.thought}`);
console.log(`🛠 Act: ${action.tool}(${action.args.join(', ')})`);
const result = toolExecutors[action.tool](action.args);
console.log(`👁 Observe: ${result.success ? '✅' : '❌'} ${result.output.slice(0, 60)}`);
console.log(`📝 Memory: 已记录第 ${i + 1} 轮结果`);
// Observe 的结果会影响下一轮的 Reason(在真实 Agent 中由 LLM 决定)
}
console.log('\n===== 第 8 轮 ===');
console.log('🧠 Reason: 构建成功,任务完成');
console.log('✅ Agent Loop 结束:支付模块已成功新增');
}
runAgentLoop();
运行输出:
🚀 启动 Agent Loop:新增支付模块
===== 第 1 轮 ===
🧠 Reason: 我需要先了解项目结构和依赖
🛠 Act: read_file(package.json)
👁 Observe: ✅ {"name":"ecommerce","dependencies":{"vue":"^3.4","vite":"^5.0"...
📝 Memory: 已记录第 1 轮结果
===== 第 5 轮 ===
🧠 Reason: 验证构建是否通过
🛠 Act: run_command(npm run build)
👁 Observe: ❌ error TS2307: Cannot find module ./types (payment.service.ts:3)
📝 Memory: 已记录第 5 轮结果
===== 第 6 轮 ===
🧠 Reason: 构建失败,缺少类型 import,需要修复
🛠 Act: edit_file(src/services/payment.service.ts)
👁 Observe: ✅ 已修改 src/services/payment.service.ts
📝 Memory: 已记录第 6 轮结果
===== 第 7 轮 ===
🧠 Reason: 修复后再次验证构建
🛠 Act: run_command(npm run build)
👁 Observe: ✅ ✓ built in 2.4s
📝 Memory: 已记录第 7 轮结果
===== 第 8 轮 ===
🧠 Reason: 构建成功,任务完成
✅ Agent Loop 结束:支付模块已成功新增
5.4 为什么 Agent「可以持续工作」?
看完这个完整流程,你应该理解了 Agent Loop 的核心价值——可持续工作。但为什么 Agent 能做到这一点,而传统 LLM 做不到?答案是三个机制的结合:
循环控制让 Agent 不会在「一次回复」后就停下,而是持续推进。工具执行让 Agent 有能力真正「动手」操作(读文件、跑命令)。反馈迭代让 Agent 能根据每一步的结果调整策略(失败了就修复)。
三者合一,Agent 就具备了像一个初级开发者一样独立完成任务的能力——这正是 OpenCode、Claude Code、Cursor 让人惊艳的原因。
💡 小结:一个真实的 Coding Agent 任务往往需要多轮循环(本例 8 轮)。其中「失败→分析→修复→再验证」的闭环(第 5~7 轮)是 Agent Loop 最有价值的部分,它让 AI 从「给一次建议就结束」变成「持续工作直到成功」。
下篇将探讨 Tool Calling 与 Observe/Memory 机制。
更多推荐


所有评论(0)