Saltar al contenido principal
Desarrollo con IA12 min de lectura

Structured Output con Spring AI: de texto a objetos Java fiables

Un LLM devuelve texto; una aplicación Java necesita datos que pueda validar, persistir y usar en reglas de negocio. Cómo funciona Structured Output en Spring AI 2.0 —entity(), validateSchema(), salida nativa del proveedor y responseEntity()—, dónde está su límite y cómo convertirlo en una frontera fiable entre un componente probabilístico y código determinista.

Cristian Osorio · DatIACode

Una aplicación clasifica tickets de soporte con un LLM. En la demo, el modelo devuelve un JSON impecable. Una semana después llega una respuesta que empieza por «La prioridad sería alta porque…», luego un JSON con la prioridad URGENT, que no existe en el enum, y después uno al que le falta un campo.

Ahí empieza el código defensivo: expresiones regulares, try/catch alrededor de Jackson y prompts cada vez más largos. El problema no es conseguir JSON: el modelo produce texto y la aplicación necesita un contrato.

En una demo puede bastar con recibir texto. En producción, en cuanto otra pieza de software usa la respuesta, deja de serlo. Structured Output convierte la respuesta probabilística del modelo en un contrato que el código Java puede tratar de forma fiable.

Este artículo explica cómo funciona en Spring AI 2.0 (la versión estable es la 2.0.1), qué garantiza cada mecanismo y qué no garantiza ninguno. La idea que lo recorre entero: estructura válida no es lo mismo que dato correcto.

Structured Output en Spring AI, en 30 segundos

  • entity() convierte la respuesta del modelo en un tipo Java, normalmente un record.
  • Por defecto es best effort: el modelo recibe el schema como instrucciones y puede incumplirlo.
  • validateSchema() comprueba la salida contra el JSON Schema y, si falla, repite la llamada indicando al modelo el error.
  • useProviderStructuredOutput() usa el mecanismo nativo del proveedor cuando el modelo lo soporta.
  • Forma, no verdad: Structured Output refuerza la forma de la respuesta, pero no garantiza que los datos sean verdaderos.

Qué es Structured Output en Spring AI

Structured Output en Spring AI permite convertir la respuesta textual de un modelo de lenguaje en un tipo Java definido por la aplicación. Spring AI genera un JSON Schema a partir del tipo esperado, guía o restringe al modelo para que produzca una respuesta compatible y después la convierte en el objeto Java correspondiente.

Con entity() por defecto, esa conformidad es best effort; validateSchema() y useProviderStructuredOutput() la refuerzan de maneras distintas, como recoge la documentación oficial de Structured Output. La llamada básica en cada framework aparece en la comparativa entre Spring AI y LangChain4j; aquí nos centramos en lo que la rodea en producción.

  1. LLM

    genera texto

  2. JSON

    forma de objeto, sin garantías

  3. JSON Schema

    campos, tipos y valores permitidos

  4. record Java

    el tipo de la aplicación

  5. Aplicación

    valida, aplica reglas y actúa

El caso básico: entity() convierte la respuesta de ChatClient en un record

El método entity() de ChatClient es la forma directa de obtener un objeto Java en lugar de un String: se le pasa la clase del tipo esperado y devuelve una instancia de ese tipo construida a partir de la respuesta del modelo.

Contrato de salidajava
public enum Priority { LOW, MEDIUM, HIGH }

public record SupportTicketClassification(
    String category,
    Priority priority,
    String summary,
    boolean requiresHumanReview
) {}
Spring AI 2.0 · ChatClient con entity()java
@Service
public class TicketClassifier {

    private final ChatClient chatClient;

    public TicketClassifier(ChatClient.Builder builder) {
        this.chatClient = builder
            .defaultSystem("Clasificas tickets de soporte de clientes B2B.")
            .build();
    }

    public SupportTicketClassification classify(String ticketText) {
        return chatClient.prompt()
            .user(ticketText)
            .call()
            .entity(SupportTicketClassification.class);
    }
}

Qué hace entity() por dentro

Con una clase como argumento, entity() crea un BeanOutputConverter y sigue estos pasos:

  • Schema: genera un JSON Schema (Draft 2020-12) a partir del record. En 2.0 los campos son obligatorios salvo que se marquen como opcionales, y los enums se traducen en listas de valores permitidos.
  • Instrucciones: añade el schema al prompt como instrucciones de formato.
  • Generación: el modelo responde, todavía como texto.
  • Conversión: deserializa la respuesta con Jackson 3. entity() está anotado como @Nullable, así que el resultado puede ser null.

