架构三段:提交、等待、取货。它不是扣子定的,是几乎所有「要跑几十秒」的接口的标准形状。 为什么异步:生成要几十秒,节点等待有上限。硬等必超时,只能提交完先返回。 任务状态有五种,不只是 done。只写「等于 done 就继续」的链,遇到 failed 会一直问下去。
这一节不写一行界面操作,只画结构。结构想错了,代码写得多漂亮都是返工。 异步这件事第 3 章讲插件时提过一句,这里是第一次真正用上。 本沙箱用真 HTTP 服务模拟 PPT 插件的三个接口, 所以下面的耗时和状态都是真跑出来的——除了「生成要多少秒」那个数,那是本课估的量级。
一、三段:提交、等待、取货
| 段 | 做什么 | 拿到什么 |
|---|---|---|
| 提交 | 把大纲和模板参数发过去 | 一个 task_id |
| 等待 | 隔几秒问一次「好了没」 | running 或 done |
| 取货 | 拿 task_id 换下载链接 | 一个 URL |
这三段是异步任务的标准形状。 几乎所有「要跑几十秒」的接口都长这样:视频转码、图片超分、大文件导出、模型微调。 认不出这个形状的人,会试图一步做完。一步做完在本地脚本里可以,在工作流里不行——节点有等待上限。 记住一句:只要一个接口返回的是「任务号」而不是「结果」,它就是异步的。
二、为什么必须异步
生成一份 PPT 取 45 秒(本课估的量级,视模板复杂度浮动)。 平台节点的等待上限通常在一分钟上下。45 秒加网络抖动、加排队,很容易就顶到上限。 所以「等满一分钟」这条路本身就不通。 不是慢,是结构上不允许。
两条出路:一是提交完立刻返回,下一轮对话再问;二是用异步节点,让平台替你去等。 这一章用第一条,因为它更好讲清楚。
三、一次生成要问几次
| 参数 | 取值 | 说明 |
|---|---|---|
| 生成时长 | 45 秒 | 本课估的量级 |
| 轮询间隔 | 3 秒 | 约生成时长的十分之一 |
| 理论轮询次数 | 15 次 | 45 ÷ 3 |
间隔太短是浪费调用,太长是白等。间隔取生成时长的十分之一左右比较稳。 这个数不是拍脑袋:生成 45 秒的活,3 秒问一次,最多白等 3 秒;要是 15 秒问一次,平均白等 7 秒多。 另一头也要算:15 次调用等于 15 次计费。所以间隔不能无限小。
四、五种状态,四种要有去处
| 状态 | 含义 | 怎么办 |
|---|---|---|
| pending | 排队 | 继续等 |
| running | 生成中 | 继续等 |
| done | 完成 | 去取货 |
| failed | 失败 | 重试一次,再失败报错 |
| timeout | 等超了 | 提示稍后再试,别重试 |
正常一轮任务:排队 1 次、生成中 5 次、完成 1 次,一共问 7 次。 只写「等于 done 就继续」的链,遇到 failed 会一直问下去,直到把调用次数耗光。 这种 bug 不报错,只烧钱。 五种状态里只有 failed 值得重试。超时重试会更慢,没权限重试永远失败。
五、架构图上还有两个东西
| 位置 | 放什么 | 为什么 |
|---|---|---|
| 提交之前 | 大纲校验 | 拦下来就不用花一次生成 |
| 取货之后 | 链接检查 | 链接打不开等于没取到 |
| 全链之外 | 超时兜底 | 整条链卡住时要有人收尾 |
前两个都是「多花一秒省几十秒」的买卖。校验放在提交前面,这一条在第 14.1 节已经讲过。 第三个最容易被忘:整条链跑了两分钟还没结果,用户那边是没有任何反馈的。 要有个地方告诉他「还在做,好了发给你」。 这一章的链是同步返回的,所以第三个只做到「超时就报错」。 真要做成「好了发给你」, 还得加一路消息推送——那是第 15 章的事。
六、动手 Demo:生成是异步的:先拿号,再取货
先看三段式,再算一次生成要轮询几次,最后列五种状态各自的去处。 末尾看三种「拿不到链接」的情况:超时、失败、没权限。
GEN_S = 45.0 # 生成一份 PPT 的时间,本课估的量级
POLL_S = 3.0 # 轮询间隔,约生成时长的十分之一
n = int(GEN_S / POLL_S) # 15 次
实跑输出:
--------------------------------------------------------------------
生成是异步的:先拿号,再取货
--------------------------------------------------------------------
① 三段:提交、等待、取货
--------------------------------------------------------------------
| 段 | 做什么 | 拿到什么 |
|---|---|---|
| 提交 | 把大纲和模板参数发过去 | 返回一个 task_id |
| 等待 | 隔几秒问一次「好了没」 | 返回 running 或 done |
| 取货 | 拿 task_id 换下载链接 | 返回一个 URL |
这三段是异步任务的标准形状。它不是扣子定的,是几乎所有「要跑几十秒」的接口都这么设计。
为什么要异步?因为生成一份 PPT 要几十秒,而节点的等待时间有上限。硬等会超时。
② 一次生成要等多久
--------------------------------------------------------------------
生成一份 PPT 取 45 秒(本课估的量级,视模板复杂度浮动)。
轮询间隔取 3 秒,理论上要问 15 次才拿到结果。
间隔太短是浪费调用,太长是白等。间隔取生成时长的十分之一左右比较稳。
平台节点的等待上限通常在一分钟上下——所以「等满一分钟」这条路本身就不通,必须走「提交完就返回,
下一轮再问」或者「用异步节点」。
③ 任务状态机
--------------------------------------------------------------------
| 状态 | 正常情况停留几轮 | 含义 |
|---|---:|---|
| pending | 1 | 排队 |
| running | 5 | 生成中 |
| done | 1 | 完成 |
正常一轮任务:排队 1 次、生成中 5 次、完成 1 次,一共问 7 次。
除了这三个,还有两个必须处理:failed(失败了)和 timeout(等超了)。
只写「等于 done 就继续」的链,遇到 failed 会一直问下去,直到把调用次数耗光。
④ 三种拿不到链接的情况
--------------------------------------------------------------------
| 情况 | 怎么认出来 | 怎么办 |
|---|---|---|
| 超时 | 问了很多次还是 running | 提示稍后再试,别重试 |
| 失败 | 返回 failed 带错误码 | 重试一次,仍失败就报错 |
| 没权限 | 返回 403 | 重试没用,去查授权 |
三种里只有第二种值得重试。超时重试会更慢,没权限重试永远失败。
这一条和第 13.9 节的判法是一路的:先分清是哪一类,再决定动作。
不分清就重试,等于拿调用次数赌运气。
①三段式:提交拿 task_id、轮询问状态、取货换链接。 ②45 秒生成、3 秒轮询,理论上问 15 次;平台节点上限一分钟,所以硬等不通。 ③五种状态:pending、running、done、failed、timeout。 ④只有 failed 值得重试,超时和没权限重试没用。 ⑤第五节补两个位置:提交前校验、取货后查链接。
30 秒实验
- 把你手上一件事拆成「提交 / 等待 / 取货」三段。拆不出来的,多半是不需要异步的。
- 查一下你用过的接口,哪些返回的是任务号而不是结果。那批就是异步的。
- 给你的轮询定个间隔,并算出最坏情况下白等几秒、总共问几次。
常见误区
- 「等久一点总能等到。」节点有等待上限,等到上限就是超时,不是慢。
- 「只处理 done 就够了。」遇到 failed 会一直问到调用次数耗光,还不报错。
- 「失败就重试,总能成。」超时重试更慢,没权限重试永远失败。先分类再决定。
自测三问(点开对答案)
1. 怎么判断一个接口是不是异步的? —— 看它返回的是任务号还是结果。返回任务号的都是异步的。 2. 为什么必须异步? —— 生成要几十秒,而节点等待有上限。硬等会超时,结构上不允许。 3. 轮询间隔怎么定? —— 取生成时长的十分之一左右。太短浪费调用,太长白等。架构定了,下一节把六个步骤真连起来。这一节最长,也是这一章的主体。
- ☐ (本篇完,下一篇 14.3 详细实现步骤)
相关笔记
- 应用场景与特点:上一节的应用场景
- 什么是插件:插件到底是什么
- 详细实现步骤:下一节动手实现
- 🐦 扣子开发 AI Agent · 索引