Agent 到底是怎么跑起来的
疑问
我最开始做 LLM 应用的时候,脑子里就一个模型:一段输入,一段输出。
我当时的困惑非常朴素:LLM 本质上不就是一段输入、返回一段输出的函数吗?一个函数调用,怎么就变成一个能自己循环、自己纠错、自己决定下一步干什么的活物了?
一开始大家都把 LLM 当函数用
2022 年前后,大家刚发现 GPT-4 能干活的时候,用法简单:
python
answer = llm("帮我总结一下这篇文章")
就一行。模型是无状态的,就像调一个高级版的翻译 API,
这个阶段的架构图,画出来就是一个箭头:
css
[输入] → [LLM] → [输出]
后来大家开始想:能不能把几个 LLM 调用串起来?比如先让模型提取要点,再让模型根据要点写摘要,最后翻译成中文。每一步的输出是下一步的输入。
这就是 DAG(有向无环图) 模式,通俗点说就是流水线。2022 年 LangChain 刚出来的时候,主打的就是这个,这就是 chain。

我当时觉得这东西特别好,顺序是死的,每一步都能打日志,哪一步挂了就停在那,如果你只是要每天定时生成一份报告,DAG 够用,而且是最省心的选择。

但问题也很明显:一旦中间某个步骤的结果不理想,你没办法让它回头重做。流水线只管往前流,不管质检。
然后有人画了一条往回指的箭头
既然问题是没办法回头,那解法就呼之欲出了:在流程图上加一条往回指的边。

图论上这叫有向有环图(DCG),但你完全可以把它理解成带重试逻辑的流水线。
2023 年 LangChain 搞了个新东西叫 LangGraph,核心就是让你能在节点之间画这种回头箭。我当时看到的第一反应是:这不就是个状态机吗,至于单独起个名字?
但后来我发现,它和我以前写的状态机有一个本质区别:判断要不要回头的那个节点,不是 if-else,是 LLM 自己决定的。
这就意味着控制流的一部分被 LLM 接管了。以前代码的逻辑是我写的,现在有一部分逻辑是模型思考出来的。
这个变化带来的一个直接后果是:你必须手动给它装一个刹车,也就是最大轮回次数
python
max_retries = 5
加了之后,它最多跑 5 轮就停。
DCG 的铁律:只要图里有环,你就必须在代码里放一个和 LLM 无关的硬性上限。
ReAct:让模型自己决定先迈哪条腿
DCG 解决了一部分问题,但它的图还是你提前画好的。你能画回头路,但你得先知道有这条路。
可是通用问题千百种,特别是通用 agent 平台
比如:「帮我查一下下周北京的天气,如果下雨,就帮我找一家带壁炉的咖啡馆,把地址发给我。」
你没法预判要搜几次,也不知道中间会碰到什么格式的网页,更不知道它会不会在搜天气的过程中发现「旧金山下周天气」这个词条下面直接有一个「雨天咖啡馆推荐」的链接,然后一步到位。
这种开放性任务,需要让模型在运行时自己决定下一步干什么。
2022 年底,谷歌发了一篇论文叫 ReAct(Reasoning + Acting),思路非常粗暴但有效:
让模型在「想一步」和「做一步」之间来回跳,直到它觉得自己可以交差了。
ReAct 不是 while true,它是一个有出口的循环 。出口就是模型自己输出Final Answer。但模型有时候会迷路,所以你必须用 max_steps 强行把它拽出来。
最外面那层壳:Agent Loop
ReAct 解决了一次性任务的自主执行问题。但还有一个问题没解决:谁来叫醒它?
真实世界里,没有人会每次打开终端手动输入一句「帮我查天气」。我们想要的是一个一直在线、随叫随到的助手。
这就是 Agent Loop,也有人叫 Event Loop。它的结构简单到你会觉得这也算一种架构?:
python
while True:
event = wait_for_input() # 等用户说话、等定时器、等消息队列
result = react_loop(event)
respond(result)
外层是死循环,靠外部信号(Ctrl+C、kill、shutdown hook)终止。内层每处理一个任务,跑的还是 ReAct 。
现在的主流玩法:三层嵌套
聊完这几代演进,那现在的 coding agent,比如 claude code,用的是哪一种?
答案是:全用上了,而且是一层套一层。
用 claude code 输入帮我写一个登录功能举例子,它内部大概是这样跑的:

- 最外层:while true 的 Agent Loop,保持存活。
- 中间层:每个任务是一个 ReAct 循环,动态规划步骤。
- 最内层:工具调用和子任务之间的依赖关系,本质上是一张 DAG。
三代架构不是替代关系,是嵌套关系。
最后
希望你看完这篇,下次再看 Claude Code 自己在那儿忙活的时候,心里大概有数------它到底在忙些什么。
