工作流可靠性与持久化

共 24 题
📑 题目列表 24 题
#
★★★

1. 线性、条件分支、并行、路由和人工介入节点如何映射成显式状态机

线性、条件分支、并行、路由和人工介入等流程结构,应如何映射成显式状态机?

  • 五种结构在状态机中的对应物:顺序链、条件边、并行分支与汇合、路由表、挂起态
  • 状态转移表与合法转移校验
  • 人工介入节点(暂停/恢复/拒绝)的状态建模

显式状态机用"状态 + 转移"两种元素表达全部流程结构:线性步骤映射为状态链,每个状态完成一个节点动作,完成后触发到下一状态的转移;条件分支映射为条件边——状态不变、转移目标由条件函数(如校验结果)决定,进入不同后继状态;并行结构映射为分支-汇合模式,一个状态发出多个并行分支(Fan-out),全部到达汇合点后由汇合状态统一收敛(Fan-in),并维护"哪些分支已完成"的完成计数;路由结构映射为路由表——按消息类型或业务字段查表决定目标状态,等价于多条件分支的组合;人工介入节点映射为"等待审批"状态,进入该状态后流程挂起,只有收到审批通过/拒绝事件才发生转移。

设计要点:所有转移都要有明确的事件与守卫条件(guard),转移表可枚举、可校验,非法转移(如跳过审批直接完成)在代码层被拒绝;并行汇合要考虑部分分支失败时的处理策略——全部成功才汇合、或部分成功降级汇合;人工节点还要建模超时与取消事件(审批超时自动升级、用户取消终止)。显式状态机的价值是流程全部可列举、可测试、可审计,模型输出或外部事件只能触发合法转移。

本题考察把流程图翻译成状态机的建模能力。回答要逐一给出五种结构与状态机元素的对应关系,并强调转移表、守卫条件与人工节点事件建模。能说明并行汇合与人工超时等细节,说明建模经验扎实。

#
★★★

2. Checkpoint、恢复、重试、补偿和去重如何保证长任务在进程重启后继续执行

Checkpoint、恢复、重试、补偿和去重是如何协同保证长任务在进程重启后继续执行的?

  • 五类可靠性机制的职责:快照、续跑、重试、回补、防重
  • checkpoint 的时机与原子性
  • 崩溃恢复的流程:加载→校验→续跑

五类机制各司其职:Checkpoint 定期把任务状态(已执行节点、中间产物引用、模型输出、工具结果)原子化持久化,是恢复的基础;恢复在进程重启后加载最近 checkpoint,从断点状态继续执行未完成节点;重试针对瞬时失败(网络抖动、限流、超时)在节点级重放;补偿针对已产生副作用但后续失败的任务,执行反向操作(如撤销已发送的通知、回滚已写入的数据)回到一致状态;去重保证同一任务或同一副作用只执行一次——通过幂等键(任务 ID + 步骤号)检查执行记录,防止重试或恢复引发重复执行。

协同流程:任务启动时先查执行记录去重,已在 checkpoint 中的步骤直接跳过;每个节点执行前生成幂等键并登记"执行中",成功后标记"已完成"并写入 checkpoint;节点失败按策略重试,重试耗尽进入补偿或失败收尾;进程崩溃后,重启时加载 checkpoint、校验状态一致性(已完成标记与外部副作用对账),从第一个未完成节点续跑。关键工程点是 checkpoint 写入要与副作用提交同序——先记后做或先做后记要统一约定,配合去重表保证"at-least-once 执行、exactly-once 生效"。

本题考察长任务可靠性的机制组合。回答要清晰区分五个机制各自的职责并说明协同流程,突出"幂等去重 + checkpoint 原子写 + 副作用对账"这条主线。能说明崩溃窗口期的状态一致性问题是加分项。

#
★★★

3. 中间产物应保存什么版本、来源和幂等信息,如何避免重复执行副作用节点

中间产物应保存什么版本、来源和幂等信息?如何避免重复执行副作用节点?

  • 中间产物的版本、来源、幂等元数据
  • 副作用节点的幂等键设计与执行登记
  • 重放/重试时跳过已生效副作用

中间产物要保存的元数据:版本(产物每次变更递增,记录内容与版本对应)、来源(哪个节点/工具/模型调用产生,含调用 ID 与时间戳)、幂等信息(与该产物关联的执行键,如任务 ID + 步骤号 + 动作类型),外加生成参数(模型版本、工具入参)供审计。存储上按产物类型区分:小结构状态进数据库、大对象(长文本、文件)进对象存储并保存引用,版本历史保留以便回溯与对比。

避免重复执行副作用节点的核心是"执行登记 + 幂等键":每个副作用节点执行前先按规则生成幂等键并查登记表,若已有"成功"记录则跳过执行直接复用结果;没有记录则登记"执行中"并执行,成功后原子更新为"成功",失败则标记失败状态供重试决策。幂等键的生成要与业务语义绑定——同一逻辑动作在不同重试下必须生成相同键(如"订单 123 发送退款通知"),而不能用随机值。对于外部系统,还要让调用本身携带幂等键(如 HTTP Idempotency-Key),保证对端也去重。这样无论重试、重放还是时间旅行,副作用都只生效一次。

本题考察中间产物治理与副作用防重。回答要给出版本/来源/幂等三类元数据,以及"执行前查登记、执行后记登记、幂等键绑定业务语义"的机制。能提到外部系统幂等键传递是工程细节加分项。