content(), entity() y responseEntity(): cuándo usar cada uno

content() devuelve texto; entity(), un objeto Java tipado; responseEntity(), ese objeto junto con la respuesta completa y su metadata. content() no es la opción pobre: si la respuesta la lee una persona, Structured Output no aporta nada.

Métodos de ChatClient para leer la respuesta del modelo en Spring AI 2.0
NecesidadMétodo de ChatClientQué obtienes
Mostrar texto a una personacontent()String
Consumir la respuesta desde código Javaentity(Clase.class)Instancia del tipo (puede ser null)
Objeto tipado más tokens y metadataresponseEntity(Clase.class)ResponseEntity con la entidad y el ChatResponse
Listas y tipos genéricosentity(new ParameterizedTypeReference<…>() {})List<T> u otro tipo genérico

Por qué los records de Java encajan como contrato de salida

Los records son la forma natural de expresar un contrato de salida: inmutables, sin boilerplate y claramente un resultado, no una entidad con comportamiento.

Las anotaciones de Jackson @JsonPropertyDescription, @JsonProperty(required = …) y @JsonPropertyOrder se reflejan en el schema, así que la descripción de cada campo llega al modelo como parte del contrato.

Un contrato con descripcionesjava
public enum RiskLevel { LOW, MEDIUM, HIGH }

public record InvoiceAnalysis(
    @JsonPropertyDescription("Número de factura tal como aparece en el documento")
    String invoiceNumber,

    @JsonPropertyDescription("Importe total con impuestos incluidos")
    BigDecimal total,

    @JsonPropertyDescription("Código de moneda ISO 4217, por ejemplo EUR")
    String currency,

    RiskLevel risk,
    List<String> anomalies,
    boolean requiresReview
) {}

Listas y tipos genéricos con ParameterizedTypeReference

Para listas y tipos genéricos, entity() acepta un ParameterizedTypeReference, porque el borrado de tipos impide pasar List<T>.class.

Con la salida nativa de OpenAI el schema no puede tener un array como raíz; la documentación recomienda envolver la lista en un record.

Lista con ParameterizedTypeReferencejava
List<SupportTicketClassification> results = chatClient.prompt()
    .user(ticketBatch)
    .call()
    .entity(new ParameterizedTypeReference<List<SupportTicketClassification>>() {});
Alternativa: envolver la lista en un recordjava
public record TicketBatchClassification(
    List<SupportTicketClassification> tickets
) {}

Por qué entity() por defecto sigue siendo best effort

Por defecto, entity() pide al modelo que respete el schema, pero no le obliga: según la documentación, el modelo es instruido, no forzado. El schema viaja como instrucciones en el prompt.

Una respuesta puede añadir texto antes del JSON, omitir campos o inventar un valor de enum. Con modelos pequeños o schemas extensos ocurre lo suficiente para romper un pipeline. Spring AI 2.0 ofrece dos mecanismos para endurecer el contrato.

validateSchema(): validar la respuesta y pedir una corrección

validateSchema() valida la respuesta contra el JSON Schema y, si no lo cumple, vuelve a llamar al modelo con el error de validación para que corrija su salida: un bucle de autocorrección con reintentos limitados.

Lo implementa StructuredOutputValidationAdvisor, que se registra solo al activar el interruptor. Según su API, maxRepeatAttempts es el número máximo de reintentos después de un fallo de validación y vale 3: una llamada inicial y hasta tres llamadas adicionales si la salida sigue sin cumplir el schema. Con 0 no hay reintentos. Para cambiar el valor se registra el advisor de forma explícita, como describe Schema Validation & Self-Correction.

Activar la validación en una llamadajava
SupportTicketClassification result = chatClient.prompt()
    .user(ticketText)
    .call()
    .entity(SupportTicketClassification.class, spec -> spec.validateSchema());
Ajustar el número de reintentosjava
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultAdvisors(StructuredOutputValidationAdvisor.builder()
        .outputType(SupportTicketClassification.class)
        .maxRepeatAttempts(2)
        .build())
    .build();

Qué pasa cuando se agotan los reintentos

