It is absolutely easy to verify Union of a string, object or other JSON type with null works.
Output just received:
completion.choices[0].message.content
'{"q":null,"r":null}'
Using schema:
{
"$defs": {
"Q": {
"additionalProperties": false,
"properties": {
"a": {
"const": 1,
"title": "A",
"type": "integer"
}
},
"required": [
"a"
],
"title": "Q",
"type": "object"
},
"R": {
"additionalProperties": false,
"properties": {
"a": {
"const": 3,
"title": "A",
"type": "integer"
}
},
"required": [
"a"
],
"title": "R",
"type": "object"
}
},
"additionalProperties": false,
"properties": {
"q": {
"anyOf": [
{
"$ref": "#/$defs/Q"
},
{
"type": "null"
}
],
"default": null
},
"r": {
"anyOf": [
{
"$ref": "#/$defs/R"
},
{
"type": "null"
}
],
"default": null
}
},
"title": "Z",
"type": "object"
}
and the code to produce it:
import openai
client = openai.Client()
from pydantic import BaseModel, ConfigDict
from typing import Literal, Union
import json
# First schema: q with a=1, b=2
class Q(BaseModel):
a: Literal[1]
model_config = ConfigDict(extra='forbid')
# Second schema: r with a=3, b=3
class R(BaseModel):
a: Literal[3]
model_config = ConfigDict(extra='forbid')
# Top-level schema using Union (anyOf)
class Z(BaseModel):
q: Union[Q, None] = None
r: Union[R, None] = None
model_config = ConfigDict(extra='forbid')
print(json.dumps(Z.model_json_schema(), indent=3))
text = "Produce a response with no subschemas"
completion = client.beta.chat.completions.parse(
model="gpt-4o",
messages=[
{"role": "system", "content": "You write JSON, choosing anyOf schemas."},
{"role": "user", "content": text},
],
response_format=Z,
)
And then the enterprising person will also see it works on [str, None] even in combination with string enums, etc, only guided by the AI’s understanding of what you want.
So you can cool your jets there mad dog, and if you actually want to discover a solution (instead of badgering 8 month old topics) - present your use case, application, and then you might discover if it is a model quality issue, a schema construction issue, or the inability for the AI to understand what you want.