工具接上之后,新问题立刻冒出来:什么时候该调用工具?一次调几个?拿到结果又该怎么接着做?

有一种失败是只说不做。模型全程在文字里推测,手里没有一件外部确认过的事实,越推测越飘。另一种失败是只做不想。一上来就胡乱调用,参数靠猜,忙活半天跟任务不沾边。

ReAct 要解决的就是这件事:让“想”和“做”交替进行。

名字先解释清楚

ReAct 是 Reasoning 和 Acting 拼出来的一个词,推理加行动。这个词来自一篇同名论文,思路是把推理和行动放进同一个循环里。

它不是某个模型的内部结构,而是一种编排方式——循环由外面的程序组织,换哪个模型都能用。它不靠改模型,靠的是每一轮喂给模型什么、以及拿它输出的什么去执行。

换个角度看这件事:推理和行动不需要两个模型、两套系统。同一段输出里,前面是写给自己看的推理,中间那条是调用请求,拿到结果之后接着往下推理——外面的程序只需要认得出“哪一段是调用请求”就够了。

三个动作,转一圈

想与做 · 两条轨交替

一轮完整的循环由三段组成:

三段走完,进入下一轮:模型看着刚拿到的观察,重新思考。

循环里真正决定质量的环节是“观察”:只有真动手拿回来的东西,才能纠正模型脑子里的猜测。

还有一点容易被忽略:那些“思考”文字,也是模型逐字生成的输出,和它给你的正式回答一样是明面上的文字。它不会发生在模型内部的暗处,反而可以被完整记录、回放——排查 Agent 问题的时候,这份记录是最有用的一手材料。

一步接一步 · 排成队

交替为什么能压住胡编

关键在外部事实的注入频率。

只靠语言推理的话,模型一口气把整条思路讲完,中间没有任何东西能打断它。它对不对,你只能等到最后才发现。

交替之后,每想一步就动一次手:每拿到一次观察,模型的推理就被一份外部事实钉了一次。方向一开始就错的话,第一次观察通常就会露馅——报错、结果为空、数字对不上——它有当场改的机会。

这个循环也解释了两件事:它为什么慢,为什么贵。每一轮都要把前面的全部内容重新过一遍模型,来回几轮的代价不小。

思考那一步,写还是不写

不同系统对“思考”的处理并不一样。有的要求模型把思考明确写出来,有的只在提示里让它“想清楚再回答”,那段推理并不落到输出里。

写出来有三个现成的好处:出了问题能回放,发现走偏能当场打断,钱花在哪里一目了然。代价也直接——每一轮的思考文字都会留在上下文里,转得越多,占的地方越大。

还有一种更省事的变体:先让模型一次性排一份计划,再照着计划一步步执行。快是快,可计划一旦在中途撞上意外——参数不对、结果不符——还是得回到逐轮交替这条老路上来。所以实践里常见的是两者搭配:先粗略计划,再逐步交替。

什么时候停

循环不能一直转下去。真实系统里通常有三道闸:

会停,是 Agent 的基本素养;没有停机条件的循环不是智能,是事故。

再看这三道闸的位置:第一道在模型那边,后两道在外面。把停机权整个交给模型是危险的,最后决定停下来的那股力量,必须握在外部。

顺带说一句,第一道闸其实不太可靠:模型有时会把没做完的事说成做完了,而且说得很有底气。所以外部的两道闸不是备用保险,是主力。

三道闸 · 该收手就收手

出错时的两种反应

出错之后,Agent 一般有两条路可走。

区分这两者的责任也落在外部程序:它决定哪种失败值得重试,哪种必须改做法。而模型能不能反思对,很大程度上取决于错误信息写得够不够具体——一句“执行失败”什么都改不了,一句“参数 date 格式不对,应为 2026-11-04 这样的写法”才能让它改对。

反面的两种失败也很常见:

这两种都能靠外部手段防:限制同一个动作连续失败的次数,并在每一轮开始前把任务目标重新强调一遍。

走一遍具体的过程

任务:确认官网首页现在返回的状态码是不是 200。

如果返回的是 301,循环会自动多转几圈:模型看到重定向,可能再请求一次目标地址,把最终结果确认清楚才回话。整个过程里,发请求的始终是外部程序;模型做的事是看结果、决定下一步。

下一站

循环转起来了。但你可能已经注意到一个隐患:每转一圈,前面的思考和观察都要重新带上一遍。

轮数一多,这些内容就会把模型能读的长度挤满。它需要一套记性——而且是会取舍、会整理的记性。这是第四篇的主题。