Skip to content

06. 缓存、Batch、Flex 与后台任务编排

版本:v1.2

最后更新:2026-07-09

适用对象:已经开始处理真实流量,正在拆同步 / 异步 / 批处理任务,或者在关注 prompt caching、background、batch、flex、priority 和 conversation state 的团队

很多团队刚进入生产期时,最容易把所有任务都塞进一条同步请求里。

表面上这样最简单,但一放量之后,常见问题会一起出现:

  • 端到端延迟越来越长
  • 长任务容易超时
  • 相同前缀反复付费
  • 低优先级任务挤占高价值流量
  • 会话状态和后台任务混在一起,恢复困难

2026-07-09 可访问的 OpenAI Prompt cachingBackground modeBatchFlex processingPriority processingConversation stateWebhooksProduction best practices 官方资料来看,更稳的思路通常不是“一个模式跑天下”,而是:

  • 先按任务价值和时效要求分层
  • 再决定同步、后台、批量、低优先级和缓存策略

0.1 真正要治理的不是“用哪个模式”,而是“哪条运行 lane 承接哪类任务”

OpenAI 当前 Background modeBatchFlex processingPriority processingConversation stateProduction best practices 放在一起看,最值得先建立的一个共识是:

  • 这些能力不是零散开关
  • 它们更像不同的运行 lane

也就是说,一个成熟系统真正要回答的通常不是:

  • “我们要不要用 batch”

而是:

  • “这类任务应该走同步 lane、后台 lane、离线批处理 lane,还是低优先级节流 lane”

一旦 lane 分错,后面会出现的往往不是一点小抖动,而是:

  • 关键在线流量被低优先级任务挤爆
  • 长任务把连接撑死
  • 低价值任务花掉高价值 lane 的预算

1. 先把五类运行模式分开

1.1 同步请求

适合:

  • 用户正在等待结果
  • 首屏体验直接受影响
  • 结果必须立即返回

1.2 后台任务

适合:

  • 单次任务很长
  • 用户不需要一直保持连接
  • 允许排队、轮询和后取结果

1.3 批处理任务

适合:

  • 请求很多,但不要求实时
  • 可统一排队
  • 追求更低单位成本

1.4 低优先级弹性任务

适合:

  • 对时延不敏感
  • 更关心成本
  • 可容忍资源波动

1.5 缓存命中型请求

适合:

  • 大量共享稳定前缀
  • 前几段上下文高度重复
  • 想同时降成本和降延迟

2. Prompt caching 真正该怎么理解

OpenAI 当前 Prompt caching 明确说明:

  • 这是自动生效的
  • 可以显著降低输入成本和延迟

2.1 它最适合哪类系统

  • system prompt 很长
  • 公共规则很稳定
  • tool schema 重复出现
  • 多个请求共享相同前缀

2.2 更稳的 prompt 组织方式

OpenAI 当前关于缓存的资料都在强调一个要点:

  • 静态内容尽量放前面
  • 动态内容尽量放后面

2.3 最容易踩的坑

  • 把动态字段插到前缀中间。
  • 每次都重排工具说明顺序。
  • 相同任务却没有稳定的 prompt_cache_key 设计。

2.4 prompt caching 更像“前缀资产治理”,不只是省一点钱

很多团队会把 prompt caching 理解成一个纯成本优化开关。

但更长期有价值的视角通常是:

  • 哪些前缀值得被平台长期稳定化

例如:

  • system / developer instructions
  • 工具 schema
  • 公共 policy
  • 稳定工作流骨架

这带来的不只是成本收益,还会影响:

  • 前缀是否易于版本管理
  • release bundle 是否容易冻结
  • route bundle 是否能稳定复用

所以 prompt caching 往往反过来要求团队把 prompt 资产治理得更干净,而不是更随意。

2.5 缓存命中也要按 route / tenant / task bucket 看

如果只看全局命中率,很多问题会被掩盖:

  • 某条高频主路径命中很好
  • 某条高价值路径却因为前缀抖动几乎不命中

更稳的做法通常是按这些维度拆开看:

  • route bundle
  • task bucket
  • tenant tier
  • prompt version

这样你才能知道:

  • 是缓存策略没设计好
  • 还是某一类路径的 prompt 本来就不适合吃缓存

2.6 prompt_cache_key、保留时长和溢出率都要进运行设计

很多团队知道“有缓存”,但不知道真正应该治理哪些变量。

