Agent 说完成,环境真的完成了吗
模型读取一次文件后,又提交了参数完全相同的读取请求。工具结果没有变化,模型仍然继续。
如果执行器只设置 maxTurns=20,这条任务会白跑十九轮后才被切断。另一个方向也有问题:模型输出一句“已经完成”,执行器立刻返回成功,目标文件可能根本不存在。
循环停止和任务成功,需要分别判断。
四个状态要分开记录
Section titled “四个状态要分开记录”Provider stop reason
Section titled “Provider stop reason”模型服务会返回 stop、length、tool use、error 或 aborted 等原因。它只说明这一轮生成为什么停下。相关类型见 packages/ai/src/types.ts。
stop 不代表目标文件存在,也不代表测试通过。
Loop 停止条件
Section titled “Loop 停止条件”Agent Loop 还要检查 assistant message 有没有工具调用、有没有排队的 steer 或 follow-up、外部是否取消、工具结果是否要求停止。Pi 的主循环见 agent-loop.ts。
Runtime terminal
Section titled “Runtime terminal”教学项目把一次 run 结束后的状态写成:
completedfailedblockedneeds_approvalbudget_exhausted它们互斥,调用方无需从最后一段自然语言猜任务状态。真实系统还应加入 cancelled 与 needs_input。
Verifier
Section titled “Verifier”Verifier 从环境检查目标条件,例如文件是否存在、内容是否包含标记、测试进程退出码是否为 0。模型可以建议运行哪项检查,不能编造退出码。
先拦住没有进展的循环
Section titled “先拦住没有进展的循环”my-pi-agent 会为每批 tool call 生成 fingerprint。下一轮再次提交相同工具名与参数,超过允许次数后直接停止,不再进入 handler。
cd agent-harness-labnpm run lab -- 07预期输出:
{ "terminal": "failed", "reason": "检测到重复工具批次,任务没有进展", "turns": 2, "toolCalls": 1}第二轮重复请求在执行前被识别,因此工具调用次数仍为 1。这个环境计数比“模型似乎放弃了”更可靠。
fingerprint 只能识别完全相同的动作。模型还可能在两个文件之间来回读取,或不断改变无关参数。执行器仍要保留最大 turn、最大工具调用、deadline、费用预算与用户取消通道。
最后检查完成条件
Section titled “最后检查完成条件”测试套件另有一个用例:模型直接回答“完成”,而 result.txt 中没有 VERIFIED。FileContainsVerifier 会把 terminal 改为 failed。
cd agent-harness-labnpm test在输出中可以找到:
模型的完成文本不能越过环境验证一次任务的顺序应当是:
模型不再请求工具 ↓Verifier 读取环境 ↓通过才写 completedVerifier 也不能随便选。若任务要求修复登录失败,只跑一个格式化检查没有意义。验收命令应随任务预先定义,Trace 则保存运行命令、退出状态与工件位置。
这样,重复动作、预算耗尽和验收失败都会得到明确状态。下一章处理更棘手的情况,工具可能已经产生副作用,进程却还没写下完成记录。