ARTICLE · 1087459
AI 只会走一步,缺一台发动机
z
AI只会走一步,缺一台发动机
李扁舟
它不是在跑我写死的流程,是在一步步给自己找路。
这是「AI Agent 认知地图」连载的第 5 篇。
上一篇收尾时我挺得意:给它装上了手,能填申请单调工具了。我琢磨着,是时候接个真活儿试试了。
结果它只走了一步,就停在那儿,等我收答案。
有手,却只会走一步
我丢给它一个任务:「苹果和特斯拉,现在哪家股价更高?贵多少?」
我以为它能自己搞定。它确实调了工具——查了两家公司的股票代码。然后,就没有然后了。它把查到的代码往那一放,等着我拍板。
问题出在哪,我后来才想明白:查股价得先知道股票代码。名字 → 代码 → 价格,这三步是一环扣一环的——第二步的输入,正是第一步的输出。
而单次调用只能干一件事:调一批工具,然后交答案。它没法走第二步,因为第二步要站在第一步的肩膀上。
单次调用是一个动作,循环才是一个人会干活。
我起初以为是自己 prompt 没写清楚,改了好几版,一点用没有。后来才承认:不是它笨,是我把它当成能自己走多步的东西了——它本来就没这个机制。

一个简单问题,它走了 3 轮
我不死心,给它接上了循环。同样的问题,这回它自己转起来了:
第 1 轮:get_ticker(苹果)→AAPL get_ticker(特斯拉)→TSLA 第 2 轮:get_price(AAPL)→228 get_price(TSLA)→245 ← 用第 1 轮的输出 第 3 轮:(不再要工具了)汇总 → 特斯拉更高,贵 17 美元
3 轮。 第 2 轮用第 1 轮的结果,第 3 轮用第 2 轮的结果。链条一环扣一环,少一环都断。
我把这三轮的记录都截了图,回头翻的时候,还是觉得有点意思。
单次调用再聪明,也干不完这种任务。差别不在脑子,在它有没有一个「回头接着走」的机制。
你也没法把三个问题一次性塞进 prompt 绕过去——代码还没查出来的时候,我根本不知道第三步里该填什么。

循环里到底循环什么
拆开看,就是四拍:
每一轮都把工具结果喂回去,模型重新决策一次。这套「想—做—看—再想」的循环,叫 ReAct。
这里有个细节,我想了很久才品出味道:它不是在跑一段我预先写死的流程。它是每看一步结果,就重新想下一步。
路,是它自己一步步试出来的。这也是它为什么灵活——我根本没告诉过它先查代码再查价,是它自己走通的。
换句话说,我交给它的不是一张画好的地图,只是一个工具箱,加一句「你自己看着办」。

循环会转不出来,得设三道闸
循环有个吓人的地方,是它可能永远转下去。实测里我设了三道闸。
第一道,它不再要工具了,就收工。 第 3 轮它的 finish_reason 从 tool_calls 变成了 stop,不再吐调用请求,直接给答案。这是很理想的一种收口。
第二道,步数到顶,强制停。 我代码里最多让它转 8 轮,到顶就打断。没有这个上限,一个转不出来的循环能把 API 额度烧光。
第三道,出错就停,并如实报。 这一道有点反直觉,我单独说。
错误不是异常,是数据
我让它算 9999/0。工具抛了 division by zero。
按我写传统程序的老习惯,这时候该弹异常、该崩了。可它没有。
那个错误被当成一条正常的结果回填给了模型。它下一轮看到「哦,除零了」,然后老实回我一句:9999÷0 无定义。
我盯着屏幕愣了一会儿才反应过来:错误从「中断」变成了「信息」。
在传统程序里,报错是流程的终点;在 Agent 的循环里,报错只是又一条线索。模型拿到它,自己决定是换个参数重试,还是就这样如实告诉你。这是它能自己恢复的底子。
以前我写程序,总想把所有错都提前堵死。这一篇让我换了思路:有些错堵不住,不如让它在路上自己长记性。
下一篇
循环有个绕不开的副作用:它一轮一轮地转,结果就一轮一轮地堆进上下文。很快,上下文就塞不下了。
它记不住那么多,接下来怎么办?这是我遇到的下一个坎。
这是「AI Agent 认知地图」连载第五篇。前四篇我都在攒零件,这一篇,我第一次看着它自己把一件事走完了。
如果这篇对你有用,点个「在看」,我们下篇见。
「AI Agent 认知地图」连载 · 第 5 篇