首页 /文章 /多 AI 协作的调度机制

多 AI 协作的调度机制

多 AI 协作的调度机制:信箱与投递器分离、三段式收信接口、至少一次投递与幂等键。读完能落一套可用的最小实现。

多AI调度协作Agent
分类:应用开发 › Agent 与工具调用 发布于 2026-09-19 82 次浏览
面向需要自己实现多 AI 协作调度的工程场景。只讲机制与实现取舍,不含产品推广。
目标:读完能落一套可用的最小实现。

1. 问题定义

单 AI 方案有三个硬约束:

约束根因解法
上下文窗口有限长任务历史占满窗口切开任务,各持部分上下文
串行吞吐低N 个子任务串行执行并行
自校验失效同一模型验收自身产出,错误自洽交叉校验(A 产出、B 验收)

常见错误起点:把多 AI 协作理解成「两个模型互相对话」。

该模型隐含两个不成立的前提:

1. 双方同时在线 —— 执行方可能正在跑长任务,无法即时响应
2. 双方共享上下文 —— 上下文共享意味着故障传播,单点污染导致双方同时失效

正确的抽象是消息传递,不是对话。


2. 核心模型

把「消息传递」拆成两个独立设计的部分:


A. 存储与寻址     消息放哪、如何检索、如何不丢       → 目标是「稳」
B. 送达与消费     何时送、送给谁、送达确认、去重      → 目标是「柔」

2.1 为什么必须分开

耦合实现(如直接函数调用)会遇到三个死结:

• 重试无依据:送达逻辑需要重试,但存储无记录,无法判断是否已发
• 清理有风险:存储需要清理,但送达未确认,可能删除未投递的消息
• 策略不可换:需要调整投递策略(批量、延迟)时,存储与投递已写死

2.2 分离后的职责

• 存储侧:只负责消息可靠落盘,对外表现为一个「信箱」
• 送达侧:只负责把新消息送到接收端(AI 会话),对外表现为一个「投递器」
信箱决定「消息在哪」,投递器决定「消息何时被看见」。

3. 调度实现

按自下而上的顺序。

3.1 通信层:pull 还是 push

实现选择:传输层用 pull,体验层模拟 push。

方案服务端状态断线恢复排查难度
长连接 push需维护在线表、连接池需重连逻辑高
**pull(轮询)****无状态****下一轮自动恢复****低(可 curl、可抓包)**

选择 pull 的理由:

• 服务端不需要知道「谁在线」,退化为纯信箱
• 客户端重启/断线无需重连逻辑,下一轮自然恢复
• 全程 HTTP,可 curl、可抓包、可压测

延迟处理:轮询间隔设为秒级,接收端即可视为准实时。用户侧无感知。

注意:轮询间隔由接收端自行配置,因此不同会话可采用不同投递策略(例如:执行中的会话拉长间隔,空闲会话缩短间隔)。

3.2 存储层:文件还是数据库

实现选择:小规模用文件(Maildir 式),规模上升后换数据库,接口保持不变。


/data/<agent>/inbox/<message-id>.json

一条消息一个 JSON 文件。该目录同时充当队列、数据库、审计日志。

文件方案优点文件方案缺点
零依赖(无需数据库服务)无事务、无索引
可直接 grep / cat / 手工修改万级条目后 `listdir` 性能下降
备份 = 拷贝目录并发写需自行加锁
故障可人工介入(翻原始文件)——

关键设计 1:消息 ID 全局唯一且时间有序


<YYYYMMDD-HHMMSS>-<from>-<to>-<毫秒末4位>
• 时间有序 → 排序直接按字符串比较,无需额外字段
• 可读 → 文件名即含来源与时间
• 冲突概率极低 → 无需中央发号器

关键设计 2:并发控制

• 一把全局锁,仅保护「写文件 / 改状态」这一个动作
• 结构上已天然隔离:一 AI 一目录、一信一文件(每个 AI 会话一个信箱)
• 锁仅用于防御「同目录同瞬间写」的边界情况
• 不需要数据库事务

迁移阈值:消息量到万级,或需要复杂查询时,换 SQLite/Postgres。上层接口不变。

3.3 收信:三段式接口

不要把「拉列表」和「读正文」合并为单一接口。


① 探测      GET /inbox?user=X&unread=1   (user = AI 会话标识,下同)
            → 仅返回元信息:id / from / subject / ts / 正文字数

② 取正文    GET /message?user=X&id=...
            → 确认需要处理时才拉取完整 body

③ 确认消费  POST /ack {user, ids:[...]}
            → 置为已读

设计收益:

• 高频轮询场景下,几十条消息仅传输数百字节(元信息与正文体积可能相差 3 个数量级)
• 「查看」与「消费」是两个语义不同的动作,不应绑定

3.4 送达层:会话注入

这是接收端真正「收到」消息的环节,也是故障密度最高的环节。


① 轮询发现未读
② 探测目标会话忙闲          ← 关键
③ 注入消息摘要到目标会话
④ 注入成功后才 ack

四个要点:

① 忙闲探测

• 注入前检查目标会话状态(如 hasActiveRun)
• 目标忙 → 保留至下一轮,不强制注入
• 原因:向运行中的会话注入消息会中断当前任务并污染上下文
• 该机制决定系统是「有效通知」还是「噪音源」

② ack 时序


正确:注入成功 → ack
错误:ack → 注入

先 ack 后注入时,若注入失败,消息将被永久丢弃(已置已读,不再被拉取)。

该错误隐蔽性强:正常路径下不报错,仅在故障路径暴露。

③ 幂等键

