面试知识库

M1 · 最小 AgentLoop —— 开发文档(面试向)#

讲为什么这么做、做了哪些取舍,不讲代码。读完能用大白话讲出来。

一句话概括#

M1 不碰真实业务,只用几个”假装在搜商品”的玩具工具,把这个项目最核心的运行方式跑通一遍:让大模型自己一步步想、自己决定调哪个工具、自己判断什么时候够了该收尾。这套”循环到模型说够了为止”的玩法,就是整个项目的发动机。先在练习区(examples/)跑顺,再上正式业务。

打个比方:M0 修好了路,M1 是第一次发动引擎、在空地上把车开起来——还没载客,先确认车能跑、能自己刹车。


1. 为什么先在”练习区”跑,不直接写正式功能#

做法:M1 的代码全放在 examples/ 练习目录里,和正式业务代码分开。

为什么:这个项目最难、最容易翻车的是”运行方式”本身——模型会不会自己停下来、会不会绕死循环。先用最简单的假工具把这套运行方式单独跑顺,搞懂了再去接真实的搜索、比价。一上来就真刀真枪,会同时被”业务逻辑”和”运行机制”两个问题夹击,出了问题分不清是哪边的错。

面试怎么讲:先用最小例子验证核心机制,再叠加复杂度。把”机制对不对”和”业务对不对”分开验证,调试起来才清楚。


2. 这个项目的发动机:循环几次,是模型自己说了算#

这是 M1 最核心的一点。

传统的”问一句答一句”是这样:用户提问 → 模型调一次工具 → 给结果 → 结束。这种方式只能处理简单请求。

但用户说”帮我搜旅行收纳袋、预算300不要塑料、再跨平台比价给推荐”——这需要好几步:先拆需求、再搜、再比价、最后给结论。关键是:这中间要走几步、按什么顺序,不是我们写死的,是模型一边做一边自己决定的。

实测里就能看到模型自主规划:它先调”拆解需求”,再调”搜商品”,然后调”比价”,比完发现信息够了,就直接用大白话给出推荐、不再调任何工具。这个”够了,收尾”的判断是模型自己下的,我们没在代码里写”调满三次就停”。

面试怎么讲:传统流水线是”我把步骤写死,模型只填空”;这套是”我只给工具和规则,走几步、什么时候停,模型自己定”。好处是能应付开放式需求;难点是得防着它停不下来(见第 5 点)。


3. 为什么用”状态图”这条路,而不是别的#

要让”模型自己循环”这件事落地,业界有四种思路,我们选了其中一种(基于 LangChain + LangGraph 的”状态图”路线)。简单说说为什么不选另外三种:

  • 不选”多个 Agent 各自为政、互发消息”:购物是强顺序的——必须先搜到、才能比价、才能推荐。让一堆 Agent 异步互发消息,反而把简单的顺序搞复杂了。
  • 不选”先列完整计划再执行”:购物的难点不在”列不出计划”(计划就一句话:搜→比→推),而在执行中才冒出来的意外——搜出来八成是塑料的、某平台没货、加上关税超预算了。这些只有走到那一步才知道,提前列计划没用。我们要的是”边走边看、随时调整”。
  • 不选”把流程画成固定流程图”:用户能自由输入”便宜又抗造、不要塑料、喜欢小众”这种话,没法预先画成固定流程;每多一种偏好组合就得加一条分支,维护会爆炸。

面试怎么讲:选型是排除法。购物场景的特点是”顺序固定但中途多变数、输入开放”,所以选了既能循环、又能随时根据中间结果调整的那条路。


4. 工具描述是写给模型看的,不是写给人看的注释#

做法:每个工具都配一段说明——叫什么名、是干什么的、每个参数什么意思。

为什么:模型就是靠这段说明来决定”现在该不该用这个工具”的。说明写得含糊(比如只写”搜索工具”),模型就会在该用的时候不用、不该用的时候乱用。写清楚(“在电商平台按关键词搜商品,返回名称和价格”),模型的判断才准。

面试怎么讲:在这种让模型自己调工具的系统里,工具的文字说明直接决定模型决策的准确度——它不是给人看的注释,是给模型读的”使用手册”。


5. 最大的坑:得明确告诉模型”什么时候该停”#

做法:在给模型的指令里专门留一段,明确写”信息够了就立刻给结论、结束,别再调工具、别反复搜同一个词”。

为什么:让模型自己决定循环次数,最大的风险就是它停不下来——一直”再查查、再确认确认”,绕圈到系统强制喊停为止,又慢又烧钱。这是这类 Agent 最常见、调试时排第一的故障。所以”什么时候收尾”必须明明白白写出来,当成头等大事。

面试怎么讲:自由度越高越要设刹车。让模型自主循环的代价就是可能死循环,解决办法是把终止条件显式写进指令——这个点几乎是所有做过 Agent 的人都踩过的坑。


6. 为什么要做”实时进度”,不能等全跑完再说#

做法:除了”一口气跑完返回结果”,还做了一个”边跑边播”的版本——模型每开始想一步、每调一个工具、每拿到一个结果,都实时报一条。

为什么:一次真实任务可能要十几秒。如果这十几秒里页面毫无反应,用户会以为卡死了。“边跑边播”能让前端实时显示”正在拆解需求…正在搜索…正在比价…”。而且这些实时事件,正是后面做前端可视化时要用的数据来源——M1 先把这个数据源接通。

面试怎么讲:长任务必须有过程反馈,不然用户以为挂了。顺便,这套过程事件就是后面前端实时展示的原料,所以早点跑通。


7. 踩坑实录:照着教程写会报”过时警告”#

情况:参考文档里用的是一个叫 create_react_agent 的老入口。照着写能跑,但会蹦出”此用法已过时、未来版本将移除”的警告。

怎么处理:查了一下当前装的库版本,发现官方已经把它换成了新入口(create_agent,而且参数名也变了)。于是改用新入口,警告消失。顺手把项目的依赖版本下限也提了上去——因为我们现在用的是新版本才有的功能,得防止别人装到旧版本、发现这个功能不存在。

为什么值得记:参考文档是从网上扒来的、可能过时。原则是”对齐它的思想,但代码按当前真实依赖来写”,不一板一眼照抄。

面试怎么讲:跟着教程/老代码走要警惕版本漂移;遇到过时用法,查官方当前版本换成新写法,并把依赖下限钉死,保证别人也能复现。


M1 验证了什么#

验证点结果
模型能自己一步步规划、调用多个工具✅ 实测自主走完 拆解→搜索→比价
循环几次由模型自判,不是写死的✅ 没写步数,模型信息够了自己收尾
模型能干净收尾、不死循环✅ 最后一步是大白话推荐、不再调工具
能实时播报执行过程✅ 每步思考/调用/结果都实时报出

面试一句话总结:M1 用最小的例子把这个项目的发动机点着了——证明了”给模型工具和规则、让它自己循环到满意为止”这套玩法能跑、且能自己刹住车。这是后面所有复杂业务的基础;最值得讲的两点是”循环次数由模型自决”和”必须显式给终止条件防死循环”。