← 所有文章

长时间运行的AI代理需要持久通道

OpenAI的后台模式文档现在描述了一个常见的代理问题:推理任务可能需要数分钟,开发者可以按ID轮询某个响应、取消该响应,并从记录下来的序列号恢复流。1

关键要点是什么?

  • 长时间运行的代理任务需要一个地址。客户端必须能够重新连接到同一项工作,从已知游标继续接收流,发送引导命令,取消任务,并检查证据。
  • 单靠轮询只能提供很薄的契约。轮询可以报告状态,但严肃的代理工作还需要命令、事件历史、可恢复流、产物、授权和检查点。
  • 持久执行只解决了系统的一部分。Temporal式工作流可以保留执行状态和事件历史,但用户仍然需要围绕运行中工作的持久通信界面。23
  • WebSockets有帮助,但套接字不是完整地址。连接中断不应抹掉用户返回该代理任务的路径。
  • 产品界面很重要。用户应该看到一个连贯的任务,其中包含证据、决策和下一步行动,而不是零散日志和乐观的状态文字。

长时间运行的AI代理不适合旧式请求-响应模型。普通请求有端点、响应和超时。严肃的代理任务则有持续时间、事件历史、中间产物、用户中断、模型和工具状态、取消规则,以及一个可能离开后再返回的人。

缺失的对象不是另一条聊天消息。真正缺失的是持久通道:一个正在运行的工作单元的稳定地址。

我之前已经论述过,托管式代理正在吸收执行环境基础设施,也论述过代理执行追踪正在成为执行环境契约。持久通道位于这两个观点之间。追踪证明发生了什么。托管执行环境让工作继续存活。持久通道则让产品和用户在工作存活期间与它对话。

旧请求模型会在哪里失效?

旧Web模型假设计算会在一次请求内完成,或者转入后台任务。数据库保存持久状态。应用服务器保持无状态。客户端可以刷新页面、命中另一台服务器,然后读取同一行数据库记录。

代理工作会从3个方面拉紧这个模型。它可能运行数分钟甚至数小时。它携带的过程状态无法干净地压缩成一条数据库记录。它还需要双向控制:观察、中断、批准、重定向、取消和恢复。

Zak Knill把同样的压力称为路由问题。他在2026年5月的文章中指出,长时间运行、有状态、可交互的代理工作需要一种可路由的基础对象。它必须能够定位正在执行工作的进程,而不只是定位存储输出的数据库。4这个视角最有价值的部分在于:客户端想说的是“把命令Y交付给任务X”,即使原来的套接字、工作进程、标签页或进程已经消失。

后台任务仍然适合简单工作。图片缩放、发票导出或夜间同步可能只需要排队中、运行中、成功或失败。只要用户需要在工作完成前引导它,代理工作就越过了这条边界。

为什么轮询不够?

轮询让客户端能够问:“完成了吗?”但它并没有提供完整的交互契约。

OpenAI的后台模式包含轮询,因为轮询解决的是超时问题。文档要求开发者在状态仍为queuedin_progress时检索后台响应,并在进入终态后停止。1同一页还暴露了取消功能,以及通过sequence_number游标恢复流的能力。这已经超出了基础轮询,指向更丰富的任务契约。1

如果产品止步于轮询,代理状态通常会散落到太多地方:

需求 薄轮询答案 持久通道答案
查看进度 status = in_progress 带时间戳和类型的追加式事件
标签页中断后重新连接 轮询最新记录 从游标N之后恢复流
重定向工作 在某处写一条备注 向任务X发送类型化信号
安全取消 翻转一个布尔值 带终态事件的幂等取消命令
审查证据 阅读最终文本 检查事件历史、产物和检查点
授权控制 信任页面会话 按任务和命令检查权限

轮询可以继续作为一种访问路径。错误在于把轮询当作产品契约。

持久通道应包含什么?

持久通道是围绕一次任务建立的具名通信契约。实现上可以使用工作流引擎、队列、事件表、WebSocket、SSE流、发布/订阅主题、托管代理会话,或这些组件的组合。产品契约比传输方式更重要。

最低契约包含9个部分:

字段或端点 用途
run_idworkflow_id 这项工作的稳定地址。
GET /runs/{id} 当前状态、所有者、时间戳、终态状态和摘要。
GET /runs/{id}/events?after=N 用于重新连接和审计的有序事件历史。
GET /runs/{id}/stream?after=N 从已知游标继续接收的可恢复实时更新。
POST /runs/{id}/signals 类型化引导命令,例如批准、修订、暂停或添加上下文。
POST /runs/{id}/cancel 带记录终态事件的幂等取消。
GET /runs/{id}/artifacts Diff、文件、报告、截图、追踪和其他证明。
checkpoint事件 便于交接和恢复的人类可读状态。
授权检查 按任务控制读取、流、信号、产物和取消权限。