• 轮询 + 重试必然导致重复投递
• 注入必须携带 idempotencyKey(幂等键:同一 ID 只执行一次,重复投递直接跳过;如 <source>-<message-id>)
• 否则重试/重放会导致接收端重复处理同一消息
• 对「执行某任务」类消息,重复处理代价不可接受

④ 长时间未读处理

• 未读超过阈值(如 10 分钟)→ 仅记录状态,不强插
• 不以「送达」为名打断正在执行的任务

3.5 投递语义:at-least-once vs exactly-once

语义实现代价
**at-least-once**落盘 + ack + 幂等键存在重复(由幂等键消解)
exactly-once需消费位点 / 去重表复杂度显著上升

选择 at-least-once。

• exactly-once 需要额外状态存储与分布式协调
• 在幂等键正确实现的前提下,at-least-once 效果等价
• 前提:幂等键的去重逻辑必须真正落地,而非仅传递参数

4. 两种调度模式

上述讨论的是「消息如何传递」。而「任务如何派发」有两种模式。

模式 A:消息总线(异步 / 解耦)


调度方 → 发消息 → 信箱 →(投递器)→ 执行方 → 执行 → 回消息 → 信箱 → 调度方
特性说明
在线要求双方无需同时在线
适用任务长任务(小时级)
适用范围跨会话、跨进程、跨机器
延迟存在(受轮询间隔影响)
结果获取异步,需等待回信

模式 B:直接调用(同步 / 即时取结果)


调度方 → 启动子会话 → 执行方执行 → 返回结果 → 调度方继续
特性说明
结果获取即时
适用任务短任务、边界明确的任务
并行能力强(可一次启动 N 个)
代价调度方需等待或挂起;子会话默认隔离,不掌握全局上下文

选型

场景选择
任务分钟级、结果需即时消费B
任务小时级A
跨机器 / 跨信任域A
需并行多个子任务B
需留痕、支持人工介入A

工程实践中通常混用。


5. 实现清单与陷阱

5.1 最小可用清单


1. 存储    文件信箱:一 AI 一目录、一信一文件、ID 含时间戳
2. 接口    三段式:探测 / 取正文 / 确认消费
3. 投递    轮询(间隔可配)+ 忙闲探测 + 注入成功才 ack
4. 幂等    注入携带 idempotencyKey
5. 加固    ID 防目录穿越(拒绝 "/" 与 "..")+ 字段长度上限
6. 扩展    规模上升后换 SQLite(接口不变)
7. 跨信任域  加签名 / 令牌 + 防重放

实现 1-5 即可得到一台可用的最小调度件。

5.2 陷阱清单

① 信箱与投递器必须分离

服务只负责存取,「何时送达」由投递端决定。

• 收益:服务极简;各接收端可独立配置投递策略
• 代价:投递端需自行实现——中心无法主动推送,因为中心不掌握各接收端的会话入口

② ack 必须晚于注入

顺序写反会导致消息永久丢失。该错误正常路径不暴露。

③ 必须先探忙闲

直接向运行中的会话注入会中断任务并污染上下文。

④ 幂等键不可省

轮询与重试天然产生重复。缺失幂等键会导致重复处理。

⑤ 文件即事实来源,且需支持人工介入

全程落盘、纯文本:任一环节故障均可人工查看、补齐、删除。

相较黑盒队列,排查成本显著更低。备份即拷贝目录。

⑥ 信任模型应与场景匹配

• 内部小规模:身份可直接用参数传递
• 跨信任域(消息要进入别人控制的系统):必须签名/令牌 + 防重放
• 不要将「内部够用」的设计直接暴露到公网

⑦ 元信息与正文分离

列表仅返回摘要,正文按需拉取。高频轮询下可显著降低流量。

⑧ 不要为接收端实现常驻工具接口

工具 schema 每轮都进入 prompt,持续占用上下文。

采用「脚本 + 拉取」模式,常驻开销为零。


6. 取舍汇总

维度选择理由
通信pull服务端无状态、断线自愈、可观测
存储文件(小规模)零依赖、可审计、可人工介入
语义at-least-once + 幂等复杂度可控,效果等价
同步性按任务长度短任务同步,长任务异步
信任按场景内网宽松,公网严格
消息体元信息/正文分离降低流量

本方案的边界

1. 不保证 exactly-once(需引入消费位点)
2. 无法实现完全无人值守(验收环节仍需人工介入,见 §7)
3. 不能替代任务方案设计——消息传递正常,方案不清晰仍然导致偏离

7. 验收:最难的部分

多 AI 协作的真正难点不是消息传递,而是判定「任务已完成」。

消息传递是工程问题;验收是定义问题。

验收的三个前提:

1. 任务开始时即存在可验证标准(而非「看起来正确」)
2. 标准可被机器检查(格式校验、测试通过、数据比对)
3. 不可机器验证的部分,必须明确由谁验证

典型陷阱:将「流程结束」等同于「结果正确」

• HTTP 200 ≠ 结果有效
• 任务状态 completed ≠ 目标达成

该混淆会使自动化系统「自信地产生错误」。

结论:

无人值守的前提不是模型能力,而是任务定义足够清晰、验收标准足够客观。
消息调度解决「能否连通」,验收机制解决「连通后是否正确」。

8. 参考实现特征

组件实现
服务单文件、标准库 HTTP 服务,零外部依赖
存储`//inbox/.json`,一信一文件
接口`/send` `/inbox` `/message` `/ack` `/health`
身份请求参数传递(内部信任模型);预留 token 校验路径
并发全局锁保护写操作;目录级天然隔离
投递各接收端自带 watcher,轮询 + 忙闲探测 + 注入后 ack
备份拷贝数据目录

该结构在千级消息量下运行稳定;量级上升时替换存储层即可,接口不变。

关键词 多AI调度协作Agent 000001