#
★★★

4. Agent 长任务(数小时、数天)应如何持久化,检查点(checkpoint)

Agent 长任务(数小时、数天)应如何通过检查点(checkpoint)持久化?

  • checkpoint 的内容:完整状态、上下文、工具会话、产物引用
  • 持久化时机与频率策略(事件驱动 + 定时)
  • 存储选型与恢复流程

长任务的 checkpoint 必须能完整还原执行现场,内容包含四部分:状态数据(当前节点、已完成步骤、任务变量)、上下文数据(对话历史、模型消息序列、检索到的内容)、工具会话状态(第三方 API 的会话令牌、游标、分页位置)与产物引用(中间产物的存储地址与版本)。只有这些齐全,恢复时才能"无缝续跑"而不是"重新理解任务"。持久化格式要向前兼容(字段可扩展),因为长任务可能跨框架版本。

持久化时机采用"事件驱动 + 定时兜底":每个有副作用或有意义进展的节点完成后立即写 checkpoint(事件驱动),同时按固定间隔(如每 5 分钟或每 N 步)兜底写入,避免长时间无事件节点导致恢复点过远。写入要原子化(先写临时副本再原子替换,或用数据库事务),防止写一半崩溃产生损坏状态。存储选型:Redis 适合频繁写入的短状态,PostgreSQL 适合结构化状态与事务一致性,S3/对象存储适合大体积快照,长任务常用"数据库存小状态 + 对象存储存大快照 + 引用关联"的组合。恢复流程是加载最新 checkpoint → 校验完整性 → 重建模型上下文与工具会话 → 从断点继续,并对账外部系统状态。

本题考察 checkpoint 设计。回答要覆盖内容四要素、事件驱动+定时兜底的写入策略、原子性要求与分层存储选型。突出"能完整还原现场"而不是"只存任务 ID"是本题核心。

#
★★★

5. Agent 任务暂停后如何从中断点恢复(context 重建、模型重连、工具状态同步)

Agent 任务暂停后如何从中断点恢复?context 重建、模型重连、工具状态同步分别怎么做?

  • context 重建:从 checkpoint 恢复消息序列与状态变量
  • 模型重连:重建模型会话与流式通道
  • 工具状态同步:恢复外部会话与游标,对账幂等

恢复分三步:第一步 context 重建——从 checkpoint 读出完整的消息序列(用户消息、模型输出、工具结果按原始顺序组装)与任务状态变量,重新构造模型上下文,保证模型"看到"与暂停前一致的对话;若上下文过长还需做摘要压缩,但压缩要保留关键事实与未完成任务。第二步模型重连——重新建立模型会话(无状态 API 直接重发完整消息序列即可;有状态会话则重建会话 ID 并重放消息),恢复流式输出通道,验证模型端上下文未丢失。第三步工具状态同步——恢复第三方工具的会话状态(OAuth 令牌、分页游标、文件句柄),并对外部系统做对账:比对 checkpoint 中"已完成副作用"与外部实际状态,发现不一致时通过幂等键去重或补偿修正。

关键原则:恢复不是"从头重跑",而是"从断点续跑"——已完成且验证过的步骤直接跳过;恢复过程本身要可观测,记录恢复事件(何时、从哪个 checkpoint、哪些步骤跳过),供审计与故障分析。恢复后还应做一次"计划有效性校验"——若暂停期间环境变化(数据被改、权限变更),需触发重规划而不是盲目续跑。为降低恢复复杂度,checkpoint 应同时保存"逻辑状态"与"物理对账信息",让恢复有据可依。

本题考察断点恢复的三条技术线。回答要分别展开 context、模型、工具三层的重建/重连/同步方法,并强调恢复后对账与计划有效性校验。核心是"续跑而非重跑"原则。

#
★★★

6. Agent 的中间结果(生成的内容、工具调用返回值)应存放在事务数据库还是对象存储,二者边界

Agent 的中间结果(生成的内容、工具调用返回值)应存放在事务数据库还是对象存储?二者的边界如何划分?

  • 两类存储的特性差异:强一致/事务 vs 大对象/低成本
  • 按数据特征分类:小结构字段 vs 大体积内容
  • 引用关联与生命周期管理

划分边界看四个特征:数据结构化程度、体积、一致性要求、访问模式。适合事务数据库的中间结果是:小体积、结构化、需要强一致与事务性的数据——任务状态、步骤记录、工具调用的元数据(调用 ID、时间、参数摘要、返回码)、幂等登记表、审计记录,它们需要与业务状态原子更新,支持事务回滚与并发控制。适合对象存储的中间结果是:大体积、非结构化或半结构化、只写一次或很少修改的数据——模型生成的长文本草稿、RAG 检索到的原始文档、文件型工具输出(图片、表格、代码包)、完整工具返回体。

边界划分的实践约定:对象存储保存"内容本身",事务数据库保存"引用 + 元数据"——数据库记录产物 ID、存储路径、大小、来源节点、版本、时间戳,读取时按 ID 拉取内容。生成的内容先写对象存储再在数据库登记,两个动作通过事务或补偿保证最终一致。访问模式也是判据:需要频繁按条件查询与统计的结果进数据库;只按 ID 取整块内容的大对象进对象存储。生命周期上两类数据都需清理策略,对象存储按引用计数与保留期归档,数据库记录在任务完成后压缩或冷存。

