生产扩展——队列、检查点、持久性 本节摘要:把多智能体系统扩到数千并发运行需要持久执行(durable execution)——工作队列加检查点,使任何工作器在任何崩溃后都能恢复任何运行,前提是租约(lease)处理、幂等副作用、确定性回放就位。LangGraph 的运行时是参考范例:它在每个超步(super-step)后写一个以 为键的检查点(默认 Postgres);工作器崩溃则释放租约,另一工作器恢复。Agent 可无限期睡眠等待人类输入。MegaAgent(arXiv:2408.09955)跑每 Agent 的生产者-消费者队列,含三态(空闲/处理/响应)与两层协调(组内聊天 + 组间管理聊天)。
本节摘要:把多智能体系统扩到数千并发运行需要持久执行(durable execution)——工作队列加检查点,使任何工作器在任何崩溃后都能恢复任何运行,前提是租约(lease)处理、幂等副作用、确定性回放就位。LangGraph 的运行时是参考范例:它在每个超步(super-step)后写一个以
thread_id为键的检查点(默认 Postgres);工作器崩溃则释放租约,另一工作器恢复。Agent 可无限期睡眠等待人类输入。MegaAgent(arXiv:2408.09955)跑每 Agent 的生产者-消费者队列,含三态(空闲/处理/响应)与两层协调(组内聊天 + 组间管理聊天)。Fiber/异步胜过每任务一线程做 LLM 流式:线程 99% 时间在等 token 时空转,fiber 在 I/O 上协作让出。反方观点:Ashpreet Bedi 的「扩展 Agent 软件」主张FastAPI + Postgres、别的不要,直到负载证明否则——简单架构比预期走得更远。本节搭一个持久检查点日志、一个每 Agent 工作队列带状态转移、一个异步 vs 线程 demo,并落实「先简单」的务实规则。
阅读完本节,你应当能够:
一个原型多智能体系统在一台笔记本上、三个 Agent、一个内存事件循环里跑得好好的。你上生产:
内存事件循环这些都不做。你需要在底层加一个持久执行层。 2026 的标准选项是:带检查点的工作流引擎(Temporal、LangGraph 运行时);带状态库的消息队列(Postgres + SQS/RabbitMQ);Actor 模型框架(MegaAgent 的每 Agent 生产者-消费者);手搓 FastAPI + Postgres(Bedi 的主张)。本节各搭一个微缩版。
一个持久执行引擎在每个「步」(LangGraph 的超步)后持久化全程序状态。崩溃时:
工作器在步中途崩溃 -> 租约超时 -> 另一工作器接起 thread_id -> 从最近检查点恢复 -> 无重复副作用
要它工作需要:状态可序列化(带活数据库连接的函数闭包活不下来);确定性恢复(给定相同状态与输入,Agent 产出相同动作,或对 LLM 调用 defer 到外部确定性预言机);副作用幂等(外部调用如工具、付款,必须幂等或用去重键)。
LangGraph 每个超步后写检查点,Temporal 每个活动后写,Restate 用事件溯源日志。三者实现同一模式。
LangGraph 的运行时是范例:每个 Agent 有一个 thread_id,状态是类型化字典,每个超步写一行到检查点表。恢复时从最近检查点回放,不从头来。Agent 可 interrupt() 等人类输入,运行时持久化并释放工作器;输入到达时,任何工作器都能恢复。
这是 2026 年 4 月的参考生产设计。
arXiv:2408.09955 描述了一个规模实验:单集群数千并发 Agent。架构:
agent i: state ∈ {Idle, Processing, Response} in_queue <- 发给 agent i 的消息 out_queue -> 回复 + 副作用 coordinators: 组内聊天 (同组 Agent 间) 组间管理聊天 (高层路由)
两层协调让组内对话密集发生、组间保持稀疏——这是在数千 Agent 上保持成本线性的模式。
LLM 调用是 I/O 密集的。一个等下一个 token 的线程 99% 时间空转。线程每个约 1MB 内存;1 万并发调用就是 10GB 仅栈。
Fiber(Python asyncio、Go goroutine、Rust tokio)在 I/O 上协作让出。同样 1 万调用轻松装进一个进程。在 LLM-Agent 规模下,异步不是优化,而是架构。
例外:CPU 密集的后处理(嵌入、tokenizer 技巧)仍要线程或进程。把 I/O 层与 CPU 层分开。
「扩展 Agent 软件」(Ashpreet Bedi, 2026)主张多数团队在测量负载前就过度工程。务实默认:FastAPI + Postgres;每个 Agent 运行是一行,状态带乐观并发就地更新;后台作业经 pg_notify 或简单 Celery worker;重试策略在应用代码里。对可管理任务、约 100 并发 Agent 运行以内,这常常就是你需要的。 测出它失败时再升级。
规则:当你撞上一个简单架构解决不了的具体问题时,才采用持久执行框架。过早采用把时间烧在不回报的仪式上。
⚠️ 这是「协调难点在状态」的生产版本——多智能体系统的全部状态(消息、计划、检查点)都在持久层里,这一层任何崩溃都让协调成果化为乌有。「先简单」不是偷懒,而是避免在没测量到痛点前就背上一套你不需要的持久执行引擎。
对付费的 Agent 运行,你要「有效一次」(至少一次交付 + 幂等消费)。工程动作:
这些是数据库工程模式,非 LLM 专属。LLM 的税只是调用慢;其余都是标准分布式系统。
Anthropic 的多智能体研究系统用「彩虹部署」:多个版本的 Agent 运行时并发跑,这样长程 Agent 不必在每次代码部署时被杀。金丝雀新版切一部分流量;旧版等其 Agent 跑完再退役。这对长程有状态系统是标准的;2026 的适配是 Agent 可活数小时,部署周期必须适应。
可序列化的持久状态(检查点、快照、或发件箱 + 可回放日志);幂等副作用;LLM 调用的异步 I/O 层;至少一次交付 + 去重;有状态工作负载的彩虹/金丝雀部署;可观测性(逐 Agent 轨迹、超步审计、重试计数)。
code/main.py 实现:
CheckpointStore——SQLite 支撑、以 thread_id 为键的检查点日志,每个超步追加一行。run_with_checkpoint(agent, thread_id)——模拟运行中途崩溃,第二个工作器从最近检查点恢复。AgentQueue——每 Agent 的 空闲/处理/响应 状态机,带小型工作队列。demo_async_vs_threads()——用 asyncio 和线程各跑 500 个并发模拟「LLM 调用」,报告墙钟与峰值内存(近似)。def run_with_checkpoint(agent, thread_id, store): state = store.load_latest(thread_id) or initial_state() while not state.done: checkpoint = store.save(thread_id, state) # 每超步先存 try: state = agent.step(state) # 可能在此崩溃 outbox.enqueue(state.pending_side_effects, dedup=thread_id) except Crash: state = store.load(checkpoint) # 从检查点恢复,副作用靠 dedup 去重 continue return state
设计要点:
store.save在agent.step之前写,是崩溃可恢复的承重顺序——先持久化意图、再执行,这样即使执行中途崩溃,恢复后靠dedup键保证副作用「有效一次」。把顺序反过来(先执行后存),崩溃就可能在恢复后重放副作用,造成重复计费/重复发送。发件箱模式把「想做」与「去做」物理分离,是这条顺序纪律的工程落地。
运行 python3 code/main.py,期望输出:模拟崩溃后检查点恢复成功;异步版在 < 1 秒内处理 500 并发调用;线程版耗时数秒,且每并发单元内存高一到两个数量级。
| 方案 | 承重机制 | 适用规模 | 何时采用 |
|---|---|---|---|
| FastAPI + Postgres(Bedi) | 行级状态 + 乐观并发 | ~100 并发运行 | 默认,先上 |
| LangGraph 运行时 | 每超步检查点 + thread_id | 中~大 | 长程、人在环、复杂重试 |
| Temporal | 每活动检查点 + 工作流引擎 | 大、跨区 | 跨区协调、复杂补偿 |
| MegaAgent 每 Agent 队列 | 三态机 + 两层协调 | 数千 Agent | 超大规模、成本线性 |
💡 心法:先简单,测出失败再升级。 Bedi 的 FastAPI + Postgres 在 100 并发内常常够;LangGraph/Temporal 的检查点机制在你撞到「小时级人在环等待」或「跨区协调」时才值回票价。颠倒顺序——一上来就上 Temporal——是本节最常见、最昂贵的过度工程。
outputs/skill-scaling-advisor.md:为持久执行选型——FastAPI + Postgres、LangGraph 运行时、Temporal、还是自研。按负载、状态保留需求、部署频率校准。
code/main.py,确认检查点恢复工作;测异步 vs 线程的并发差异。thread_id 每超步写一行,崩溃靠租约超时 + 另一工作器恢复。下一节,我们直面本章最沉重的话题——失败模式:MAST 分类、群体思维、单一文化、级联错误,看多智能体系统为何崩、以及如何在崩之前堵住。