Si la salida sigue sin poder convertirse al tipo esperado después de los intentos de corrección, la aplicación debe tratar explícitamente el fallo y no asumir que dispondrá de una entidad válida. En la práctica: capturar el error de conversión, comprobar que el resultado no es null y decidir qué ocurre entonces, ya sea revisión humana, reintento diferido o un error controlado. Además, validateSchema() no admite streaming, porque necesita la respuesta completa para validarla.

useProviderStructuredOutput(): el schema como restricción nativa del proveedor

useProviderStructuredOutput() envía el JSON Schema al proveedor como restricción de su API, en lugar de como instrucciones en el prompt: el schema deja de ser una petición y actúa durante la generación. La referencia es Provider-Native Structured Output.

La documentación de Spring AI 2.0 enumera como soportados OpenAI, Anthropic, Google GenAI, Mistral AI y Ollama, este último según el modelo. Que el proveedor lo soporte no significa que cualquiera de sus modelos acepte todas las construcciones de JSON Schema.

Salida estructurada nativa del proveedorjava
SupportTicketClassification result = chatClient.prompt()
    .user(ticketText)
    .call()
    .entity(SupportTicketClassification.class, spec -> spec.useProviderStructuredOutput());
  • Fallo silencioso: si las opciones del modelo no implementan StructuredOutputChatOptions, Spring AI ignora la opción sin avisar y vuelve al modo basado en prompt.
  • Soporte parcial: $ref, arrays muy anidados, allOf/anyOf/oneOf, regex y tipos recursivos son limitaciones habituales incluso en proveedores compatibles.
  • Particularidades: OpenAI no admite un array como raíz del schema; en Ollama, los modelos con modo de razonamiento pueden devolver texto plano.
  • Activación global: AdvisorParams.ENABLE_NATIVE_STRUCTURED_OUTPUT lo activa de forma general. Por compatibilidad, está desactivado por defecto.

Combinar salida nativa y validación: cuándo compensa

La combinación más robusta es activar ambos: la salida nativa restringe la respuesta antes de que exista y validateSchema() la comprueba después, incluso si el modo nativo se desactiva sin avisar.

Restricción nativa y validación con reintentojava
SupportTicketClassification result = chatClient.prompt()
    .user(ticketText)
    .call()
    .entity(SupportTicketClassification.class, spec -> spec
        .useProviderStructuredOutput()
        .validateSchema());
Cuándo activar useProviderStructuredOutput() y validateSchema() a la vez
Compensa combinar ambosProbablemente sobra
Pipelines automatizados sin persona en medioPrototipos y pruebas de concepto
Resultados que se persisten en base de datosRespuestas conversacionales
Decisiones posteriores: routing, prioridades, alertasContenido que solo lee una persona
Datos enviados a otra API o a un workflowSalidas sin procesamiento posterior

responseEntity(): el objeto tipado y además tokens y metadata

responseEntity() devuelve la entidad Java y el ChatResponse completo, con los tokens consumidos y la metadata para trazas y métricas. Admite las mismas sobrecargas que entity(), según la API de ChatClient.

Con validateSchema() refleja lo que ha costado de verdad obtener un objeto válido, reintentos incluidos.

Entidad, respuesta original y consumojava
ResponseEntity<ChatResponse, SupportTicketClassification> response = chatClient.prompt()
    .user(ticketText)
    .call()
    .responseEntity(SupportTicketClassification.class, spec -> spec.validateSchema());

SupportTicketClassification classification = response.entity();
long totalTokens = response.response().getMetadata().getUsage().getTotalTokens();

StructuredOutputConverter y BeanOutputConverter: cuándo bajar de nivel

StructuredOutputConverter<T> es la abstracción bajo entity(): un FormatProvider con las instrucciones de formato y un Converter<String, T>. BeanOutputConverter<T> genera el schema desde una clase y deserializa con Jackson; también existen MapOutputConverter y ListOutputConverter, descritos en Output Converters.

Compensa bajar a este nivel con formatos que no son JSON, respuestas que el converter estándar rechaza (por ejemplo, JSON envuelto en un bloque de Markdown), uso directo de ChatModel o streaming. Un converter propio debe implementar getJsonSchema() para participar en validateSchema() y useProviderStructuredOutput().

entity() solo funciona con call(). En streaming, la alternativa documentada es incluir el formato del converter en el prompt, acumular el stream y convertir al final, sin validación ni reintentos.

Streaming con conversión al finaljava
BeanOutputConverter<SupportTicketClassification> converter =
    new BeanOutputConverter<>(SupportTicketClassification.class);

