为什么我们放弃了中心化调度器:Nexus 协议的设计选择
一段从 Kubernetes 启发到完全反叛的工程旅程
林思羽
亚诺尔科技 · 协议组负责人
团队里大家都有 Kubernetes 的背景,所以 Nexus 早期版本理所当然地有一个 controller-manager 风格的中心调度器。简单、清晰,遵循"中心做决定,边缘做执行"的经典分层。但我们很快发现,这个模式在 AI Agents 协同的场景里水土不服。
问题不在性能,在语义
一开始我们以为问题会是性能:千 Agent 规模下中心节点会成为瓶颈。但实测发现,性能完全可以靠分片解决。真正卡住我们的是语义。
考虑这个场景:一个边缘安防 Agent 检测到异常,需要附近 5 个 Agent 协同响应——3 个负责验证、1 个负责通知、1 个负责现场处置。如果决策走中心调度器:
- Agent A 上报异常 → 走网络到中心
- 中心查询拓扑、能力、当前负载 → 选出 5 个 Agent
- 指令下发回边缘
- 5 个 Agent 收到指令开始执行
这个回路在网络好的时候是 80–200ms,听起来可以接受。但在边缘场景下,AI Agents 看到的世界是亚秒级变化的——回路走完时,最初触发的"异常"可能已经发生过两次了。
真正的问题:状态在哪里?
更深层的问题是:中心调度器要做出好的决策,它必须了解全网的拓扑、能力分布和实时状态。但这个状态最准确的位置永远在边缘——而不在中心。中心永远在追实时状态,永远落后。
“当中心化决策依赖的状态本质上属于边缘时,中心化就成了一种谎言——它假装拥有它实际上没有的信息。”
— Nexus 设计文档 · 2024
Nexus 的选择:邻域协商 + 全局收敛
我们最终的协议有两层。每个 Agent 维护一个动态邻域——它直接通信的邻居集合(典型 30–80 个节点)。绝大多数决策在邻域内部协商即可完成,延迟低、状态新鲜、不依赖任何中心。
只有当一个决策的影响超出邻域范围(比如跨集群任务编排),协议才会启动一次全局协商。全局协商不是中心做决定——它是一次"请所有邻域的代表节点投票"的过程,依然没有中心。
关键不变量
- 局部决策:30ms 内闭环
- 全局协商:280ms 内收敛(1000+ Agent 规模)
- 断网时:邻域内仍可独立工作
- 没有任何节点是必须的——任何一个挂掉都不会让系统停转
代价是什么?
坦诚一点:去中心化协议比中心调度器难写。我们花了 14 个月才把第一版协议跑稳。
调试也更难——你不能像看 K8s controller 日志一样看到"调度器为什么这样决定"。我们后来不得不构建全链路决策回放系统,这本身又是一个独立的大工程(参见上一篇 Nexus 2.0 发布文)。
但我们认为这个代价值得。因为在 AI Agents 协同的世界里,状态的真实位置就在边缘——任何中心化的设计都是在和这个事实做斗争。
▸工程教训:选择架构时,问"状态本质上属于哪里",比问"这样写更简单吗"更重要。前者决定了系统的天花板,后者只影响早期开发速度。
下一篇我们会讲讲 Nexus 状态层为什么放弃了原生 CRDT 而做了魔改——这是另一段类似的旅程。