The Agent Loop - 理解 Agent 循环的本质

1363 字
7 分钟
The Agent Loop - 理解 Agent 循环的本质

“One loop & Bash is all you need.”

这句话出自 Claude Code 的设计哲学,概括了 Agent 的本质。不是框架,不是复杂的提示词链,不是精心编排的工作流——只是一个循环,加上 Bash 工具。

这个循环长什么样?

def agent_loop(messages: list):
while True:
response = client.messages.create(
model=MODEL, system=SYSTEM, messages=messages,
tools=TOOLS, max_tokens=8000,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason != "tool_use":
return
results = []
for block in response.content:
if block.type == "tool_use":
output = run_bash(block.input["command"])
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": output,
})
messages.append({"role": "user", "content": results})

就这么简单。while True 加一个 stop_reason 检测,这是 Agent Loop 的全部骨架。

谁在决策?#

看这段代码,你可能会有疑问:循环这么简单,智能在哪里?

答案:循环本身没有智能

概念定义职责
Agent模型本身决策、感知、推理、行动
Harness工具 + 循环 + 反馈执行、反馈、安全护栏
Loopwhile True + stop_reason完全服从模型决定
Hook边界守护安全护栏,不替模型决策

Agent 是模型——那个在行动序列数据上学会了感知、推理、行动的神经网络。不是框架,不是提示词链,不是工作流编排。

Harness 不替模型做判断。它只做三件事:

  1. 执行:运行工具,返回结果
  2. 反馈:把结果 append 到 messages
  3. 护栏:Hook 提供安全边界

决策权完全在模型。循环只是忠实地执行模型的意图。

stop_reason:唯一的退出条件#

回到代码的关键行:

if response.stop_reason != "tool_use":
return

这是循环唯一的退出条件。stop_reason 有四种值:

含义循环行为
tool_use模型调用了工具继续循环,执行工具
end_turn模型主动结束退出循环
max_tokensToken 耗尽,被迫截断退出循环
stop_sequence遇到停止序列退出循环

为什么必须用 stop_reason 检测,而不是检测 tool_use 是否存在?

新手容易犯的错误:看到响应里有 tool_use block 就执行,没有就退出。这看起来合理,但会在 max_tokens 截断时出问题。

max_tokens 被触发时,响应可能包含一个未完成的 tool_use block。模型还没说完,工具调用可能缺少参数或格式错误。如果这时执行它,就会产生错误行为。

正确的做法:只有当 stop_reason == "tool_use" 时才执行工具——这表示模型完整地表达了调用意图。

验证你的理解#

读到这里,用两个问题检验你的心智模型是否稳固:

Q1:循环能不能阻止模型重复调用同一个命令?

比如 ls → del → ls,模型连续两次调用 ls。

:::details 答案 不能,也不应该。ls → del → ls 是合理的验证行为:删除后确认文件是否消失。

循环不替模型做决策。Hook 可以提供安全护栏(比如”禁止删除系统文件”),但不是决策替代。 :::

Q2:如果要在循环里加”智能检测”防止无限循环,好主意吗?

:::details 答案 坏主意。这违背了职责分离原则。

Harness 的职责是执行、反馈、护栏——不是判断模型的意图是否”合理”。如果模型陷入无限循环,问题在模型(提示词、上下文、能力边界),不是循环。

Hook 可以设置超时或调用次数上限作为硬边界,但这是安全护栏,不是”智能判断”。 :::

如果这两个问题你都能答对,说明你已经理解了 Agent Loop 的本质:循环服从模型,Harness 不替模型决策

messages:给模型”时间感”#

还有一个关键机制:messages[] 的累积。

再看代码的两处 append:

# 第 8 行:记录模型的响应
messages.append({"role": "assistant", "content": response.content})
# 第 17 行:记录工具执行结果
messages.append({"role": "user", "content": results})

每次循环,messages 都在增长。模型能看到完整的对话轨迹:

user: 请帮我列出当前目录
assistant: [tool_use: ls]
user: [tool_result: file1.txt, file2.txt, file3.txt]
assistant: 文件列表如下:...

这就是模型的”时间感”——它知道自己做过什么,看到了什么结果。没有这个累积,模型就像失忆了,每次调用都从零开始。

messages 是 Agent 的记忆载体。Context Compact(L06)会讲解当 messages 太长时如何压缩,但核心原理不变:累积历史,给模型上下文。

验证你的理解#

Q3:如果每次循环都清空 messages,会发生什么?

:::details 答案 模型会”失忆”——每次调用都从零开始,不知道自己做过什么。

比如:模型调用 ls 看到文件列表,然后调用 del file.txt。如果 messages 被清空,模型就不知道刚才看到了什么文件,也不知道删除是否成功。

messages 的累积是 Agent 能做复杂任务的前提:它需要知道自己”走到哪里了”。 :::

扩展视角:循环上的叠加#

理解 Agent Loop 后,你会发现后续的课程都在这个循环上叠加机制——循环本身始终不变:

课程叠加机制循环的变化
L02Tool Use加工具,不改循环
L03TodoWrite循环上加规划
L04Subagent循环派生子循环
L05Skill Loading循环中注入知识
L06Context Compact循环的上下文管理
L07-L12持久化与团队协作循环的状态保存

核心洞察:无论机制多复杂,骨架始终是 while True + stop_reason。理解 L01,就理解了后续所有课程的根基。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!

赞助
The Agent Loop - 理解 Agent 循环的本质
https://firefly.cuteleaf.cn/posts/learn-claude-code/01-agent-loop/
作者
AltumSisy
发布于
2026-04-01
许可协议
CC BY-NC-SA 4.0
Profile Image of the Author
AltumSisy
Hello, I'm AltumSisy.
公告
欢迎来到我的博客!这是一则示例公告。
音乐
封面

音乐

暂未播放

0:00 0:00
暂无歌词
分类
标签
站点统计
文章
32
分类
3
标签
25
总字数
68,347
运行时长
0
最后活动
0 天前

文章目录