本题考察存储选型边界。回答要给出结构化+事务性→数据库、大体积+只读→对象存储的判据,并落到"数据库存引用、对象存储存内容"的经典模式。强调登记与写入的一致性是关键工程点。

#
★★★

7. 如何检测无进展循环、工具来回调用和状态振荡,并触发安全终止

如何检测无进展循环、工具来回调用和状态振荡,并触发安全终止?

  • 三类异常行为的信号特征
  • 检测机制:状态指纹、转移计数、振荡识别
  • 安全终止流程与告警

三类异常的信号:无进展循环表现为连续多步状态无实质变化——同一节点重复执行、模型重复输出相似内容、任务变量与产物都没有更新,检测方法是计算"状态指纹"(对状态关键字段做哈希),连续 N 次指纹相同即判定停滞;工具来回调用表现为两个(或几个)工具交替调用——如查询工具与解析工具互相调用对方的结果却无新产出,检测方法是记录工具调用序列,识别"ABABAB"型重复子序列;状态振荡表现为状态在几个值之间反复跳转——如同一个开关被反复切换、金额在加与减之间震荡,检测方法是记录状态转移历史,用滑窗检测周期循环。

检测到异常后的安全终止流程:先尝试一次轻干预(重置提示、清除局部上下文、要求换一种方式),干预无效再终止;终止时保留现场(最后状态、调用序列、指纹历史)供分析,并区分"真死循环"与"长思考"——阈值要与正常响应时间分布对齐,避免误杀。终止后进入降级路径:标记该任务为失败或回退到人工,同时记录告警与根因线索。这些检测应做成运行时内置能力(每步钩子),而非事后人工翻日志。

本题考察运行时异常检测。回答要给出三类异常各自的信号与检测算法(状态指纹、子序列识别、周期检测),并强调阈值校准与安全终止流程。能说明"先干预再终止"与现场保留是工程成熟度的体现。

#
★★★

8. 单 Agent 与多 Agent 在上下文同步、Token 消耗、调试和故障隔离上如何比较

单 Agent 与多 Agent 在上下文同步、Token 消耗、调试和故障隔离上如何比较?

  • 上下文同步:单 Agent 天然一致 vs 多 Agent 需显式同步
  • Token 消耗:多 Agent 的重复上下文化与通信开销
  • 调试与故障隔离的对比

上下文同步方面,单 Agent 只有一个上下文,状态天然一致,无需同步机制;多 Agent 每个 Agent 有独立上下文,共享信息必须显式传递(消息、共享存储、主控下发),存在同步延迟与不一致风险——Agent A 更新的事实 Agent B 可能还拿着旧版,需要版本号或写后读同步。Token 消耗方面,单 Agent 只维护一份上下文,但上下文随任务增长快速膨胀;多 Agent 总消耗通常更高——共享背景信息要在多个上下文里各存一份,加上消息传递与主控汇总的开销,且每个 Agent 的提示词与工具说明都会重复计费。

调试方面,单 Agent 链路简单、问题定位快,但上下文里信息混杂,难以隔离"是哪个环节坏了";多 Agent 每层可独立观测与单测,定位粒度细,但需要跨 Agent 的消息追踪(关联 ID 贯穿),调试工具复杂度上升。故障隔离方面,多 Agent 优势明显——子 Agent 崩溃只影响其职责范围,可单独重启与替换,主控可降级重分配;单 Agent 一处状态损坏往往需要整个任务重跑。工程结论:任务简单、强一致需求高时选单 Agent(省 Token、好调试);任务可拆解、需要并发与隔离时选多 Agent,但要为上下文同步与通信开销买单。

本题考察单/多 Agent 架构权衡。回答要按四个维度对比,明确"单 Agent 一致性与成本占优、多 Agent 隔离性与并行占优"的结论,并指出多 Agent 的上下文重复消耗是常被低估的代价。

#
★★★

9. Agent 任务被人工取消(cancel)时应如何优雅终止正在进行的工具调用和模型流

Agent 任务被人工取消(cancel)时,应如何优雅终止正在进行的工具调用和模型流?

  • 取消信号的传播:先停模型流,再停工具调用
  • 已提交副作用的收尾与登记
  • 取消后的状态标记与资源释放

优雅取消分四步:第一步传播取消信号——向 Agent 运行时发送取消请求,运行时立即停止新的模型调用调度,对正在流式生成的模型输出发起中断(终止流式连接,不再累积输出);第二步终止工具调用——对正在执行的工具调用按能力处理:支持取消的工具(HTTP 请求 AbortController、数据库查询取消)发送取消指令;不支持取消的工具(已提交的第三方异步任务)则登记"取消中"状态,等待其自然结束后丢弃结果、不进入下一步。第三步收尾已发生副作用——检查已完成的副作用列表,登记取消现场(执行到哪一步、哪些副作用已生效),必要时触发补偿(如撤销半完成的操作),并把部分结果(如有)保存供用户查看。第四步状态标记与资源释放——任务标记为 cancelled(区别于 failed),记录取消原因与操作者,释放会话、连接与临时资源,写入审计日志。

关键原则:取消不是"立即杀进程",而是"停止新工作 + 收尾已做工作 + 可恢复现场";取消点要设计在节点边界——模型调用和工具调用之间是安全的取消窗口,副作用执行中应等其完成或明确中断,避免留下"执行了一半"的脏状态。对无法取消的长时间外部调用,设置取消超时,超时后强制分离并登记待对账。

