尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Agent明明说完成了,为什么还在不停转圈

Agent明明说完成了,为什么还在不停转圈 文章目录前言1. 先把三个词摆清楚不然后面全白看2. 工具调用step 为什么总说“还没完”2.1 没有工具调用呢模型直接说完了3. 三个入口长得像干的事完全不同3.1 自激问题文件观察器把自己玩醒了4. 结束前的最后一扇窗turn-stopping4.1 那个著名的三步测试4.2 这扇窗也能让循环停不下来5. 更隐蔽的“多跑一次”重试6. max-tokens一旦达到翻不了案7. 产品层面别用一个“正在思考”盖住所有阶段8. 结尾排查清单拿去抄P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看 传送门https://blog.csdn.net/HHX_01前言你见过这种界面吗回答已经完整显示了Agent 还在转圈或者它刚说了一句“完成了”转头又发起一次模型请求。这画面像极了开会时领导说“我讲完了”然后大家又默默听了四十分钟。先别急着骂它死循环。它可能不是疯了只是太有责任感。模型输出结束和任务结束本来就是两套判断——就像你女朋友说“我没事”和“我真的没事”中间隔着一整个宇宙。这一篇接着拆 DeepSeek Harness0.1.6-alpha.2提交ddefc45fbc7f8e46dd73185e68295696d1297887。重点看agent.ts里的turn()和step()一个管运行周期一个管单步执行。界面上的状态都得对照这两个函数的返回条件来看。1. 先把三个词摆清楚不然后面全白看动手之前先把三个单位摆出来。这三位长得像但绝对不是三胞胎顶多算同款发型单位在这里表示什么request / attempt一次模型调用尝试可能成功也可能失败后重试step一次已经进入的循环步骤包含请求尝试及对应工具执行turn从turn/start到turn/end的一次运行周期可以包含多个 step结论先放这儿一次请求返回不代表这个 step 的动作都做完了一个 step 结束也不代表 turn 就能收工。另外同一个 step 遇到能恢复的请求错误还可能原地重试。翻译成人话外卖显示“已送达”不代表饭已经在你的桌子上老板说“会开完了”也没人敢第一个站起来走。这三个单位的关系就像点外卖、等外卖、吃外卖——你以为是一件事其实是三件事而且账单还分开算。2. 工具调用step 为什么总说“还没完”最常见的路径模型生成一条工具调用流结束后Harness 提交 assistant 消息执行工具记录结果。这时候step()返回的不是 completed而是null——意思是本 turn 还得继续除非工具执行明确给出了结束信号。翻译一下step()不是拒绝下班是它知道还有活没交接完。为什么因为工具跑完还得再来一次模型请求处理结果。就像你让同事去查个数据他查完回来你还得看数据、给结论——工具只是把活干完收尾永远得你自己来。第一篇里的读、改、测流程就是这样三次工具请求之后还有一次最终说明总共四次请求。注意这只是默认路径不是铁律。源码里有工具主动 conclude turn 的分支取消和异常也能终止过程。实现调度器的时候别照着口头解释写一个无条件的continue——那相当于把“他应该回来了”当成“他已经在座位上了”。2.1 没有工具调用呢模型直接说完了假设模型直接给出一段完整文字step()确实可以返回 completed。但turn()还有一步检查收件箱——有没有属于下一步的输入这个检查是为了接住模型生成期间冒出来的新事实。比如文件监控插件发现依赖刚被改动或者用户补了一句“顺便考虑一下空数组”。这类输入如果会影响当前任务运行时就不能只凭模型刚才那句 finish 就把 turn 掐了。这就好比你已经说了“晚安”老婆突然说“对了还有一件事”——睡意全无turn 也别想结束。3. 三个入口长得像干的事完全不同源码里有三个长相相近、语义不同的入口followup(message) → next-turn并唤醒 steer(message) → next-step并唤醒 inject(message) → next-step不主动唤醒followup()是把输入排到后续的 turnsteer()是影响接下来这一步的输入inject()更适合插件补上下文运行中可以接续消费空闲时就先留着等下一次唤醒。这仨的区别用生活场景解释就是followup你老婆说“没事”——这话是留给以后吵架用的steer她说“你再想想”——直接影响你接下来这一步inject同事在你桌上贴了张便利贴——你忙完才看不打断你。3.1 自激问题文件观察器把自己玩醒了这三个入口还决定了一件事输入要不要主动唤醒循环。如果文件观察器每次发现变化都唤醒模型那 Agent 自己改文件又会触发观察器——好家伙这不是 Agent这是俄罗斯套娃版的《土拨鼠之日》。多出一圈调用还算轻的严重时能连续自激模型累死账单烧穿。选inject可以避免把每个观察事件都变成新的唤醒请求。但插件自己也得有点数别无限注入重复信息。你往别人桌上贴便利贴可以贴一万张同内容的那叫骚扰。4. 结束前的最后一扇窗turn-stopping当 step 已经具备结束条件、且下一步收件箱为空时循环会发出一个串行扩展点agent/turn-stopping。注意这不是“已经结束”的通知。它处在结束前的窗口期监听者仍然可以往里面加下一步输入。等监听完成后循环会再检查一遍收件箱和取消信号然后才决定是否退出。你可以把它理解成登机广播广播说“请登机”但你没上飞机之前广播会一直循环而且你随时可能发现自己忘带了充电宝。4.1 那个著名的三步测试仓库里有一个受控测试模型脚本依次回答step 1、step 2、step 3三次回复都是纯文字没有工具调用。监听者在 stopping 窗口检查已完成的步骤数不足三步就steer(continue)。最终断言同一个 turn 里跑出三步、发生三次请求。这个测试我们实际跑通了。它证明的是运行时允许在结束前追加工作。不是模型自己忽然决定多想两轮——模型没那么有主见它只是老实回答是监听者在后面喊“继续继续别停”。4.2 这扇窗也能让循环停不下来这个扩展点是把双刃剑。一个插件如果每次 stopping 都塞入新消息那模型无论说多少次“完成”turn 都不一定结束。这时候光改提示词、让模型“回答完就停止”解决不了问题。真正的驱动条件不在这——就像你让一个话痨“说到点就停”他诚恳地点点头然后继续说了二十分钟。该检查的是输入是谁追加的、什么时候追加的、有没有终止条件以及外层有没有预算和用户取消机制。扩展点提供的是“继续运行”的能力继续条件和停止条件得由业务逻辑自己定。你可以给它加菜但得有人负责喊“够了”。5. 更隐蔽的“多跑一次”重试还有一种更隐蔽的情况模型请求失败后的重试。step()内部本身就有一层尝试循环firstAttempt保证本 step 的用户消息只承认一次不会每次重试都重复追加。同一份步骤输入、同一次预处理可能要经过多个调用尝试才拿到有效输出。这就像考试没及格重考——题目还是那道题但你不能把上次的答案直接粘上去监考老师认得你。所以数数的时候要有自己的口径算成本数 request看业务进展数 step看用户这一轮怎么收束数 turn。把三个数字揉成一句“Agent 调用了 N 次”最需要解释的信息就丢了——信息量直接从 4K 掉到 240p。日志也要分清有效的 assistant 消息和没成功落到模型历史里的 attempt是两回事。重试失败的片段可以留作诊断材料但不能随手当成“已经说给模型听”的历史——这就像草稿纸上的演算过程不能直接算作答卷的一部分。日志这块儿下一篇接着拆。6. max-tokens一旦达到翻不了案源码还记录了max-tokens这个结束事实在 turn 里是黏性的。一旦某个 step 达到上限后面就算正常完成也不能把整个 turn 的结果悄悄降回普通 completed。最终回复完整不代表之前的步骤没发生过截断。这个状态必须保留。调用方得知道运行经历过什么才能决定要不要向用户提示、要求补做、或者记录诊断。这不是说凡是碰到 token 上限的任务都失败了——而是不能把重要的运行事实藏起来。就像你面试表现完美但简历上那段空窗期HR 还是看得见的。7. 产品层面别用一个“正在思考”盖住所有阶段从产品角度看最好不要用一个“正在思考”的状态盖住所有阶段。模型正在生成、工具仍在执行、结束前扩展还没处理完——这是三种不同的等待。用户看到完整文字后还在等至少应该有机会知道系统在等什么。不然用户只会觉得这玩意儿是不是卡了——和你看加载圈转了十秒时的想法一模一样。不过要展示这些状态就得订阅运行时的事实不能靠文字内容猜。回复里出现“已完成”不构成状态转换出现“让我检查一下”也不保证后面真的执行了工具。翻译一下男朋友说“马上到”和真的到了是两码事领导说“我考虑一下”和真的考虑了也是两码事。8. 结尾排查清单拿去抄这一篇相关的loop.spec.ts共 65 个测试、inbox.spec.ts共 7 个测试都在固定提交上通过。重点包括停止窗口追加下一步、空闲注入不启动 turn、工具执行中的注入顺序。它们用受控回复核对调度语义不衡量真实模型的任务成功率。所以turn 结不结束取决于五件事模型动作、工具结束信号、收件箱、结束前扩展、取消状态。排查“为什么还在跑”的时候逐项过一遍模型是不是还在生成——数 request工具是不是还在执行——看 step 返回收件箱里是不是还有货——查 inbox有没有插件在 stopping 窗口疯狂加菜——查扩展监听者外层有没有预算和取消机制——问产品只改模型的结束措辞改变不了运行时条件。话痨不会因为你说“说完了就闭嘴”就闭嘴运行时也不会因为模型说“完成了”就真的完成。最后说句实在话如果上面五条都查完了还没头绪先重启。重启治不好的才轮到我们接着看代码。P.S. 无意间发现了一个巨牛的人工智能教程非常通俗易懂对AI感兴趣的朋友强烈推荐去看看传送门https://blog.csdn.net/HHX_01
返回列表