在多 Agent 编程系统里,MiMo Code 通过把需求拆成子任务分发给不同角色的 Agent,来并行完成编码、审查与测试。高可用性并不只是多开几个进程,而是要让任意一个 Agent 失效时,整体开发流仍能继续推进且不丢进度。这就需要从任务模型、通信机制和容错策略三个层面做针对性设计。

任务拆解与调度隔离
高可用的第一步是让任务可被安全拆分。MiMo Code 中通常采用有向无环图来描述开发任务,每个节点是一个原子工作单元,例如生成某个模块的接口定义或编写单元测试。调度器根据节点依赖关系把任务派发给空闲 Agent,并给每个任务分配全局唯一的 task_id 与版本号。这样即使同一个功能被两个 Agent 同时认领,也能通过版本比对丢弃旧结果。
调度隔离要求每个 Agent 只拥有自己任务上下文的读写权限,不能越权修改其他人的中间产物。实践中可以用命名空间加锁实现,比如在共享存储里以 /task/{task_id}/owner 记录持有者。当持有者心跳超时,锁服务自动释放并触发重新派发。下面这段伪代码展示了任务认领的加锁逻辑:
import redis
r = redis.Redis(host='127.0.0.1', port=6379)
def claim_task(task_id, agent_id, ttl=30):
# 尝试以 NX 方式获取任务锁
ok = r.set(f'task:{task_id}:owner', agent_id, nx=True, ex=ttl)
if ok:
return True
current = r.get(f'task:{task_id}:owner')
if current == agent_id.encode():
r.expire(f'task:{task_id}:owner', ttl)
return True
return False
这种隔离方式把故障域控制在单个任务内。某个 Agent 崩溃只会影响它正在处理的节点,已经完成的下游节点因为结果已持久化而不会被污染。相比让所有 Agent 共享同一份可变状态,隔离调度显著降低了连锁失效的概率。
消息总线与状态一致性
多 Agent 之间不能直接调用彼此内存,必须依赖消息总线交换进度与产物。MiMo Code 常用的做法是使用支持持久化的日志型总线,例如基于 Kafka 或 NATS 流式存储。每个 Agent 把自己的产出作为事件追加到对应主题,其他 Agent 订阅后更新本地视图。由于事件只追加不修改,总线的重放能力成为高可用的关键。
状态一致性在这里不追求强一致,而是最终一致加幂等消费。Agent 可能因为网络抖动重复收到同一事件,所以消费者要把处理动作写成幂等操作,比如写入数据库前先按 event_id 查重。下面示例展示用幂等表防止重复执行构建:
INSERT INTO build_log (event_id, task_id, status)
VALUES ('evt_001', 't_100', 'done')
ON CONFLICT (event_id) DO NOTHING;
当总线某个节点宕机,生产者可暂存消息到本地队列,恢复后补发。消费者从最后提交的偏移量继续读取,不会漏掉协作信号。这种基于日志的通信让 MiMo Code 在部分组件不可用时仍能保持开发流的可追溯与可恢复,比远程过程调用更适应不稳定环境。
故障转移与快照回滚
真正的高可用还要解决 Agent 自身跑飞的问题。MiMo Code 应给每个 Agent 配备独立沙箱与定期快照。快照内容包含当前任务栈、已生成代码补丁和测试记录。一旦监控发现 Agent 连续心跳丢失或 CPU 占用异常,控制器杀掉旧实例,用最近快照拉起新实例并重新认领任务。
回滚策略要和版本控制结合。所有 Agent 写出的代码先进临时分支,只有经过审查 Agent 签名才合入主干。若新实例恢复后发现临时分支冲突,可直接丢弃并用快照里的补丁重放。以下代码演示基于快照重启时如何重置任务状态:
# 使用最近快照恢复 Agent 工作目录 cp -r /snapshots/agent_3_latest/* /work/agent_3/ cd /work/agent_3 git checkout -b recover_$(date +%s) python runner.py --resume --task_id=$TASK_ID
除了进程级转移,还要防范共享资源成为单点。比如中央调度器可以做成主备双活,通过选主协议切换。当主节点失效,备节点在秒级接管派发且不重复已派任务,因为任务锁和事件日志都在外部存储。把计算与状态分离,MiMo Code 的多 Agent 协作流就能在常规硬件故障下保持开发不中断,达到业务可接受的高可用水平。