String json = chatClient.prompt()
    .user(ticketText + "\n\n" + converter.getFormat())
    .stream()
    .content()
    .collectList()
    .block()
    .stream()
    .collect(Collectors.joining());

SupportTicketClassification result = converter.convert(json);

Structured Output no es Bean Validation

La validación de JSON Schema comprueba la estructura: campos, tipos y valores permitidos. Jakarta Bean Validation comprueba reglas sobre los valores: rangos y formatos del negocio. Structured Output no invoca un Validator sobre el resultado de entity().

Un campo entero acepta un descuento de 95 aunque la política no permita pasar del 30 %. @Min y @Max no se aplican solas: hay que invocar el Validator, como con cualquier DTO externo.

Contrato con restricciones de negociojava
public record DiscountProposal(
    @NotBlank String customerId,
    @Min(0) @Max(30) int discountPercent,
    @NotBlank String justification
) {}
La validación de dominio la ejecuta la aplicaciónjava
public DiscountProposal propose(String context) {
    DiscountProposal proposal = chatClient.prompt()
        .user(context)
        .call()
        .entity(DiscountProposal.class, spec -> spec.validateSchema());

    if (proposal == null) {
        throw new IllegalStateException("El modelo no devolvió ninguna propuesta");
    }
    Set<ConstraintViolation<DiscountProposal>> violations = validator.validate(proposal);
    if (!violations.isEmpty()) {
        throw new ConstraintViolationException(violations);
    }
    return proposal;
}

Estructura válida no significa respuesta correcta

Structured Output puede, como mucho, asegurar que la respuesta tiene la forma del contrato, no que los valores sean ciertos. Esta factura cumple el schema y puede tener el importe equivocado:

JSON válido, dato sin comprobarjson
{
  "invoiceNumber": "F-2026-9182",
  "total": 3840.00,
  "currency": "EUR",
  "risk": "LOW",
  "anomalies": [],
  "requiresReview": false
}
  1. Parsing

    ¿puedo leerlo? La respuesta es JSON parseable

  2. Schema

    ¿cumple el contrato? Campos, tipos y valores permitidos

  3. Semántica

    ¿el dato es correcto? Respecto al documento y al negocio

Parsing y schema son terreno de Structured Output; la semántica exige reglas deterministas (que las líneas sumen el total), comprobaciones contra sistemas reales (que la factura exista en el ERP), revisión humana cuando proceda y evals que midan si la aplicación resuelve bien la tarea.

Structured Output, JSON mode y Tool Calling: diferencias

JSON mode garantiza JSON sintácticamente válido; Structured Output, una estructura definida por un schema; Tool Calling permite al modelo pedir que se ejecute una función.

En Tool Calling el schema describe los argumentos de una herramienta, y la documentación de Spring AI aclara que StructuredOutputConverter no se usa ahí. Structured Output se aplica a la respuesta final. En 2.0 ambos usan el mismo generador de schemas, con papeles distintos.

Diferencias entre JSON mode, Structured Output, Tool Calling y validación en Java
ConceptoQué resuelveQué no resuelve
JSON mode del proveedorQue la respuesta sea JSON válidoQue tenga los campos y tipos que espera tu código
Structured OutputQue la respuesta final siga un JSON Schema y se convierta en un tipo JavaQue los valores sean correctos
Tool CallingQue el modelo pida ejecutar una función con argumentos estructuradosConvertir la respuesta final en un contrato de datos
Validación en JavaQue los valores cumplan las reglas del negocioQue el dato sea cierto respecto a la fuente

Caso completo: clasificación y enrutado de tickets de soporte

Un ticket llega con este texto: «Desde ayer no podemos cerrar pedidos porque SAP devuelve un error al contabilizar». La aplicación debe decidir departamento, prioridad y si hace falta revisión humana.

El LLM interpreta, Structured Output normaliza y las decisiones las toma código Java testeable. Ticket y TicketRoute son tipos propios de la aplicación.

Contrato del análisisjava
public enum Department { FINANCE, OPERATIONS, IT, SALES }

