READ · UNDERSTAND · TRANSFER
阅读理解,按需巩固
先沿着原理、问答和迁移案例阅读。需要检查理解时,再切换巩固练习或展开个人记录。
核心知识 · 工作流升级的结构兼容与业务兼容
先理解核心原理
先备概念:Schema 与序列化、版本路由、持久化状态不变式
旧状态能反序列化只是结构兼容;安全恢复还要求新代码保留原步骤、批准、预算和工具语义。发布需要为未完成运行定义版本归属与迁移边界。
数据库保存状态不保存解释它的语义
字段 amount 从元改成分,JSON 类型都还是数字,但继续执行会产生百倍错误。节点重命名可能让等待任务的恢复目标不存在,工具契约改变可能让旧回执无法理解。记录 workflow、state_schema、tool_contract 和关键配置版本,不能让所有旧任务自然落到最新逻辑。
兼容不只有一条路径
新增可选字段与默认值适合小型兼容变更;明确语义变更使用确定性迁移;难以迁移的长期任务保留旧执行器收尾。LangGraph 当前文档区分已结束与中断线程的拓扑迁移限制,状态键改名会丢失已有键的保存状态,不兼容类型也可能出问题。框架允许某改动不等于业务允许,仍要检查批准与操作身份。
迁移作为独立数据操作
迁移输入原快照,输出新状态和记录,不调用外部写工具、不重复消耗预算。用 source_version 条件写和原子快照切换防重复及半途宕机,原状态在成功前保留。夹具覆盖运行中、待审批、unknown 和完成状态,验证已确认回执、取消状态、剩余预算及批准绑定不丢失。
回滚需要双向契约
代码回滚不会逆转新状态,也不会撤回外部动作。可以先采用扩展兼容、双读阶段再收缩,或将新状态留给新执行器收尾并暂停新入口。移除旧版本前统计未完成任务与版本分布。反例是灰度通过的新任务都成功,但一条等待三天的旧审批恢复时执行了新动作;灰度要覆盖旧任务恢复而非只测新流量。
回到问题:怎样回答?
Checkpoint 保存的是状态,不保证未来代码仍理解它。每个运行应记录工作流、状态 Schema、工具和配置版本,兼容版本可直接恢复,不兼容时通过明确迁移或旧 Worker 处理。迁移前保留原始快照并验证不变式,不能让模型猜旧字段含义。回滚需要考虑新状态是否还能被旧代码读取。
实现与取舍
变更可能破坏哪些东西
节点重命名、状态字段拆分、枚举含义变化、工具结果格式变化都可能影响恢复。即使 JSON 仍可反序列化,旧的金额单位或状态语义也可能不再适用。先定义工作流版本和状态 Schema 版本,任务建立时固定版本,部署不能静默把所有旧任务映射到最新逻辑。
三条可选路径
小型兼容变更采用新增可选字段与默认值;需要改变含义时编写确定性迁移;高风险长期任务可以留在旧 Worker 上运行到完成。迁移函数输入旧状态、输出新状态和迁移记录,不执行业务副作用。对未知字段和不支持版本明确拒绝,而不是用空值继续跑。
迁移怎样验收
从脱敏快照构建恢复夹具,包含运行中、等待审批、结果未知和已完成任务。验证步骤完成记录、预算消耗、批准绑定和工具回执不丢失。迁移本身要可重复执行或通过版本条件只执行一次。新状态保存成功前保留旧状态,避免迁移中断后无法恢复。
回滚的边界
代码回滚不自动逆转数据迁移。提前说明哪些版本可双向读、哪些必须继续由新 Worker 收尾,以及如何暂停新任务。发布前统计未完成运行按版本分布,清空或迁移后才移除旧执行器。面试者应提出“发布不兼容变更时有任务仍在运行”这一现实约束。
工程推演
- 场景
- 面试假设:将 status=waiting 改成多个等待子状态,旧任务仍停在审批。
- 设计决策
- 按状态版本确定迁移,保留批准、预算和动作引用。
- 验证目标
- 旧任务能安全恢复或明确阻塞,不绕过审批。
- 适用边界
- 某些语义变化无法自动迁移,需要人工处理或保留旧运行环境。
连续追问与解答
沿着问题的前提和约束继续向下读。先理解参考解答,再尝试收起答案,用自己的话解释因果和取舍。
第 1 层节点名称改动会影响什么?
从状态字段兼容进入拓扑恢复地址的兼容。
参考解答
等待任务保存的下一节点可能仍指向旧名称,改名或删除会使恢复无目标或进入错误路径。框架迁移能力取决于线程状态;保留别名适配或按旧工作流版本路由,再迁移待执行位置。节点语义变化同样需要业务版本判断,不能只给新节点换个旧名字。
第 1 层迁移执行一半宕机怎么办?
迁移过程本身也需要恢复与幂等。
参考解答
小快照迁移在本地事务中原子提交,新状态和迁移版本同时成功;大规模迁移逐个运行处理,使用唯一迁移 ID 与条件写记录进度。宕机后重做未完成项,已完成项返回现有结果。原快照保留到验证结束,迁移函数不包含业务副作用。
沿着这个回答继续深入
第 2 层迁移需要改三张表,分三次保存可不可以?
父问解决单快照原子性后,多表约束扩大了事务边界。
参考解答
如果三张表共同表达批准、预算和执行位置,分次暴露会产生不一致状态。能放一个事务就一起提交;无法跨存储原子提交时,先写新版本不可见数据,再用可信指针切换,并记录补偿或重试进度。迁移中间态不能被 Worker 当可恢复任务。
沿着这个回答继续深入
第 3 层新状态已切换,但验证发现批准丢失,能补一个 approved=true 吗?
切换后的验证失败触及授权不变式,需要事实修复而非字段补齐。
参考解答
不能凭运行曾经等待推断批准已存在。回到保留的原快照与审批账本核对真实批准;无法证明就阻断恢复并重新审批。修复保留 actor、动作版本与有效期,验证其他不变式。迁移错误不能用默认成功状态掩盖。
第 1 层代码回滚为何不等于状态回滚?
发布回退涉及运行数据而非仅部署包。
参考解答
数据可能已变成旧代码不理解的结构或语义,旧代码也可能误解释新字段。回滚前验证读取兼容矩阵;单向迁移后保留新执行器收尾或暂停受影响任务,不强制加载。外部已完成动作独立记录,不能通过回滚把它当未执行重试。
举一反三:条件变了,怎样推导?
先找出改变的条件,再判断原方案中哪些前提仍成立。下面的案例是教学推演,便于将原理迁移到新问题。
新增可选观测字段
改变的条件:结构扩展,不改变业务步骤
延伸问题:要让所有旧任务重新迁移一次吗?
推导与参考解答
若默认值明确且不影响批准、预算或控制流,可以按缺省读取,不必昂贵全量迁移;仍确认序列化器、校验器和旧代码容忍该字段。未知观测值不能填成“验证成功”。兼容变更也记录版本以便追踪。
保持不变的原理:迁移成本随语义变化而定,结构扩展不能制造虚假的事实。
工具从查询改为自动提交
改变的条件:字段结构未变,但副作用变化
延伸问题:旧快照还能直接进入同名节点吗?
推导与参考解答
不能据名字和类型相同认定兼容。原任务可能只授权读取,新逻辑增加外部写动作,应保持旧路径或重新审阅批准。给工具语义版本与流程行为版本分开记录;迁移不能偷偷扩大操作范围。
保持不变的原理:结构兼容不替代行为与授权兼容,持久化状态不能升级用户意图。
易错点
- 永远用最新代码加载所有快照
- 迁移中执行外部写操作
- 丢弃旧状态的未知字段
参考资料
依据公开技术资料设计;参考资料支持技术机制,场景与评分标准为本站设计,不代表某公司面试原题。 新增问答与迁移案例用于原理讲解,来源核查与案例运行验证分别记录。
检查自己理解到哪一步
读完后可以对照这些标准解释原理、边界和取舍。掌握程度由你自评;需要进一步验证时,再完成下方小任务。
- 基础达标
- 能区分持久化状态版本与工作流代码版本,并在恢复时检查。
- 中高级信号
- 能设计确定性迁移、恢复夹具和旧 Worker 并存。
- 资深信号
- 交代单向迁移、审批不变式和发布回滚边界。
巩固练习 按需完成 · 建议 15 分钟
为 waiting 状态拆分设计 v1 到 v2 迁移,保留原批准与预算。
展开验收要求与检查点
- 旧快照可追溯
- 重复迁移不重复消耗预算
- 无法判断的状态明确阻塞
重点检查
- 知道持久化不等于跨版本兼容
- 有明确迁移与旧版本策略
- 回滚考虑数据状态