长任务 Agent 与持久状态
模型的推理发生在一次调用里,但真实工作跨越时间。可靠的 Agent 必须能够暂停、恢复、被看见,并把完成变成交付。
构建 Oracle 之后,我们很快遇到了一个比“如何让 Agent 做更多事”更基础的问题:它的工作到底应该活多久?
一次模型调用可能只需要几秒,一次网络请求也总会结束,但真实任务并不服从这个时间尺度。研究可能需要等待新的材料,生成可能持续很久,用户可能离开页面,也可能在中途回来补充要求。如果 Agent 的生命周期和一次请求绑定在一起,它可以完成一次漂亮的演示,却很难成为可以依赖的产品。
我们逐渐意识到,请求只是工作的起点,而不应该成为工作的容器。
请求结束,不代表工作结束
传统软件很容易把一次交互理解为一次完整事务:收到输入,执行逻辑,返回结果。对于确定性的短任务,这个结构简单而有效。
但 Agent 面对的是开放目标。它可能需要多轮判断、多个工具和不断变化的材料。执行时间越长,页面、连接和单次计算就越不可能始终保持可用。如果系统要求所有事情都在一次请求里完成,那么任何等待都会变成超时,任何离开都会像中断,任何恢复都只能从头再来。
这不是性能问题,而是生命周期设计错了。
更合理的关系是:一次请求创建或推进一项工作,工作拥有独立于请求的状态。用户可以离开,界面可以关闭,某一步也可以暂时无法继续,但任务本身不应该因此失去已经获得的结果。
暂停是一种正常状态
我们最初也容易把任务分成两种状态:运行中与已完成。后来发现,真实工作里最重要的往往是它们之间的部分。
Agent 可能在等待用户作出选择,等待外部结果,或者发现继续行动前需要补充条件。这些都不是失败。相反,知道什么时候不应该继续,是系统判断力的一部分。
因此,暂停不能只是停止某个进程。系统需要保留已经完成的行动、仍未解决的问题和下一次继续所需的上下文。用户回来时,Agent 应该从有意义的位置继续,而不是把整段过程重新播放一遍。
这让我开始把暂停理解为一种产品能力:它让人能够进入 Agent 的工作过程,改变方向,然后把控制权重新交还给系统。
可恢复性比重试更重要
失败后再试一次听起来很合理,但对于长任务,盲目重试经常制造更多问题。
某一步可能已经成功,只是结果没有及时返回;某个文件可能已经产生,再执行一次就会得到重复产物;任务也可能在多个状态更新之间被同时推进。系统如果不知道此前究竟发生了什么,就无法判断应该重试、跳过,还是等待。
所以可靠性不只是“失败后继续尝试”,而是“在不确定中仍然知道从哪里继续”。这要求系统能区分已完成的事实、尚未确认的结果和仍然安全的下一步。
模型可以决定下一步做什么,但它不应该独自承担对执行历史的记忆。恢复能力来自模型之外:明确的状态、稳定的边界,以及对重复行动保持警惕的运行系统。
进度必须成为产品语言
后台继续运行,并不等于用户会相信它仍在工作。
如果所有进度只存在于日志里,用户看到的就只有一个长时间没有变化的界面。他无法判断任务是在推进、等待、失败,还是已经完成了一部分。系统内部拥有再多状态,对用户而言也仍然是黑箱。
我们开始把进度看作 Agent 产品的一部分,而不是调试信息。用户不需要看到每一个内部步骤,但应该理解当前发生了什么:任务正在处理什么、为什么停下、是否需要自己行动,以及哪些结果已经可以使用。
通知也应该服务于这些状态变化。真正值得打断用户的,不是系统又执行了一步,而是工作完成了、需要决定,或者产生了可以继续使用的结果。
完成不等于交付
长任务还暴露了另一个容易被忽略的区别:系统完成了执行,不代表用户已经得到交付。
一个 Agent 可能产生许多中间材料。它们帮助后续判断,却不一定都是用户最终需要的结果。如果产品把所有文件平铺出来,用户仍然要自己分辨哪些是草稿、哪些是过程材料、哪些才是可以带走的成果。
因此,交付物必须成为明确的产品概念。系统不仅要知道某一步是否结束,还要知道它产生的结果扮演什么角色,是否已经足够完整,以及应该如何回到用户面前。
这使“完成”从一个运行状态变成了用户结果。Agent 的责任不应该止于停止计算,而应该延伸到让工作变得可见、可理解、可继续使用。
可靠性是一种协作结构
这一阶段,团队同时在界面、任务运行和后台协作等不同部分推进 Oracle。我们反复遇到的暂停、恢复、通知、重复执行和交付问题,并不属于某一个孤立模块。
它们共同说明:Agent 的可靠性无法靠一个更强的模型、一条更长的队列,或者一个更复杂的状态字段单独解决。它存在于各部分之间是否拥有一致的工作定义。
运行系统要知道任务能否继续,产品要让用户理解任务在哪里,交付层要知道哪些结果真正属于用户。只要其中一层仍然把 Agent 当成一次请求,整个体验就会在那个边界上断开。
工作发生在时间里
Agent 与传统生成式功能最不同的地方,也许不是它能调用多少工具,而是它开始承担跨越时间的责任。
用户启动一项任务,实际上是在和产品建立一种持续的约定:系统不会因为页面关闭而忘记,不会因为一次失败而把已经完成的工作抹去,也不会把一堆中间材料伪装成最终结果。
模型的推理发生在瞬间,工作却发生在时间里。
一个真正可靠的 Agent 系统,必须让前者能够在后者之中持续成立。


讨论
评论区
关于文章本身,也欢迎留下不同意见或补充。