Comparación de la salida estructurada entre proveedores populares de LLM: OpenAI, Gemini, Anthropic, Mistral y AWS Bedrock
Las APIs ligeramente diferentes requieren un enfoque especial.
A continuación, se presenta una comparación de soporte lado a lado de salida estructurada (obtener JSON de forma confiable) entre los principales proveedores de LLM, además de ejemplos mínimos en Python

Ya hemos revisado cómo solicitar salida estructurada del LLM alojado en Ollama. Una vez que el JSON vuelve por la red, la validación de salida estructurada de LLM en Python que funciona explica cómo analizar, realizar comprobaciones con Pydantic, reintentos y pruebas en su servicio. Aquí revisamos cómo solicitar lo mismo de otros proveedores.
Matriz TL;DR
| Proveedor | Modo “JSON” nativo | Aplicación de Esquema de JSON | Parámetro típico | Notas |
|---|---|---|---|---|
| OpenAI | Sí | Sí (de primer nivel) | response_format={"type":"json_schema", ...} |
Funciona a través de la API de Respuestas o Completions de Chat; también puede hacer llamada de funciones. |
| Google Gemini | Sí | Sí (de primer nivel) | response_schema= + response_mime_type="application/json" |
Devuelve JSON estrictamente validado cuando se establece un esquema. |
| Anthropic (Claude) | Indirecto | Sí (a través de Uso de Herramientas con esquema JSON) | tools=[{input_schema=...}] + tool_choice |
Fuerza al modelo a “llamar” a su herramienta definida por el esquema; produce argumentos con forma de esquema. |
| Mistral | Sí | Parcial (solo JSON; sin esquema del servidor) | response_format={"type":"json_object"} |
Asegura JSON, pero usted valida contra su esquema en el lado del cliente. |
| AWS Bedrock (plataforma) | Varía según el modelo | Sí (a través del esquema Tool/Converse) | toolConfig.tools[].toolSpec.inputSchema |
La API Converse de Bedrock valida la entrada de la herramienta contra un esquema JSON. |
Salida Estructurada de LLM - Información General
La salida estructurada de LLM se refiere a la capacidad de los modelos de lenguaje grandes (LLMs) para generar respuestas que se adhieren estrictamente a un formato o estructura predefinido y específico, en lugar de producir texto libre. Esta salida estructurada puede estar en formatos como JSON, XML, tablas o plantillas, lo que hace que los datos sean legibles por máquina, consistentes y fácilmente analizables por software para su uso en diversas aplicaciones.
Las salidas estructuradas difieren de las salidas tradicionales de LLM, que generalmente generan texto de lenguaje natural abierto. En cambio, las salidas estructuradas imponen un esquema o formato, como objetos JSON con claves y tipos de valores definidos, o clases específicas en la salida (p. ej., respuestas de opción múltiple, clases de sentimiento o formatos de filas de base de datos). Este enfoque mejora la confiabilidad, reduce errores e alucinaciones y simplifica la integración en sistemas como bases de datos, API o flujos de trabajo.
La generación de salidas estructuradas en LLMs a menudo involucra técnicas como:
- Especificar instrucciones detalladas del prompt para guiar al modelo a producir salida en el formato deseado.
- Utilizar herramientas de validación y análisis como Pydantic en Python para asegurar que la salida coincida con el esquema.
- A veces, imponer restricciones de decodificación basadas en gramática o autómatas finitos de estado para asegurar el cumplimiento a nivel de tokens con el formato.
Los beneficios de las salidas estructuradas de LLM incluyen:
- Legibilidad por máquina y facilidad de integración.
- Reducción de variabilidad y errores.
- Mejora de la predictibilidad y verificabilidad para tareas que requieren formatos de datos consistentes.
Los desafíos incluyen el diseño de esquemas efectivos, el manejo de datos anidados complejos y posibles limitaciones en las capacidades de razonamiento en comparación con la generación de texto libre.
En general, la salida estructurada permite que los LLMs sean más útiles en aplicaciones que requieren datos precisos y formateados, en lugar de únicamente texto legible por humanos.
Ejemplos de Salida Estructurada en Python
Todos los fragmentos extraen la información de evento como JSON: {title, date, location}. Reemplace las claves/modelos a su gusto.
1) OpenAI — Esquema JSON (estricto)
from openai import OpenAI
import json
client = OpenAI()
schema = {
"name": "Event",
"schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string", "description": "YYYY-MM-DD"},
"location": {"type": "string"}
},
"required": ["title", "date", "location"],
"additionalProperties": False
},
"strict": True
}
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "user", "content": "Extrae el evento de: 'PyData Sydney es el 2025-11-03 en Darling Harbour.'"}
],
response_format={"type": "json_schema", "json_schema": schema},
)
data = json.loads(resp.choices[0].message.content)
print(data)
La función de Salidas Estructuradas de OpenAI aplica este esquema en el lado del servidor.
2) Google Gemini — esquema de respuesta + MIME JSON
import google.generativeai as genai
from google.genai import types
# Configure con su clave de API
# genai.configure(api_key="su-clave-de-api")
schema = types.Schema(
type=types.Type.OBJECT,
properties={
"title": types.Schema(type=types.Type.STRING),
"date": types.Schema(type=types.Type.STRING),
"location": types.Schema(type=types.Type.STRING),
},
required=["title", "date", "location"],
additional_properties=False,
)
resp = genai.generate_content(
model="gemini-2.0-flash",
contents="Extrae el evento de: 'PyData Sydney es el 2025-11-03 en Darling Harbour.'",
generation_config=genai.GenerationConfig(
response_mime_type="application/json",
response_schema=schema,
),
)
print(resp.text) # ya es JSON válido según el esquema
Gemini devolverá JSON estricto que cumple con response_schema.
3) Anthropic (Claude) — Uso de Herramientas con esquema JSON
from anthropic import Anthropic
import json
client = Anthropic()
tool = {
"name": "extract_event",
"description": "Devuelve los detalles del evento.",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title", "date", "location"],
"additionalProperties": False
}
}
msg = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=256,
tools=[tool],
tool_choice={"type": "tool", "name": "extract_event"}, # fuerza el esquema
messages=[{"role": "user", "content":
"Extrae el evento de: 'PyData Sydney es el 2025-11-03 en Darling Harbour.'"}],
)
# Claude "llamará" a la herramienta; capture los argumentos (que coinciden con su esquema)
tool_use = next(b for b in msg.content if b.type == "tool_use")
print(json.dumps(tool_use.input, indent=2))
Claude no tiene un interruptor de “modo JSON” genérico; en cambio, el Uso de Herramientas con un input_schema le da argumentos validados y con forma de esquema (y puede forzar su uso).
4) Mistral — modo JSON (validación en el lado del cliente)
from mistralai import Mistral
import json
client = Mistral()
resp = client.chat.complete(
model="mistral-large-latest",
messages=[{"role":"user","content":
"Devuelve JSON con las claves title, date (YYYY-MM-DD), location para: "
"'PyData Sydney es el 2025-11-03 en Darling Harbour.'"}],
response_format={"type": "json_object"} # garantiza JSON válido
)
data = json.loads(resp.choices[0].message.content)
print(data)
# Consejo: valide `data` contra su Pydantic/JSON Schema localmente.
json_object de Mistral aplica la forma JSON (no su esquema exacto) — valide en el lado del cliente.
5) AWS Bedrock — Esquema de Herramienta de API Converse (agnóstico al modelo)
import boto3, json
bedrock = boto3.client("bedrock-runtime", region_name="us-east-1")
model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"
tools = [{
"toolSpec": {
"name": "extract_event",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"title": {"type": "string"},
"date": {"type": "string"},
"location": {"type": "string"}
},
"required": ["title","date","location"],
"additionalProperties": False
}
}
}
}]
resp = bedrock.converse(
modelId=model_id,
toolConfig={"tools": tools},
toolChoice={"tool": {"name": "extract_event"}}, # fuerza el esquema
messages=[{"role":"user","content":[{"text":
"Extrae el evento de: 'PyData Sydney es el 2025-11-03 en Darling Harbour.'"}]}],
)
# Extrae el contenido de toolUse
tool_use = next(
c["toolUse"] for c in resp["output"]["message"]["content"] if "toolUse" in c
)
print(json.dumps(tool_use["input"], indent=2))
Bedrock valida la entrada de la herramienta contra su esquema JSON y muchos modelos alojados (p. ej., Claude) lo admiten a través de Converse.
Guía práctica y validación
- Si desea las garantías más fuertes en el lado del servidor: salidas estructuradas de OpenAI o esquema de respuesta de Gemini.
- Si ya usa Claude/Bedrock: defina una Herramienta con un esquema JSON y fuerce su uso; lea los argumentos de la herramienta como su objeto con tipo.
- Si usa Mistral: habilite
json_objecty valide localmente (p. ej., con Pydantic).
Patrón de validación (funciona para todos)
from pydantic import BaseModel, ValidationError
class Event(BaseModel):
title: str
date: str
location: str
try:
event = Event.model_validate(data) # `data` de cualquier proveedor
except ValidationError as e:
# manejar / reintentar / pedir al modelo que corrija con e.errors()
print(e)
Enlaces útiles
- https://platform.openai.com/docs/guides/structured-outputs
- https://ai.google.dev/gemini-api/docs/structured-output
- https://docs.mistral.ai/capabilities/structured-output/json_mode/
- https://aws.amazon.com/blogs/machine-learning/structured-data-response-with-amazon-bedrock-prompt-engineering-and-tool-use
- https://github.com/aws-samples/anthropic-on-aws/blob/main/complex-schema-tool-use/README.md
- https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html
- Cómo solicitar salida estructurada del LLM alojado en Ollama
- Hoja de referencia de Python