长周期代理怎样恢复任务并核对执行结果
长周期代理怎样恢复任务并核对执行结果
公开原文:Long-horizon agents and durable execution
一项工作如果要等多个系统和参与者陆续回应,模型返回一段合理的答案只是开始。过程中的真正难题,是在下一次响应到达时弄清已经做过什么、现在仍能做什么,以及哪些结果仍需查证。系统重启、外部接口返回超时和等待期间发生的业务变化,会把这三个问题混在一起。一个能恢复执行的程序,如果不能分辨已完成动作与尚未证实的动作,恢复得越顺畅,反而越容易把错误传播到后续环节。
原文如何区分长周期任务与连续推理
原文所讨论的周期,指从提出目标到外部结果出现的经过时间。其采购示例包含询价、人员批准、发出订单和等待到货。等待可能占据绝大部分时间,进程无需一直保持运行,模型也无需在沉默期间不断推理。作者介绍的持久化执行模型,会记录与外界交互的步骤结果。程序在故障后重新运行时,可以利用记录重建状态,并跳过已经留下完成记录的外部步骤。Temporal 和 Cloudflare Workflows 是文章讨论的实现例子,具体接口不同,但都提供记录步骤与等待事件的机制。
作者还强调,恢复程序状态与恢复业务的正确性是不同的问题。执行器可以知道某次请求没有留下成功记录,却无法由此知道对方没有处理请求。等待期间的价格、库存或授权也可能发生变化。文章由此引入幂等处理、外部事件、状态变化和运行中流程版本等问题。这是一篇架构论述,通过工程示例解释各项机制承担的职责,没有给出跨行业的节省比例,也没有把示例运行当成通用的可靠性证明。
编辑分析:把意图、动作和结果作为三种记录
设计时可以从一件简单的事开始:同一次业务操作会留下哪些可以相互核对的证据?模型提出一项动作,属于意图。执行服务收到指令并向外部系统发出请求,属于动作。外部系统生成了可查询对象,或业务负责人确认目标已经达成,才属于结果。三种记录可能紧邻出现,也可能隔很长时间。把它们归并为一个成功字段,会丢失对故障最有用的信息。只保存模型的说明同样不够,因为自然语言记录可以漏掉某次调用,也可能把预计结果当成事实。
意图应保存可识别的业务对象、当时适用的授权和产生意图的上下文版本。动作应保存稳定的操作标识、请求类别和重试状态。结果应关联外部对象或独立证据,并注明何时观察到。流程引擎里的步骤状态为这些记录提供了组织方式,不过同一个请求在客户端、网关和外部系统里可能拥有不同标识。团队需要事先定义如何把它们对应起来,否则恢复时容易在多个日志里找到看似合理、实际指向不同对象的记录。
确认完成的证据取决于目标。接口返回接受,通常只能说明对方进入了处理流程。如果任务目标是生成可用文件,还需要确认文件已就绪、能读取、属于预期版本。若目标是撤销一个旧权限,发出撤销命令之后还应核对权限表或在可控环境执行只读验证。业务层应在提交前写清完成条件,执行器据此选择核查方法。这样一来,出现模糊回复时,代理有明确规则可以依靠,而不必从一句看起来积极的状态文本推断任务已经结束。
重试需要先判断动作能否安全重复。查询通常可以重新发起,但即使是查询,如果在循环中不断运行,也可能耗尽配额或触发限流。创建操作更需要稳定的幂等标识。标识应绑定同一份业务意图,由重试沿用,而不是每次重新计算一个随机值。若参数发生了实质变化,应创建一项新意图并明确与旧意图的关系。否则,去重层可能吞掉真正的变更,或把两个不同对象错误合并。
外部接口有时只保留短期幂等记录,长期等待会跨过这个期限。此时,恢复后应先通过对方支持的查询手段核对对象状态。若对方既无幂等能力也无可靠查询接口,系统就应把未知结果留给人工核对,同时保持下游动作暂停。流程可以记录一项未解决的任务,并继续处理不相关的分支。对已提交动作盲目重试,可能造成两个外部对象都存在,后续自动对账又会误以为其中一个属于别的请求。
假设案例一:发布一份跨系统的研究数据集
假设一个研究团队要把整理完成的数据集发布到公共存储和目录服务。目录登记需要审核,审核过程中人员可以要求补充说明。数据上传与目录提交分别使用不同的服务,审核通知通过回调到达。团队希望代理完成材料收集、提醒和状态核对,让人员集中处理资料是否适合公开这一判断。这个例子只用于分析系统行为,没有对应的真实数据集或实测结果。
任务启动时先记录待发布版本及其校验值。发布前的审查结论要绑定这份版本,也要绑定允许公开的字段范围。上传工具可以使用同一个版本标识查询和重试,但目录服务可能为每次登记生成新的记录。如果发送登记请求后网络中断,应先用已有外部引用或对应的校验值查找记录。查到与本次意图相符的已登记对象,再把它与任务绑定。查到多个对象时,由负责人确认保留哪一个,代理不自行猜测对象归属。
如果审核意见在同一时段通过邮件和回调各到一次,事件处理层应按同一审查记录去重,而不根据投递渠道分别推进。反过来,审核意见确实被更新时,应通过版本或者事件序号确认哪个结论生效。延迟到达的旧意见不能覆盖较新的拒绝或撤回。即便回调重复无害,事件处理器也要记录收到时间和来源,以便发现投递顺序与业务发生顺序不一致。处理的目标是保留可解释的因果关系,不是要求所有外部系统都按同一个时钟运行。
假如审核通过后,团队替换了一个文件,旧批准只针对原版本。代理可以继续协助准备新一轮材料,但需要重新核验公开范围。此时按执行历史直接跳过审批,是把程序上一步的完成误当成对所有后续版本都有效的授权。为了使这一点可以测试,维护者可构造三个场景:批准后内容不变、批准后只修改展示说明、批准后替换真实数据。是否需要重新审查应由各类改动对授权范围的影响决定,并写进流程规则。代理只负责应用能够核对的规则。
这个案例还有反向风险。如果每次格式修订都让所有人重新走完整审核,参与者会越来越倾向于绕过流程。把批准范围绑定到真正决定公开风险的资料,可以减少重做。附加的便利措施也应有边界。例如代理可以提示审核人存在未处理请求,但不能因为任务等待太久就自行降低权限门槛。长周期自动化的收益来自减少重复协调,而批准的价值恰恰在于让有责任的人保有实质性的停止能力。
假设案例二:跨时区安排一个共享设备的维护窗口
假设多个实验团队共享一套测试设备。代理可以协调停机时间、收集设备使用安排并检查维护完成情况。团队分布在不同时区,有人通过日历更新,有人通过消息回复,现场维护者另有操作系统。若程序把某个时间段标为等待确认后离线,恢复时应处理最新日历变更、取消请求和现场检查状态。只按照最先看到的同意回放,可能导致维护开始时设备仍在使用。
先把需要严格遵守的条件列出来,例如设备必须处于空闲状态,现场人员必须确认有能力恢复,维护窗口尚未过期。将这些条件放在操作前的检查里,而不是只写在提醒文本里。模型可以理解自然语言中的时间偏好,也可以推荐新的日期,但设备是否空闲应由可信状态确认。即使模型正确概括了上周的会议纪要,那份纪要也不能证明眼下设备已释放。
这一流程可以使用固定的超时规则。到达约定时间前仍有关键确认缺失,就进入延期判断,并记录哪个条件没有满足。若系统同时收到延期和旧确认,应按状态版本处理,确保旧事件不能使任务重新进入正在执行的阶段。需要再次发起维护时,应有新的执行窗口与操作标识。旧窗口的日志保留为证据,并明确它与新窗口的区别,便于在事后辨认哪个动作发生在哪一轮。
恢复操作同样需要验收。现场系统返回命令完成,和共享设备重新通过测试,是不同层次的结果。可以将一项小范围健康检查作为恢复后的独立动作,并要求记录预期输出。如果检查失败,流程保持故障状态,同时把已经成功的前置步骤显示给负责人。这样便于人工接管,也防止程序把“已执行恢复命令”误作“可以开始正常预约”。
将所有信息持续交给模型并不能简化这些条件。设备事件可能很多,完整历史不适合每次请求都发送。可以生成一份面向决策的当前视图,包含最近有效的预约、关键审批和未解决的风险,而持久化系统保留细节供查询。摘要如果与权威状态冲突,应以能够独立复核的状态记录为准。代理还应能解释信息缺失的原因,例如设备监控暂时不可用,或者消息提到了某个对象但无法把它映射到实际设备。这比填补缺失更能帮助负责现场操作的人判断下一步。
如何验证恢复行为和版本变更
最容易展示的测试是让进程在两个步骤之间停止,然后确认它可以重新启动。真正需要优先验证的边界,是外部调用已经生效但完成记录还没有写入的短暂区间。此时模拟网络中断,并观察恢复后是先查询还是直接重复动作。另一类测试要把同一个事件以不同顺序发送多次,包括在任务取消后到达的旧消息。检查目标应是外部对象数目、最终状态和实际触发次数,而不是只看流程引擎界面上有没有绿色标记。
版本变更需要复用真实形状的旧历史,但可以用去标识化的合成数据。将早期运行记录交给新版流程,确认等待中的实例仍能识别已有步骤。若要改变某个决定的解释方式,应明确旧实例是继续沿用旧逻辑、转到新版本,还是被暂停等待人工迁移。不同选择有不同代价。保留旧逻辑会增加运维复杂度,立即切换可能改变已经承诺的行为,而暂停会拉长用户等待时间。选择应依据旧承诺和新缺陷的影响,而不是只看部署是否方便。
模型升级也是版本变更的一种。对于已经产生并持久化的决定,恢复时宜保留所使用的模型或策略版本及结构化结果,以便解释当时为什么进入某一阶段。对于还没有发生的决定,可以按升级政策采用新版本,但应设置能够比较的观察点。比如在只读条件下比较新旧模型如何解释同一批申请,把会改变授权范围的差异交给规则或人工处理。重新调用模型只因为它的结果以前没有成功写入,是一种可能的恢复办法,不过仍要检查它产生的新意图是否与已发出的外部请求冲突。
错误监控也要贴近实际风险。队列深度和平均处理时间有用,却可能掩盖少数一直无法确认的任务。团队可以观测等待外部确认的最长时长、未知结果的积压、重复事件被拦截的次数,以及进入人工核查后的解决时间。每个指标都应能追到合成测试或真实记录,避免把“重试减少”单独解释为稳定性变好。重试减少也可能是事件没有到达,或者任务提前停在某个默认分支。
一个有效的故障演练还应该明确谁能接管。接管界面应呈现当前目标、已核对事实、可能已生效的外部操作、下一项危险动作以及恢复入口。人需要看到为什么系统暂停,同时能区分自动恢复所需信息与业务判断所需信息。若人工操作会改变任务状态,该操作也应写入同一历史并带有权限和时间记录。否则,代理恢复后可能看不到人工已经完成的步骤,又重新走一遍流程。长周期协作的成本,往往来自交接信息不一致,演练应覆盖这一点。
反论证、适用条件与局限
对于只涉及两三个确定步骤的任务,轻量队列、幂等写入和一张状态表可能已经足够。引入通用工作流运行时会增加部署、排查、数据保留和版本管理成本。选择之前可以先回答:是否有跨日等待,外部事件是否可能乱序,重复操作造成的后果如何,团队是否需要在升级后恢复许多旧实例。只有这些需求超过现有实现的承载能力,才有理由引入更多机制。使用一种成熟运行时也不能省掉业务层的接口契约和验收定义。
还有一种反对意见认为,在不同条件下让模型动态选下一步,会使流程难以测试。对于法律或安全边界明确的步骤,这个担心成立。可以用固定状态机定义什么操作允许发生,用模型处理含糊输入、生成候选和总结异常。若流程的每一步早已由规则完全确定,动态选择的收益会很小。如果最难的部分是理解非结构化输入,保留模型处理该部分,再用常规控制逻辑把结果送入后续流程,往往能以更低的维护成本覆盖多数需求。
权限检查和审计也有隐私成本。记录更多请求内容有利于追溯,但长期保存完整对话、外部系统响应或附件内容,可能形成一份额外的敏感数据副本。可先确定恢复必须依赖哪些字段,将其他材料放在有明确权限和期限的原系统,通过受控引用访问。处理过程应区分长期有效的业务事实与仅适合短期调试的上下文。若有依法或依约删除资料的义务,工作流历史的留存设计也要考虑这一点。
架构选择还受外部接口能力限制。如果合作系统无法可靠标识对象,缺少稳定的查询结果,或者不提供可验证事件,流程引擎无法凭空补齐这些事实。团队可以把部分步骤交给人工复核,或者在权限允许时增加独立观察点。对实物交付等外部事实,数据系统里的状态有时仍需与实际检查对应。本文的两个假设场景只能解释这些取舍的因果链,无法给出适用于所有领域的指标阈值或自动化比例。
对系统价值的评估也不宜从成功演示直接外推。一次演示很容易选中外部系统都按预期回应的路径。实际评估还需要观察等待中的取消、人工接管、重复请求、跨版本恢复和业务约束变化。对照的基础可以是一段时期内同类任务的完成证据与人工介入记录,同时注意任务难度和输入构成变化。结果好坏应反馈到流程设计,例如减少误报提醒、完善某个查询接口或收紧风险动作的入口,而不只是更换一个模型。
对账结果也需要定期回看
一项外部动作即使已经核对,后续仍可能被撤销或替换。任务结束后应由业务方决定是否需要短期回看,以及什么变化值得重开流程。比如发布后发现目录中展示的版本与审核通过的版本不同,可以先冻结后续推广,再查询哪个步骤引入了差异。若目录只是因为索引刷新延迟而显示旧状态,则应保留现有记录并等待预先定义的核对时点。两种情形表面相似,却对应完全不同的行动,应该通过证据区分。
对账还可以反过来帮助系统变简单。如果连续多次人工介入都因为某个外部字段缺失,优先解决字段在源系统中的产生和传递,通常比让模型从更多历史文本里猜测更稳妥。如果某类不确定结果总能通过一个明确的状态查询解决,可以把这次查询加入正式流程,并保留何时触发的记录。这样,过去的失败会变成可以测试的程序行为,同时避免为了偶发异常而把全部历史都交给模型处理。
结论
长周期代理最重要的能力之一,是在隔了一段时间之后仍能交代任务发生了什么。持久化执行提供可恢复的步骤记录和等待机制,业务规则负责解释这些记录是否仍然有效。把模型的建议、发出的动作和外部确认拆开后,可以逐项定义去重、重试、授权和验收。遇到未知结果时,流程能够保存证据和交出控制权。这样的系统才能在等待和故障之后继续推进,并且让参与者有办法核对它为什么这样做。