同一套 tools,create 能用,parse 却报 is not strict,该改哪里
parse 的 is not strict 异常发生在请求发送前。需要自动解析工具参数时生成合规的严格 schema;保留非 strict 工具时继续用 create,并单独校验回答文本。
同一套 tools,create 能用,parse 却报 is not strict,该改哪里
把 client.chat.completions.create() 换成 parse(),本想少写几行 JSON 校验,结果请求还没发出就抛出:
Only `strict` function tools can be auto-parsed
先确认异常类型和堆栈。官方 issue #1733 的讨论明确指出,这个 ValueError 来自 SDK 的自动解析助手,发生在发送 HTTP 请求之前。它不能直接当成服务端的 HTTP 400,更不能推出所有工具调用都必须与结构化回答绑定。官方说明
历史复现使用 openai 1.47.0 的 beta.chat.completions.parse。以下示例以 openai 1.109.1、Pydantic 2 为基线,使用 client.chat.completions.parse;其他版本应先核对入口和类型接口。
先决定要自动解析什么
如果你希望 SDK 把工具参数直接还原成 Pydantic 对象,可以用公开的 pydantic_function_tool() 构造工具定义。下面先只生成 schema,不发送请求:
from pydantic import BaseModel
from openai import pydantic_function_tool
class SearchDocs(BaseModel):
query: str
tool = pydantic_function_tool(SearchDocs, name="search_docs")
assert tool["function"]["strict"] is True
assert tool["function"]["parameters"]["additionalProperties"] is False
然后把生成的工具交给 parse:
import os
from openai import OpenAI
with OpenAI(api_key=os.environ["OPENAI_API_KEY"]) as client:
completion = client.chat.completions.parse(
model=os.environ["OPENAI_MODEL"],
messages=[{"role": "user", "content": "查找客户端超时配置"}],
tools=[tool],
)
for call in completion.choices[0].message.tool_calls or []:
if call.function.name == "search_docs":
args = call.function.parsed_arguments
assert isinstance(args, SearchDocs)
print("工具参数已完成类型校验")
第二段需接在第一段之后,运行会调用模型并可能计费。它只读取参数,不执行搜索函数。SDK 支持这种自动工具参数解析方式;不需要自行导入下划线开头的内部转换函数。SDK 解析助手
自己手写 schema 时,仅添加 strict: true 还不够。对象属性、必填项以及嵌套对象都要满足服务端支持的严格 schema 约束。对简单工具可以先用公开 helper,复杂结构则逐层核对,避免本地检查通过后又遇到服务端 schema 错误。
原工具必须保持非 strict,就保留 create
有的项目会保留可选参数,或由现有系统处理宽松的工具输入。此时不必为了使用 parse() 改掉整套业务接口。
继续使用 create();若需要结构化的最终文本,传入明确的 json_schema response format,再自行验证文本。下面是一个简单、完整的格式定义,可作为现有 create 调用的 response_format 参数:
response_format = {
"type": "json_schema",
"json_schema": {
"name": "answer",
"strict": True,
"schema": {
"type": "object",
"properties": {"answer": {"type": "string"}},
"required": ["answer"],
"additionalProperties": False,
},
},
}
工具参数和回答文本是两条需要分别处理的数据。遇到工具调用先处理工具分支;遇到拒绝、截断或没有文本时,不要直接对 message.content 运行 JSON 解析。合法 JSON 也需要再检查必需字段和业务约束。结构化输出指南
验收看三件事
- 原来的本地 strict 异常消失,实际发送的工具定义符合选择的路线
- 工具被调用时,参数通过你的校验;工具没被调用时,空列表不会导致越界
- 拒绝、输出截断和非法参数各有失败分支,不能把 HTTP 200 当成全部验收


