Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第 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 成功标准

如果这一章写得足够好,读者至少应该能回答以下问题:

  1. 短任务和长任务到底怎么区分,为什么不能只按耗时判断。
  2. 同步请求、异步任务、Batch、Workflow、Agent Runtime 和 Multi-Agent 分别是什么。
  3. 当前真实工程里有哪些典型长任务场景,它们为什么天然是长任务。
  4. 为什么很多 Agent 系统走着走着,会重新走到状态机、Checkpoint、审批和治理层上来。
  5. 当一个系统从简单走向复杂时,应该如何渐进演进,而不是一开始就过度设计。

6.1.4 本章明确不做什么

本章不尝试替代每一个具体领域的完整实现指南,例如:

  • 不展开讲 Spark 的算子执行机制和 Shuffle 内部细节。
  • 不展开讲 Flink 的状态后端、Barrier 对齐和 Watermark 算法实现。
  • 不展开讲某个特定 Agent 框架的 API 用法。
  • 不给出某个具体业务系统的全部表结构和部署脚本。

本章要做的,是在这些具体技术之上,抽象出一套更稳定的任务处理方法论。


6.2 现状、问题定义与典型长任务场景

6.2.1 当前系统通常怎么处理任务

大多数系统的任务处理方式,都经历过一个相似演进:

  1. 最开始是同步函数或同步接口,逻辑简单、调用直接、状态靠内存和调用栈保存。
  2. 接着为了削峰和解耦,开始把任务扔到 MQ 或后台 Worker。
  3. 任务再复杂一点,就出现批处理、定时 Job、分片执行、重试队列和补偿任务。
  4. 当任务带有明显阶段边界、审批节点和发布风险时,团队会走向显式 Workflow。
  5. 当任务不再只是“执行规则”,而是要理解目标、动态规划步骤、根据中间结果调整策略时,Agent Runtime 开始出现。
  6. 当规划、执行、审查三类职责冲突加剧,才会进一步考虑 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 的特别之处在于:单条事件处理可能非常快,但整个作业是一个持续运行、持续维护状态、持续做 Checkpoint 和恢复的系统。

它的“长”,不是一次任务执行十小时,而是作业生命周期本身长期存在。换句话说,它不是“长时间才结束”,而是“长期运行并持续维护状态”的长任务。

场景五:Agent 长任务处理

例如:

  • 代码 Agent 理解需求、改多个文件、运行测试、失败后调整方案
  • 调研 Agent 分阶段检索、阅读、总结、交叉验证
  • 运维 Agent 查日志、查监控、生成诊断报告、等待人工确认后再继续

这些任务之所以是长任务,不是因为模型思考得久,而是因为:

  • 任务有多个步骤
  • 步骤之间要传递中间状态
  • 经常要等待人或系统反馈
  • 工具调用带副作用,不能随便重试

场景六:Multi-Agent 协作任务

例如复杂研发任务、深度研究任务、规划-执行-审查闭环系统。

这类任务之所以更复杂,是因为它不仅要管理执行状态,还要管理:

  • 角色边界
  • 共享状态
  • 通信协议
  • 终止条件
  • 审查和仲裁机制

它本质上是“协作型长任务”。

场景七:复杂业务流程与审批链路

例如:

  • 订单履约编排
  • 售后退款流程
  • 资金结算和对账
  • 内容审核发布
  • 风控审批和人工复核

这些任务显然不是单请求问题,而是带有组织角色、审批边界和正式业务副作用的长期推进问题。

场景八:基础设施与平台运维任务

例如:

  • 大规模数据迁移
  • 集群升级
  • 灰度发布
  • 索引重建
  • 批量回刷缓存

这类任务说明,长任务不仅存在于业务中台,也深度存在于基础设施层。

6.2.5 一个统一归纳

从当前主流工程现实来看,长任务大致可以归纳为五大类:

  1. 大批量数据处理类:供应商同步、Spark ETL、索引重建。
  2. 持续运行状态类:Flink 实时任务、实时风控、持续流处理。
  3. 高认知多步骤类:代码 Agent、调研 Agent、运维 Agent。
  4. 多角色协作类:Multi-Agent 规划-执行-审查协作。
  5. 高风险业务流程类:审批、发布、结算、履约编排。

这五类场景虽然技术栈不同,但都共享同一组约束:

  • 需要状态
  • 需要恢复
  • 需要治理
  • 需要审计
  • 往往需要分阶段推进

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 七种主流执行方案

从简单到复杂,可以把主流方案归纳成七类:

  1. 同步短任务
  2. 异步任务 / MQ Consumer
  3. Batch / 分布式 Job
  4. 阶段化 Workflow
  5. 单 Agent
  6. Stateful Agent Runtime
  7. 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 一个很实用的决策顺序

可以把选型过程压缩成下面这个顺序:

  1. 如果不需要状态持久化,优先考虑 同步短任务单 Agent
  2. 如果只是主链路不适合同步阻塞,但流程简单,优先考虑 异步任务 / MQ Consumer
  3. 如果要处理大批量对象并支持恢复,优先考虑 Batch / 分布式 Job
  4. 如果存在显式阶段边界和强治理要求,优先考虑 阶段化 Workflow
  5. 如果长任务同时需要动态规划和策略调整,升级到 Stateful Agent Runtime
  6. 只有当单执行单元无法同时承担规划、执行、审查职责时,才进入 Multi-Agent

如果把这套顺序翻译成更像评审会里的提问方式,大概会是下面这样:

第一问:这个任务能不能在一次请求里闭环?
  能
    → 同步短任务,必要时用单 Agent 做轻量认知增强
  不能
    → 进入长任务语境

第二问:它只是要异步化,还是要显式恢复?
  只是异步化
    → 异步任务 / MQ Consumer
  需要显式恢复
    → Batch / Workflow

第三问:它的复杂度主要来自“海量对象推进”还是“多阶段治理”?
  海量对象推进
    → Batch / 分布式 Job
  多阶段治理
    → 阶段化 Workflow

第四问:固定流程已经不够,是否还需要动态推理和策略调整?
  不需要
    → 继续留在传统执行系统
  需要
    → Stateful Agent Runtime

第五问:单个智能执行者是否已经无法同时承担规划、执行、审查?
  还可以
    → 单 Agent / Runtime
  不可以
    → Multi-Agent

这棵判断路径背后的核心思想其实很朴素:

  • 先判断有没有“长任务骨架”问题。
  • 再判断有没有“智能决策”问题。
  • 最后才判断有没有“协作分工”问题。

顺序一旦反过来,团队就很容易在基础治理能力没建好的时候,过早引入复杂智能架构。

6.4.4 很容易混淆的三个方案:异步任务、Batch 与 Workflow

很多团队在长任务建设初期,最容易混淆的不是 Agent,而是下面三个传统方案:

  • 异步任务 / MQ Consumer
  • Batch / 分布式 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 最后压缩成三条原则

如果要把本章压缩成三句话,我建议记住这三条:

  1. 先看执行跨度:是否需要跨边界持久推进。
  2. 再看认知复杂度:是否需要动态规划和工具选择。
  3. 最后看协作复杂度:是否需要角色分工与审查闭环。

只有把这三个问题分开看,任务处理方案的选型才会真正清楚。