每个事件都需要类型、序列号、时间戳、参与者、载荷引用和脱敏策略。没有这种结构,事件日志就会变成另一份聊天记录。

通道也需要品味。用户需要决策时,不要流式输出每个token。不要把工具失败藏在友好的加载动画后面。不要把运行中的代理变成通知风暴。好的通道只展示少数真正有助于用户信任、引导或停止工作的事件。

现有系统如何指向这种模式?

Temporal为执行侧提供了一套成熟词汇。一次工作流执行拥有事件历史、重放、确定性工作流代码,以及用于外部世界工作的活动,例如API调用、数据库查询、LLM调用和文件I/O。2Temporal的TypeScript消息传递文档把工作流描述为可接收查询、信号和更新的有状态服务。客户端可以按工作流ID获取工作流句柄、查询状态、发送信号并执行更新。3

这个模型可以自然映射到代理工作。查询回答“该任务报告了什么状态?”信号回答“请改变方向。”更新回答“执行一项可追踪变更并返回结果。”事件历史回答“发生了什么?”团队不必使用Temporal才能借鉴这种形状,但这种形状给代理产品提供了比“后台任务加聊天”更好的词汇。

Cloudflare Durable Objects指向另一个部分:可寻址协调。Cloudflare把每个Durable Object描述为一个全局唯一、带存储能力的实例,适合在多个客户端之间进行有状态协调。5其WebSocket文档描述了长生命周期的双向连接,以及WebSocket Hibernation:对象休眠时保持客户端连接,收到消息后再唤醒对象。6这并不意味着Durable Objects是通用代理执行环境。但它说明,对于实时代理界面来说,一个可寻址的协调对象为什么显得顺理成章。

Anthropic关于长时间运行代理的文章补充了人的工作这一侧。文章指出,代理在跨越多个上下文窗口时仍然吃力,并描述了一种模式:后续会话逐步推进工作,同时为下一次会话留下清晰产物。7持久通道应该把这些产物带到产品界面中,而不是埋进私有日志里。

我会先构建什么?

我会从一个小型任务服务开始,而不是一套宏大的编排平台。

创建一个runs表,记录所有权、状态、时间戳和当前摘要。创建一个run_events表或流,使用单调递增的序列号。大型载荷和产物单独存储,再从事件中引用。添加一个可恢复流端点和一个类型化信号端点。让取消保持幂等。把每一次状态转换都写进事件日志。

然后约束事件词汇:

事件类型 含义
run.started 系统接受了工作,并分配了稳定ID。
agent.plan.updated 代理更新了当前计划或检查点。
tool.started 工具或命令开始执行,并记录脱敏后的参数。
tool.finished 工具或命令结束,并记录状态、耗时和证明引用。
artifact.created Diff、文件、截图、报告或追踪已可用。
human.signal.received 用户发送了类型化引导命令。
run.blocked 任务需要权限、输入或外部状态。
run.cancelled 系统接受取消请求,并停止工作。
run.completed 工作以成功终态结束,并附带证据。
run.failed 工作以失败终态结束,并附带证据。

这样,UI就可以展示一个连贯的任务。用户可以离开、返回、审查事件、检查产物,并从同一个地址继续引导工作。代理也可以停止在文字里声称成功,转而把证据附加到状态转换上。

团队应避免什么?

应避免3种捷径。

第一,避免纯聊天记录。聊天可以发起工作,也可以收集澄清信息。但它不应成为长时间运行任务唯一的执行对象。

第二,避免把原始token流当作主要进度界面。token流有助于开发者调试延迟,但大多数用户需要的是里程碑、阻塞项、产物和决策。持久通道仍然可以为专家检查暴露原始事件。

第三,避免泄露私有过程。面向公众的产品界面应展示证据,而不是私有提示词、钩子正文、本地文件路径或内部评分机制。用户需要足够的信息来信任工作,但不需要知道让工作得以完成的每个内部技巧。

这条隐私边界同样适用于关于代理系统的公开写作。分享契约。私有机制应继续保持私有。

持久通道如何改变评估?

持久通道会让评估少一些表演性。

