JSON Mode Intermediate
JSON mode constrains the model to output valid JSON. The provider guarantees that the response will be parseable JSON, eliminating the most common failure mode of structured output: invalid syntax.
OpenAI JSON Mode
Python
from openai import OpenAI import json client = OpenAI() # Basic JSON mode response = client.chat.completions.create( model="gpt-4o", response_format={"type": "json_object"}, messages=[ {"role": "system", "content": "Extract data as JSON."}, {"role": "user", "content": "Alice is 30 and lives in NYC."} ] ) data = json.loads(response.choices[0].message.content) # {"name": "Alice", "age": 30, "city": "NYC"}
OpenAI Requirement: When using
response_format: {"type": "json_object"}, you must include the word "JSON" in either the system or user message. Otherwise, the API returns an error.
OpenAI Structured Outputs (Schema-Enforced)
OpenAI also offers a stricter mode that enforces a specific JSON Schema:
Python
response = client.chat.completions.create(
model="gpt-4o",
response_format={
"type": "json_schema",
"json_schema": {
"name": "person",
"strict": True,
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"age": {"type": "integer"},
"city": {"type": "string"}
},
"required": ["name", "age", "city"],
"additionalProperties": False
}
}
},
messages=[
{"role": "user", "content": "Alice is 30 and lives in NYC."}
]
)
# Guaranteed to match the schema exactly
Anthropic JSON via Tool Use
Anthropic does not have a dedicated JSON mode, but you can use tool use to get structured JSON output:
Python
import anthropic client = anthropic.Anthropic() response = client.messages.create( model="claude-sonnet-4-20250514", max_tokens=1024, tools=[{ "name": "extract_person", "description": "Extract person information from text.", "input_schema": { "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "integer"}, "city": {"type": "string"} }, "required": ["name", "age", "city"] } }], tool_choice={"type": "tool", "name": "extract_person"}, messages=[ {"role": "user", "content": "Alice is 30 and lives in NYC."} ] ) # Extract the structured data from tool_use block tool_block = next(b for b in response.content if b.type == "tool_use") data = tool_block.input # {"name": "Alice", "age": 30, "city": "NYC"}
Google Gemini JSON Mode
Python
import google.generativeai as genai model = genai.GenerativeModel("gemini-2.0-flash") response = model.generate_content( "Extract: Alice is 30 and lives in NYC.", generation_config=genai.GenerationConfig( response_mime_type="application/json", response_schema={ "type": "object", "properties": { "name": {"type": "string"}, "age": {"type": "integer"}, "city": {"type": "string"} } } ) )
Comparison Table
| Feature | OpenAI JSON Mode | OpenAI Structured | Anthropic (Tool) | |
|---|---|---|---|---|
| Valid JSON guaranteed | Yes | Yes | Yes | Yes |
| Schema enforcement | No | Yes | Partial | Yes |
| Requires schema | No | Yes | Yes | Optional |
Best Practice: When possible, use schema-enforced structured output rather than plain JSON mode. Plain JSON mode guarantees valid JSON but not the correct structure. Schema enforcement guarantees both.