← capítulo

Salida estructurada y modo JSON

Capítulo 5 · deja de parsear prosa, empieza a declarar schemas

La hora

El problema

El modelo te entrega un string.

Está bien para un humano. Es un bug en cuanto lo lee código — el día que antepone "Sure! Here's the JSON:" a la respuesta.

El schema es el contrato

class CalendarEvent(BaseModel):
    name: str
    date: str
    participants: list[str]

Declara la forma una vez. Ambos proveedores la hacen cumplir.

OpenAI: responses.parse

response = client.responses.parse(
    model="gpt-5.4-nano",
    input=f"Extract the event:\n{TEXT}",
    text_format=CalendarEvent,
)
event = response.output_parsed   # a real CalendarEvent

Se hace cumplir al decodificar, no se sugiere en el prompt.

Gemini: response_schema

response = client.models.generate_content(
    model="gemini-3.1-flash-lite",
    contents=f"Extract the event:\n{TEXT}",
    config=types.GenerateContentConfig(
        response_mime_type="application/json",
        response_schema=CalendarEvent,
    ),
)
event = response.parsed

El mismo modelo, dos SDKs

Un solo modelo de Pydantic. text_format en OpenAI, response_schema en Gemini. La forma deja de ser un asunto por proveedor.

Ponlo a trabajar — tres apps

Cada una es una app web con docker compose up.

Conclusión

Cuando el output alimenta código, declara un schema. Convierte "casi siempre parseable" en "validado o falló". "Casi siempre" es la frase que te despierta a las 2am.