public record TicketAnalysis(
    Department department,
    Priority priority,
    @JsonPropertyDescription("Resumen de una frase, sin datos personales")
    String summary,
    List<String> detectedSystems,
    boolean humanReview
) {}
Servicio: interpretación con Spring AIjava
public TicketRoute analyzeAndRoute(Ticket ticket) {
    TicketAnalysis analysis = chatClient.prompt()
        .system("""
            Analizas tickets de soporte interno.
            Marca humanReview si el ticket menciona importes, datos de clientes
            o sistemas de facturación.
            """)
        .user(ticket.body())
        .call()
        .entity(TicketAnalysis.class, spec -> spec
            .useProviderStructuredOutput()
            .validateSchema());

    return routingPolicy.decide(ticket, analysis);
}
Política de enrutado: decisiones deterministasjava
@Component
class RoutingPolicy {

    TicketRoute decide(Ticket ticket, TicketAnalysis analysis) {
        if (analysis == null || analysis.department() == null || analysis.priority() == null) {
            return TicketRoute.manualTriage(ticket, "Clasificación incompleta");
        }

        boolean touchesErp = analysis.detectedSystems() != null
            && analysis.detectedSystems().stream().anyMatch("SAP"::equalsIgnoreCase);

        Priority priority = touchesErp && ticket.blocksOperations()
            ? Priority.HIGH
            : analysis.priority();

        return analysis.humanReview() || priority == Priority.HIGH
            ? TicketRoute.withReview(analysis.department(), priority, analysis.summary())
            : TicketRoute.automatic(analysis.department(), priority, analysis.summary());
    }
}
  1. Ticket

    texto libre del usuario

  2. Spring AI

    prompt con contexto y ChatClient

  3. Structured Output

    salida nativa y validación del schema

  4. TicketAnalysis

    record tipado

  5. Reglas Java

    política de enrutado testeable

  6. Destino

    ServiceNow, Jira o CRM

Arquitectura recomendada: una frontera entre lo probabilístico y lo determinista

Structured Output no convierte al LLM en determinista. Define una frontera verificable para que el resto de la aplicación sí pueda seguir comportándose como software determinista. A un lado, el prompt, el modelo y su variabilidad; al otro, un record, validaciones y reglas de dominio cubiertas por tests. El JSON Schema es el contrato entre ambos.

Esa frontera debe ser estrecha, con un DTO específico para el LLM, y explícita, con validación y reglas antes de persistir o actuar.

Si una empresa ya trabaja con Java y Spring Boot, incorporar IA no debería exigir un stack paralelo. Es el enfoque con el que trabajamos en desarrollo de soluciones con Spring AI.

Diagrama en tres bandas. Arriba, la parte probabilística: Prompt, LLM y Structured Output. En el centro, una franja discontinua rotulada «Contrato · JSON Schema». Abajo, la parte determinista: record Java, Validación y Reglas de dominio, que terminan en Servicio, Base de datos y API
Lo que cruza la frontera tiene forma comprobable; las decisiones se toman en código determinista.

Errores habituales al usar Structured Output en producción

La mayoría de los problemas vienen del diseño del contrato, no de la API:

  • Schema demasiado grande: exponer el dominio completo multiplica los errores posibles. Mejor un DTO pequeño.
  • Campos ambiguos: un String status admite cualquier cosa; un enum hace detectable el error.
  • Confiar solo en el prompt: «Devuelve exactamente este JSON» no es un contrato; el schema sí.
  • Persistir lo que devuelve el modelo: antes de guardar o actuar, comprobar nulls, Bean Validation y reglas de dominio.
  • Ignorar el coste de los reintentos: medirlo con responseEntity() y fijar un límite.
  • Schemas complejos: tipos recursivos y uniones funcionan peor, sobre todo con salida nativa.
  • Confundir schema correcto con dato correcto: el error de fondo, y el más caro.

Cuándo usar Structured Output y cuándo no

Structured Output tiene sentido cuando la respuesta alimenta a otra pieza de software.

Tabla de decisión: cuándo aplicar Structured Output
Situación¿Structured Output?Motivo
El resultado alimenta otra función o servicioEl consumidor necesita tipos, no frases
Se persiste en base de datosHay que validar antes de guardar
Se usa para routing o para activar reglasUna decisión no puede depender de interpretar texto
Respuesta conversacional en un chatNo suele hacer faltacontent() es suficiente
Contenido para lectura humanaNo suele hacer faltaEl formato libre es el objetivo

Structured Output dentro de una aplicación con RAG y agentes

Structured Output no sustituye a RAG ni a Tool Calling: normaliza lo que el modelo concluye para que el código pueda actuar. La arquitectura completa la desarrollamos en Spring AI, RAG y agentes.

