Prompt 已是结构化对象,但还不是可直接发送的 JSON。ModelClient 在每次请求尝试中重新编译模型、Input、工具、Reasoning、输出 Schema、缓存键和 Provider 特例,并在网络前清理不能跨 Provider 的内部元数据。
具体问题与启用条件
本节逐项说明请求 body 的编译合同。Lite 的方言差异已在 5.4 解释,输出 Schema 的服务端校验边界在 5.24。
| 条件来源 | 决定字段或状态 | 对本机制的影响 |
|---|---|---|
| 模型 | verbosity、reasoning summary、Lite、tool 能力 | 控制字段存在性 |
| Provider | OpenAI/Azure、认证模式 | 控制 store、内部 metadata 和请求压缩 |
| Prompt | tools、parallel、output_schema | 提供本次采样约束 |
协议、类型与状态所有权
| 状态或协议 | 所有者 | 生命周期 | 关键不变量 |
|---|---|---|---|
| Prompt | Turn/Step | 逻辑采样 | 不含传输身份 |
| ResponsesApiRequest | ModelClient | 一次尝试 | 完整描述模型可见请求 |
| Raw tools JSON | 序列化缓存 | 请求内共享 | 内容相等可用于增量比较 |
| 临时 item IDs/metadata | 请求准备阶段 | 线请求 | 非目标 Provider 前清除 |
机制调用链如下:
Prompt
→ clone/格式化 Input
→ 清理内部 metadata 与不允许的 Item ID
→ ToolSpec 序列化为 Raw JSON
→ 按能力构造 reasoning/text
→ 加入 cache key、service tier、store/stream
→ ResponsesApiRequest
→ JSON body 或 response.create
机制怎样工作
请求固定包含 model、input、tool_choice=auto、stream=true 和 include=[reasoning.encrypted_content]。Base Instructions、tools 与 parallel 字段按标准/Lite 分支产生。Reasoning effort 使用显式值或模型默认,summary 仅在模型支持时加入;verbosity 同理。输出 Schema 被包装为 text.format={type: json_schema, name: codex_output_schema, strict, schema}。
序列化前还有协议卫生处理。发往非 OpenAI Provider 时,内部 chat metadata 与 encrypted function args 会被清掉,避免把私有字段泄漏给兼容端。没有约定前缀的服务端 Item ID 也会被清除,以免把旧服务的对象标识当作新请求可引用对象。store 只在 Azure 特例开启,请求压缩只在 OpenAI Codex backend 且配置启用时使用 zstd。
Python 风格伪代码
这段伪代码保留生产实现中会改变结果的状态、分支和异步边界;认证 SDK、遥测字段和 Rust 所有权样板被折叠为明确的领域对象。
def compile_request(prompt: Prompt, model: ModelInfo, provider: Provider) -> Request:
items = format_input(prompt.input, lite=model.use_responses_lite)
if not provider.is_openai:
for item in items:
item.drop_internal_metadata_and_encrypted_args()
for item in items:
if not item.id_has_server_prefix():
item.id = None
return Request(
model=model.slug,
instructions=compile_instructions(prompt, model),
input=items,
tools=compile_tools(prompt, model),
tool_choice="auto",
parallel_tool_calls=parallel_allowed(prompt, model),
reasoning=reasoning_controls(model),
text=text_controls(model.verbosity, prompt.output_schema,
prompt.output_schema_strict),
include=["reasoning.encrypted_content"],
stream=True,
store=provider.is_azure,
prompt_cache_key=session_cache_key(),
)
失败、取消与恢复
| 故障或边界 | 已发生的状态 | 对上层的结果 | 能否直接重试 | 恢复动作 |
|---|---|---|---|---|
| ToolSpec 无法序列化 | 尚未联网 | JSON/请求构造错误 | 否 | 修复工具 Schema |
| 输出 Schema 非法 | 可能已进入请求 body | 服务端 InvalidRequest | 否 | 修正 Schema |
| 私有 metadata 发往兼容 Provider | 存在泄漏风险 | 兼容性或安全错误 | 否 | 请求前清理 |
| 临时 Item ID 被复用 | 引用语义不可信 | 服务端拒绝或串错对象 | 否 | 按前缀清除 |
设计取舍与验证
每次尝试重建请求比缓存整份 JSON 更耗 CPU,但能读取最新认证、History 和能力状态,也让 HTTP/WS 共用同一逻辑请求。RawValue 缓存工具 JSON减少重复编码;其内容相等仍参与增量请求属性比较。Provider 特例集中在编译边界,避免污染 Prompt。
| 可验证契约 | 证据方式 | 预期结果 |
|---|---|---|
| Schema 映射包含 name/type/strict | 序列化单元测试 | text.format 精确匹配 |
| 非 OpenAI 清理内部字段 | 请求捕获 | 私有 metadata 不在线上 |
| 标准与 WS response.create 逻辑字段一致 | 双协议序列化测试 | 除 type/previous/generate 外相同 |
Mini Codex 对照
Mini Codex 应把编译器写成接近纯函数,返回可测试 dict;传输适配器只负责编码和发送。可以省略 Azure store 与 zstd,但要保留内部字段清理和 output schema 映射。
本节边界
至此请求 JSON 已经确定。5.7 从 HTTP POST 建立 SSE 开始,追踪返回事件怎样形成成功或失败终态。
评论
登录后即可评论