e2e智能体循环源码深读tool-loop 如何驱动模型-动作循环【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2ee2e 是一款面向 Web 与移动端的开源 AI 端到端测试框架你用一句自然语言描述测试目标智能体就会自己驱动应用去达成它。这篇文章深读 e2e 智能体的心跳——tool-loop 循环底盘带你看懂模型-动作循环是如何被一轮一轮驱动、被安全收口的。一、先看懂一次agent.act背后发生了什么在测试里写一行agent.act(把套餐升级到 Pro)框架并不会立刻去点按钮而是启动一个智能体步骤step内部是一个反复转动的循环模型读取当前屏幕语义树 可选截图产出一个工具调用如tap、type、scroll循环执行该工具把屏幕上发生了什么变化作为结果送回给模型模型基于新结果决定下一步直到它认为目标达成或彻底无解模型调用专门的complete_step工具提交passed / failed / blocked判决循环结束。这个模型 → 动作 → 观察 → 模型的闭环就是典型的tool-loop工具循环。下面进入源码看 e2e 如何把它做成一个稳如底盘的机器。二、循环底盘tool-loop.ts的主循环整个循环的核心在 tool-loop.ts它被作者称为 chassis底盘createToolLoopExecutor 是底盘的入口。你只需提供三样东西系统提示词system、工具集tools、开场提示buildPrompt其余的循环纪律全部由底盘继承每个步骤构造一个全新的 LoopRun 实例持有本轮的全部状态已用轮数、硬性停止信号、循环守卫状态、转录记录等run() 主循环 是一个for(;;)死循环靠stopWhen条件刹车。// packages/e2e/src/agent/tool-loop.ts 主循环骨架示意 for (;;) { const loop this.buildLoop(tools); const result await loop.generate({ prompt, ... }); // 文本回复、上下文溢出、工具选择被拒……各自有恢复路径 // 都不命中时才 break进入判决结算 }buildLoop 把循环注册给 AI SDK 的ToolLoopAgent两条stopWhen就是刹车片模型自己刹车complete_step一旦落判立即停止预算刹车累计轮数达到maxModelCalls默认 25 轮即止重试也共用同一份轮数预算绝不偷偷续命。一个很妙的设计哲学写在文件头注释里硬性停止预算耗尽/超时/取消由底盘直接终结循环绝不把控制权交给模型——预算是外边界模型只有建议权。三、每轮必过的策略关卡prepareTurn真正让循环聪明的是 prepareTurn——每发送一次模型请求前底盘都要按固定顺序检查四件事。️ 循环守卫3 次重复先警告5 次强制收场模型有时会转圈同一操作反复发、或在 A-B-A-B 的短周期里打转。loop-guards.ts 是纯检测器默认阈值 很克制守卫警告强制收场同一调用含参数连续重复3 次5 次2~4 步短周期重复2 轮3 轮连续失败的工具结果3 次5 次检测逻辑在 checkLoopGuards调用身份 工具名 精确序列化入参所以点两次不同按钮绝不会被误判为重复。守卫的纪律同样写得很清楚——守卫从不替模型编造判决警告只是往历史里注入一条[SYSTEM NOTICE]让模型改换思路强制收场则是下一轮只给它complete_step一个工具判决依然由模型自己写下。⏰ 收尾通知剩 5 轮提醒剩 2 轮只给交卷键常量定义 里藏着两条时间线轮数线剩余 5 轮时注入快收尾了提醒剩余 2 轮时强制只提供complete_step留两轮而不是两轮强制是容忍模型交出一个不合规判决后还有机会修正时钟线剩余步骤时间低于 60 秒且不超过总预算的 1/4时提前要求模型现在就交最优判决——因为慢速模型一回合就要几十秒让模型带着自己的总结离场远好过一次没有结论的STEP_TIMEOUT。四、complete_step判决工具与封闭式错误码循环的终点是一把锁。createVerdictTool 创建了complete_step工具规则是封闭式的passed 应用表现符合预期且已验证failed 不符合blocked 凭据/环境/测试搭建受阻——blocked必须携带一个封闭清单内的 errorCode否则被拒回给模型重写判决规则原文第一个被接受的判决是最终的之后再交卷一律无效一个真实踩坑的细节某些模型习惯在 passed 判决上附带ACTION_FAILED早期用 schema 拒绝会导致它反复重发直到预算耗尽——现在的策略是丢弃多余码并明确告知而不是打回。五、异常恢复把翻车翻译成模型能读懂的话tool-loop 里最见功力的是它几乎不给硬失败留空间每种异常都有恢复路径普通工具失败→ 经 guard() 包装变成tap failed: ...文本送回模型它自己决定换路模型用纯文本回复、没有工具调用→ continueAfterTextReply 注入一条你上轮什么也没干的系统提示在同一轮预算上再问一次模型拒绝强制工具选择HTTP 400或悄悄降级→ freeToolChoiceRetry 把该模型记入进程级记忆后续改用auto模式 只允许工具调用规则代价只是每模型一次往返上下文窗口溢出→ overflowRetry 收缩历史被取代的整屏省略、超长文本截断后只重试一次第二次溢出才真正报错。此外每个回合都被 recordTurn 逐条记账既供--debug输出完整转录也在报告里保留末尾 12 轮的裁剪版——循环的每一步都可审计。六、内置智能体 底盘 语法工具集现在可以回到全貌。内置智能体在 default-agent.ts 中装配结构小到一眼看穿底盘tool-loop.ts判决、预算、硬停止、循环守卫、收尾通知、转录——文件头注释 说得直白换掉大脑纪律不变工具词汇表createGrammarTools 把每个手势做成独立工具——tap、double_tap、long_press、right_click、hover外加像素坐标系的tap_at等。作者特意不用一个工具 kind 参数因为实测有模型会给普通按钮乱填kind导致双击——工具必须被选择描述才能把边界说清基线规则BASE_RULES 教会模型核心世界观屏幕是带稳定 id 的节点树、每个动作结果已含变化所以动作后不必再 observe、绝不臆造 id、只有看到证据才判 passed。而这个底盘是可复用的设备端执行器、API 执行器都能调用createToolLoopExecutor换上自己的工具词表就免费继承整套循环纪律——这正是 executor.ts 定义的步骤执行器插座的意图换执行器只换思考方式预算、录制、判决语法一概不动。七、新手源码阅读路线图如果读完本文想亲自过一遍建议按这个顺序读约 1500 行核心代码tool-loop.ts — 主循环、prepareTurn、四类恢复路径全文重点loop-guards.ts — 228 行的纯函数守卫最适合入门primitives.ts —complete_step判决工具与语法工具集default-agent.ts — 内置智能体的最终装配executor.ts — 理解框架管预算、执行器管思考的信任模型。 一句话总结e2e 的 tool-loop 把让模型自由行动变成了让模型在有刹车、有护栏、有审计的轨道上行动——这大概就是智能体测试框架能进入生产 CI 的关键差别。【免费下载链接】e2eNext generation e2e testing framework for web and mobile apps.项目地址: https://gitcode.com/GitHub_Trending/e2e6/e2e创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考