本题考察取消语义的工程实现。回答要给出传播、中断、收尾、标记的四步流程,并强调副作用收尾与节点边界取消点。能区分"可取消/不可取消"工具的处理是细节加分项。

#
★★★

10. Agent 状态机中的“并行分支”如何同步汇合,避免某个分支拖垮整体

Agent 状态机中的"并行分支"应如何同步汇合,避免某个分支拖垮整体?

  • 并行分支的发起与完成登记
  • 汇合策略:全等 / 部分完成 / 超时降级
  • 分支隔离:失败分支不影响健康分支

并行分支的实现:主状态发起多个分支(Fan-out),每个分支有独立的任务 ID 与完成标志,统一登记在汇合点的完成表;汇合点(Fan-in)维护"待完成分支集合",分支完成时更新登记并触发汇合检查。同步策略分三种:严格汇合——所有分支成功才继续,任何分支失败则整体失败,适合强依赖场景;部分汇合——设定最低完成数(如 5 个分支至少 3 个成功)或关键分支必达,非关键分支失败可降级为默认值;超时汇合——为每个分支设最大等待时间,超时未完成的分支按"失败"或"用缓存结果"处理,避免慢分支无限阻塞。

避免分支拖垮整体的关键是隔离与超时:每个分支有独立的执行容器与超时预算,慢分支超时后标记失败并从汇合集合剔除,不让它阻塞汇合;失败分支的异常不向健康分支传播(各自 try-catch、独立回滚);汇合后还要检查"部分失败的一致性"——已成功分支的产物若依赖失败分支的输出,需要补偿。实践上还要考虑 Token 预算在分支间的分配(避免一个分支烧光总预算),以及汇合点本身的幂等(重放时已完成分支不重复执行)。

本题考察并行编排的汇合控制。回答要给出 Fan-out/Fan-in 的登记机制、三种汇合策略与超时隔离手段。核心是"分支隔离 + 超时降级 + 汇合策略选择"三件套。

#
★★★

11. Workflow 的“幂等性”应做到哪一层(请求层、节点层、副作用层)

Workflow 的"幂等性"应做到哪一层?请求层、节点层、副作用层分别指什么?

  • 三层幂等的含义与防护对象
  • 各层的实现方式
  • 幂等层次的完整性与取舍

三层幂等由外到内:请求层幂等——同一个用户请求(或重试请求)只触发一次工作流,通过请求 ID + 去重表实现,防护重复提交与客户端重试;节点层幂等——同一工作流实例中每个节点只执行一次,通过(工作流 ID + 节点 ID + 执行序号)幂等键与执行登记表实现,防护重放、恢复与时间旅行导致节点重复执行;副作用层幂等——同一逻辑副作用只对外部世界生效一次,通过业务幂等键(订单号+动作)传递给外部系统(HTTP Idempotency-Key、数据库唯一约束、消息去重 ID)实现,防护即使节点重放也不会重复扣款、重复发信。

三层要完整搭配:只做请求层,进程重启后节点级重放仍会重复;只做节点层,外部系统收到重复调用仍可能重复生效;只做副作用层,节点本身的昂贵计算仍会重复消耗。工程实践通常三层全做,但按成本取舍——副作用层最难做(依赖外部系统配合),所以设计原则是"节点层防重放 + 副作用层防重复生效 + 请求层防重复提交",每层用幂等键 + 登记状态(未执行/执行中/成功/失败)驱动。判断幂等做到位的测试方法是:把同一输入重放多次,比对外部状态与产物是否与执行一次完全一致。

本题考察幂等的分层设计。回答要给出三层的定义、防护对象与实现方式,强调三层互补关系,并用"重放测试"作为验收方法。能指出副作用层依赖外部配合是最难层是工程认知的加分项。

#
★★

12. 持久化的 Agent 状态如何支持“时间旅行”调试,又避免回放时重复触发副作用

持久化的 Agent 状态如何支持"时间旅行"调试?又怎样避免回放时重复触发副作用?

  • 时间旅行的原理:基于 checkpoint 历史的分支回放
  • 回放与真实执行的区分:dry-run 模式
  • 副作用防护:回放用桩、幂等键、只读快照

时间旅行依赖"逐步持久化的状态历史":每个节点完成后的 checkpoint 都保留(而不是只留最新),形成一个状态时间线;调试时选择任意历史 checkpoint 作为起点,在其上重新执行后续节点,观察不同分支的结果——相当于"从任意时间点 fork 出一个平行执行"。实现要求:状态要能完整还原到任意历史点(版本化存储),节点代码要能在"回放上下文"中运行(不依赖真实外部状态),执行记录要区分"真实执行"与"回放执行"。

避免回放重复触发副作用的机制:回放运行时进入隔离模式——副作用节点不真正执行,而是从"副作用记录表"返回历史上该节点的真实结果(已经执行过的节点直接复用结果);对未执行过的节点做 dry-run,用桩或模拟器代替真实外部调用(HTTP 用 mock、数据库用事务回滚的副本、消息不真正发送);所有回放产生的调用打上"replay"标签,若配置允许写则必须走幂等键并在登记表标记来源为回放,防止污染生产数据。时间旅行的安全边界是"可观察、可重算、不可乱写",产品形态上提供"重放到此处"与"从此处新分支"两种入口,并明确提示回放结果只用于调试。

本题考察时间旅行调试的实现与安全。回答要讲清"历史 checkpoint 时间线 + fork 回放"原理,以及"副作用复用记录、dry-run、replay 标签"三层防护。核心是回放只观察不破坏真实世界。