Si tu equipo necesita reforzar la recuperación de información, tenemos formación en bases de datos vectoriales y búsqueda semántica.

  1. RAG

    recupera la información relevante

  2. LLM

    interpreta la información en contexto

  3. Structured Output

    normaliza el resultado en un tipo

  4. Java

    decide con reglas deterministas

  5. Tool

    actúa sobre otros sistemas

Qué abstrae Spring AI frente a hacerlo manualmente

Spring AI resuelve la parte repetitiva; diseñar el contrato y decidir qué hacer con el resultado sigue siendo tarea tuya.

Qué parte del trabajo de Structured Output abstrae Spring AI
TareaHaciéndolo a manoCon Spring AI 2.0
Describir el formato esperadoInstrucciones escritas en el promptJSON Schema generado a partir del record
Obtener el objetoExtraer el JSON y deserializar con Jacksonentity()
Detectar respuestas mal formadasParser propio y try/catchvalidateSchema()
Restringir la generaciónCódigo específico para cada proveedoruseProviderStructuredOutput()
Reglas de negocio y corrección del datoResponsabilidad de tu códigoSigue siendo responsabilidad de tu código

Conclusión

Una aplicación Java no debería tratar la salida de un LLM como texto cuando el resto del sistema espera datos. entity() da el caso básico, validateSchema() y useProviderStructuredOutput() lo endurecen y responseEntity() lo hace medible.

Pero tipar una respuesta no convierte al modelo en determinista. Structured Output reduce la incertidumbre sobre la forma; la del contenido sigue necesitando validación, reglas de dominio, tests y evals.

El objetivo no es conseguir que el modelo devuelva JSON. El objetivo es que el resto de la aplicación pueda confiar en el contrato sin fingir que el modelo ha dejado de ser probabilístico.

Fuentes técnicas

Preguntas frecuentes

¿Qué es Structured Output en Spring AI?

Es el mecanismo de Spring AI para convertir la respuesta textual de un LLM en un tipo Java, normalmente un record. Genera un JSON Schema a partir del tipo, lo comunica al modelo (como instrucciones en el prompt o como restricción nativa del proveedor) y convierte la respuesta en un objeto. Por defecto, la conformidad con el schema es best effort.

¿Qué diferencia hay entre content() y entity() en Spring AI?

content() devuelve un String, adecuado cuando el texto lo lee una persona. entity() devuelve un objeto Java tipado, adecuado cuando otra pieza de software consume el resultado.

¿Qué hace validateSchema() en Spring AI?

Valida la respuesta contra el JSON Schema y, si no lo cumple, repite la llamada indicando el error para que el modelo corrija. maxRepeatAttempts vale 3 por defecto: una llamada inicial y hasta tres reintentos. Cada reintento suma tokens, latencia y coste, y la aplicación debe tratar el caso en que tampoco así se obtenga una entidad válida.

¿Qué es useProviderStructuredOutput()?

Envía el JSON Schema al proveedor como restricción de su API en lugar de como instrucciones en el prompt. La documentación de Spring AI 2.0 la da como soportada en OpenAI, Anthropic, Google GenAI, Mistral AI y Ollama (según el modelo). Si las opciones del modelo no la soportan, Spring AI la ignora sin avisar.

¿Structured Output y Tool Calling son lo mismo?

No. Tool Calling usa un JSON Schema para describir los argumentos de una herramienta que el modelo pide ejecutar. Structured Output convierte la respuesta final del modelo en un contrato de datos.

¿Funciona Structured Output con streaming en Spring AI?

No con entity(): solo funciona con call(), y validateSchema() tampoco admite streaming. La alternativa es añadir al prompt el formato de un BeanOutputConverter, acumular el stream y convertir el texto completo al final.

¿Structured Output garantiza que la respuesta sea correcta?

No. Garantizar la estructura y garantizar la verdad son problemas distintos: una respuesta puede cumplir el JSON Schema y contener un importe o una clasificación errónea. La corrección del contenido necesita reglas de dominio, comprobaciones contra sistemas reales, tests y evals.

  • Leer artículo
    Desarrollo con IA18 min

    Spring AI vs LangChain4j: qué framework elegir para IA en Java

  • Leer artículo
    Desarrollo con IA13 min

    Spring AI, RAG y agentes: cómo construir aplicaciones Java con inteligencia artificial real

  • Leer artículo
    Desarrollo con IA11 min

    Java + Spring AI: cuándo y por qué elegirlo para IA en empresa

Ver todos los artículos