多智能体协作的收敛:怎么防止互相等待 停住的任务与等待的三种成因两个智能体同时开工一个等另一个先产出接口定义另一个等前一个先确认字段。双方都在等双方都没有报错调度器看到的状态是运行中。时间过去很久唯一的异常是没有任何新输出。这类问题比崩溃更难发现。崩溃有堆栈等待只有沉默。多智能体系统里最常见的收敛障碍不是模型能力不够而是依赖关系没有被写成机器能检查的形式于是每个参与者都在按自己的理解等别人。要解决它先要承认一件事等待必须有上限而且这个上限要由系统强制不能靠提示词里写一句“尽快完成”。等待大致有三种成因值得逐一对照。隐式依赖排在最前。任务描述里写着“参考上游结果”但没有说明上游是谁、产出什么格式、什么时候算完成。参与者只能猜猜不到就停下来等一个不会到来的信号。共享状态争用也不少见。多个智能体要改同一份文件或同一张表谁先写谁后写没有约定。为了不覆盖别人的成果大家选择先读后等结果谁都不写。还有礼貌性等待。提示词里要求“确认对方完成后继续”模型就会真的去等一个明确确认而对方也在等确认。这类等待最隐蔽因为每个参与者都在遵守指令。把依赖写成图调度层面需要的是一张有向图节点是任务边是数据依赖每个节点声明输入来自哪个节点的哪个产出。图建好之后等待就变成了可检查的状态而不是参与者的主观感受。配套要有输入契约上游交付什么字段、什么格式、缺失时怎么办。契约不清下游即使拿到产出也无法开始仍然会退化成等待。图还要允许标记可选依赖。不是所有输入都必须等到标清楚哪些可以先用默认值推进能显著减少互相卡住的情况。依赖是否满足判断权要交给调度器而不是留给参与者自己看。参与者只负责声明自己需要什么调度器负责检查并放行。角色一旦混在一起每个智能体都会养成“先等等看”的习惯等待就变成了默认行为。用租约和超时打破僵局所有权要明确。同一份共享资源在任一时刻只有一个写入者写入者持有租约租约到期自动释放。这样“等别人写完”就变成了“等租约到期”而租约一定会到期。超时要分级。单步执行有超时依赖等待有超时整个任务有总超时。任何一级超时都产生一个明确事件而不是继续静默。死锁检测可以很简单一组任务互相等待超过阈值且没有任何一个在执行就判定为环按预设策略打破。通常让代价最小的那个先用默认输入推进并把这件事记进事件流。defschedule(tasks,now,wait_limit300):done{t.idfortintasksift.statusdone}fortintasks:ift.status!waiting:continuemissing[dfordint.depsifdnotindone]ifnotmissing:t.statusreadyelifnow-t.waiting_sincewait_limit:ift.optional_deps.issuperset(missing):t.statusready# 可选依赖缺失用默认值推进else:t.statusblockedt.reasonfdeps unmet:{missing}cycledetect_cycle([tfortintasksift.statusin(waiting,blocked)])ifcycle:break_cycle(cycle)returntasks收敛的判据要写死一个任务什么时候算结束要在启动前写清楚所有节点到达终态、没有节点处于等待、汇总产出已经落盘。三个条件缺一个就不算完成调度器不能因为“看起来差不多了”就收工。还要提醒一点等待本身不是进度。状态是运行中、心跳正常、日志还在刷这些都不能证明任务在向前走。真正能证明进展的只有新产出或者状态迁移两者都没有就应该按停滞处理。同时要区分完成和卡住。完成有产出卡住有原因。任何一个进入阻塞的节点都必须带原因字段否则事后无法判断是依赖缺失、资源争用还是单纯超时。最后是退出策略。允许部分完成但要说清楚缺哪部分、影响什么。比起一个假装成功的汇总一份标明缺口的报告更有用。