#
★★

13. 跨进程、跨机的 Agent 任务(多副本部署)如何用分布式锁防止重复执行

跨进程、跨机的 Agent 任务(多副本部署)如何用分布式锁防止重复执行?

  • 分布式锁的选型与语义(Redis/数据库/ZooKeeper)
  • 锁的粒度:任务级、节点级
  • 锁的可靠性:超时、续租、防误删

多副本部署下同一任务可能被多个实例同时拾取,防重的核心是分布式锁 + 领取语义:任务入队后进入"可领取"状态,实例用分布式锁原子领取——只有拿到锁的实例能将该任务标记为"执行中"并绑定执行实例 ID,其余实例看到"执行中"则跳过。锁的选型:Redis 分布式锁(SET NX EX)延迟低、适合高吞吐;数据库行锁或唯一索引(任务 ID 唯一约束 + 状态字段)实现最简单且天然持久;ZooKeeper/etcd 提供顺序锁与故障感知,适合强一致场景。锁的粒度至少要到"任务级"(同一任务同时只有一个实例执行),精细到节点级可支持多实例并行执行同一任务的不同分支,但一致性维护成本更高。

锁的可靠性四要点:设过期时间防止持有者崩溃导致死锁;长任务要"续租"——执行中定期延长锁有效期(心跳),避免任务未完成锁已过期;释放时校验"锁归属"(用唯一 token 防止误删他人锁);领取后把状态写入持久存储(不只依赖锁本身),即使锁丢失,状态机与幂等键仍能兜底——锁是"并发控制的第一道闸",checkpoint 与去重表是"最终防线"。监控上要记录锁等待时间与争用率,锁等待超时应告警而非无限阻塞。

本题考察多副本下的并发防重。回答要覆盖锁的选型、粒度与"领取-续租-防误删-持久兜底"的可靠性设计。强调锁不是唯一防线、状态机与幂等表兜底是关键认知。

#
★★

14. Agent 工作流中的错误传播策略,哪些错误重试、哪些回退、哪些直接失败

Agent 工作流中的错误传播策略应如何设计?哪些错误重试、哪些回退、哪些直接失败?

  • 错误分类:瞬时/持久/业务性
  • 三类处理策略:重试、回退、失败
  • 重试参数与回退条件的界定

策略的第一步是错误分类:瞬时错误(网络超时、限流、服务暂时不可用、连接重置)具备"重试可能成功"的特征;持久错误(参数非法、权限不足、数据不存在、schema 不匹配)重试必然失败;业务性错误(业务规则不满足、状态冲突)需要回到上游重新决策。分类依据是"重试是否有收益":有收益→重试,无收益→走其他路径,无法判定→按持久错误处理并记录。

三类处理:重试——对瞬时错误采用指数退避 + 抖动,重试次数与退避上限按外部系统限流策略配置,重试期间任务状态标记"重试中"且幂等键不变;回退(fallback)——对"路径失败但任务可继续"的错误,切换到备选方案(换工具、换模型、降级为默认值、走简化流程),回退要记录原因与影响范围;直接失败——对持久错误、重试耗尽后的错误、不可逆操作前的错误,立即终止该分支,标记失败原因,触发补偿或人工接管。设计原则:重试要"有限且有界",回退要"可解释",失败要"有现场";错误传播路径应显式建模在状态机里(每条边定义错误处理策略),而不是靠全局 try-catch 兜底。

本题考察错误传播策略设计。回答要给出错误三分类与策略映射(瞬时→重试、路径性→回退、持久→失败),并强调策略显式建模在状态机边上的做法。能说明重试参数与退避细节是加分项。

#
★★

15. 长任务(>1 小时)应如何定期回报进度(heartbeat)

长任务(>1 小时)应如何定期回报进度(heartbeat)?

  • heartbeat 的内容:存活信号 + 进度信息 + 阶段明细
  • 发送机制:定时心跳 + 事件驱动
  • 心跳的消费方:用户展示、监控告警、任务管家

长任务的心跳要包含三类信息:存活信号(任务还在运行、执行实例正常)、进度信息(当前阶段、已完成步骤/总步骤、预计剩余时间)、关键事件(里程碑完成、异常与恢复、外部依赖等待)。发送机制采用"定时心跳 + 事件驱动":固定间隔(如每 30-60 秒)发送一次状态快照,保证存活可感知;阶段切换、里程碑、错误恢复等关键事件即时推送,让用户看到"有进展"而不是"卡住"。

心跳的消费方决定内容设计:用户侧——展示进度条、当前阶段说明、已产出摘要,让用户能判断任务是否健康、可否离开,并提供"取消/暂停"入口;监控侧——心跳超时(如 3 个周期未收到)触发告警,区分"任务卡死"与"网络中断",超时超过阈值自动重试或通知人工;任务管家——心跳同时作为续租信号,用于扩展锁有效期。心跳数据与 checkpoint 解耦:心跳是"轻量状态广播"(可丢、可延迟),checkpoint 是"权威持久化"(必须可靠),心跳丢失不意味着任务失败,只有心跳持续缺失且 checkpoint 停滞才判定异常。

本题考察长任务的进度可见性设计。回答要给出心跳的信息构成、双通道发送机制与三类消费方的差异化设计。核心是"心跳轻量可丢、checkpoint 权威可靠"的职责分离。

#
★★