OpenAI 当前 Prompt caching 文档里,几个特别值得写进运行手册的点是:

  • 缓存通常依赖 prompt 初始前缀的哈希,常见是前 256 tokens 的前缀路由心智
  • prompt 至少到 1024 tokens 以上才真正具备缓存收益面
  • 可以通过 prompt_cache_key 影响路由和命中稳定性
  • 相同前缀与同一 prompt_cache_key 如果速率太高,官方文档提到大约在 15 RPM 量级可能出现 overflow,导致部分请求被分流到别的机器,命中率反而下降

这意味着缓存设计不该只看“有没有命中”,还要同时看:

  • 同一路由是否用了稳定的 prompt_cache_key
  • 某个热点前缀是否被单 key 打爆
  • prefix 版本切换时是否做了灰度,不要所有流量瞬时切前缀

同样要注意 retention policy:

  • in_memory 更偏短时命中,官方文档给出的典型心智是空闲 510 分钟,最长到 1 小时
  • 24h extended retention 更适合长周期重复任务,但也意味着你需要更认真地评估数据保留与区域处理要求

所以对生产团队来说,真正该治理的不是“开没开缓存”,而是:

  • 哪些 bundle 值得稳定成共享前缀
  • 哪些流量该共用 key
  • 哪些流量需要拆 key 防热点溢出
  • 哪些模型和项目该使用哪种 retention policy

3. Background mode 适合什么,不适合什么

OpenAI Background mode 当前最值得注意的几个点非常直接:

  • background=true 让长任务异步运行
  • 响应对象可以轮询状态
  • 支持取消
  • 也支持背景流式

3.1 它最适合的场景

  • 长推理
  • 长输出
  • 多步工具编排
  • 用户不需要卡在连接上等待

3.2 它不该被当成什么

它不等于:

  • 批处理
  • 实时聊天
  • 纯离线大规模补算

它更像:

  • 单任务级别的异步执行模式

3.3 运行设计里最该补的几件事

  1. 任务状态机。
  2. 轮询频率。
  3. 取消策略。
  4. 失败后怎么重试或转人工。

3.4 一个很容易忽视的边界

OpenAI 当前 Background mode 资料明确提到:

  • 它为了轮询会保留响应数据一段时间

这意味着后台任务模式不仅是运行问题,也会影响数据治理设计。

3.5 background job 最好有明确状态机

很多团队做后台任务时,只会记录:

  • pending
  • done
  • failed

但对真实 AI 长任务来说,这通常不够。

更稳的状态机往往至少包括:

  • queued
  • running
  • waiting_for_tool
  • waiting_for_review
  • cancelled
  • failed_retryable
  • failed_terminal
  • completed

这样一来,值班、回放和人工接管时才能真正回答:

  • 它现在卡在哪一段
  • 是该重试、该恢复,还是该转人工

3.6 长任务最好显式设计 checkpoint / resume point

很多 background 任务最大的坑不是:

  • 一次失败了

而是:

  • 失败后只能从头再跑

如果任务里包含:

  • 长推理
  • 多步工具调用
  • 审批等待
  • 多轮状态恢复

那么更稳的做法通常是为关键节点打 checkpoint,至少明确:

  • 哪一步之前的结果可复用
  • 哪一步之后必须重新算
  • 哪些外部副作用不能重放

否则重试策略很容易把系统从“可恢复”变成“重复执行事故”。

3.7 Background mode 最好和 webhook、stream cursor、ZDR 边界一起设计

OpenAI 当前 Background modeWebhooks 文档合起来看,有三个非常容易被忽略的运行点:

  1. background=true 适合把长任务从同步连接里拿开,但官方文档明确说明,它为了轮询会暂存响应数据,大约 10 分钟,因此不兼容 ZDR 保证。
  2. 如果同时启用 background=truestream=true,你可以拿到流式事件并记录 sequence_number,也就是更适合恢复的 stream cursor。
  3. 如果不想全靠轮询,官方 Webhooks 文档已经给出 response.completed 这一类事件入口,更适合做后台完成通知。

因此更稳的 background lane 通常不会只做“丢个任务然后轮询”,而是会同时补三层:

  • 控制面:任务状态机、取消接口、checkpoint、人工接管入口
  • 事件面:webhook 订阅、签名校验、重复投递去重、事件重放窗口
  • 客户端面:轮询退避、stream cursor 恢复、任务详情页

