早上打开电脑,一份 Agent 日报已经躺在文件夹里,运行日志的最后一行写着 success。如果只看这两个信号,任务似乎已经完成。
但再往下查,情况可能完全不同:五个来源只读到四个,通知渠道没有真正送达,或者文件虽然保存成功,任务状态却在写入前中断。它们都可能留下一个看起来完整的结果,却代表着截然不同的完成程度。
我在一套本地写作工作流里专门回放了这些故障,最后得到的判断是:
对于长期 Agent,完成不是一个状态,而是一条证据链。
这个问题正在变得越来越实际。官方 OpenAI Docs 将 Agents API 描述为用于构建持久云端 Agent 的托管框架,由平台管理会话、编排、上下文压缩和恢复,应用提供工具并选择执行环境。Agents API 文档呈现的已经不是一次问答,而是一段可以持续推进、调用工具和保存工作的执行过程。
Agent 能连续工作得越久,我们越不能把“返回了一段文字”当作完成证明。
以 Agents API 为例,一次工作循环被称为 turn。它可能完成、失败或被取消。官方文档明确提醒:turn 显示为 completed,并不保证其中每个工具都执行成功;会话处于空闲状态,也不等于任务成功。会话文档要求开发者继续检查输出和工具结果。
一个真实任务至少包含五层完成状态。
层级 | 需要确认的问题 | 可以保留的证据 |
|---|---|---|
运行层 | 本轮 Agent 是完成、失败,还是被取消? | 会话状态、turn 状态、错误码 |
工具层 | 搜索、读取、写入等关键工具是否分别成功? | 工具结果、失败来源、重试记录 |
产物层 | 文件是否保存,内容是否仍是生成时的版本? | 文件路径、内容哈希、来源版本 |
交付层 | 消息、工单或报告是否确实送达? | 回执、外部对象 ID、投递状态 |
业务层 | 结果是否满足最初约定的验收条件? | 检查项、人工复核、最终结论 |
运行层成功,只能说明 Agent 生命周期走到了某个结束状态。工具仍可能局部失败,产物可能不完整,外部交付也可能处于未知状态。这五层不能被一个绿色的 completed 合并掉。
明确失败通常不难发现。程序抛出异常、会话进入 failed、文件没有生成,开发者自然会调查原因。
真正棘手的是“假完成”。
一种情况是部分来源失败。Agent 读到了大部分资料,最后仍生成一份语言流畅的摘要。如果没有同时记录缺失来源,读者看到的是完整报告,系统看到的也可能是成功运行,但任务实际上只完成了一部分。
另一种情况是产物已经保存,完成状态却没有写入。程序恢复后只看到任务尚未结束,于是重新调用模型、重新选择资料,再保存一次。同一个业务日期由此出现两份不同日报,甚至触发两次通知。
还有一种情况更难判断:外部操作已经发生,响应却在返回途中丢失。系统既不能确定消息是否送达,也不能直接重发。重发可能重复,不重发可能漏交付。
这几类问题的共同点是:模型给出了很像结果的结果,业务闭环却没有得到证明。
我用 Python 3.12.13、SQLite 和 Markdown 实现了一套本地写作日报工作流,任务包括发现资料、保存正文版本、生成日报、记录运行状态和导出稿件。随后使用可重复的离线输入,主动制造了五类故障。
故障或操作 | 实际观察结果 |
|---|---|
同一计划连续执行两次 | 第二次没有新增资料读取,文章、版本、报告和任务各保留一条记录 |
一个来源超时 | 正常来源继续处理,日报保存,整体状态标为 partial |
所有来源失败 | 保存状态报告,整体状态标为 degraded,不伪装成“今天没有内容” |
报告保存后、完成登记前中断 | 恢复后复用原报告,内容哈希不变,报告记录仍为一条 |
数据库与自有稿件恢复到新目录 | 稿件内容保留,报告路径切换到恢复目录 |
这些结果只验证本地工作流在上述故障下的行为,不代表生产环境的长期稳定性,也没有证明外部消息能够做到恰好投递一次。
它们真正说明的是:完成证明不能只保留最终回答,还要覆盖任务身份、输入版本、工具结果、产物版本和交付状态。
安全重试的前提,是系统知道“这次重试”和“另一次新任务”的区别。
在日报场景中,我使用任务类型和业务日期组成任务身份:
daily:2026-10-18当天手动补跑或断线恢复时,只要处理的仍是同一个逻辑任务,就复用这个身份。显式要求重新生成,则创建新的修订版本,而不是悄悄覆盖原结果。
Agents API 的会话文档也建议为每一次逻辑消息提交创建幂等键。请求因超时或响应丢失而自动重试时,应复用相同的会话 ID、消息和幂等键;新的逻辑提交则使用新的键。这项机制解决的是请求层的重复提交问题。
业务系统仍需定义自己的任务身份。API 幂等不能替你判断“生成今天的日报”和“重新生成今天的日报”是不是同一件事。
长期任务经常跨过数据变化的边界。Agent 上午读取一篇文章,下午恢复时原文已经更新;原计划七点生成日报,电脑十点才从休眠中恢复。任务日期没有变化,实际处理的资料却可能已经不同。
因此,完成记录至少要区分两种时间:业务时间表示结果属于哪一天、哪一个计划任务;观察时间表示系统实际在什么时候读取资料。
内容也需要版本标识。网页正文可以保存内容哈希,代码任务可以保存提交 SHA,配置和提示词也应记录实际使用的版本。否则,重试后即使得到正常结果,也无法证明两次处理的是同一批输入。
一个 Agent 可以同时调用搜索、数据库、浏览器、文件系统和外部接口。最终文本只是汇总,不能成为唯一证据。
更可靠的做法,是提前区分关键工具和可选工具。主要数据源失败时,任务不能标为完全成功;补充资料失败时,可以继续生成,但应把结果标为 partial。如果系统仍在等待函数结果或环境连接,则要处理 required_actions,而不是把暂时空闲理解为成功。
Agent 说“文件已经生成”,只是一个陈述。系统还需要检查文件是否存在、能否打开、结构是否完整,并把产物绑定到生成时的输入版本。
对于文本报告,一个实用的最小集合是:文件路径、内容哈希、选用资料 ID、资料版本和生成时间。代码任务还可以加入提交 SHA、测试结果和构建产物;数据分析则可以保留查询、数据快照标识和导出文件。
如果程序在文件保存后中断,恢复逻辑应先核对已有产物。内容一致就继续登记,内容缺失或损坏才重新生成。恢复不等于“让模型凭记忆再做一遍”。
文件写入、外部消息和业务确认通常不在同一个事务里。文件保存成功后,通知可能失败;通知接口返回超时,消息却可能已经送达;报告成功送达,内容仍可能不符合验收标准。
所以,一条可核对的完成记录至少应该接近下面这样:
{
"job_key": "daily:2026-10-18",
"business_date": "2026-10-18",
"observed_at": "2026-10-18T07:34:21+08:00",
"turn_status": "completed",
"tool_status": "partial",
"artifact": {
"path": "reports/2026-10-18.md",
"sha256": "按实际内容计算"
},
"delivery_status": "not_configured",
"verification": "needs_human_review"
}这条记录不会因为 turn 完成就声称日报已经交付,也不会把尚未配置的通知渠道写成发送成功。它提供的是一条可以继续检查的状态链。
Agents API 可以记录会话事件、历史、turn、工具调用、子 Agent 活动和 token 使用情况。官方 OpenAI Docs 的可观测性说明展示了如何查看这些轨迹。
这些信息能回答“Agent 做过什么”,却不能自动回答“业务是否满意”。
日志显示浏览器访问了某个页面,不代表读到了正确版本;记录显示文件写入成功,不代表格式符合投稿要求;子 Agent 都正常返回,也不代表汇总时没有遗漏冲突结论。
可观测性负责留下证据,验收标准负责判断证据是否足够。
长任务中断后,最直觉的做法是重新运行,但失败的 turn 仍可能已经修改文件或调用外部工具。直接重跑,反而可能扩大问题。
Agents API 的错误恢复文档建议在重试前取回会话、turn 和已保存的 items,并检查已经发生的动作。遇到暂时性错误,再按照间隔和次数限制,只继续未完成的工作。
可以把恢复顺序压缩成五步:
对于长时间运行的 Agent,这套顺序比“失败就重跑”更重要。
无论使用哪一种模型或 Agent 框架,把任务交给后台持续运行之前,都可以先回答下面七个问题:
completed 之后还要检查哪些产物和外部操作?如果这些问题没有答案,Agent 工作时间越长,积累的不确定性可能越多。
持续会话、上下文恢复、多 Agent 协作和丰富工具,正在扩大 Agent 可以承担的工作范围。但能力范围扩大,并不会自动带来交付确定性。
真正可用的长期 Agent,不只是能够在无人盯着时继续工作,还应该在恢复后知道哪些步骤已经完成,在部分失败时说清楚缺了什么,在重复执行时不制造新的副作用,并在最后拿出可以核对的完成证据。
当 Agent 从一次问答走向持续工作,人不必再守着它点击每一步。但我们必须把“什么叫完成”定义得比以前更清楚。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。