看懂 Agent Loop:鉴别真假 AI 产品的第一性标准

$
内容纲要

你在一个 AI 投放助手里输入一句话:「帮我看看计划 A 最近怎么回事,消耗越来越高,效果越来越差。」

它不会立刻回答你。

它会先去查数据。查一次还不够,可能查完总消耗,又查分素材,再对比行业均值。查了好几轮,最后才告诉你:问题出在哪。

这篇文章就做一件事:跟踪你那句话发出去之后的完整旅程。它怎么被”听懂”,数据怎么被查出来,结论怎么一步步得出来,中间哪些环节会出错、出了错会怎样。

先交代一个前提,后面全靠它:模型本身不会查数据。它只会做一件事——读一段文字,生成下一段文字。所以整个旅程的本质是:一个只会读写的”大脑”,配上一套替它跑腿的机制。这套机制叫 Agent Loop,智能体循环。

第一站:先把”记忆”发给模型

你的那句话发出去后,系统做的第一件事不是回答,而是把它放进一份对话历史里,然后整份发给模型。

为什么要整份重发?因为模型没有记忆。它不记得你 30 秒前说过什么,更别说昨天。每次调用都是第一次见面,必须把前情提要全部塞给它。

模型像一个每天失忆的顾问。你每次找他,都得把之前的谈话记录重新给他看一遍,他才能接上话。

这个特点不是小事。如果历史发漏了——比如漏了你上周说过的”只看计划 A”——模型可能转头就去查计划 B。失忆的代价就是答非所问。

所以,对话历史是这场旅程的地基。模型每做一轮判断,都要把更新后的历史重新读一遍。

第二站:模型说”我要查数据”

模型读完历史,没有直接回答,而是返回一句:我要调用消耗查询工具,查计划 A 近 7 天数据。

注意,模型只是”说”要查,它自己不会查。它输出的只是一段结构化的文字:工具名,加参数。真正去查的,是外面那层循环代码。模型是大脑,循环是手脚。

这一轮,模型可能不止查一个东西。它说”顺便再查下行业均值”。一轮两个调用,回来两条结果。

问题来了:两条结果,哪条是计划 A 的消耗,哪条是行业均值?

每条工具结果都带一个编号,跟发起调用的那句话一一对应。没有这个编号,”计划 A 消耗”和”行业均值”就会送错,后面基于数据的诊断全错。

这就像快递单号。同时寄出两个包裹,回来的两件货必须贴单才知道谁是谁。对号这件事,是刚需,不是优雅设计。

第三站:查到的结果去了哪

循环执行完工具,拿到结果——比如”7 天消耗 12 万,环比涨 38%”——然后把这条结果追加进对话历史,再次把整份历史发给模型。

这一步叫写回。它是整个循环最容易被忽视、也最要命的一步。

模型下一轮能”知道”查询结果,唯一途径就是结果出现在它重读的历史里。不写回,查了等于白查,模型下一轮还在问:数据呢?

到这里,一个完整的圈转完了:发历史 → 模型说要查 → 真的去查 → 结果写回 → 再发历史。

agent 的”智能”,就是靠这个圈一圈圈转出来的。第二轮,模型读到消耗数据,可能说”再查下分素材的数据”,于是再转一圈。第三轮,读到素材 X 的 CPM 涨了 40%,它说”问题找到了”,不再调用工具。

旅程结束,结论给你。

Agent Loop 循环全景:发历史 → 模型判断 → 执行工具 → 结果写回 → 再发历史
Agent Loop 循环全景:发历史 → 模型判断 → 执行工具 → 结果写回 → 再发历史

第四站:循环什么时候停下来

刚才说,转到第三圈模型”说完了”,旅程结束。这里其实藏着两个问题:循环怎么知道模型说完了?万一模型一直不肯说完呢?

先看第一个。模型每次回答完,都会附带一句”我为什么停下来”:想调工具,还是说完了。循环拿它当红绿灯——想调工具就接着转,说完了就收工。

再看第二个。万一模型判断失误,一直”再查一下”,循环就永远停不下来,钱和时间都在烧。所以需要一个兜底:一次模型调用算一个 iteration,默认最多 90 次。这就是那脚刹车。

有意思的是,这个限制叫”预算”而不叫”上限”。因为它不是一个静态计数器,而是一份可以消耗、可以共享的资源。

共享是什么意思?假如这次诊断中,主 agent 派了一个子 agent 去拉 30 天的长周期数据。子 agent 花掉的调用次数,是从主 agent 的 90 次里扣的,不是另外再领一份。主 agent 自己用了 10 次,子 agent 用了 15 次,主 agent 就从剩下的 65 次接着干活。

这个设计一口气推出三个结论:不管派多少层子 agent,总成本封顶在 90;层数再多也不会指数级烧钱;父子在同一个钱包里抢资源,模型被迫把钱花在刀刃上。