特别要注意的一点是,OpenAI 当前 webhook 文档明确说明:

  • webhook 端点要尽快回 2xx
  • 如果不成功会重试,最长可持续到 72 小时的指数退避交付

这意味着 webhook handler 最好只做:

  • 验签
  • 记录事件
  • 投递到你自己的 worker 队列

而不要在入口上直接做重计算或复杂数据库事务。

4. Batch 真正解决的是“批量异步且更便宜”

OpenAI 当前 Batch 明确说明:

  • 适合异步请求组
  • 有更高的独立限额池
  • 成本更低
  • 有明确的 24 小时交付心智

4.1 最适合放进 Batch 的任务

  • 批量标注
  • 离线评测
  • 数据 enrich
  • 夜间批量摘要
  • 大量历史文档抽取

4.2 不适合放进 Batch 的任务

  • 用户在等
  • 结果要秒级返回
  • 一次失败就需要即时人工接管

4.3 为什么它和 Background mode 不能混着想

二者都不是同步请求,但差别很大:

  • Background mode 更像“单个长任务异步跑”
  • Batch 更像“一大批请求成组离线跑”

4.4 Batch lane 最值得先单独隔离哪些流量

更适合优先放进 batch lane 的通常是:

  • 离线评测
  • 历史数据补算
  • 规则抽取回填
  • 全量归档摘要
  • 夜间大规模 enrich

这类流量如果混进主在线 lane,最常见的后果是:

  • 抢限额
  • 抬高成本曲线
  • 干扰核心用户时延

所以 batch 的价值往往不只是更便宜,而是:

  • 帮你把“本就不该在线跑的事”彻底从在线面拿开

4.5 Batch 不是“大请求列表”,它有自己的输入契约和失败语义

OpenAI 当前 Batch 官方文档已经把几个很关键的输入约束写得很清楚:

  • 输入文件是 .jsonl
  • 每一行都要带唯一的 custom_id
  • 每个输入文件只能对应单一模型
  • 当前 completion window 只有 24h
  • 单个 batch 最多 50,000 个请求,输入文件最大 200MB

这些限制的工程含义非常直接:

  • custom_id 不是装饰字段,它是你回收结果、定位失败和做增量重放的主键
  • 单模型输入意味着“按模型拆 batch”通常应该在作业装配阶段就完成
  • 24h completion window 说明 batch 更像“当天回收的离线作业”,不该被拿来承诺细粒度实时 SLA

更重要的是,Batch 有自己独立的失败语义。

OpenAI 当前文档明确说明:

  • Batch 使用和同步请求不同的独立 rate limit pool
  • 过期 batch 会进入 expired
  • 未完成的请求会被取消
  • 已完成部分仍然会产出 output file,并按已完成请求计费
  • 过期或错误请求会写进 error file

所以 batch lane 最值得先落下来的不是“怎么发请求”,而是这几个回收动作:

  1. custom_id 回填原始任务表。
  2. 对 output file 和 error file 做双文件回收。
  3. 只对失败或过期子集做增量重投,而不是整批重跑。
  4. 把 batch 结果与同步 / background lane 的产物对象统一到同一个 artifact schema。

5. Flex processing 适合放在哪一层

OpenAI Flex processing 当前明确说明:

  • 它更便宜
  • 但更慢
  • 也可能出现资源不可用

所以它更适合:

  • 非生产主路径
  • 非严格 SLA
  • 成本敏感的异步任务

5.1 更适合的场景

  • 离线评测
  • 数据改写
  • 大规模清洗
  • 回放补算

5.2 不适合的场景

  • 用户正等待页面返回
  • 线上关键业务
  • 严格交付时限任务

5.3 Flex 最适合做“成本兜底 lane”,而不是默认主路径

很多团队第一次看到更便宜,会想把更多任务往 flex 放。

但更稳的用法通常是:

  • 把 flex 当成成本敏感型 lane
  • 而不是主生产默认 lane

更典型的承载对象是:

  • 回放补算
  • 离线指标重算
  • 大量低优先级改写
  • 非紧急批量评测

也就是说,flex 解决的不是“所有任务都更省”,而是:

  • 某些可等待任务有没有更便宜的承载面

5.4 Flex 最好提前写好 fallback ladder,而不是 429 了再想办法

