Definición de un JSON Schema para output_config.format
output_config.format solo garantiza una respuesta válida según el schema si el schema que le proporcionas está bien formado.
Busca en todas las páginas de la documentación
output_config.format solo garantiza una respuesta válida según el schema si el schema que le proporcionas está bien formado.
Esta página cubre exactamente cómo escribir ese schema: los dos campos que cada objeto necesita, cómo construirlo manualmente frente a generarlo a partir de un modelo Pydantic, y cómo encajan el anidamiento, los arrays y los enums.
El schema que pasas a output_config.format es un JSON Schema estándar, con dos convenciones que la API de Claude requiere en cada objeto: un array required que lista cada propiedad, y additionalProperties: false.
Acertar con estos dos en cada objeto anidado es la fuente más común de errores de schema.
Puedes escribir el schema como un diccionario Python plano, o generarlo automáticamente a partir de un BaseModel de Pydantic con .model_json_schema().
Ambos enfoques producen el mismo formato de transmisión; Pydantic simplemente te ahorra tener que mantener un diccionario y un tipo analizado sincronizados manualmente.
No todas las palabras clave de JSON Schema son compatibles, por lo que un schema que parece razonable aún puede ser rechazado o ignorado silenciosamente en algunas partes; consulta la referencia de tipos de campo y restricciones para ver la lista completa.
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
from anthropic import Anthropic
client = Anthropic()
schema = {
"type": "object",
"properties": {
"title": {"type": "string"},
"priority": {"type": "string", "enum": ["low", "medium", "high"]},
},
"required": ["title", "priority"],
"additionalProperties": False,
}
response = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
output_config={"format": {"type": "json_schema", "schema": schema}},
messages=[{"role": "user", "content": "Resume este informe de error como un ticket."}],
)Cuándo usar esto:
from pydantic import BaseModel, Field
from anthropic import Anthropic
class BugReport(BaseModel):
title: str = Field(description="Un resumen corto y de una línea del error")
priority: str = Field(description="Uno de: low, medium, high")
steps_to_reproduce: list[str] = Field(description="Lista ordenada de pasos de reproducción")
affected_component: str
client = Anthropic()
response = client.messages.parse(
model="claude-sonnet-5",
max_tokens=1024,
output_config={
"format": {"type": "json_schema", "schema": BugReport.model_json_schema()}
},
messages=[{
"role": "user",
"content": (
"Convierte esto en un informe de error: La página de pago falla cuando un usuario "
"aplica un código de descuento con caracteres especiales. Ocurre cada vez "
"en el módulo de pagos. Inicia sesión, añade un artículo al carrito, aplica un código como "
"'SAVE#10', haz clic en pagar. Esto bloquea todas las compras, por lo que es de alta prioridad."
),
}],
)
report: BugReport = response.parsed_output
print(report.title)
print(report.priority)
for step in report.steps_to_reproduce:
print("-", step)Lo que esto demuestra:
Field(description=...) en un modelo Pydantic se convierte en la description del JSON Schema que el modelo lee al decidir qué poner en cada campo.list[str] se convierte automáticamente en un array de elementos string; no se necesita un schema de array manual.response.parsed_output devuelve una instancia real de BugReport, no un diccionario, por lo que el acceso a atributos y los verificadores de tipos funcionan.output_config.format toma un envoltorio type: "json_schema" alrededor de tu objeto schema; el schema en sí es un documento JSON Schema estándar.required le dice a la API que cada propiedad listada debe estar presente en la respuesta; omitir una propiedad de required la hace opcional, lo cual rara vez es lo que quieres para una tarea de extracción fija.additionalProperties: false cierra el objeto; sin él, la API (y cualquier validador estricto que superpongas) no puede garantizar que el modelo no agregará campos adicionales no solicitados.required como additionalProperties: false se necesitan en cada objeto del schema, incluidos los objetos anidados; establecerlos solo en el nivel superior no se propaga hacia abajo.| Enfoque | Lo que escribes | Lo que obtienes |
|---|---|---|
| Diccionario escrito a mano | Un dict Python plano que coincide con la sintaxis de JSON Schema | Control total, pero mantienes el schema y cualquier tipo posterior por separado |
Pydantic model_json_schema() | Una subclase de BaseModel con campos tipados | Schema generado automáticamente; response.parsed_output devuelve una instancia de tu modelo |
Los schemas escritos a mano son útiles para formas muy simples y únicas, o cuando no quieres una dependencia de Pydantic. Para cualquier cosa con más de dos o tres campos, un modelo Pydantic evita que el schema y el tipo de datos de tu aplicación se separen a medida que la forma evoluciona.
from pydantic import BaseModel
class LineItem(BaseModel):
sku: str
quantity: int
class Order(BaseModel):
customer_name: str
items: list[LineItem]
# Order.model_json_schema() produce un objeto de nivel superior con una propiedad de array "items"
# cuya palabra clave "items" apunta al schema del objeto LineItem anidado;
# cada nivel aún necesita su propio required + additionalProperties: false, que
# Pydantic genera automáticamente para ti.properties, items, $ref/$def), que es exactamente lo que Pydantic emite para modelos anidados.required y additionalProperties: false; Pydantic maneja esto correctamente por sí solo, pero si escribes schemas anidados a mano, agrega ambos a cada objeto anidado tú mismo.from pydantic import BaseModel
class Ticket(BaseModel):
subject: str
urgency: str
schema = Ticket.model_json_schema()
print(schema["required"]) # ['subject', 'urgency']
print(schema["additionalProperties"]) # Falsemodel_json_schema() de Pydantic establece required y additionalProperties: false automáticamente para un BaseModel estándar sin campos opcionales; esta es una razón para preferirlo sobre escribir el diccionario a mano.Optional[str] o al que se le asigna un valor predeterminado se excluye de required por Pydantic; si deseas que todos los campos sean obligatorios en la respuesta, evita los valores predeterminados y Optional en los campos que importan.response.parsed_output de client.messages.parse(...) está tipado como una instancia del modelo que pasaste, por lo que los IDE y los verificadores de tipos entienden la forma sin anotaciones adicionales.| Campo | Tipo | Descripción |
|---|---|---|
output_config.format.type | str | Siempre "json_schema" para esta característica. |
output_config.format.schema | dict | El documento JSON Schema que describe la forma de respuesta requerida. |
schema.required | list[str] | Cada nombre de propiedad que debe estar presente en la respuesta, por objeto. |
schema.additionalProperties | bool | Debe ser False en cada objeto del schema. |
additionalProperties: false en un objeto anidado. Establecerlo solo en el nivel superior deja los objetos internos abiertos. Solución: verifica que cada objeto anidado en el schema también lleve additionalProperties: false; si escribes schemas a mano, es fácil pasarlo por alto en un campo profundamente anidado.properties pero no en required. El campo se vuelve opcional, por lo que el modelo puede omitirlo y tu código debe verificar defensivamente su presencia. Solución: incluye cada campo que realmente necesitas en required, y solo haz que los campos sean opcionales cuando la respuesta genuinamente pueda no tenerlos.enum y anidamiento simple.Optional para una tarea de extracción "debe tener todo". Los campos opcionales/con valor predeterminado se eliminan automáticamente de required, lo que debilita la garantía que realmente querías. Solución: mantén los campos no opcionales sin valor predeterminado cuando cada valor deba estar presente en la respuesta.priority: "high" aún puede ser válido según el schema y ser factualmente incorrecto. Solución: mantén tu propio paso de validación o revisión posterior para la corrección, independientemente de la conformidad del schema.| Alternativa | Úsala Cuando | No la uses Cuando |
|---|---|---|
| Diccionario de schema escrito a mano | La forma es pequeña, fija y no quieres una dependencia de Pydantic | La forma tiene más de unos pocos campos o evoluciona con frecuencia |
Pydantic model_json_schema() | Ya tienes (o quieres) una clase Python tipada para los datos | Necesitas el schema en un contexto no Python y no puedes compartir el modelo |
input_schema estricto (strict: true) | Quieres restringir los parámetros de una llamada a herramienta en lugar de la respuesta final del mensaje | Estás restringiendo la respuesta de texto general del asistente, no una invocación de herramienta |
| Solo instrucciones JSON basadas en prompt | Prototipado rápido donde la salida ocasionalmente mal formada es aceptable | Cualquier pipeline de producción que analice la respuesta programáticamente |
model_json_schema() establece ambos automáticamente para un BaseModel sin campos opcionales.False en cada objeto del schema.required y el modelo puede incluirlo o no.required en lugar de hacer los campos opcionales por costumbre.{"type": "string", "enum": ["low", "medium", "high"]}enum es una construcción bien soportada y es la forma estándar de restringir un campo a un conjunto fijo de valores.properties para objetos anidados y items para arrays funcionan, y Pydantic genera esto automáticamente para modelos anidados y campos list[...].Optional) es excluido de required por Pydantic.Optional en esos campos.required / additionalProperties: false.output_config.format restringe toda la respuesta del mensaje; el input_schema de una herramienta (con strict: true) restringe los parámetros de una sola llamada a herramienta.{
"type": "object",
"properties": {"answer": {"type": "string"}},
"required": ["answer"],
"additionalProperties": False,
}BaseModel de Pydantic es la ruta de conveniencia común porque .model_json_schema() produce el schema directamente.dataclass simple no tiene esto incorporado; escribirías el schema de diccionario tú mismo si no quieres una dependencia de Pydantic.Versiones de Stack: Escrito contra la línea de modelos Claude actual a partir de ~junio de 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (el predeterminado) y Claude Haiku 4.5 - y el SDK oficial de Python
anthropic(última versión 0.x). Los nombres de modelos, versiones de SDK y precios cambian rápidamente; verifica los detalles actuales en platform.claude.com/docs antes de confiar en ellos.
Revisado por Chris St. John·Última actualización: 13 jul 2026