16. 任务队列(Queue)与工作流引擎(Workflow Engine)在 Agent 长任务编排上如何分工,何时仅靠队列即可、何时需要状态机与 DAG

任务队列(Queue)与工作流引擎(Workflow Engine)在 Agent 长任务编排上如何分工?何时仅靠队列即可,何时需要状态机与 DAG?

  • 队列的定位:异步解耦、削峰、重试载体
  • 工作流引擎的定位:状态管理、依赖编排、恢复
  • 选型判据:任务有无依赖图与长生命周期状态

队列解决"异步执行与解耦":任务提交后立即返回,消费者异步处理,队列负责顺序、重试、死信与削峰;但队列本身不关心任务内部的状态与步骤依赖——一个任务在队列里就是一个消息,消费完即结束。工作流引擎解决"多步骤编排与状态管理":维护任务的状态机、步骤依赖(DAG)、checkpoint、人工节点与恢复逻辑,能够表达"步骤 B 依赖步骤 A 的结果,C 与 D 可并行"这类结构。

选型判据看两点:任务是否有依赖图——多个步骤存在先后与并行依赖(需要 DAG),就需要工作流引擎;单个独立步骤、无内部结构,队列即可。任务是否长生命周期——数小时到数天的任务需要断点恢复、进度查询与取消,工作流引擎天然支持;秒级短任务队列足够。实践上两者常组合:工作流引擎把每个"可执行的节点"作为消息投递到队列,队列负责执行弹性与重试,工作流引擎负责编排与状态——即"队列做执行层、引擎做编排层"。只用一个队列却硬编码状态机逻辑(消息里塞阶段字段、人工轮询推进)会在任务种类增多后失控,这时应升级为工作流引擎。

本题考察队列与工作流引擎的分工。回答要讲清两者定位(执行 vs 编排)、选型判据(依赖图、生命周期),并给出"引擎编排 + 队列执行"的组合架构。能指出"用队列硬编码状态机"的坏味道是加分项。

#
★★

17. 长任务为何需要异步提交、状态查询、通知、取消和过期清理,而不能保持一个 HTTP 连接

长任务为何需要异步提交、状态查询、通知、取消和过期清理,而不能保持一个 HTTP 连接?

  • 长连接的问题:网关超时、连接资源、客户端断线
  • 异步任务五要素:提交、查询、通知、取消、清理
  • 异步化与事件驱动架构的配合

长任务不能保持 HTTP 连接的原因:一是网关与代理有连接超时(通常几十秒到几分钟),长任务(数小时)必然被中间层掐断;二是长连接占用连接资源(连接数、内存、端口),高并发下资源被长任务耗尽;三是客户端随时可能断线(浏览器关闭、网络切换),保持连接无法保证任务继续;四是连接期间无法处理认证刷新、负载均衡与实例重启。因此必须"提交与执行解耦":提交接口只做校验与入队,立刻返回任务 ID。

异步任务体系包含五要素:异步提交——返回任务 ID,任务后台执行;状态查询——按任务 ID 查询进度与结果(轮询或订阅);通知——任务完成/失败/关键节点通过 webhook、WebSocket、邮件等主动推送,替代客户端空轮询;取消——提供取消接口,优雅终止;过期清理——任务结果与临时资源设保留期,超期自动归档或删除,防止存储无限增长。通知与查询组合使用:查询接口兜底(断线后重新连接可查询),通知保证实时性。这个模式本质是"请求-响应 + 任务状态机 + 事件通知"的标准异步范式。

本题考察异步任务架构的完整性。回答要先讲清长连接的三类问题(超时、资源、断线),再给出五要素体系及查询与通知的组合。核心是"提交与执行解耦 + 状态可查询 + 事件可通知"。

#
★★

18. Time-travel 回放如何帮助定位错误节点,回放时怎样避免再次触发真实副作用

Time-travel 回放如何帮助定位错误节点?回放时怎样避免再次触发真实副作用?

  • 回放定位错误的原理:二分定位 + 分支比对
  • 回放环境的隔离设计
  • 副作用防护:结果复用、mock、标签

Time-travel 回放定位错误的原理:状态历史记录了每个节点执行前后的完整快照与产物,定位时从任务起点逐步回放,二分查找"第一个产出与预期不符或状态异常的节点";因为每步都有快照,可以精确对比"该节点输入相同但输出不同"的情况,从而把错误收敛到具体节点与具体输入上;配合分支回放,还能对比同一输入下不同分支选择的后果,定位"是决策错了还是执行错了"。相比只保留最终结果,时间旅行把"失败现场"变成了"可反复检查的实验室"。

回放避免真实副作用的三层防护:第一层结果复用——历史中已执行节点的副作用结果从记录表直接读取,不重新执行;第二层环境隔离——未执行节点的外部调用全部注入替身:HTTP 用可录制回放的 mock(录真实响应、回放时重放)、数据库用事务回滚或副本库、消息与邮件走测试通道,回放上下文标记为 dry-run;第三层写入防护——回放过程中任何"真实写"动作都被拦截(配置文件开关强制只读),若业务上必须验证写入,则走专门沙箱环境并打 replay 标签。验收标准:回放任意次数,外部系统状态零变化。

本题考察回放调试的安全实践。回答要讲清二分定位与快照对比的定位方法,以及"复用、mock、只读防护"三层机制。核心是"回放可观察不可破坏",验收标准是外部零副作用。

#
★★

19. 为什么“自动恢复”不一定好,应如何让用户感知任务仍在运行而非“卡死”