OpenAI 当前 Flex processing 文档里,有几个很实用但经常被漏掉的运行提醒:

  • Flex 可能更慢,所以官方示例直接把 SDK timeout 提到了 15 分钟
  • SDK 会自动重试一部分 408
  • Flex 可能返回 429 Resource Unavailable
  • 这类资源不可用错误不会计费

这意味着 flex lane 不适合只写成一句:

  • “低优先级任务走 flex”

更稳的设计通常会显式给出 fallback ladder:

  1. 先走 service_tier=flex
  2. 如果命中 429 Resource Unavailable,进入指数退避重试
  3. 超过重试阈值后,改投 background standard lane
  4. 如果任务已经过了业务最晚完成时刻,直接取消或转人工

同时最好明确每个任务 bucket 的:

  • 最大等待时长
  • 最大重试次数
  • 是否允许升级到 standard
  • 是否允许升级到 priority

否则 flex 很容易从“成本兜底 lane”演变成“没人知道什么时候能结束的黑箱队列”。

6. Priority processing 适合什么

OpenAI Priority processing 当前强调:

  • 更低且更稳定的延迟
  • 更适合高价值、面向用户、流量相对稳定的场景

6.1 更适合的场景

  • 关键在线问答
  • 重要客户工作台
  • 需要稳定时延的核心流程

6.2 不适合的场景

  • 数据补算
  • 测试洪峰
  • 评测回放
  • 高度突发的批量任务

6.3 Priority lane 最好有明确配额和资格门槛

如果把 priority 当成“谁都能走的快车道”,结果通常会很糟:

  • 成本抬升
  • 高价值任务反而失去稳定低延迟

更稳的做法通常会明确:

  • 哪些产品入口能走 priority
  • 哪些租户能走 priority
  • 哪些 bucket 允许升级进 priority
  • 进入 priority 后的观察指标和回退条件

这样它才更像:

  • 保关键时延目标的生产 lane

而不是:

  • 新功能一着急就乱开的加速按钮

6.4 Priority 还要注意共享限额和 ramp rate 降级

OpenAI 当前 Priority processing 文档明确提到两件很关键的事:

  • Priority 和 Standard 在同一模型上共享 rate limit 账户
  • 如果流量 ramp 太快,部分 priority 请求可能被降级回 standard,并在响应里体现为默认 tier

官方文档给出的当前心智是:

  • 如果已经来到至少 1M TPM
  • 并且 15 分钟内增幅超过 50%

就可能触发 ramp rate 保护。

这件事对生产治理的含义很大,因为它说明:

  • priority 不是独立无限资源池
  • 它更适合稳定高价值流量,而不是突发型迁移流量

因此更稳的上线方式通常是:

  • 用 feature flag 按小时级逐步切流,而不是一次性全量改路由
  • 避免把 ETL、eval replay 这类高度突发任务放进 priority
  • 单独监控 service_tier 实际落点,不只看请求时传了什么参数

另外,OpenAI 官方也明确说明:

  • cache discount 仍适用于 priority 请求

这意味着真正成熟的策略不是“要低延迟就不用管缓存”,而是:

  • 高价值同步 lane 也要继续吃前缀缓存收益

7. Conversation state 为什么会影响编排

OpenAI Conversation state 当前把多轮状态管理拿出来单讲,本身就说明:

  • 长会话
  • 多轮工具
  • 上下文恢复

不是简单把历史消息继续拼上去就能稳住。

7.1 更适合显式管理状态的场景

  • 长对话
  • 多页面连续任务
  • 后台任务恢复
  • 需要精确控制上下文范围的系统

7.2 更适合注意的边界

  • 哪些状态放模型上下文
  • 哪些状态只放运行时
  • 哪些状态必须持久化
  • 哪些状态只在本轮有效

7.3 状态分层最好和运行 lane 一起设计

很多团队把 conversation state 单独看成“会话问题”,但真实系统里它和 lane 设计是绑在一起的。

例如:

  • 同步 lane 更适合轻状态、短上下文
  • background lane 往往需要 resumable state
  • batch lane 通常更适合无会话或弱会话设计

如果状态分层没设计清楚,就很容易出现:

  • 在线请求带了太多历史状态
  • 后台任务恢复时拿不到关键上下文
  • 批处理任务错误复用了会话态

7.4 previous_response_idconversationstore=false 不是一回事

OpenAI 当前 Conversation stateMigrate to the Responses API 文档放在一起看,最值得团队统一的一个心智是:

  • “状态延续”至少有三种不同级别

