---
title: Structured Output — Making LLMs Speak JSON
description: LLMs generate prose. UIs need data structures. Structured output bridges the gap so AI responses render as rich flight and hotel cards.
canonical: https://nowah.xyz/blog/structured-output-making-llms-speak-json
lastModified: "2026-08-07T08:08:25.450Z"
---

# Structured Output — Making LLMs Speak JSON

LLMs generate prose. UIs need data structures. Structured output bridges the gap so AI responses render as rich flight and hotel cards.

LLMs think in prose. They generate natural language text one token at a time. This is great for conversation. It is terrible for user interfaces.

When our agent finds three flights for your Tokyo trip, the UI needs to render three interactive flight cards. Each card requires specific data in a specific structure: airline name, departure time, arrival time, duration, number of stops, price, cabin class, baggage policy. This data needs to be in a machine-readable format that the frontend can parse and render as a rich component.

The bridge between LLM prose and UI rendering is structured output: the ability to make LLMs produce valid JSON objects that conform to a defined schema. It sounds simple. Getting it to work reliably in production took significant engineering.

## The rendering problem

![Illustration for this section](https://pics.nowah.xyz/website-media/ai-research-035-img-1.webp)

Imagine the agent's response as pure text:

"I found three great flights for you. The first is a direct flight on ANA departing at 10:15 AM, arriving at 2:30 PM next day, 11 hours 15 minutes, for $520. The second is..."

A human can read this and extract the information. A UI cannot render it as interactive cards without parsing natural language, which is unreliable and fragile.

Now imagine the same response with structured output:

The agent produces both a text narrative ("Here are your top [three options](/blog/why-three-options-not-three-hundred)...") and a JSON array of flight objects, each with typed fields. The frontend receives the JSON, maps it to a flight card component, and renders interactive cards with airline logos, time displays, and booking buttons.

The user experience is dramatically different. Text [responses feel](/blog/launching-streaming-responses-agent-feel-fast) like reading a report. Structured card responses feel like using a product.

Users prefer rich card responses over plain text by significant margins. Cards are scannable. They enable comparison. They have interactive elements (tap to book, tap to see details). They are what users expect from a travel booking experience.

## JSON mode and structured output

Modern frontier models support JSON mode: a configuration that guarantees the model's output is valid JSON. This eliminates the most basic failure mode (invalid JSON that breaks the parser) and is a significant improvement over the regex-extraction days.

Beyond basic JSON mode, structured output allows you to define a schema that the output must conform to. Not just "produce valid JSON" but "produce JSON matching this exact schema with these fields, these types, and these constraints."

For our flight offer schema:

```
FlightOffer:
 airline: string (IATA carrier code)
 departure: datetime (ISO 8601)
 arrival: datetime (ISO 8601)
 duration: string (e.g., "11h 15m")
 stops: integer
 price: number
 currency: string
 cabin: enum (economy, premium_economy, business, first)
 baggage_included: boolean
```

When the model produces output conforming to this schema, the frontend knows exactly what to expect. No parsing ambiguity. No missing fields. No type mismatches.

JSON mode reliability has improved dramatically with frontier model updates. The combination of schema enforcement and improved model training means structured output failures are now rare.

## Schema design for travel

![Supporting diagram](https://pics.nowah.xyz/website-media/ai-research-035-img-2.webp)

Designing schemas for travel data requires balancing completeness with simplicity.

**Too few fields** and the card lacks useful information. A flight card without baggage policy or fare class leaves users wondering about hidden costs.

**Too many fields** and the model is more likely to produce errors or hallucinate values for fields it does not have data for\. If the schema includes a "legroom\_inches" field but the source data does not provide legroom information, the model might invent a number\.

**Nested structures** add complexity but are sometimes necessary. A multi-segment flight (with connections) requires an array of segments, each with its own departure, arrival, and duration. The schema needs to handle both direct flights (one segment) and connections (multiple segments) gracefully.

**Optional vs required fields.** Some information is always available (airline, departure, arrival, price). Some is sometimes available (baggage policy, seat map, aircraft type). Required fields must always be present. Optional fields should be included when available and omitted when not, rather than filled with placeholder values.

Our schemas evolved through production use. Early versions had too many required fields, leading to hallucinated values. Current versions mark most fields as optional and let the frontend handle missing data gracefully (showing "check with airline" for unavailable baggage information rather than displaying a hallucinated value).

Schema design affects both output quality and [function calling](/blog/function-calling-breakthrough-enabled-agents) accuracy. A well-designed schema is the single most effective intervention for improving the reliability of structured AI responses.

## Error handling when structure breaks

Even with JSON mode and schema enforcement, structured output can fail.

**Partial output.** The model starts producing valid JSON but is cut off by a token limit. The JSON is incomplete and invalid. We handle this by detecting truncation and either requesting continuation or falling back to text-only presentation for that response.

**Schema violation.** The model produces valid JSON that does not match the schema. A string where a number was expected. A missing required field. We validate against the schema before rendering and fall back gracefully for non-conforming output.

**Inconsistent data.** The JSON is structurally valid and schema-conforming, but the data is internally inconsistent. A departure time after the arrival time. A duration that does not match the departure-arrival gap. We run sanity checks on the data and flag inconsistencies.

**Hallucinated values.** The model fills an optional field with a hallucinated value rather than omitting it. The flight card shows "32 inches legroom" when the source data did not include legroom information. We mitigate this by cross-referencing structured output against the source tool call data.

Each failure type has a specific handler. The principle is: never render bad data. Fall back to text or partial rendering rather than showing incorrect information in a card.

## The UX payoff

The investment in structured output pays off in user experience.

**Flight cards** show airline, times, duration, stops, and price at a glance. Users can compare three options in seconds. Tap a card to see full details. Tap the booking button to proceed.

**Hotel cards** show property name, location, price, rating, and a photo. Users can evaluate a hotel in a glance rather than reading a paragraph.

**Itinerary views** show day-by-day plans with activity blocks, transport segments, and timing. The structured data enables timeline visualization that text cannot match.

**Comparison views** place two or three options side by side with matching fields aligned. This is only possible with structured data where each option has the same field set.

The difference between a text-based travel assistant and a card-based travel assistant is the difference between reading a magazine and using a product. Structured output is what makes the product possible.

Structured output is one of those capabilities that is invisible when it works and painfully obvious when it does not. When it works, users see beautiful, interactive travel cards. When it does not, they see broken layouts or walls of text. The engineering effort to make it work reliably is substantial, but the result is the polished experience that users expect from the best travel app.

---

Nowah is an AI travel agent that searches and books real flights and hotels through conversation — no filters, no thirty open tabs. [Plan your next trip](https://app.nowah.xyz).
