Agent 跑三分钟的任务,HTTP 等不了,异步长任务的三个接口

发布时间:2026/10/24 2:24:32
Agent 跑三分钟的任务,HTTP 等不了,异步长任务的三个接口

Agent 跑三分钟的任务,HTTP 等不了,异步长任务的三个接口

让 Agent 查一次季度报表,它要调五个工具,翻两次知识库,最后写一段总结,全程三分钟。同步接口扛不住这个时长,网关默认超时一分钟,反向代理再来一刀,浏览器自己也会放弃。用户看到的是转圈然后报错,后端日志里任务其实已经跑完了,钱也花了。

三段式

把一次调用拆成三个接口。提交接口返回任务 ID,立刻返回,毫秒级。查询接口按任务 ID 给状态,排队中、执行中、完成、失败,带进度和已完成的分步结果。结果接口取最终产物。想要更省事就再加一个回调,任务完成时服务端主动通知前端,前端不用轮询。

这套结构的老祖宗是批处理系统的作业控制,用在 Agent 上正合适,因为 Agent 任务天然有中间状态,每一步工具调用都可以先落盘。

队列用哪个

任务要排队,就有了队列选型的问题。RabbitMQ 的强项是任务分发,有确认机制、重试、延迟队列,一条消息被消费者拿到,处理失败可以重新入队。Kafka 的强项是日志流,顺序写、可回放、高吞吐,消费者自己记录消费位置,适合做数据管道和事件溯源。

Agent 任务队列要的是重试、延迟、优先级、死信处理,这些是 RabbitMQ 的主场。如果任务本身是长流程事件流,要回放要审计,才考虑 Kafka。不少项目上来就用 Kafka 做任务队列,最后发现延迟重试要自己实现,得不偿失。

幂等这件事

用户手抖点两次提交,或者前端重试,同一个任务就排队两遍,工具调用两遍,钱花两遍。做法是让客户端生成请求 ID 随提交带上,服务端拿这个 ID 去重,重复提交返回同一个任务 ID。别指望用户不点两次。

工具级也要幂等。取消订单这类操作,同一个订单重复执行要能识别出来,别第二次报错也别真的执行两遍。参数校验三层里的业务层正好能兜住这一类。

状态机与超时

任务状态得是个明确的状态机,别用一堆布尔值拼。排队、执行、成功、失败、取消,状态之间的迁移写清楚,谁能迁到谁。超时是必然要处理的,执行超过上限就标失败并回收资源,不能让一个卡死的任务占着 worker 到天荒地老。

终止条件也得有。执行循环篇讲过的重试上限,在异步任务里变成任务级的总预算,包括耗时预算和 token 预算,超了就停,把已完成的部分交回去。半成品比死循环有价值。

回调要签名

如果做回调,回调地址会暴露在公网上,必须签名加时间戳,接收方校验后才能信任内容。回调还可能被重放,时间戳加 nonce 能挡住。回调失败要有限次重试,重试策略用指数退避,别一秒一次打爆对方。

结合系列

ChatServer 篇的接口设计和错误语义,在这套结构里同样适用,提交接口的错误码和查询接口的状态要能对上。会话隔离篇的身份校验在异步场景要多考虑一层,任务属于谁,查询时必须校验归属,不能只凭任务 ID 就能查别人的结果。审核队列篇讲的是人工介入的排队,这里讲机器执行的排队,两者可以在同一套状态机里共存。