为什么"自动恢复"不一定好?应如何让用户感知任务仍在运行而非"卡死"?

  • 自动恢复的隐患:掩盖问题、重复副作用、用户无感知
  • 恢复策略的分级:自动/确认后恢复/人工介入
  • 用户感知设计:进度、心跳、恢复提示

自动恢复不一定好的原因:一是掩盖问题——频繁自动恢复会掩盖系统性故障(外部服务持续不可用),让问题在后台反复重试空耗资源,不如及时暴露;二是副作用风险——无感知的自动恢复可能在用户不知情时重复执行或部分重放,产生用户不可预期的结果;三是信任问题——用户看到任务"失败又自己成功"或长时间无反馈,会怀疑系统可靠性。因此恢复要分级:低风险、瞬时错误可自动恢复;影响面大或不可逆的节点,恢复前需用户确认或至少显著告知;反复失败的任务应停止自动恢复,转人工诊断。

用户感知设计上,要让"运行中"与"卡死"可区分:持续更新的进度信息(当前阶段、完成度、最近动作、预计剩余时间)、心跳时间戳("3 秒前还在工作")、以及卡顿时的主动提示("正在等待外部系统响应,已等待 2 分钟");长时间无进展时主动推送"仍在运行"的保活通知。恢复发生时也要告知用户"任务曾中断,已从 X 处自动恢复,跳过步骤 Y",配合可查询的恢复日志。原则是"自动恢复可以,但要看得见、可解释、能叫停"。

本题考察恢复策略与用户体验的平衡。回答要先论证自动恢复的三类隐患,再给出分级恢复策略与用户感知设计。核心观点:自动恢复应以"可感知、可解释、可干预"为前提。

#
★★

20. 持久化的 Agent 状态如何与外部系统状态(数据库、第三方 API)保持一致,防止状态漂移与重复副作用

持久化的 Agent 状态如何与外部系统状态(数据库、第三方 API)保持一致,防止状态漂移与重复副作用?

  • 状态漂移的成因:双写、异步、崩溃窗口
  • 对账机制:定期校验 + 事件补偿
  • 单一事实源原则与幂等外呼

状态漂移的成因:Agent 状态与外部系统各自独立变更,双写时一写成功一写失败、异步调用时序错乱、崩溃窗口(checkpoint 写入前副作用已生效)都会造成两边不一致。防止漂移的原则是"单一事实源":外部系统(数据库、第三方 API)是业务事实的权威,Agent 状态只是"执行视图",恢复时以外部状态为准回填 Agent 状态,而不是反过来。所有外呼都要携带业务幂等键(如订单号+动作),让外部系统可去重,这是防止重复副作用的第一道闸。

一致性机制三件套:写序约定——统一"先记后做"或"先做后记"(先登记意图再执行,执行后按结果更新状态,崩溃后按登记表对账);对账任务——定期(或恢复时)把 Agent 状态与外部状态逐项比对,发现差异按规则修复(外部有而本地无→补记;本地有而外部无→检查是否需补偿或回滚);事件补偿——对"半生效"操作(如已扣款但任务未完成)执行补偿动作(退款、撤销、标记待人工),补偿本身也要幂等。监控上对账差异要告警,区分"可自动修复的时序差异"与"需要人工裁决的业务差异"。

本题考察跨系统一致性。回答要覆盖漂移成因、单一事实源、写序约定、对账与补偿四层机制。核心是"外部系统是权威、Agent 状态是视图、幂等与对账保一致"。

#
★★

21. 事件溯源与状态机快照两种持久化在 Agent 场景下各有哪些工程取舍

事件溯源与状态机快照两种持久化在 Agent 场景下各有哪些工程取舍?

  • 两种模型的核心差异:事件日志 vs 状态快照
  • 事件溯源的优势:完整历史、可重放、审计
  • 快照的优势:读取快、实现简单、恢复直接

事件溯源(Event Sourcing)把每次状态变更记录为不可变事件(追加日志),当前状态由事件重放得到,历史完整可审计、可重建任意时刻状态、可修正历史后重放;状态机快照(Snapshot)周期性保存当前状态的完整副本,读取与恢复直接加载,实现简单、延迟低。工程取舍:事件溯源的优势在"审计与时间旅行"——Agent 场景需要回溯"模型为什么做出某决策"、复现错误、回放调试,事件日志是天然素材;代价是重放开销(长任务事件多时重放慢,需要快照压缩)、事件 schema 演进管理、查询当前状态需要物化视图。

快照的优势在"简单高效"——恢复快、读取即所得、无需重放逻辑;代价是历史缺失——只有最新状态,无法回答"当时为什么是这样"的问题,且崩溃窗口内未快照的变更会丢失。Agent 场景的工程实践是"混合":以事件日志为权威记录(完整历史、审计与重放),定期生成快照做压缩(加速恢复),恢复时"最近快照 + 快照后事件重放";变更以事件形式写入、状态以快照形式读出(CQRS 思想)。选型判据:审计与调试要求高、状态演进复杂→事件溯源;要求简单快速、历史价值低→快照即可。

本题考察持久化模型的选型。回答要对比两者的本质差异与优劣,并给出"事件为权威 + 快照做压缩"的混合实践。核心是"审计需求决定是否引入事件溯源,快照解决重放性能"。

#

22. LangGraph Durable Execution、CrewAI Flows 与 AutoGen Actor 模型应按哪些需求选型

