LAN worker 不是万能并行
远程执行看起来很简单:把任务丢给 LAN 上的 worker,让它跑完再回来。但实际操作中,我发现一个反复出现的卡点——默认所有任务都能并行,默认每个 worker 都能拿任何任务直接跑。
这个假设在一次实际协作中暴露了问题。那次我给 Agent 下了一串指令,让它同时处理几个远程任务。Agent 照做了,开始并行调用 LAN worker。但很快就有任务悄悄失败了——不是报错,而是静默超时。
租约不是形式主义
我停下来想,为什么超时?不是网络问题,不是计算量太大,而是这些任务根本不应该同时跑在同一个 worker 上。每个 worker 有自己的执行租约,租约的意思是:你拿到了这段时间的执行权,但也只限于这段时间和这个范围。
超出租约的任务,worker 不会拒绝你,但它会默默丢掉结果。这比直接报错更危险——因为你以为任务完成了,其实没有。
在 jianfei-plan 的 LAN policy 里,租约有几个核心参数:执行时间上限、资源配额、可操作范围。每个 worker 在注册时声明这些参数,调度器根据参数分配任务。但如果你绕过调度器直接调用 worker,租约参数不会被自动检查。你的任务可能在执行中途被 worker 的租约超时机制截断,但你看不到任何报错——因为超时机制是 worker 内部的静默行为。
这种静默失败是最难诊断的。你的日志里没有错误,你的状态表显示任务已完成,但实际上结果被丢弃了。排查这种问题往往要花几个小时,因为你会先检查网络、再检查数据、再检查逻辑,最后才想到可能是租约超时。而租约超时本身不需要几个小时来排查——如果你一开始就检查租约边界,五分钟就能定位问题。问题不是排查难,是你没想到要排查这个维度。
边界是效率的前提
很多人觉得,设置边界是在限制效率。其实反过来了。没有边界的并行,表面上看起来都在跑,实际上大量任务在做无用功。
那次之后,我养成了一个习惯:在给 Agent 下达远程执行指令前,先明确两个问题。第一,这个任务在哪个 worker 的租约范围内?第二,这个任务是否依赖前序任务的完成状态?
如果依赖前序结果,那就不该并行。如果超出租约范围,那就不该分配到那个 worker。这两个判断看起来很简单,但我在实际操作中经常遗漏,因为人总倾向于"越多越快越好"。并行越多,看起来进度越快。但并行越多,出错概率也越高。出错概率和并行数量不是线性关系——两个并行任务的冲突概率是一两种,四个并行任务的冲突概率是六种,八个并行任务的冲突概率是二十八种。
Agent 的角色不是替你记住这些边界,而是在你给出模糊指令时,主动提醒你:这个任务有依赖,不能并行;这个 worker 的租约还有五分钟,你的任务预计需要八分钟。可惜大多数 Agent 还做不到这一点。它们更擅长执行,而不是替你做边界校验。所以边界检查这件事,目前还是人来做更靠谱。
从卡点提炼方法
那次卡点让我学到了一个具体的工作方法:每次远程执行前,先做一遍租约和依赖的快速扫描。不是写文档,不是画流程图,就是在脑子里或者一张纸上,花三十秒确认三件事:
- 哪些任务之间有依赖关系?依赖关系意味着串行,不能并行。比如"先读取配置再修改参数"就是依赖关系——参数修改依赖配置读取的结果。
- 每个 worker 当前能承的任务量是多少?任务量不是"能跑多少个",而是"租约时间内能完成多少个"。一个 worker 租约十分钟,你的任务平均需要三分钟,那它最多能承三个任务。超过三个,最后几个可能超时。
- 有没有任务会超出某个 worker 的执行时间上限?时间上限是硬约束,不是软建议。超时不是"晚一点完成",而是"结果被丢弃"。
三十秒的扫描,省下来的可能是好几个小时的调试时间。因为并行失败的诊断成本远高于串行执行的等待成本。你花一小时排查为什么某个并行任务的结果不对,远不如一开始就让它排在正确的位置上。
这个方法后来我用 jianfei-plan 的 LAN policy 固化下来了。每次分配远程任务,policy 自动检查租约边界和依赖关系。不是所有东西都需要自动化,但这个卡点确实值得被程序化——因为它太容易犯,犯了又太容易忽略。
还有一个容易被忽略的细节:租约检查不应该只在任务分配时做,还应该在任务执行过程中持续做。一个任务在分配时通过了租约检查,但执行过程中可能因为其他任务的加入导致租约时间被压缩。比如一个 worker 的租约是十分钟,你分配了一个预计八分钟的任务,通过了检查。但分配之后又有两个短任务被塞进同一个 worker,你的八分钟任务现在要和两个短任务争抢资源,实际执行时间可能超过十分钟——超出租约了。持续检查不是每秒都查,而是在关键节点查:任务开始执行时、每个子步骤完成时、任务即将进入长时间计算前。这些节点的检查成本很低,但能防止大量静默失败。
说到底,LAN worker 不是万能并行,并行也不是效率的默认选项。效率的前提是边界清晰,而边界需要人先想清楚,再让 Agent 帮你守住。想清楚边界的那一刻,比并行执行的所有代码都重要。