OpenAI Agents SDK 工程笔记:ModelSettings.prompt_cache_retention 提示缓存保留策略、24h 延长缓存与生产禁区
账单里写着已开 24h 延长提示缓存,命中率却几乎不动。变更单里只有一行 prompt_cache_retention="24h",稳定前缀里仍塞着每回合变的时间戳和租户密文。缓存前缀对不上,保留再久也打不中。另一边有人把 in_memory 理解成没落盘所以密钥可以写进系统提示,审计还把请求里根本没出现的字段记成已声明 24h。
这篇只讲保留策略这一道闸。结论全部在 openai-agents 0.23.1 的 model_settings.py 与两条 model adapter 上核对过,离线假请求脚本不调用真实模型,结果落在 _w/fail-smoke/retention.csv。

图注 左侧为 0.23.1 实测取值与发出行为,右侧为四类种植失败。
源码里的字段与接线
ModelSettings.prompt_cache_retention 类型是 Literal["in_memory", "24h"] | None,默认 None。
| 取值 | 发出行为 |
|---|---|
None(默认) | 请求体不带该键,走厂商默认 |
in_memory | 原样写入 prompt_cache_retention |
24h | 原样写入,打开延长提示缓存,前缀最多保持 24 小时 |
Chat Completions 与 Responses 两条路径都经 _non_null_or_omit 转发。None 不会变成空字符串,也不会被改写成 in_memory。文档写明,设为 24h 才打开延长提示缓存。
它和 prompt_cache_options 不是同一旋钮。后者用形如 {"mode": "explicit", "ttl": "30m"} 的配置配内容块断点,管哪一段能进缓存。prompt_cache_retention 管命中的前缀保留多久。混成一个旋钮,验收会同时读错两张表。
离线 smoke 四类种植失败
脚本直接构造 ModelSettings,模拟 adapter 的非空才写入规则,并对假前缀做稳定性检查。
| case | 配置 | 结果 | 说明 |
|---|---|---|---|
| baseline_none_omitted | None | 请求无该键 | 健康默认 |
| healthy_24h_stable_prefix | 24h | 键=24h 且前缀稳定 | 健康路径 |
| healthy_in_memory | in_memory | 键原样发出 | 健康路径 |
| F1_drift_prefix_claim_24h | 24h | 前缀每回漂移仍宣称省钱 | 命中 F1 |
| F2_in_memory_as_secret_vault | in_memory | 把 in_memory 当可塞密钥 | 命中 F2 |
| F3_retention_vs_options_ttl | 24h+options | 两旋钮并存仍宣称已钉死 | 命中 F3 |
| F4_none_audited_as_24h | None | 省略却按 24h 审计 | 命中 F4 |
F1 最常见。系统提示模板每次渲染都带当前时间、请求号或租户密文,前四十个字符已经对不上。配置写着 24h,命中标志长期为未命中,财务却按已开延长缓存报省钱。SDK 不会替你检查前缀是否稳定。
F2 出在安全叙事。in_memory 只是保留策略字面量,不是未落盘许可。密钥、会话令牌、客户隐私写进稳定前缀,保留策略挡不住泄露面。正确做法是密钥名与索取位置写进流程,密钥本身不进提示。
F3 出在配置命名。有人同时设 prompt_cache_retention="24h" 和 prompt_cache_options={"ttl":"30m"},对外只说缓存策略已钉死。两个字段都会进请求体,监控若只采其中一个,故障时无法判断是保留时长错了还是断点 ttl 错了。
F4 出在审计。None 表示请求省略该键。若变更单和监控把省略写成已声明 24h 或 in_memory,事后对账会对不上实际发出的参数快照。审计必须落实际发出的字面量,省略就记 omitted。
推荐契约
from agents import ModelSettings
model_settings = ModelSettings(
prompt_cache_retention="24h", # 生产要延长命中时显式声明;禁止把 None 写成已开 24h
# prompt_cache_options 另列变更单,勿与 retention 混成一个旋钮
)
# 监控必须同时落:发出的 retention 字面量、前缀指纹、缓存命中/未命中
契约五条。一,生产若依赖延长缓存,必须显式 "24h",禁止把 None 解释成已声明策略。二,稳定前缀禁止每回漂移的时间戳、请求号、租户密文。三,prompt_cache_retention 与 prompt_cache_options 分列变更单与监控列。四,in_memory 不得写成密钥可写许可。五,审计字段写实际发出值,省略记 omitted。
生产禁区
| 禁区 | 为什么 |
|---|---|
| 前缀每回漂移仍宣称 24h 省钱 | F1 命中率为零 |
| 把 in_memory 当可塞密钥 | F2 扩大泄露面 |
| retention 与 options.ttl 混成一旋钮 | F3 故障不可定位 |
| None 省略却按 24h 审计 | F4 对账失败 |
| 多租户共用同一长前缀却不落租户隔离 | 串扰与误命中 |
| 只看最终成功不落命中标志 | 假省钱长期绿 |
当天最小实验
九十分钟够用。准备三段假系统前缀,一段稳定,两段带时间戳漂移。
- 基线
None,断言请求体无prompt_cache_retention,记 CSV。 - 设
24h且前缀稳定,断言键发出且 claim 合法。 - 种植 F1,漂移前缀加 claim_24h,断言失败。
- 种植 F2,
in_memory加密钥进前缀加 claim_secret_ok,断言失败。 - 种植 F3,retention 与 options 同开且宣称同一旋钮,断言失败。
- 种植 F4,None 却 audit_as=24h,断言失败。
- 提交 runbook,生产显式字面量,监控三列。
验收要看四类种植失败能否稳定复现,并且 prompt_cache_retention、前缀指纹、命中标志可查。少改几次提示词不能代替这些字段。
和相邻旋钮并排验收
第一,preserve_raw_usage 管的是原始用量载荷是否保留,不决定缓存保留多久。第二,prompt_cache_options 管断点与内容块 ttl。第三,本字段只管保留策略字面量是否发出、发成什么。三套都写成缓存已经优化却只打开其中一套时,事故会表现为配置绿、命中红。
并排最小做法是同一份假脚本输出表,列包含 case、retention、emitted_key、prefix_stable、claim_24h、fail。任一 F1 到 F4 命中不得进入生产。
变更单里要写明的三句话
- 本变更显式设置
ModelSettings.prompt_cache_retention为24h或in_memory,并附前缀稳定性说明。 - CI 增加省略审计、漂移前缀、双旋钮混用三类种植用例。
- 监控已采发出字面量、前缀指纹、命中/未命中。省略却宣称 24h,或命中长期为零却宣称省钱时开缺陷。
审计字段最少清单
每次请求至少落 run_id、prompt_cache_retention_emitted、prefix_fingerprint、cache_hit、prompt_cache_options_present。缺发出字面量或命中标志,F4 与假省钱会长期绿着。
预发口令
第一,发出字面量是不是和变更单一致?None 不得写成已开 24h。第二,稳定前缀是否去掉每回漂移字段?第三,retention 与 options 是否分列?三句都过,提示缓存保留策略才算起作用。
如何做稳定前缀
把会变的内容挪出缓存前缀。时间戳、trace id、用户原文、租户密钥放在可变段。角色设定、工具清单摘要、长期政策放在稳定段。预发用同一用户连打十次,比对前缀指纹。指纹抖动超过约定阈值,先修模板再谈 24h。
多租户不要共用一段含权限说明的长前缀。隔离可以靠独立部署、独立缓存命名空间或把租户标识放进不可缓存段。监控要能按租户看命中率,避免平均值盖住某一租户的零命中。
与账单、容量规划的叠加
延长缓存省的是重复前缀的计费与延迟。前缀不稳时,账单不会自动变好看,只会多一项已开 24h 的自我安慰。容量规划应同时看缓存命中率、未命中时的全量提示长度、以及因漂移导致的重复写入。
版本升级时重点看 prompt_cache_retention 是否仍经 _non_null_or_omit 转发,以及 prompt_cache_options 字段形状有没有变。接口漂移就冻结策略变更,先修种植脚本。
值班排障顺序
命中率掉零时,先不要只怪模型。先读发出参数快照里的 prompt_cache_retention。若是 omitted 却宣称 24h,先改审计与变更单。若已是 24h,再比对前缀指纹是否抖动。指纹稳而仍不命中,再查供应商侧状态与 prompt_cache_options 断点。把这一顺序写进值班手册,能减少先改模型、后发现前缀每回都在变的循环。
适用边界
适合已经固定系统前缀、需要把保留策略钉死并可审计的生产链路。不适合指望设了 24h 就自动省钱,也不适合把保留策略当成密钥保险箱。失败含义是请求可能仍成功,但命中率、账单与审计会对不上你的宣称。
数字与行为均按本机 openai-agents 0.23.1 核实。默认 None 表示省略。in_memory 与 24h 原样发出。离线 CSV 见 _w/fail-smoke/retention.csv。若你升级次版本,先重跑种植脚本再改 runbook,不把本文当永恒接口说明书。
失败注入与回归节奏
每次改系统提示模板或租户隔离方案,先跑种植包再合入。回归最小集就是本文 CSV 中的基线、healthy_24h 与 F1 到 F4。若新增显式断点路径,另开一行测 prompt_cache_options,不得借用 retention 字面量冒充断点已配好。
排障时先问三句。发出快照里的 retention 是什么?前缀指纹相对上一小时有没有变?命中标志是什么?三句对不上,先修观测再谈调参。对得上且命中长期为零,再去看前缀内容与供应商侧状态。
把种植包里的 F1 与 F4 当作假省钱和假审计的复现件。值班手册里写明,先对字段,再改模型。
与财务对账的最小约定
财务按已开延长缓存估算节省时,必须附带同期命中率。命中率低于约定阈值,不得把配置字面量写成已兑现节省。对账表至少含发出字面量占比、稳定前缀占比、命中率、未命中全量提示长度。缺一列,假省钱就能过会。
预发和生产用同一套种植包。预发只跑健康路径、生产只看账单,是 F1 与 F4 最喜欢的土壤。
更多推荐


所有评论(0)