Agent服务故障:自动化为什么必须能排队
自动化 Agent 最危险的误解之一是:
触发了
=
执行了
OpenAI 状态页记录了一次 Workspace Agents 与 ChatGPT Work 错误率升高事件:8月27日18:00左右开始确认异常,19:07进入恢复监控,22:14确认全部恢复。
这类故障本身很正常。真正需要工程团队提前设计的是:
如果Agent平台暂时不可用,
你的业务事件去哪?
例如新邮件、PR更新、客户工单、审批到达和定时任务。如果这些触发直接调用 Agent:
Webhook
→ Agent API
Agent 失败时,事件就可能直接丢失。
事件触发和Agent执行必须解耦
正确结构:
Event
↓
Durable Inbox
↓
Task Queue
↓
Agent Runtime
Agent 挂了:
Queue堆积
平台恢复:
继续消费
故障影响的是处理延迟,而不是业务数据完整性。
Inbox先保证“事件没丢”
create table agent_event_inbox (
event_id varchar(128) primary key,
source varchar(64) not null,
resource_id varchar(256) not null,
payload_ref varchar(512) not null,
received_at timestamptz not null,
status varchar(32) not null
);
Webhook 收到以后:
写Inbox
→ ACK
不要等 Agent 完成才 ACK。
如果 Agent 要跑 5 分钟,而 Webhook Provider 只等 10 秒,后者会误以为失败并重试,最后你得到重复事件。
Task Queue再保证“可以慢慢做”
public enum AgentTaskStatus {
PENDING,
RUNNING,
RETRY_WAIT,
COMPLETED,
FAILED,
DEAD_LETTER,
EXPIRED
}
Agent API 出现:
429
5xx
timeout
通常进入:
RETRY_WAIT
而不是立即 FAILED。
Retry一定要指数退避
最差做法:
每秒重试
平台故障时只会制造 Retry Storm。
更合理:
5s
15s
45s
2m
5m
15m
并加 Jitter。
import random
def backoff(attempt, base=5, cap=900):
delay = min(
base * (2 ** attempt),
cap
)
return delay * random.uniform(
0.8,
1.2
)
这样多个 Worker 不会在同一秒一起冲击恢复中的服务。
不是所有失败都能Retry
429
5xx
timeout
多半是临时故障。
401
403
invalid input
policy denied
通常不能盲重试。
可以分类:
public enum FailureClass {
TRANSIENT,
THROTTLED,
AUTH,
POLICY,
INVALID_REQUEST,
UNKNOWN
}
策略:
TRANSIENT:
Retry
THROTTLED:
Respect Retry-After
AUTH:
Refresh Credential or Stop
POLICY:
Stop
INVALID_REQUEST:
Dead Letter
UNKNOWN:
Reconcile
UNKNOWN为什么最危险
假设 Agent 正在:
发邮件
真实流程:
Tool执行成功
↓
响应返回途中断线
↓
Agent平台只看到timeout
如果你简单重跑整个任务:
用户可能收到两封邮件
这不是普通失败。
它是:
外部副作用状态未知
必须先 Reconcile。
Side Effect Ledger不能省
create table agent_side_effect (
idempotency_key varchar(256) primary key,
run_id varchar(128) not null,
capability varchar(128) not null,
action_hash varchar(64) not null,
status varchar(32) not null,
provider_receipt varchar(512)
);
状态至少:
PLANNED
EXECUTING
CONFIRMED
FAILED
UNKNOWN
如果状态是 CONFIRMED,Retry 只恢复后续步骤。
如果是 UNKNOWN:
先查询Provider
不能再次执行。
Provider恢复不代表业务恢复
状态页变绿:
22:14 Resolved
并不代表你的业务队列已经清空。
假设故障期间积压:
20,000 Tasks
恢复后还需要:
Backlog Recovery
所以内部 SLO 不能只看 Provider Status。
还要看:
Oldest Task Age
Queue Depth
Recovery ETA
恢复时最怕“洪峰”
服务恢复瞬间,20,000 个 Task 同时发出去:
又把服务打挂
所以需要 Recovery Ramp:
第1分钟:并发10
第2分钟:20
第3分钟:40
第4分钟:80
不断观察:
Error Rate
P95
429
Queue Drain Rate
再增加。
Priority Queue很重要
积压任务不应该 FIFO 一把梭。
例如:
P0:
安全告警
支付确认
P1:
客户工单
P2:
PR Review
P3:
日报/摘要
恢复时:
P0先清
P3最后
旧任务不一定都要补跑
例如:
每5分钟生成Slack摘要
故障3小时:
积压36个任务
全部补跑毫无意义。
更合理:
36个
→合并成1个“最新状态摘要”
所以 Task 要带:
Missed Schedule Policy
三种Missed Schedule策略
public enum MissedSchedulePolicy {
CATCH_UP,
LATEST_ONLY,
SKIP
}
例子:
月度对账:
CATCH_UP
10分钟摘要:
LATEST_ONLY
过时监控报告:
SKIP
定时 Agent 没有这个字段,故障恢复时很容易疯狂补历史任务。
Task还需要Expires At
public record AgentTask(
String taskId,
String taskType,
int priority,
Instant createdAt,
Instant expiresAt,
String idempotencyKey,
MissedSchedulePolicy missedPolicy) {
}
过期任务:
EXPIRED
不要继续占模型额度。
自动Fallback不能一刀切
Provider A 故障:
切Provider B
听起来简单,但有两个问题。
第一:
B是否真的可用?
第二:
B是否允许处理这类数据?
比如主模型满足:
Region=EU
Zero Retention
备用模型不满足。
所以 Failover 必须重新过:
Tenant Policy
Data Class
Region
Model Policy
Failure Domain也要先判断
故障可能在:
Agent Product
Model Provider
Region
Tool Provider
Internal Runtime
如果只是 Web UI 故障,底层 API 可能正常。
如果是内部 Tool 故障,换模型没有任何帮助。
定义:
public enum FailureDomain {
AGENT_PRODUCT,
MODEL_PROVIDER,
REGION,
TOOL_PROVIDER,
INTERNAL_RUNTIME
}
根据 Domain 决定:
Retry
Fallback
Queue
Degrade
Stop
UI状态必须区分“排队”和“失败”
差:
Task failed
好:
Queued
Delayed
Retrying
Waiting for provider recovery
如果用户知道任务还安全地在队列里,就不会不断重复点击。
重复点击反而制造新的任务和成本。
我会监控这8个指标
agent_task_queue_depth
agent_task_oldest_age_seconds
agent_task_retry_total
agent_task_dead_letter_total
agent_provider_error_rate
agent_recovery_throughput
agent_task_expired_total
agent_duplicate_side_effect_blocked_total
其中最有价值的是:
Oldest Task Age
它直接告诉你业务真正延迟了多久。
Recovery SLO
例如:
Provider恢复后
95% P1任务
30分钟内完成
这比:
“Provider已经恢复”
更接近业务体验。
最好做一次Chaos Test
主动阻断 Agent Provider 30 分钟:
Event继续进入
Provider全部失败
然后检查:
事件是否丢失
Retry是否风暴
队列是否正确堆积
Side Effect是否重复
恢复后是否限流
Priority是否正确
过期任务是否合并
不做这种测试,排队设计往往只停留在架构图里。
Agent 服务出现故障并不可怕。
真正危险的是业务系统默认:
调用失败
=
事件消失
成熟的自动化应该做到:
事件先落地
任务可等待
副作用可去重
恢复可限流
过期可合并
Fallback重新鉴权
这样 Provider 故障最终表现为:
延迟上升
而不是:
业务状态缺失
这是 Agent 从“好用工具”进入关键自动化系统必须补上的可靠性层。
更多企业级 AI 应用、Agent、RAG 与模型工程化内容,我会继续整理在 智元界:
https://www.zyentor.com/