结构化输出遇到拒绝回复,怎样让它进入明确状态而不是 JSON 解析重试
结构化输出请求也可能得到拒绝内容。客户端若对每一段文本直接执行 JSON 解析,拒绝会被误记成格式错误,然后进入“再试一次、修成 JSON”的循环。应先按官方响应信封和内容类型路由,再决定哪些内容可进入业务解析。
拒绝不是一种坏格式
OpenAI 官方结构化输出资料单独说明 refusal 的处理,Responses 示例中它属于消息内容类型。本文先确认生命周期状态,再遍历消息内容,识别拒绝项。拒绝理由作为拒绝状态的信息保存,业务 payload 保持不可用,不把理由字符串塞进业务 Schema。
这一顺序也避免把合法的拒绝说明误当答案。比如界面显示“暂无法处理此请求”,可以给用户明确状态;后台却不能同时写入一条“提取成功、内容为空”的业务记录。成功空值和拒绝在统计、重试与人工介入方面都有不同含义。
三个合成信封独立验收
附件准备 completed 且带合法 JSON、completed 且带 refusal,以及 completed 但正文是非法 JSON 三种样本。预期分别得到 accepted、refused 和 parse_error。检查器记录格式修复分支的计数,拒绝项必须触发零次修复。这里的修复只是本地计数器,没有调用另一模型,也没有发起真实重试。
失败反例是先提取所有可显示文字,合成一个字符串再尝试解析;它丢掉了内容类型这一证据。另一个反例是检查字符串是否含“抱歉”,普通答案也可能包含这个词,无法稳定识别拒绝。类型字段与生命周期状态应按精确协议值读取,不能靠自然语言关键词猜测。
混合或未知内容需要保守合同
实际响应可能含多种输出项。应用应定义自己需要哪类结果、允许多少个业务文本块,出现拒绝与业务文本混合时如何处置。本例采取拒绝优先隔离,不从剩余片段拼出一个看起来能用的对象。这是本文应用合同,不把它冒称为所有客户端的官方默认策略。
拒绝状态也不自动等于账号权限不足、网络故障或请求参数错误。那些情况可能发生在不同层,应保留独立错误代码。日志只保留定位所需的安全信息,避免将敏感请求与拒绝理由全文扩散到多个系统。
后续是否允许修改任务后再次请求,应由业务与用户意图决定,不能在解析器里偷偷执行。本文样本只核对已有合成响应的状态流转,不测试真实模型的安全策略或拒绝概率。验收报告应写“拒绝路由与零修复分支通过”,不写“结构化输出请求均已成功”。
配套文件与依据
本文的合成输入和参考结果可下载独立样本 a018.json,离线检查器 a018.py与样本放在同一目录后运行。检查器不调用模型接口。 使用 Python 3.12 或兼容版本,将上述文件下载到同一目录,执行 python a018.py。
留言讨论
评论发布后会被人工复核,违规内容将被删除。
如果发表没有反应,可以前往联系我们告诉我们。