评估者不必只问最终答案是否听起来可信,而是可以检查整次任务:

  • 任务是否以正确的所有者、权限和范围开始?
  • 代理是否在行动前输出了计划?
  • 每个声称存在的产物是否都来自记录事件?
  • 失败是否产生了有用的检查点?
  • 用户信号是否按预期改变了任务?
  • 取消是否以唯一终态结束?
  • 最终报告是否引用了事件日志中的证据?

这份清单把证据关口变成了执行环境可以直接支持的东西。它也连接到清理层:许多代理产品会凭借让混乱任务变得可理解、可恢复、可审查而胜出。

快速总结

长时间运行的AI代理需要持久通道,因为用户需要一条稳定路径回到正在进行的工作。轮询可以报告状态,但无法独自承载完整契约。一次好的代理任务需要工作流ID、有序事件、可恢复流、类型化信号、幂等取消、产物引用、权限和人类可读的检查点。持久执行让工作继续存活;持久通道让用户和产品能够与它互动。

FAQ:长时间运行的AI代理与持久通道

长时间运行的AI代理必须使用Temporal吗?

不必。Temporal为团队提供了强大的工作流词汇和成熟执行模型,但持久通道契约可以运行在更简单的基础设施上。先从稳定任务ID、有序事件、可恢复流、类型化命令和产物开始。当重试、重放、计时器和运营规模足以证明其必要性时,再迁移到工作流引擎。

WebSockets足够展示代理进度吗?

不够。WebSockets提供实时双向连接。产品仍然需要持久地址、事件历史、重新连接游标、权限和终态。套接字可以承载通道,但不应定义整个通道。

轮询总是不好吗?

不是。轮询适合简单状态检查,也可以继续作为回退路径。问题始于轮询成为观察、引导或恢复长时间运行代理任务的唯一方式。

小团队应先构建什么?

先构建一个runs资源和一个追加式run_events日志。当事件日志拥有序列号后,再添加可恢复流。类型化信号只应覆盖产品能够安全兑现的命令:批准、暂停、修订、添加上下文和取消。

代理任务事件中应包含什么?

记录状态转换、计划、工具开始和结束、产物创建、人工信号、阻塞项、取消、失败和完成。敏感载荷不要放在内联事件文本中。私有细节应存放在经过脱敏的引用和访问检查之后。

参考资料


  1. OpenAI,“Background mode,” OpenAI API文档,访问日期:2026年5月18日。来源用于异步后台Responses、按响应ID轮询、终态状态、取消、sequence_number游标,以及通过starting_after恢复流。 

  2. Temporal,“Temporal Workflow,” Temporal文档,访问日期:2026年5月18日。来源用于Workflow Executions、事件历史、重放、确定性工作流代码,以及用于API调用、数据库查询、LLM调用和文件I/O的活动。 

  3. Temporal,“Workflow message passing - TypeScript SDK,” Temporal文档,访问日期:2026年5月18日。来源用于作为有状态服务运行的工作流、查询、信号、更新、工作流句柄和工作流ID。 

  4. Zak Knill,“LLMs are breaking 20 year old system design,” /dev/knill,2026年5月13日。来源用于路由基础对象视角、轮询批评、WebSocket作为连接的区分,以及持久通道论证。 

  5. Cloudflare,“Durable Objects,” Cloudflare Developers文档,访问日期:2026年5月18日。来源用于说明Durable Objects是全局唯一、带存储能力的有状态协调对象。 

  6. Cloudflare,“Use WebSockets,” Cloudflare Developers文档,访问日期:2026年5月18日。来源用于Durable Objects作为WebSocket端点、长生命周期双向连接,以及WebSocket Hibernation行为。 

  7. Anthropic,“Effective harnesses for long-running agents,” Anthropic Engineering,2025年11月26日。来源用于跨越多个上下文窗口的长时间运行代理、跨会话的增量进展,以及留给后续会话的清晰产物。 

相关文章

智能体执行追踪是执行环境契约

SHEPHERD、AI Workflow Store和WildClawBench指向同一个智能体可靠性层:类型化追踪、可复用工作流和原生执行环境评估。

1 分钟阅读

AI代码审查需要异议,而不是共识

AI代码审查需要独立代理保留异议、验证发现、将不确定性转交给人类,并在团队合并PR前重新审查修复。

2 分钟阅读

Ralph循环:我如何在夜间运行自主AI代理

我构建了一个使用停止钩子、生成预算和文件系统记忆的自主代理系统。以下是失败经验以及真正能交付代码的方法。

3 分钟阅读