When using LLM structured output, is the "required" field in your JSON schema... actually required?
That was my starting question, so I ran a simple test across OpenAI, Anthropic, and Gemini: a schema with name, birth_date, and death_date. I tested it on a living person, so death_date has no meaningful value.
OPENAI
OpenAI structured output has a strict parameter. That changes things significantly.
With strict=False, the schema is a best-effort guide. With death_date not in required, the model included it anyway as an empty string.
With strict=True, two hard constraints are enforced at the API level: every property must be in required, and additionalProperties must be False. Break either and you get a 400 error. No optional fields. But with no way to express null, the model returns an empty string for death_date.
The fix: mark the type as ["string", "null"]. The field stays required, the model returns null.
ANTHROPIC
Anthropic actually respects the required field. Death_date not in required? Omitted. Required but not nullable? Empty string. Nullable? Null. Same syntax as OpenAI: ["string", "null"]. Perfectly consistent across every run.
Anthropic has no strict mode, but additionalProperties: False is always mandatory, skip it and you get a 400 error.
GEMINI
Gemini is the most surprising. When death_date is not required, the behavior is non-deterministic: sometimes omitted, sometimes included as '', 'null', or 'N/A'. Add it to required and it's always present, but the model still picks whatever string it feels like to represent "no value".
Without a way to express null, Gemini is just inconsistent. The fix is nullable, but the syntax differs. Instead of ["string", "null"] like OpenAI and Anthropic, Gemini uses "nullable": True (the documentation says ["string", "null"] is supported, but the Python SDK won't accept it). Only then does it consistently return null. On a side note, additionalProperties is not supported and throws a 400 error if present.
CONCLUSION
So, is "required" actually required? It depends on the provider. But the real answer is: always use nullable for fields that may have no value, regardless of provider.
#LLM #AI #Python #StructuredOutput #OpenAI #Anthropic #Gemini
4