做产品的同学可以直接抄这个设计。给 agent 产品设计计费时,“一个任务一个共享钱包”比”每次调用单独算”更贴近工程现实,也更容易向客户解释成本。

迭代预算扣减:90 次预算如何在父子 agent 之间消耗
迭代预算扣减:90 次预算如何在父子 agent 之间消耗

后台:内部记录和发给模型的,是两份

到这里,旅程的主线讲完了。但有个后台环节值得单独看一眼。

前面我一直说”把整份历史发给模型”,其实不完全准确。系统内部存的历史,和实际发给模型的,是两份东西。

内部那份是底稿,什么都记,包括模型的思考过程、token 统计这些调试信息。排查问题时全靠它,信息越全越好。

发出去那份是誊写后的信。把模型看不懂、也不需要看的内部字段剥掉,再把 system prompt(人设、规则、工具说明)拼在最前面。

为什么必须分两份?算笔账:一条模型回复带着 500 token 的思考过程,不剥掉,每轮都原样发出去,十轮对话光这几条就多烧几千 token。而且多余字段发给 API,轻则浪费,重则直接报错。

system prompt 也是同理。它每次调用时临时拼在最前面,不存进历史。否则它会被持久化、被每轮重发几十份。

底稿像日记,什么都写;寄出的信像工作邮件,只写对方需要知道的。这个“内部字段不出系统边界”的分层意识,在任何 API 设计里都成立。

内部底稿与寄出信件的对比:哪些字段被剥掉
内部底稿与寄出信件的对比:哪些字段被剥掉

基建:让循环在多平台跑得起

到目前为止,讲的是单次对话。但真实产品里,这个循环要同时服务终端、Telegram、飞书等十几个平台,还要控制成本。这需要三个基建决策。

第一个:循环主体用同步写,异步工具走桥。

八成工具——读写文件、跑命令——本来就是同步的。少数工具,比如网络请求、浏览器操作,是异步的。如果为了少数派把整个循环改成异步,所有同步工具都得白包一层,报错堆栈变深,调试难受。

所以选择是:循环保持同步,遇到异步工具,就交给一个常驻的事件循环去跑。这座桥不能临时搭。想象 agent 在广告后台连续翻页拉报表,浏览器登录态得一直保持。桥一拆,连接就断,下一轮得重新登录。

第二个:agent 实例复用,而不是每条消息新建。

多平台入口下,每条消息都新建一个 agent 实例很浪费。真实做法是按配置签名缓存复用——模型、密钥、工具集没变,就接着用旧的。只有重置会话、换模型时才淘汰。

深层原因是钱。模型厂商的缓存机制要求 system prompt 在多轮之间保持不变才能命中,命中就意味着更便宜更快。实例复用,system prompt 就不变,缓存就一直命中。

但比实现更重要的是一条铁律:对话历史每次从数据库传入,实例随时可能被淘汰重建。代码不许依赖实例”活着”。

第三个:续聊时,system prompt 读回旧的,不重新组装。

继续一个老会话时,直接从数据库把当初那份 system prompt 读回来。为什么不重新拼一份?因为重新拼的可能不一样——记忆文件中途被改了一行,新拼的就和旧会话对不上,缓存当场失效。

这里藏着一个真实的工程拉扯:记忆要更新,缓存要不变。两头都要,就得在架构上做取舍。这个拉扯,后面讲记忆系统的那篇会展开。

三个决策放一起看,产品上的启示只有一句:会话状态全部外置,实例本身无状态。这是 agent 产品能水平扩展、能多端同步的架构前提。哪天你想做”手机上聊一半,电脑上接着聊”,靠的就是这个。

复盘:六个岗位,一张表

整趟旅程走完了。回头看,agent 能干活,靠的是六个岗位各就各位:

岗位谁干的出事会怎样
大脑模型:读历史、做决策没有它,agent 是空壳
记忆对话历史:每轮整份重发漏了,模型失忆、答非所问
手和眼睛工具调用:真的去查数据没有它,agent 只会空谈
汇报结果写回:放回历史漏了,查了等于白查
刹车停止原因 + 迭代预算没有它,要么中断要么烧钱
分拣员底稿与寄信分离不分,报错或白烧 token

这张表可以存下来。以后不管是自己写 agent,还是评审别人的方案,六个岗位挨个问一遍,比泛泛地问”你们 agent 稳不稳”有用得多。

最后,三个能带走的判断。

一,鉴别真假 agent。拿到任何 agent 产品,先问它的循环在哪。模型说完”我要查”之后,有没有一层代码真的去查、把结果喂回去?找不到这层,就是 prompt 套壳。

二,计费设计抄作业。共享钱包式的预算模型可以直接搬进产品方案:一个任务一个预算,子任务从父任务里扣,总成本天然封顶。

三,扩展性的前提。会话状态外置,实例无状态,历史落库。多端同步、水平扩容,都靠这个地基。

下一篇,我们拆开”手和眼睛”这个岗位,看看一个生产级 agent 的工具系统是怎么注册、怎么分发的。