第一种是:

  • previous_response_id

它适合把一轮接一轮的响应串起来,形成线程式上下文延续。对于很多短会话、多轮问答、单页面连续交互,这已经足够。

第二种是:

  • conversation

OpenAI 当前文档明确说明,Conversations API 会把 conversation 作为可长期存在的对象,能跨 session、device、job 继续使用;其中 items 可以包含 message、tool call、tool output 等。它更适合:

  • 多设备续聊
  • 多页面连续任务
  • 后台任务恢复后继续上下文
  • 需要把工具轨迹也当会话资产保留的系统

第三种是:

  • store=false 下的手动状态管理

如果你出于数据保留或合规原因不想默认保存 response,就要自己决定:

  • previous_response_id 还是手动回放 item
  • 是否需要带上 reasoning.encrypted_content
  • 哪些状态放你自己的数据库,哪些只在本轮使用

OpenAI 当前文档还明确指出:

  • 普通 response 默认保存 30
  • 但挂到 conversation 里的 items 不受 30 天 TTL 约束

所以 conversation state 设计绝不是“要不要记历史消息”这么简单,而是要一起回答:

  • 这个状态是短期线程态、长期会话态,还是合规受控态
  • 这个状态是否允许跨设备、跨任务、跨后台作业恢复
  • 这个状态是否需要脱离 OpenAI 对象,落到你自己的 durable store

8. 更稳的任务编排心智:先分价值,再分模式

8.1 高价值 + 强时效

更适合:

  • 同步
  • 流式
  • 必要时 priority

8.2 高价值 + 弱时效

更适合:

  • background
  • 明确状态机
  • 可取消与恢复

8.3 低价值 + 大批量

更适合:

  • batch
  • flex
  • 夜间补算

8.4 高频 + 前缀稳定

更适合:

  • prompt caching
  • 固定前缀治理

8.5 高风险 + 可等待

更适合:

  • background
  • 明确审批等待状态
  • 可恢复 checkpoint
  • 必要时人工接管

8.6 低价值 + 可中断

更适合:

  • flex
  • batch
  • 非高优先级 lane

这类区分很关键,因为很多团队把“异步”当成一种模式,但真实系统里:

  • 高价值异步
  • 低价值异步

其实应该走完全不同的控制面

9. 生产里最值得先绑定的几个指标

9.1 同步链路

  • p95 延迟
  • 首包时间
  • 工具等待时间
  • 超时率

9.2 后台链路

  • queued 时间
  • in_progress 时间
  • 取消率
  • 最终失败率

9.3 批处理链路

  • 批次完成率
  • 单请求均摊成本
  • 24 小时内交付率

9.4 缓存链路

  • cached tokens
  • 命中率
  • 命中后时延变化

9.5 状态链路

  • 会话恢复成功率
  • 背景任务续跑成功率
  • 人工接管率

9.6 lane 治理指标

  • 各 lane 请求占比
  • lane 间升级 / 回退比例
  • priority lane 占用率
  • flex / batch 对主生产 lane 的隔离效果
  • 因 incident mode 被强制改道的比例

这些指标很重要,因为很多系统的问题不是某一条请求坏了,而是:

  • 某类任务整体走错 lane 了

10. 最容易踩的坑

  • 把所有任务都做成同步请求。
  • 该批量的任务没批量,该后台的任务没后台。
  • 以为用了缓存就不用管 prompt 组织。
  • 把低优先级离线任务挤进主生产流量。
  • 长任务有状态,却没有恢复和取消模型。
  • 没有 checkpoint,长任务一失败就只能整条重跑。
  • 没有 lane 配额,高价值和低价值任务抢同一条资源池。
  • 把 flex 当默认主路径,而不是成本敏感补充 lane。
  • conversation state 和执行 lane 脱节,恢复时状态拿不回来。

11. 推荐搭配阅读

12. 重点官方资源

以下入口在 2026-07-09 检查时可访问:

13. 什么时候该跳到别的目录

  • 当你开始建设发布门禁、trace 基线和失败回流时,跳到 [05-可观测性、Tracing与Trace Grading](./05-可观测性、Tracing与Trace Grading)。
  • 当你开始治理更细的模型路由、缓存策略和成本优化时,跳到 平台工程
  • 当你开始治理审批等待、人工接管和事故恢复时,跳到 安全治理