第 6 章 任务处理方法论:从短任务、长任务到 Agent 协作
本章讨论的不是某个具体中间件,也不是某个特定框架的使用说明,而是一套跨传统后端系统、数据系统与 Agent 系统都成立的任务处理方法论。读完这一章,你应该能判断:一个任务到底该做成同步请求、异步消费、批处理、阶段化 Workflow、单 Agent、Stateful Agent Runtime,还是 Multi-Agent 协作系统。
很多工程问题表面上长得完全不同。
- 供应商酒店数据同步,要跑十个小时,中途还会遇到接口限流和分页游标失效。
- Spark 离线任务每天凌晨跑数仓加工,失败后要从某个 Stage 恢复,而不是全部重刷。
- Flink 实时作业一直在跑,单条事件处理很快,但整个作业要长期维护状态、Checkpoint 和 Exactly-once 语义。
- 代码 Agent 需要理解需求、扫描代码、修改多个文件、跑测试、等待人工确认,再继续下一轮执行。
- 多 Agent 调研系统要让 Planner 拆任务、Worker 并行查资料、Reviewer 审核结论,最后再统一收敛。
如果只从技术栈看,这些系统横跨电商中台、大数据平台、流计算、机器学习和 AI Agent;如果只从执行方式看,它们却都属于同一类问题:任务无法在一次请求内闭环完成,必须跨时间、跨步骤、跨系统甚至跨角色持续推进。
这正是“任务处理方法论”要回答的问题。
很多团队在系统早期都能把东西做出来,但一旦任务变长、链路变深、依赖变多,问题就开始集中爆发:
- 原本同步函数能跑通的逻辑,放大后开始超时、阻塞、重试风暴。
- 原本塞进一个 MQ Consumer 的任务,后来长成“大 Consumer 泥球”,没人敢动。
- 原本只靠对话上下文驱动的 Agent,任务稍微复杂就忘记做到哪一步、哪些动作已经执行过、哪些结果需要人工确认。
- 原本只想“加一个自动化”,最后却变成没有状态边界、没有审计、没有回退路径的危险系统。
所以这一章不会从“工具怎么用”开始,而是从一个更根本的问题开始:任务应该如何被拆分、推进、治理和演进。
6.1 背景、目标与范围
6.1.1 为什么现在要建立任务处理方法论
系统设计讨论里,大家很容易把注意力放在“架构图长什么样”“数据库怎么拆”“缓存怎么配”“QPS 有多高”。这些当然重要,但在很多真实系统中,决定复杂度的往往不是单点组件,而是任务本身的执行形态。
一个任务如果可以在单次请求里完成,工程重点通常是性能、正确性和接口契约;一个任务如果要持续十分钟、十小时甚至长期运行,工程重点立刻变成:
- 怎么知道现在做到哪里了
- 中间失败后从哪里恢复
- 哪些步骤允许重试,哪些步骤不能重复执行
- 哪些依赖失败可以降级,哪些失败必须阻断
- 哪些结果必须经过审查、审批或人工确认
- 当任务复杂到单个执行者已经扛不住时,是否需要拆成多个协作角色
传统后端系统早就被这些问题教育过,所以有了同步请求、异步任务、批处理、状态机、Workflow、补偿、对账、审批、回滚这些工程实践。现在 Agent 系统之所以越来越像“长任务系统”,不是因为它们变得传统了,而是因为只要任务一旦跨边界推进,就一定会重新遇到同样的状态、恢复与治理问题。
这就是现在必须做这件事的原因:我们不需要再把“传统系统”和“Agent 系统”当成两套割裂的方法论,而应该用一套统一框架理解它们。
6.1.2 本章目标
本章希望帮助读者建立三层能力。
第一层能力,是判断能力。你需要能快速判断一个问题到底更像短任务还是长任务,它的复杂度主要来自执行跨度、认知复杂度,还是协作复杂度。
第二层能力,是选型能力。面对同步任务、异步任务、Batch、Workflow、单 Agent、Stateful Agent Runtime、Multi-Agent 这些方案,能够知道它们分别适合什么场景、代价是什么、升级路径是什么。
第三层能力,是治理意识。也就是理解:真正让任务系统进入生产可用状态的,不是“能跑起来”,而是“能恢复、能审计、能降级、能回退、能演进”。
6.1.3 成功标准
如果这一章写得足够好,读者至少应该能回答以下问题:
- 短任务和长任务到底怎么区分,为什么不能只按耗时判断。
- 同步请求、异步任务、Batch、Workflow、Agent Runtime 和 Multi-Agent 分别是什么。
- 当前真实工程里有哪些典型长任务场景,它们为什么天然是长任务。
- 为什么很多 Agent 系统走着走着,会重新走到状态机、Checkpoint、审批和治理层上来。
- 当一个系统从简单走向复杂时,应该如何渐进演进,而不是一开始就过度设计。
6.1.4 本章明确不做什么
本章不尝试替代每一个具体领域的完整实现指南,例如:
- 不展开讲 Spark 的算子执行机制和 Shuffle 内部细节。
- 不展开讲 Flink 的状态后端、Barrier 对齐和 Watermark 算法实现。
- 不展开讲某个特定 Agent 框架的 API 用法。
- 不给出某个具体业务系统的全部表结构和部署脚本。
本章要做的,是在这些具体技术之上,抽象出一套更稳定的任务处理方法论。
6.2 现状、问题定义与典型长任务场景
6.2.1 当前系统通常怎么处理任务
大多数系统的任务处理方式,都经历过一个相似演进:
- 最开始是同步函数或同步接口,逻辑简单、调用直接、状态靠内存和调用栈保存。
- 接着为了削峰和解耦,开始把任务扔到 MQ 或后台 Worker。
- 任务再复杂一点,就出现批处理、定时 Job、分片执行、重试队列和补偿任务。
- 当任务带有明显阶段边界、审批节点和发布风险时,团队会走向显式 Workflow。
- 当任务不再只是“执行规则”,而是要理解目标、动态规划步骤、根据中间结果调整策略时,Agent Runtime 开始出现。
- 当规划、执行、审查三类职责冲突加剧,才会进一步考虑 Multi-Agent 协作。
问题在于,很多团队虽然现实中已经走到了第 3、第 4 甚至第 5 步,但脑子里仍然停留在第 1 步:用短任务思维去理解长任务问题。
6.2.2 典型错误:用短任务思维处理长任务
短任务思维的核心默认前提是:
- 请求会很快结束
- 执行现场不会丢
- 出错后整体重试就行
- 状态不需要被别人接手
- 成功或失败很容易定义
这些前提一旦放到长任务里,几乎全部失效。
典型的错误做法包括:
把复杂长任务塞进一个同步接口
最初看起来实现很快:前端发请求,后端一口气做完抓取、转换、写库、发消息和索引更新。但只要数据量一大、依赖一抖、步骤一多,就会变成超时、线程阻塞、调用链炸裂、失败后无法恢复的系统。
把复杂流程直接塞进一个 MQ Consumer
这类系统刚开始往往运行正常,因为“反正异步了”。但异步只是把主链路压力移走,并没有解决状态治理。随着条件分支增加,Consumer 会长成一个没人敢改的大泥球:
- 一个消息里同时处理抓取、校验、发布、通知
- 出错时不知道该重试消息还是人工补数据
- 顺序、幂等、状态边界全靠注释和经验维护
把 Agent 的对话历史当成正式状态系统
这是当前很多 Agent 系统最容易犯的错误。对话上下文当然能保存一部分信息,但它并不等于状态机,也不等于 Checkpoint,更不等于审计日志。只要任务跨会话、跨时间、跨角色,单靠上下文窗口就会立刻暴露问题:
- 模型忘记之前做过什么
- 中断后不能安全恢复
- 某个工具调用到底有没有落地副作用说不清
- 某个结果到底有没有经过 reviewer 审核说不清
6.2.3 如果不改,会发生什么
如果继续用错误的任务处理形态去承接更高复杂度的问题,后果通常不是“偶尔不优雅”,而是系统性失控:
- 故障恢复时间持续拉长,因为没有恢复点,只能整批重跑。
- 线上风险上升,因为危险副作用没有被阶段边界和审查机制隔离。
- 团队维护成本上升,因为真正的任务状态散落在日志、数据库、队列和开发者脑子里。
- Agent 系统幻觉和误动作放大,因为缺少显式 reviewer、policy 和人工接管点。
也就是说,问题并不是“有没有任务处理方法论都能做”,而是“没有方法论时,系统复杂度会以最坏的方式自己长出来”。
6.2.4 典型长任务场景
下面这些场景,今天在工程实践中都天然属于长任务。
场景一:供应商数据同步与主数据接入
例如酒店、机票、商品、库存、价格等供应商供给同步,或者 ERP / WMS / OMS / PIM 数据接入。
这类任务通常具备这些特征:
- 数据量大,需要分页、分片或游标推进
- 外部系统慢且不稳定
- 中途失败后不能从头重跑
- 结果会影响正式业务数据,必须有治理和发布保护
这正是 Batch + Checkpoint + Workflow 最典型的场景。
场景二:机器学习模型训练与模型交付
模型训练不是一次普通函数调用,而是一条很长的流水线:
- 数据准备
- 特征工程
- 训练
- 评估
- 产物导出
- 模型注册
- 灰度发布
它天然需要:
- 记录实验参数和版本
- 保存中间产物
- 按阶段恢复
- 做上线前评估和审查
所以它本质上是一个长任务系统,只是执行者不是传统业务服务,而是训练集群和实验平台。
场景三:Spark 大数据离线任务
Spark 作业通常由多个 Stage、Shuffle、依赖表和资源调度共同构成。一个报表任务、画像计算任务或离线指标加工任务,虽然表面上是“跑个 ETL”,但实际上关注的是:
- 数据分批和 DAG 拓扑
- 上游依赖是否 ready
- 某个 Stage 失败后如何恢复
- 结果如何继续进入数仓、报表、特征平台
这类任务更接近 Batch / DAG Workflow。
场景四:Flink / Streaming 流处理任务
Flink 的特别之处在于:单条事件处理可能非常快,但整个作业是一个持续运行、持续维护状态、持续做 Checkpoint 和恢复的系统。
它的“长”,不是一次任务执行十小时,而是作业生命周期本身长期存在。换句话说,它不是“长时间才结束”,而是“长期运行并持续维护状态”的长任务。
场景五:Agent 长任务处理
例如:
- 代码 Agent 理解需求、改多个文件、运行测试、失败后调整方案
- 调研 Agent 分阶段检索、阅读、总结、交叉验证
- 运维 Agent 查日志、查监控、生成诊断报告、等待人工确认后再继续
这些任务之所以是长任务,不是因为模型思考得久,而是因为:
- 任务有多个步骤
- 步骤之间要传递中间状态
- 经常要等待人或系统反馈
- 工具调用带副作用,不能随便重试
场景六:Multi-Agent 协作任务
例如复杂研发任务、深度研究任务、规划-执行-审查闭环系统。
这类任务之所以更复杂,是因为它不仅要管理执行状态,还要管理:
- 角色边界
- 共享状态
- 通信协议
- 终止条件
- 审查和仲裁机制
它本质上是“协作型长任务”。
场景七:复杂业务流程与审批链路
例如:
- 订单履约编排
- 售后退款流程
- 资金结算和对账
- 内容审核发布
- 风控审批和人工复核
这些任务显然不是单请求问题,而是带有组织角色、审批边界和正式业务副作用的长期推进问题。
场景八:基础设施与平台运维任务
例如:
- 大规模数据迁移
- 集群升级
- 灰度发布
- 索引重建
- 批量回刷缓存
这类任务说明,长任务不仅存在于业务中台,也深度存在于基础设施层。
6.2.5 一个统一归纳
从当前主流工程现实来看,长任务大致可以归纳为五大类:
- 大批量数据处理类:供应商同步、Spark ETL、索引重建。
- 持续运行状态类:Flink 实时任务、实时风控、持续流处理。
- 高认知多步骤类:代码 Agent、调研 Agent、运维 Agent。
- 多角色协作类:Multi-Agent 规划-执行-审查协作。
- 高风险业务流程类:审批、发布、结算、履约编排。
这五类场景虽然技术栈不同,但都共享同一组约束:
- 需要状态
- 需要恢复
- 需要治理
- 需要审计
- 往往需要分阶段推进
6.3 核心判断与关键设计决策
在正式讲各种方案之前,先把这章最关键的几个判断讲清楚。
6.3.0 先建立一个统一分类框架
很多任务讨论之所以容易跑偏,是因为团队一上来就直接争论“要不要上 Kafka”“要不要上 Airflow”“要不要上 Agent”,但没有先把任务本身分类。
更稳的做法,是先按下面五个维度给任务画像:
| 维度 | 关注的问题 |
|---|---|
| 执行时长 | 是不是能在一次请求里闭环,还是会持续分钟到天级 |
| 确定性 | 是固定步骤,还是需要动态判断、规划和路径调整 |
| 状态需求 | 是否需要记录进度、中间结果、恢复点 |
| 依赖复杂度 | 是单系统问题,还是跨系统、跨团队、跨角色问题 |
| 失败影响 | 失败后是简单重试,还是需要补偿、跳过、人工介入 |
按这五个维度看,很多常见任务就能快速归类:
- 短任务:一次 HTTP 请求、简单 API 调用、单条消息处理,通常快速失败、快速重试。
- 长任务:无法在单次请求或单个进程内完成,必须拆分、持久化状态并持续推进。
- Agent 类任务:除了执行跨度,还带有推理、规划、工具调用和路径调整能力。
尤其在数据处理任务里,这五个维度几乎总会同时出现:数据量大、来源不稳、依赖多、恢复要求高、幂等要求强。所以很多数据平台问题,表面像“跑个任务”,本质上却是长任务治理问题。
6.3.1 判断一:短任务与长任务的区别,不在耗时,而在执行跨度
很多人以为“几秒内完成的是短任务,几小时完成的是长任务”。这是一种很常见但不准确的区分方式。
更准确的判断标准是:任务是否需要跨边界持续推进。
这里的边界包括:
- 跨请求边界
- 跨进程边界
- 跨时间边界
- 跨步骤边界
- 跨系统边界
- 跨角色边界
如果一个任务必须跨越这些边界中的多个,并且中途还需要持久化状态、支持恢复和接受治理,那么它本质上就是长任务。
6.3.2 判断二:Agent 不是另一套宇宙,它只是更智能的执行单元
把“传统系统”和“Agent 系统”完全对立起来,是近几年很常见的一种认知误区。
传统系统关注的是:
- 任务定义
- 状态推进
- 幂等与补偿
- 调度和治理
Agent 系统在这些事情之外,多出来的不是“抛弃这些约束”,而是:
- 更强的语义理解能力
- 更强的动态规划能力
- 更强的工具选择和路径调整能力
所以更合理的理解是:Agent 给执行系统加了大脑,但并没有消灭任务系统的骨架。
6.3.3 判断三:不要按“技术潮流”选方案,要按复杂度来源选方案
一个方案是否合适,取决于复杂度主要来自哪里。
如果复杂度来自执行跨度,就要先解决状态、恢复和阶段推进问题。
如果复杂度来自认知判断,就要考虑单 Agent 或 Runtime。
如果复杂度来自职责冲突和并行协作,才考虑 Multi-Agent。
换句话说,合理的判断顺序应该是:
先看执行跨度
→ 再看认知复杂度
→ 最后看协作复杂度
6.3.4 判断四:默认从最小可行执行单元开始
很多系统真正的问题不是“起点太简单”,而是“起点太复杂”。
一个成熟架构师要克制地做决策:
- 能用同步短任务解决,就不要先上 Workflow
- 能用 Batch 解决,就不要默认上 Agent Runtime
- 能用单 Agent 解决,就不要为了“更像 AI 系统”直接拆成多 Agent
这不是保守,而是尊重复杂度成本。
6.3.5 判断五:治理层不是附属品,而是长任务系统的核心竞争力
真正把系统带进生产环境的,不是“会执行”,而是“能在失败、异常和风险面前稳住”。
所以一旦进入长任务语境,设计必须天然包含:
- 状态边界
- 审查边界
- 恢复路径
- 回退路径
- 权限和预算约束
6.4 执行方案谱系总览与选型框架
讲方法论,不能只讲抽象。我们还需要一个完整的“方案谱系”,把主流执行方案摆在同一张图上看。
6.4.1 七种主流执行方案
从简单到复杂,可以把主流方案归纳成七类:
- 同步短任务
- 异步任务 / MQ Consumer
- Batch / 分布式 Job
- 阶段化 Workflow
- 单 Agent
- Stateful Agent Runtime
- Multi-Agent
这七类方案不是互斥关系,也不意味着系统必须逐一经历。它们更像是一条复杂度逐级上升的执行谱系。
如果只记名字,很容易把它们误解成“七个平级工具箱”。更准确的理解是:它们分别对应七种不同的主导矛盾。
| 方案 | 主导矛盾 | 最适合解决的问题 | 最容易失控的点 |
|---|---|---|---|
| 同步短任务 | 请求内快速闭环 | 简单查询、简单写入、轻量工具调用 | 一旦跨时间就会开始阻塞和超时 |
| 异步任务 / MQ Consumer | 主链路不该被阻塞 | 通知、缓存刷新、轻量后台处理 | 逻辑越长越容易长成大 Consumer |
| Batch / 分布式 Job | 大批量对象如何推进 | ETL、全量同步、索引重建、修数 | 没有 Checkpoint 时只能全量重跑 |
| 阶段化 Workflow | 多阶段流程如何治理 | 审批、发布、复杂同步、长链路编排 | 建模不足时流程边界会模糊 |
| 单 Agent | 不确定输入如何理解 | 轻量分析、诊断、一次性辅助任务 | 容易把推理能力误当治理能力 |
| Stateful Agent Runtime | 多步智能任务如何恢复 | 代码 Agent、调研 Agent、运维 Agent | 状态、审查、权限设计不到位会很危险 |
| Multi-Agent | 单执行者已无法兼顾多职责 | 规划-执行-审查闭环、复杂协作 | 通信和共享状态成本急剧上升 |
所以这一节最重要的不是记住七个名词,而是建立一个感觉:
- 前四类更偏传统执行系统。
- 后三类更偏智能执行系统。
- 真正决定是否升级,不是“想不想用新技术”,而是主导矛盾有没有变化。
6.4.2 一个统一的选型维度
判断该用哪一类方案时,我建议统一看九个维度:
| 维度 | 关注的问题 |
|---|---|
| 执行跨度 | 是否需要跨请求、跨时间、跨步骤推进 |
| 状态持久化 | 中途失败后是否要从中间状态恢复 |
| 流程灵活性 | 执行路径是预定义的还是动态规划的 |
| 治理要求 | 是否需要审批、审查、审计、回退 |
| 认知复杂度 | 是否需要推理、归纳、策略调整 |
| 协作复杂度 | 是否需要多角色协作 |
| 风险等级 | 任务副作用是否高风险 |
| 工程成本 | 方案搭建、维护、观测成本有多高 |
| 可演进性 | 后续是否容易平滑升级 |
这九个维度看起来很多,但它们的重要性并不相同。实际评审时,我建议先抓三层优先级:
第一层,先看“任务会不会跨边界持续推进”:
- 执行跨度
- 状态持久化
- 风险等级
如果这三项判断错了,后面的所有选型基本都会跑偏。因为你可能会拿一个同步接口去硬扛本该有 Checkpoint 的长任务,或者拿一个单 Agent 去承接本该有人工审查的高风险动作。
第二层,再看“执行路径是固定的还是动态的”:
- 流程灵活性
- 认知复杂度
这一步决定你是在传统 Workflow 体系里继续前进,还是要引入 Agent。
第三层,最后再看“是不是已经复杂到需要多人分工”:
- 协作复杂度
- 治理要求
- 工程成本
- 可演进性
也就是说,不要一上来就讨论 Multi-Agent。大多数系统根本不是卡在“协作不够”,而是卡在“状态没建好、恢复点没定义、风险边界没隔离”。
6.4.3 一个很实用的决策顺序
可以把选型过程压缩成下面这个顺序:
- 如果不需要状态持久化,优先考虑
同步短任务或单 Agent。 - 如果只是主链路不适合同步阻塞,但流程简单,优先考虑
异步任务 / MQ Consumer。 - 如果要处理大批量对象并支持恢复,优先考虑
Batch / 分布式 Job。 - 如果存在显式阶段边界和强治理要求,优先考虑
阶段化 Workflow。 - 如果长任务同时需要动态规划和策略调整,升级到
Stateful Agent Runtime。 - 只有当单执行单元无法同时承担规划、执行、审查职责时,才进入
Multi-Agent。
如果把这套顺序翻译成更像评审会里的提问方式,大概会是下面这样:
第一问:这个任务能不能在一次请求里闭环?
能
→ 同步短任务,必要时用单 Agent 做轻量认知增强
不能
→ 进入长任务语境
第二问:它只是要异步化,还是要显式恢复?
只是异步化
→ 异步任务 / MQ Consumer
需要显式恢复
→ Batch / Workflow
第三问:它的复杂度主要来自“海量对象推进”还是“多阶段治理”?
海量对象推进
→ Batch / 分布式 Job
多阶段治理
→ 阶段化 Workflow
第四问:固定流程已经不够,是否还需要动态推理和策略调整?
不需要
→ 继续留在传统执行系统
需要
→ Stateful Agent Runtime
第五问:单个智能执行者是否已经无法同时承担规划、执行、审查?
还可以
→ 单 Agent / Runtime
不可以
→ Multi-Agent
这棵判断路径背后的核心思想其实很朴素:
- 先判断有没有“长任务骨架”问题。
- 再判断有没有“智能决策”问题。
- 最后才判断有没有“协作分工”问题。
顺序一旦反过来,团队就很容易在基础治理能力没建好的时候,过早引入复杂智能架构。
6.4.4 很容易混淆的三个方案:异步任务、Batch 与 Workflow
很多团队在长任务建设初期,最容易混淆的不是 Agent,而是下面三个传统方案:
异步任务 / MQ ConsumerBatch / 分布式 Job阶段化 Workflow
它们都能“异步干活”,但解决的问题层次完全不同。
| 方案 | 核心目标 | 典型边界 | 最强能力 | 最常见问题 |
|---|---|---|---|---|
| 异步任务 / MQ Consumer | 把动作从主链路剥离 | 一个消息处理一个相对单一的后台动作 | 解耦、削峰、快速接入 | 容易长成大 Consumer 泥球 |
| Batch / 分布式 Job | 大批量对象推进与恢复 | 批次、分片、页、游标 | Checkpoint、分片并行、持续跑完 | 阶段治理和审计能力偏弱 |
| 阶段化 Workflow | 多阶段流程推进与治理 | Stage、审批、发布、人工介入 | 显式状态、强治理、可审计 | 建模成本更高 |
可以把它们的差别记成三句话:
- 异步任务解决的是“不要阻塞主链路”。
- Batch解决的是“海量对象怎么分批推进并从中间恢复”。
- Workflow解决的是“多阶段流程怎么治理、审计和人工接管”。
对供应商酒店同步这类问题来说:
- 如果只是“收到变更后异步刷新一个缓存”,
MQ Consumer就够。 - 如果是“每天全量拉几百万酒店并支持失败续跑”,更像
Batch。 - 如果还要再加上清洗、校验、质检、发布、人工审核,那就已经是
Workflow。
接下来,我们按方案逐个展开。
6.5 方案一:同步短任务
6.5.1 定义与特点
同步短任务是最基础、最常见的执行形态。它通常在单次请求、单次 RPC 或单次函数调用里闭环完成。
它的典型特点是:
- 请求内完成
- 执行路径固定
- 状态主要存在调用栈和内存里
- 失败通常整体报错或整体重试
6.5.2 适用场景
同步短任务适合以下类型的问题:
- 查询接口
- 单次规则计算
- 单次写操作
- 简单聚合接口
- 轻量工具调用
- 一次性问答型 Agent
例如,一个商品详情查询接口、一个优惠券可用性校验接口、一个简单的 Seatalk 机器人问答,都更像短任务。
6.5.3 端到端链路与职责边界
同步短任务的端到端链路通常很直接:
Input
→ Validation
→ Business Logic
→ Optional Dependency Calls
→ Response
在这种模式下,职责边界比较清晰:
- 网关负责接入、鉴权、限流
- 应用负责执行业务逻辑
- 下游服务或数据库负责提供依赖能力
同步 / 异步边界几乎不存在,所有动作都发生在一个请求上下文里。
6.5.4 契约、幂等与失败处理
同步短任务虽然简单,但并不意味着可以没有契约意识。
至少要明确:
- 请求字段的必填、可选和默认值
- 响应字段的语义和兼容性
- 写操作是否需要幂等键
- 下游超时后是失败、重试还是默认降级
短任务的失败处理通常比较直接:
- 读请求:可整体重试或快速失败
- 写请求:如果有副作用,必须明确幂等语义
6.5.5 优缺点与边界
优点:
- 实现成本低
- 调试简单
- 调用链直观
- 对团队认知负担小
缺点:
- 不擅长跨步骤恢复
- 不适合长时间阻塞
- 不适合复杂状态推进
- 危险副作用治理能力弱
边界很明确:一旦任务开始跨时间、跨步骤、跨系统持续推进,同步短任务就不应再继续硬扛。
6.6 方案二:异步任务与 MQ Consumer
6.6.1 定义与特点
异步任务的核心价值,是把“不适合同步阻塞的动作”从主链路中剥离出来。
常见模式是:
主请求
→ 写 DB / 发 MQ
→ 立即返回
后台 Consumer / Worker
→ 处理后续动作
6.6.2 适用场景
常见适用场景包括:
- 发通知
- 刷新缓存
- 生成报表
- 回写非核心下游
- 执行轻量后台任务
这类任务的共同点是:异步化能改善主链路体验,但任务本身通常仍然比较单一。
6.6.3 端到端链路与同步 / 异步边界
异步任务的关键边界,在“主链路何时结束,后台任务何时接手”。
常见链路是:
Request
→ Persist Intent / Publish Event
→ Return
Consumer
→ Consume Message
→ Execute Side Effect
→ Ack / Retry / DLQ
这类系统里最重要的设计点不是“怎么发 MQ”,而是:
- 消息什么时候被认为已可发布
- 失败后由谁负责重试
- 主链路和异步链路的状态怎么对齐
6.6.4 消息契约、顺序与重试
异步任务至少要显式定义:
- 消息体字段语义
- 幂等键
- 顺序要求
- 消费成功的判定条件
- 最大重试次数
- 进入 DLQ 的条件
如果这些没有定义清楚,异步化只会把问题从接口层转移到消息层。
6.6.5 常见反模式:大 Consumer 泥球
这是非常值得警惕的反模式。
当团队把“复杂长任务”都扔给一个 Consumer 处理时,系统会慢慢演化成:
- 一个消息触发十几个副作用
- 顺序逻辑、补偿逻辑、回退逻辑全部塞在一起
- 状态只存在日志里,没有正式状态契约
这说明系统已经超出了“异步任务”的适用边界,应该升级到 Batch 或 Workflow。
6.6.6 优缺点与边界
优点:
- 解耦主链路
- 削峰填谷
- 改善用户响应时间
缺点:
- 状态通常较粗
- 调试比同步任务复杂
- 一旦流程变深,极易失控
边界结论:异步任务解决的是“异步化”,不是“复杂长任务治理”。
6.7 方案三:Batch 与分布式 Job
6.7.1 定义与特点
Batch 与分布式 Job 是传统工程里最典型的长任务方案之一。它们面向的是大批量对象处理和较长时间窗口推进。
它们的典型特点是:
- 按批次组织任务
- 按分片、分页、游标或时间窗口推进
- 支持 Checkpoint
- 支持续跑、重试和补偿
6.7.2 适用场景
最常见的适用场景包括:
- 供应商全量同步
- Spark 离线计算任务
- 数仓 ETL
- 索引重建
- 大规模历史数据修复
- 账务和库存对账
6.7.3 任务切分、分片与 Checkpoint
Batch 的核心不是“后台慢慢跑”,而是可推进、可追踪、可恢复。
所以它必须回答:
- 任务如何切分成批次
- 批次如何切分成分片或页
- 每个分片完成到哪里算一个安全恢复点
典型 Checkpoint 可以是:
- 最后一页页码
- 最后一个游标
- 最后处理 ID
- 已完成 shard 列表
没有 Checkpoint 的 Batch,本质上只是一个长循环脚本,不是成熟的长任务方案。
6.7.4 状态契约与执行推进
Batch 系统通常至少需要三层状态:
- 任务级状态:这个批次是否开始、是否结束
- 分片级状态:哪个 shard 完成了,哪个仍在跑
- 对象级状态:哪条记录成功、失败、跳过或待补偿
很多系统失败就失败在只有任务级状态,没有对象级状态。最终看起来“批次成功了”,但具体错了哪些对象,根本追不出来。
6.7.5 依赖、风险与治理
Batch 方案的治理重点通常包括:
- 并发度控制
- 资源调度
- 重试与 DLQ
- checkpoint 恢复
- 人工补数据
- 结果审计
对于 Spark 这类任务,治理重点偏资源调度与 Stage 恢复;对于供应商同步这类任务,治理重点偏对象级状态、数据质量与发布保护。
6.7.6 优缺点与边界
优点:
- 非常适合大批量对象处理
- 适合显式恢复
- 工程实践成熟
缺点:
- 交互性较弱
- 对动态规划支持弱
- 阶段治理能力取决于额外建模
边界结论:当任务主要难点是“批量推进与恢复”,Batch 是主力方案;当难点进一步变成“阶段治理和强审计”,就该升级到 Workflow。
6.7.7 数据处理长任务的六步法
如果把供应商同步、ETL、数仓加工、索引重建这类任务抽象成一套统一方法,我更推荐下面这套六步法:
第一步:任务拆分
先不要急着写 Worker,而是先定义任务单元怎么拆。
常见切分方式包括:
- 按国家、城市、商家、仓库等业务维度分片
- 按时间窗口分片
- 按页、游标、ID 范围分片
- 按阶段拆成
Extract -> Transform -> Load -> Validate -> Publish
拆分的目标不是“并行看起来很高级”,而是让任务天然具备可推进、可恢复、可隔离失败的结构。
第二步:状态管理与 Checkpoint
数据任务必须有正式恢复点。至少要能回答:
- 已处理到哪个游标或页码
- 已完成哪些 shard
- 哪些对象成功、失败、跳过
- 当前任务版本和输入快照是什么
成熟做法通常会组合使用:
- 进度元数据表
- 对象级状态表
- 中间结果存储
- 输入版本号或哈希校验
第三步:幂等性设计
所有写操作默认都应该假设会被重复执行。
这意味着:
- 写库优先使用
UPSERT、唯一键约束或版本覆盖 - 对外副作用要有幂等键
- 同一批次、同一对象重复处理不能制造额外副作用
一个很实用的经验是:把幂等键设计成“任务 ID + 批次 / 分片 ID + 对象 ID”。
第四步:错误处理与重试策略
不要把所有失败都当成一种失败。
更合理的分层是:
- 瞬时错误:限流、超时、短暂网络抖动,适合指数退避重试
- 部分失败:允许子批次或单 shard 重试,不必全量重跑
- 永久失败:进入
DLQ、失败池或人工处理队列
真正决定工程质量的,往往不是“会不会重试”,而是“能不能只重试该重试的那一小部分”。
第五步:编排与治理
当数据任务进入正式生产后,光“跑完”是不够的,还必须具备治理能力:
- 依赖管理
- 并发度控制
- 结果发布保护
- 审批和人工介入点
- 成功率、耗时、数据漂移、资源消耗监控
这也是为什么很多 ETL / 同步任务最后会从简单脚本升级到 Airflow、Temporal 或内部 Workflow 平台。
第六步:演进与优化
长任务系统几乎都是逐步演进出来的。
典型路径往往是:
串行脚本
→ 分片并行 Batch
→ 带 Checkpoint 的 Pipeline
→ 带治理能力的 Workflow
→ 在局部阶段引入 Agent 辅助判断
比如地址标准化、类目映射、异常记录归因这类“规则难穷尽但风险可控”的环节,就很适合在稳定 Workflow 骨架里嵌入 Agent,而不是反过来让 Agent 主导整个数据链路。
6.8 方案四:阶段化 Workflow
6.8.1 定义与特点
阶段化 Workflow 是在 Batch 之上进一步显式建模“阶段边界、职责边界和治理边界”的方案。
它的核心思路不是把任务拆得越细越好,而是把天然不同性质的步骤拆开。
6.8.2 适用场景
典型适用场景包括:
- 供应商数据同步
- 审批流
- 复杂业务流程
- 跨系统数据发布
- 内容审核与正式发布
6.8.3 端到端链路与职责拆分
以供应商同步为例,一个成熟的 Workflow 往往天然会拆成下面这类职责:
- Sharder:定义边界和调度单位
- Fetcher:负责忠实拉取外部数据
- Transformer:负责标准化和语义映射
- Publisher:负责正式发布和写前保护
关键不在“分四步”,而在于:
- 把慢源不稳定性和正式发布风险隔离开
- 把原始数据、标准数据和正式数据隔离开
- 让每个阶段都能独立观察、恢复和治理
6.8.4 状态、事件与幂等
Workflow 的核心资产通常包括:
- 阶段状态
- 阶段间事件
- 对象级状态 Ledger
- 幂等约束
- 版本保护
这类系统特别适合引入显式状态机,因为“当前能不能进入下一阶段”本身就是一种正式业务规则。
6.8.5 降级、熔断、人工接管与回滚
Workflow 系统之所以适合高风险场景,是因为它很容易内建治理能力:
- 某一阶段异常时可以熔断,不继续放大影响
- 某些对象异常时可以进入人工审查或补偿池
- 发布前可以做 review gate
- 高风险操作可以要求审批
6.8.6 优缺点与工程价值
优点:
- 职责边界清晰
- 治理能力强
- 审计和补偿更自然
- 适合高风险长任务
缺点:
- 建模成本高
- 对前期设计要求高
- 不适合边界尚不稳定的小任务
边界结论:Workflow 不是为了让系统显得高级,而是为了解决强治理长任务的结构化问题。
6.9 方案五:单 Agent
6.9.1 定义与特点
单 Agent 的核心不是“有一个聊天机器人”,而是让一个执行单元同时具备:
- 目标理解
- 步骤规划
- 工具选择
- 结果整合
在很多轻量任务里,它比规则系统灵活得多。
6.9.2 适用场景
典型适用场景:
- 问答
- 查询分析
- 轻量诊断
- 一次性辅助任务
- 小范围代码解释或修改建议
6.9.3 输入、推理、工具调用、输出链路
单 Agent 的典型链路是:
Input
→ Reasoning
→ Tool Selection
→ Tool Execution
→ Output
它非常适合“高认知密度、低执行跨度”的问题。
6.9.4 上下文、结果和工具契约
单 Agent 虽然灵活,但仍然需要约束:
- 输入边界要清楚
- 工具权限要受控
- 输出结构最好可解析
- 高风险结果不能直接信任
6.9.5 失败、审查与边界控制
单 Agent 最大的误区,是把“会推理”误当成“会治理”。
它的天然边界包括:
- 上下文窗口有限
- 状态持久化能力弱
- 恢复能力弱
- 工具副作用控制弱
所以单 Agent 更像“认知增强的短任务执行器”,而不是完整长任务系统。
6.9.6 优缺点与边界
优点:
- 灵活
- 接入成本低
- 对不确定输入友好
缺点:
- 不擅长长链路恢复
- 容易出现上下文膨胀
- 治理能力取决于额外框架
边界结论:单 Agent 适合做起点,但不能天然承担所有长任务系统职责。
6.10 方案六:Stateful Agent Runtime
6.10.1 定义与特点
Stateful Agent Runtime 的核心价值,在于把 Agent 从一次模型调用,提升为一个被 Runtime 托管的长任务执行单元。
它典型会包含:
- Goal
- Planner
- Step Queue
- Executor
- State Store
- Reviewer
- Policy Layer
- Resume Loop
6.10.2 适用场景
最典型的适用场景包括:
- 代码 Agent
- 调研 Agent
- 运维 Agent
- 多步业务助手
- 需要暂停、恢复、审查的智能执行系统
6.10.3 在 Agent 中如何落地 Task / Step / State / Checkpoint
这是 Runtime 和单 Agent 的根本区别。
在 Runtime 中:
- Task 不再只是 prompt,而是正式任务定义
- Step 不再只是隐式思考过程,而是显式执行单元
- State 不是聊天历史,而是正式状态存储
- Checkpoint 是恢复边界,而不是“模型大概记得做到哪了”
6.10.4 状态、事件、审查与策略契约
一个成熟的 Agent Runtime 至少要定义:
- 任务状态
- 步骤状态
- 等待状态
- 工具调用结果状态
- reviewer 通过 / 拒绝 / 返工状态
- 预算和风险策略
这说明它本质上已经重新走到长任务系统的核心结构上来了。
6.10.5 暂停恢复、人工确认、回退与治理
这类系统天然要支持:
- 中途暂停
- 等待人工确认
- 等待外部事件
- 基于 checkpoint 恢复
- 危险动作回退或阻断
这些能力不是可选增强,而是 Agent 长任务要进入生产环境的基本要求。
6.10.6 优缺点与升级条件
优点:
- 保留 Agent 的认知灵活性
- 具备长任务治理能力
- 适合复杂多步任务
缺点:
- 系统复杂度明显上升
- 对观测和审计要求高
- 设计失误时更容易出现隐蔽问题
升级条件也很明确:当单 Agent 已经无法稳定承载长链路执行时,Runtime 才值得引入。
6.11 方案七:Multi-Agent 协作
6.11.1 定义与特点
Multi-Agent 不是“多几个模型一起聊”,而是把规划、执行、审查、协调等不同职责拆给不同角色化执行单元。
6.11.2 适用场景
典型适用场景:
- 复杂研发任务
- 并行调研
- 规划-执行-审查闭环
- 跨领域分析任务
6.11.3 角色划分与协作链路
最小可行结构通常是三角模型:
- Planner
- Worker
- Reviewer
在此基础上可以继续扩展:
- Supervisor
- Router
- Specialist Agent
- Memory Manager
6.11.4 共享状态、消息契约与终止条件
Multi-Agent 最难的地方,不是“再多接几个模型”,而是:
- 状态谁持有
- 消息如何交接
- 什么时候返工
- 什么时候结束
- 谁拥有最终裁决权
如果这些问题不显式定义,系统很快就会进入循环讨论、重复劳动和责任稀释。
6.11.5 审查、仲裁、风险控制与人工接管
Multi-Agent 一旦落地,治理比单 Agent 更重要。
需要重点控制:
- 角色权限
- 通信协议
- 终止条件
- 共享状态
- 风险升级路径
- 人工接管入口
6.11.6 优缺点与过度设计边界
优点:
- 适合复杂任务分治
- 适合隔离职责冲突
- 便于引入 reviewer 和 specialist
缺点:
- 通信成本高
- 责任边界复杂
- 调试和治理难度高
- Token 和时间成本显著上升
边界结论:Multi-Agent 不是默认架构,而是当单执行单元和单 Runtime 已经无法良好承载复杂职责时的一种受控分工机制。
6.12 跨方案对比:如何选择合适的任务处理方案
讲完七类方案后,我们需要把它们拉回同一张表里比较。
6.12.1 一张统一对比表
| 方案 | 状态持久化 | 恢复能力 | 流程灵活性 | 治理能力 | 工程成本 | 典型场景 |
|---|---|---|---|---|---|---|
| 同步短任务 | 弱 | 弱 | 低 | 低 | 低 | 查询、单次写入、轻量问答 |
| 异步任务 / MQ Consumer | 弱到中 | 中 | 低 | 低到中 | 低到中 | 通知、缓存刷新、轻量后台处理 |
| Batch / 分布式 Job | 中到强 | 强 | 中 | 中 | 中 | 数据同步、Spark 任务、索引重建 |
| 阶段化 Workflow | 强 | 强 | 中 | 强 | 中到高 | 供应商同步、审批流、复杂发布 |
| 单 Agent | 弱到中 | 弱 | 强 | 弱 | 低到中 | 问答、分析、轻量诊断 |
| Stateful Agent Runtime | 强 | 强 | 强 | 中到强 | 高 | 代码 Agent、调研 Agent、运维 Agent |
| Multi-Agent | 强 | 中到强 | 很强 | 中到强 | 很高 | 复杂协作、规划执行审查闭环 |
6.12.2 一条渐进式升级路径
实践里最常用的升级路径通常是:
同步短任务
→ 异步任务
→ Batch / Workflow
→ 单 Agent
→ Stateful Agent Runtime
→ Multi-Agent
当然,系统不一定严格按这个顺序走,但背后的方法论是稳定的:
- 先解决执行跨度
- 再解决认知问题
- 最后解决协作问题
6.12.3 三个常用的选型建议
建议一:默认从最小可行方案起步
不要用 Multi-Agent 去解决一个同步接口就能解决的问题,也不要为一个短生命周期脚本搭一整套 Workflow 平台。
建议二:一旦出现状态恢复需求,就停止使用短任务思维
这是很多系统的分水岭。只要你开始认真讨论 checkpoint、人工恢复、局部重试,就说明任务已经进入长任务语境。
建议三:治理问题不能靠“多加一点 prompt”解决
很多 Agent 系统的问题,本质上不是模型不够聪明,而是状态、审查、权限和回退机制没建出来。
6.13 本章小结
这一章想建立的,不是一套新名词,而是一种更稳定的系统设计视角。
6.13.1 先分清复杂度来自哪里
系统设计里最容易犯的错误,是在错误的维度上用力。
有的任务难在执行跨度,有的难在认知判断,有的难在协作治理。方案选型必须先识别复杂度来源。
6.13.2 短任务、长任务、Agent 和 Multi-Agent 不是割裂概念
它们本质上都是统一执行模型在不同复杂度区间下的不同实现。区别只是:
- 执行跨度有多大
- 状态是否需要外置持久化
- 是否需要动态规划
- 是否需要多角色协作
6.13.3 真正成熟的任务系统,拼的不是“会不会执行”,而是“会不会治理”
无论你最后选择的是 Batch、Workflow、Agent Runtime 还是 Multi-Agent,只要系统进入长任务区间,就绕不开以下核心能力:
- 状态
- 恢复
- 幂等
- 补偿
- 审计
- 风险控制
- 人工接管
6.13.4 最后压缩成三条原则
如果要把本章压缩成三句话,我建议记住这三条:
- 先看执行跨度:是否需要跨边界持久推进。
- 再看认知复杂度:是否需要动态规划和工具选择。
- 最后看协作复杂度:是否需要角色分工与审查闭环。
只有把这三个问题分开看,任务处理方案的选型才会真正清楚。