为什么需要回程闲置保护?
对象:opencode-goal 插件的子代理静默死亡巡检(
sweep_idle_children+prompt_sent_at登记)。本文讲清它为什么存在、为什么只能是现在的形状------每一个"只能",背后都是一次真机事故。
0. 导语:两种死法,一种看不见
2026-09-06 下午,il2cpp R* 主代理下十几个子代理同时遭遇 provider 熔断(APIError: temporarily unavailable,17:06--17:11 波及十几个会话)。熔断过去后,问题来了:有些子再也没说话。父等回程,等到天荒地老。
子代理有两种"消失":
- 异常死:模型报错、会话终结------有错误事件,可走异常上报(首错即报、同签名去重),父立刻知道;
- 静默死 / 完工不报 :无错误事件,转 idle,不回程------父没有任何信号,只能干等。
第二种是本巡检存在的全部理由:派发后子代理既无回程又无响应,只能判定挂了。没有这个巡检,静默死的子= permanently lost,父的调度闭环永远等不到它的那一块。
1. 第一次实现错在哪:对所有空闲子挨个发消息
第一版巡检的逻辑是朴素的:转空闲超窗(idle_nag_ms,默认 120000)且无 relay 回程 → 通知父。结果真机炸了:同一子"空闲未回程"x10、"已挂"x13,每 2 分钟一轮,几十条通知淹没父会话。根因两条,都是"把不该盯的也盯了":
- 从未派发的裸空闲子也被盯:重启遗留、已完成、abort 过的子,全在 children 列表里,全被当成"未回程";
- busy 观察重置计时:复活消息会让死孩子短暂 busy,旧代码 busy 即清零重计时------"复活→忙→再闲→再报"无限循环。
教训:提示的权力必须有边界。知道≠打扰,能看见≠该说话。
2. 现在的形状:成对 1:1,有派才有盯
重写后的巡检(src/server.ts,sweep_idle_children)核心只有三行门禁:
ts
const sent_at = prompt_sent_at.get(kid);
if (sent_at === undefined) continue; // 从未派发:零打扰
if (now - sent_at < nag_ms) continue; // 窗内:等
if (idle_nag_state.get(kid)?.revived) continue; // 本集已复活过:额度用完
- 登记点只有一处 :
manage_subagent prompt派发成功时prompt_sent_at.set。没派发就没记录,没记录就永不打扰------重启/kill 后内存清空,旧子自动退出视线; - 清除点三处:relay 回程(成对完成)、abort 人工接管、新一集重派(重置);
- busy 只跳过不重置:工作中(含消化复活激活)不打扰,也不重计时。
3. 动作:复活一次,上报一次,用完即停
超窗未回程只做两件事,每派发集各一次:
- 向子发存活检查与唤醒(要求它经 relay 回程报告状态);
- 向父发"已挂":
该子代理派发后超窗零回程零响应(1:1 未应答=挂了)+ 复活结果 + 处置(重派或 task 新建承接)。
之后无论子回不回程,插件不再重复打扰------额度用完。父要救,自己重派(重派=新一集,新额度)。复活投递失败(会话已终结)直接提示父新建承接,不空等。
4. 真机证据:两边都验证过
- 反面(旧逻辑):同一子"空闲未回程"x6--11、"已挂"x3--13,时间戳每 ~2 分钟一轮,父会话通知刷屏------这就是改写的直接动因;
- 正面 (新逻辑):provider 熔断波下,日志连发
dead child rescue ... revived: true,父会话收到 181 次异常上报/已挂通知------每子一次,不多不少;重启后旧子零打扰,洪水消失; - 边界 :
send_prompt超时有界(10 秒),失败返回 false,不冻结 TICK;巡检整体 try/catch,失败静默,绝不阻断主循环。
5. 如何验证
scripts/goal-idle-nag-test.mjs(10/0),每条都是一个行为契约:
- F1 裸空闲超窗零通知;F2 派发超窗判挂上报 1 次+复活 1 次;F3 无新证据不重复;
- F4 忙→闲不新开集;F5 回程后零打扰;F6 重派=新额度可再判挂;F7 abort 后零打扰。
线上:搜 dead child rescue 看复活记录;数父会话"已挂"通知(应每子每集一次,多一次即回归)。
6. 一句话总结
回程闲置保护不是"盯着所有空闲子",而是"只盯自己派出去没回来的":有派必有应,超窗唤醒一次、上报一次,额度用完即停。知道的权力,配上不打扰的义务。