LangGraph Durable Execution、CrewAI Flows 与 AutoGen Actor 模型应按哪些需求选型?

  • 三种机制的核心抽象:图 + 持久执行 / 流程 + 事件 / Actor + 消息
  • 选型需求维度:持久化、并发、协作模式
  • 与团队与生态的匹配

三者抽象不同:LangGraph Durable Execution 以"状态图 + 持久化执行"为核心——节点与边构成显式 DAG,checkpoint 保证进程重启续跑,适合步骤明确、需要断点恢复与确定性编排的任务;CrewAI Flows 以"流程 + 事件驱动"为核心——用 Python 代码声明流程与条件,事件驱动步骤衔接,开发体验接近普通代码,适合团队熟悉 Python、希望低门槛编排的场景;AutoGen Actor 模型以"Actor + 消息传递"为核心——每个 Agent 是独立并发主体,通过消息异步交互,适合需要真实并发、动态对话式协作的场景。

选型维度:持久化与恢复要求高(长任务、中断续跑)→ LangGraph;编排简单直观、团队协作为主、任务结构偏固定→ CrewAI Flows;高并发消息交互、需要动态多 Agent 对话、分布式部署→ AutoGen。此外还要考虑:语言生态(三者都支持 Python,但 AutoGen 的 .NET 版本等生态差异)、可观测性配套(LangGraph 有 LangSmith 等)、团队已有技能栈与维护成本。选型不是"谁更好"而是"任务结构匹配哪种抽象"——确定性图、事件流、消息并发分别对应三类典型任务。

本题考察编排框架选型。回答要讲清三种抽象的本质差异与适用任务类型,再从持久化、并发、协作模式等需求维度给出选型映射。核心是"用任务结构与需求匹配抽象"而非横向比功能。

#

23. Agent 任务的 SLA 应如何定义(成功率、延迟、成本)

Agent 任务的 SLA 应如何定义?成功率、延迟、成本分别如何设置指标与阈值?

  • SLA 指标选择:成功率、延迟分布、成本上限
  • 阈值设定:按任务类型分层
  • 监控与违约处理闭环

SLA 定义分三个维度:成功率——定义"成功"的判定标准(产出通过验收规则,而非"模型没报错"),按任务类型设目标(简单任务 99%+,复杂开放任务 85%-95%),并统计"一次成功率"与"含重试成功率"两个口径;延迟——用分位数而非平均值(P50 用户体验、P95 常见故障、P99 极端情况),按任务复杂度分层(实时问答 P95 < 3s,深度研究 P95 < 10min),并分解"排队延迟、模型调用延迟、工具延迟"三段以便定位;成本——设单任务成本上限(Token 预算 + 外部调用预算)与总预算月度上限,防止长尾任务烧穿预算。

SLA 落地要点:指标要可采集、可归因(按任务类型、模型、工具维度聚合);阈值与业务价值挂钩——高价值任务可放宽成本、收紧成功率,反之亦然;建立违约闭环——SLA 违例自动告警、归因、复盘,把反复违约的任务类型标记出来做专项优化(改提示词、换模型、加规则)。SLA 还应包含"可恢复性"目标(任务中断恢复率、恢复时长),因为长任务场景下"成功完成"不等于"一次跑完"。SLA 不是纸面数字,要配监控面板与定期的 SLO 复盘。

本题考察 Agent 服务 SLA 设计。回答要给出成功率、延迟(分位数)、成本三维指标及分层阈值,并强调可采集可归因与违约闭环。能提到"一次成功率与含重试成功率双口径"是加分项。

#

24. Agent 任务回滚(rollback)应做到什么粒度,整个任务、单步、状态变更

Agent 任务回滚(rollback)应做到什么粒度?整个任务、单步、状态变更分别适用什么场景?

  • 三种粒度的语义与适用场景
  • 回滚的实现:补偿 vs 状态还原
  • 粒度选择与成本权衡

三种粒度对应不同需求:整个任务回滚——把任务恢复到初始状态或标记为"从未发生",适合任务整体失败、产物不可用、用户要求完全撤销的场景,实现上是重置任务状态 + 执行全部已生效副作用的补偿(逆向操作);单步回滚——回退到某个历史 checkpoint,重新执行后续步骤,适合"定位到错误节点后修正重跑"的场景,实现依赖版本化状态与 checkpoint 历史;状态变更级回滚——只撤销某次状态变更(如撤销某条写入、恢复某个字段),最小粒度,适合局部错误不影响整体、无需重跑的场景,实现上是变更级 undo 日志或补偿动作。

粒度选择的权衡:粒度越细,回滚越精准、影响越小,但需要越多的版本记录与补偿逻辑,复杂度和存储成本越高;粒度越粗,实现越简单,但可能把"不需要回滚的部分"一并撤销。工程实践的分层:默认"单步回滚"(以 checkpoint 为单位,够用且实现成本适中);高风险操作保留"变更级补偿"(每个副作用定义逆向操作);"整个任务回滚"作为兜底手段,同时配套"回滚前确认"——因为回滚本身也有副作用(撤销通知、退款等),需要人工确认与留痕。回滚粒度要与"幂等 + 补偿 + checkpoint"体系一体设计。

本题考察回滚粒度设计。回答要给出三种粒度的语义、适用场景与实现方式,并说明"粒度越细越精准但成本越高"的权衡与分层实践。核心是回滚粒度与幂等补偿体系的一体化设计。