structured outputs: claude vs openai, in practice
both anthropic and openai now offer structured outputs. they look like the same feature. they aren’t.
openai: a hard constraint
openai’s structured outputs — response_format: { type: "json_schema", schema } — is a hard constraint. the model can’t emit a token that would violate the schema. the upside: you never get malformed json. the downside: when the model “wants” to say “i don’t have enough information”, it can’t — the schema forces it to fill in the fields, and you get a confidently-wrong response.
anthropic: a strong suggestion
anthropic’s approach is softer. you describe the schema in the system prompt, you instruct the model to return json, and you parse. claude is good at it. it’s not guaranteed. the upside: claude can refuse, ask for clarification, or return partial results — the schema isn’t a straitjacket. the downside: you need to handle malformed responses.
what i do in practice
- if i’m confident the model has enough context to answer, openai’s mode is one less thing to handle.
- if i’m running a workflow where “i don’t know” is a valid answer, claude is less likely to hallucinate a structured lie.
- for tool-use specifically, both models accept json schema and behave similarly. tool calls are where this matters most.
the bug i hit twice before learning: openai’s structured-outputs mode silently makes every field required unless explicitly marked optional. claude does what the schema says. if i was migrating between providers, i’d run my schemas through a validator first.
the meta point: “structured output” sounds like a uniform feature. it isn’t. one provider’s hard constraint is the other’s strong suggestion. that affects which failure modes you build around.