🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)
🔧 AI Nachrichten Major AI platforms go down in unprecedented simultaneous outage(03.09.2026 um 17:34 Uhr)
🔧 AI Nachrichten ChatGPT, Claude, and Grok Down? Users Report Widespread Outages(03.09.2026 um 19:14 Uhr)
🔧 AI Nachrichten OpenAI Launches GPT-6 Astra, Says We May Have Entered the AGI Era(03.09.2026 um 22:08 Uhr)
🔧 AI Nachrichten Claude Comes to CarPlay as Fifth Major AI Chatbot App(05.09.2026 um 05:31 Uhr)
🔧 AI Nachrichten OpenAI’s GPT-6 Astra Is AGI, Says NVIDIA CEO Jensen Huang(07.09.2026 um 06:31 Uhr)
🔧 AI Nachrichten Blame AI companies for Mac mini and Mac Studio shortage(31.08.2026 um 10:32 Uhr)

🔧 Programmierung 🕛 kürzlich 6 Min Lesezeit
0

Stop Begging Your LLM for Valid JSON: Self-Correcting Structured Output in Spring AI 2.0

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht
📺
dev.to

Every developer who has worked with LLMs has been there. You ask the model for JSON. You describe the schema. You say "please only respond with valid JSON." And sometimes, it still breaks.



Your application crashes because the model returned a string where you expected an integer. Or it wrapped the JSON in markdown code blocks. Or it omitted a required field.



Spring AI 2.0 has a solution that treats this like a real engineering problem instead of a prayer.






The Problem



When you use structured output in Spring AI, the workflow goes like this:




  1. You define a Java type (a record, class, or enum)

  2. Spring AI generates a JSON schema from that type

  3. The schema gets appended to the prompt sent to the LLM

  4. The model returns a response

  5. Spring AI attempts to deserialize the response into your type



This works well with frontier models like Claude and GPT-4. But smaller open-source models, like Llama 3.2 1B running locally via Ollama, fail more often. They might return null for a primitive field, omit required fields, or produce malformed JSON.



When it fails, you get a deserialization exception. Your endpoint returns a 500 error. Spring AI provides no built-in recovery mechanism.






The Old Approach: Hope



Consider a conference talk submission system. Speakers submit messy, unstructured abstracts. You want to extract structured data:




CODE
public record TalkSubmission(
String title,
String abstractText,
Level level, // BEGINNER, INTERMEDIATE, ADVANCED
Track track,
int duration,
List<String> tags,
String speakerHandle
) {}






Here is what the basic typed response looks like:




CODE
@PostMapping("/typed")
public TalkSubmission typed(@RequestBody String rawSubmission) {
return chatClient.prompt()
.system(systemPrompt)
.user(spec -> spec.text("Extract the talk submission: {submission}")
.param("submission", rawSubmission))
.call()
.entity(TalkSubmission.class);
}






You define your type. Spring AI generates the schema and appends it to the prompt. The model gets the instruction. And you hope it works.



Dan Vega, Spring Developer Advocate at Broadcom, puts it bluntly in his by Christian Tzolov (Spring AI team), the validation loop works as follows:




  1. The model responds

  2. Spring AI validates the response against the generated schema

  3. If validation passes, you get your typed record back

  4. If validation fails, the specific validation error (e.g., "expected int, got null for field duration") is appended to the user prompt and the call is re-issued

  5. The model sees the exact error on each retry, not a blind re-try



This is powered by StructuredOutputValidationAdvisor, a recursive advisor that is auto-registered when you call validateSchema(). Default is 3 retry attempts. The model knows exactly what went wrong and can correct it on the next attempt.



To customize the retry count, build your own advisor instance:




CODE
var validationAdvisor = StructuredOutputValidationAdvisor.builder()
.outputType(TalkSubmission.class)
.maxRepeatAttempts(5)
.build();

ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(validationAdvisor)
.build();









Provider-Native Structured Output



Some frontier models support structured output at the API level. Instead of appending the schema to the prompt text, the schema is sent as an API constraint. The provider's runtime enforces conformance, meaning invalid responses cannot be emitted at all.



Spring AI 2.0 exposes this through useProviderStructuredOutput():




CODE
TalkSubmission result = chatClient.prompt()
.system(systemPrompt)
.user(spec -> spec.text("Extract the talk submission: {submission}")
.param("submission", rawSubmission))
.call()
.entity(TalkSubmission.class, spec -> spec
.useProviderStructuredOutput()
.validateSchema());






Supported providers as of Spring AI 2.0:





  • OpenAI: GPT-4o and later models with JSON Schema support


  • Anthropic: Claude 3.5 Sonnet and later models


  • Google GenAI: Gemini 1.5 Pro and later models


  • Mistral AI: Mistral Small and later models with JSON Schema support


  • Ollama: Models with JSON Schema support (model-specific)



Native structured output is off by default because support varies across models. If a model does not support it, the flag is silently ignored and the prompt-based approach is used instead.



Note: .entity() is only available on .call(), not on .stream(). Typed parsing requires the complete response, so streaming responses cannot be deserialized into a typed object.






Known Limitations



OpenAI does not accept top-level JSON arrays. If you need a List<T>, wrap it in a container record first:




CODE
// Does NOT work with OpenAI native structured output:
List<TalkSubmission> list = chatClient.prompt()
.call()
.entity(new ParameterizedTypeReference<List<TalkSubmission>>() {},
spec -> spec.useProviderStructuredOutput()); // fails

// Works: wrap in a container
record SubmissionList(List<TalkSubmission> submissions) {}
SubmissionList result = chatClient.prompt()
.call()
.entity(SubmissionList.class, spec -> spec.useProviderStructuredOutput());






Ollama with reasoning models (like Qwen variants) may emit internal reasoning traces as plain text instead of JSON. Use a non-reasoning model, or combine with validateSchema() so malformed responses are automatically retried.






When To Use What



Not every scenario needs all features enabled. Based on the official docs and video demonstration:



Frontier models (Claude, GPT-4, Gemini):





  • useProviderStructuredOutput() for API-level enforcement


  • validateSchema() as a safety net for edge cases

  • These models rarely fail, but the combination gives you two layers of protection



Open-source models (Llama, Mistral via Ollama):





  • useProviderStructuredOutput() may have no effect (model-specific)


  • validateSchema() is essential

  • These models fail more often, especially with complex schemas or small parameter counts



Production systems:




  • Always enable validation. The overhead is minimal compared to a 500 error

  • Log validation failures to identify which prompts or models need improvement

  • Customize maxRepeatAttempts based on your latency budget






The Bigger Picture



This feature represents a shift in how we think about LLM integration. For too long, the industry treated unreliable model output as a prompt engineering problem. Write a better prompt. Be more specific. Add examples. Pray harder.



Spring AI 2.0 treats it as a systems problem. Validate. Retry. Self-correct. The same principles we apply to any unreliable external service: network calls, database queries, third-party APIs. LLMs are no different.



If you are building production applications with LLMs, schema validation is not optional. It is basic engineering.






Sources:



Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
3 Quellen
GPT-6 Astra Release Today? OpenAI’s Next Major AI Model Is Almost Here
1 Quelle
Apple accuses OpenAI of destroying evidence as trade-secrets fight intensifies
1 Quelle
Major AI platforms go down in unprecedented simultaneous outage
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Stop Begging Your LLM for Valid JSON: Self-Correcting Structured Output in Spring AI 2.0

Thematisch verwandte Begriffe: Stop, Begging, Your, Valid · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...