跳转至

审计里的 completed 不是业务成功:一次没有修复的排查

现象

2026 年 9 月 12 日一次只读审查中,排查失败任务时发现:审计表 agent_turn_audit 里对应请求的状态是 completed。第一反应是业务失败被错误记成了成功,若属实则说明状态机有缺陷。

核对

排除这个怀疑,先要弄清字段语义:这个字段记的到底是业务结果,还是请求生命周期。方向确定后沿源码核对,审查全程只读,没有改代码、没有写生产数据库。

沿源码确认:上游编排层(goagent orchestrator)的失败收尾函数 completeTurnFailure 与成功路径调用同一个持久化函数 completeWithResponse,响应和调试元数据走完全一致的落库流程。失败的请求同样要落库保存,落完状态就是 completed。

机制

completed 只描述请求生命周期,不描述业务结果,这是状态计算逻辑决定的。落库时状态由 auditCompletionStatus 算出:

if debug.Agent.FinishReason == "cancelled" {
    return "cancelled"
}
if debug.Failure != nil && debug.Failure.Retryable {
    return "retryable_failed"
}
return "completed"

只有两种终结有特殊状态:模型结束原因是取消,或失败可重试。其余所有终结——包括不可重试的业务失败——都落 completed,状态机里没有"成功完成"和"失败完成"的区分。

失败信息没有被状态抹掉:错误码和失败摘要作为响应和调试元数据写进同一行审计记录,completed 的记录里带着完整失败详情。业务任务本身的状态在另一处,本次正确记录为失败。

两个状态各自正确,只是记录的东西不同:审计字段记"请求有没有落下来",业务状态记"任务成没成"。"记成成功"的疑虑经源码核对排除。

处理

无需修改状态机。需要修正的是查询和报表对这个字段的解释:面向业务判断时读业务任务终态,面向审计完整性时才看请求保存状态。