Туториал
Почему JSON от ИИ всё ещё ломается? Structured Output, JSON Schema и validation — гид 2026
json_schema + strict, а CI красный: Structured Output держит ключи и типы, не правильность классификации и не обрезанный JSON.
Hooking LLMs into extraction, labeling, or agent tool args means JSON failures are normal. In 2026, OpenAI json_schema + strict, Gemini responseSchema, Anthropic output_config.format, and Apple @Generable beat “return JSON only” by an order of magnitude—yet incidents continue. Many failures sit outside Structured Output’s scope, or the Schema cannot compile on that model, or the pipeline stops at JSON.parse. This guide organizes around why errors persist, maps 2026 capability boundaries, Schema authoring, and local validation—and links our Structured Output, Gemini, DeepSeek, and MCP articles.
What Structured Output fixes—and what it does not
Align expectations first. Structured Output constrains the next token at decode time, so output usually satisfies JSON syntax and Schema shape—keys, required, types, enums, additionalProperties. OpenAI docs separate this from JSON mode, which only promises syntax.
It does not guarantee correct business labels, faithful numbers, intact arrays when max_tokens cuts off, or successful downstream APIs after tool args. Semantics and engineering remain your code. Frustration after enabling strict often means the bug was never a shape issue.
Do not conflate tool argument JSON with final structured answers. MCP tools/call, function.arguments, and DeepSeek strict tools constrain different hops—some only json_object, some beta strict on a Schema subset. Rate guarantees per hop, not “Schema everywhere.”
Four layers: syntax, shape, semantics, engineering
A four-layer taxonomy beats “JSON is broken”:
| Layer | Symptoms | Structured Output helps? |
|---|---|---|
| Syntax | JSON.parse throws, trailing commas, truncated strings | Mostly yes with JSON/Schema modes; token limits can still truncate |
| Shape | Missing keys, wrong types, bad enums, extra fields | Yes with json_schema + strict if Schema stays in supported subset |
| Semantics | Valid shape but wrong class, hallucinated ids | No—sampling, rules, retrieval, or human review |
| Engineering | Double parse, BOM, stream splice bugs, stale Schema cache | No—unify validation entrypoints and version Schemas |
Syntax: still using raw prompts? max_tokens too low? Regex from markdown instead of structured fields? Shape: strict true? all properties in required? unsupported keywords? Semantics: Schema pass ≠ safe to persist.
Treat Schema validation as a hard gate and business rules as a second gate for high-risk domains.
What 2026 APIs actually guarantee
There is no portable Schema—only vendor subsets. Rough engineering map:
| Vendor / mode | Config | Guarantee |
|---|---|---|
| OpenAI json_schema + strict | response_format or Responses text.format | Shape + types + required; refusal when model declines |
| Gemini responseSchema | generationConfig.responseSchema | JSON + Schema fields; keyword set differs slightly |
| DeepSeek json_object | response_format.type = json_object | Syntactic JSON; shape via prompt + local Schema |
| Tool arguments strict (beta) | tools[].strict or equivalent | Argument shape; beta subset limits |
OpenAI makes Structured Output first-class on Responses after Assistants sunset—json_schema under text.format. Schema body reuses; shell fields change—see our Assistants → Responses migration article. Gemini responseJsonSchema updates: Gemini API JSON guide. DeepSeek V4-Flash stays on json_object: DeepSeek V4-Flash JSON article.
Apple @Generable structures in Swift; encode to JSON before HTTP/persist. Stateless MCP does not replace argument validation—Stateless MCP guide.
Five JSON Schema rules for models
Schema is both docs and compile input. For models:
- Prefer flat objects; deep nesting and heavy $ref raise compile failures.
- additionalProperties: false and list every property in required under OpenAI strict.
- Use description on enums—enum limits values, description disambiguates edge cases.
- Avoid giant oneOf matrices; split calls or use category + sub-schema.
- Pin one Schema file for API, CI, runtime, and JSONVue manual triage.
See Understanding JSON Schema. Spec keywords ≠ model-supported keywords—test violating fixtures.
Our AI Structured Output tutorial covers OpenAI examples; this article focuses on failure modes and validation chains.
Validation pipeline: parse → Schema → business
Run the same three steps on every hop:
- Parse: JSON.parse; on failure log raw text, request id, model version.
- Schema: validate with supported dialect; emit path/keyword for Diff against fixtures.
- Business: ranges, cross-field rules, source alignment, foreign keys—catch semantics.
Vendors document Schema subsets and refusals; client-side validation remains best practice. Centralize at the gateway to avoid drift.
Version Schemas on breaking changes; bump tool names or schema_version to bust stale MCP caches.
Triage checklist and JSONVue workflow
When production JSON fails:
- Identify hop: structured field, content, or tool arguments?
- Check tokens: finish_reason length? truncated JSON?
- Compare strict flag and Schema file: full required? unsupported keywords?
- Keep valid / missing-field / wrong-enum fixtures in CI.
- Sample semantics even when Schema passes.
Paste raw output into JSONVue formatter, validate with JSON Schema validator, compare expected vs actual in JSON Diff.
If only one vendor fails, test the same Schema on OpenAI strict vs Gemini responseSchema—shape matches but enums differ → semantics/description, not parser bugs.
Читать: Structured Output, Gemini JSON, DeepSeek, миграция Assistants.
FAQ
Why does Schema validation fail with strict on?
Mismatched local vs request Schema, strict false, incomplete required, or unsupported keywords. Validate the same file in JSONVue first.
Can Structured Output replace Schema validation?
No. Model-side shape compliance plus local validation for drift, truncation, non-model hops, and business rules.
json_object vs json_schema?
Fixed fields → json_schema + strict. Loose JSON → json_object + mandatory local Schema (DeepSeek-only stacks).
Who validates tool arguments?
Model may offer strict beta; execution must parse, Schema-validate, then call APIs. Same for MCP tools/call.
Summary and next steps
JSON still fails in 2026 because Structured Output covers syntax and shape only; APIs differ on keywords; over-full Schemas fail compile, loose ones drift. Use four layers, parse→Schema→business, versioned Schemas and fixtures.
Next: reproduce one failure in JSONVue. For API wiring read Structured Output, Gemini JSON, DeepSeek V4-Flash, Assistants migration; for agent tools read Stateless MCP.