Agent Experiences

Generative UI & Context Design

Interfaces a model assembles at runtime — and how to keep them predictable.

Definition

Generative UI is an interface assembled by a model at runtime in response to a specific request, rather than laid out in advance by a designer. Instead of rendering a fixed screen and filling it with data, the system decides which components to show, how to arrange them, and what controls to offer — per response. The design discipline around it is mostly about constraint: deciding what the model may choose from, what it may never choose, and how a person keeps a stable mental model of a surface that is different every time.

What makes it different from dynamic UI

Interfaces have always varied at runtime. A templated dashboard changes with the data; a personalized feed changes with the user; a rules-driven form shows a field when a checkbox is ticked. All of that is variation within a design a person authored. Every branch existed before the user arrived, and somebody decided each one was acceptable.

Generative UI moves the composition decision itself to inference time. Nobody enumerated the branches. The consequences follow directly: the output space is open rather than reviewed, the same request can produce different layouts on different runs, and the qualities designers usually guarantee — hierarchy, consistency, accessibility, correct affordances — become properties that have to be enforced by the system around the model rather than assumed from the artifact.

The spectrum of generative UI

“Generated interface” covers approaches that differ enormously in risk. It helps to place any system on a spectrum of how much authority the model has over the rendered result.

1. Selection — the model picks components

The model chooses from a fixed library and supplies typed props: render a flight-results card, a confirmation control, a chart with these series. Everything rendered was designed, reviewed, and tested by a human; the model only decides which piece applies and with what data.

This is where the streamed component-based approach popularized by the Vercel AI SDK sits — a tool call resolves to a real React component streamed into the conversation — and it is also the shape of MCP UI patterns, where a tool returns a renderable surface the host application displays inside its own frame. It is the least glamorous end of the spectrum and where nearly all production systems live.

2. Composition — the model arranges layouts

The model composes known components into novel arrangements: this comparison needs three panels side by side, this answer needs a table plus a map plus a set of filters. The primitives are still trusted; the structure is not. Risk shifts from “what is rendered” to “does the result have coherent hierarchy, sane density, and a sensible reading order” — which is exactly what layout constraints, slot systems, and a small number of approved page skeletons exist to bound.

3. Emission — the model writes the interface

The model produces arbitrary markup, styles, or code, and the surface renders it. This is what artifact-style side panels do when they display a generated app or document. It is genuinely powerful for one-off, user-directed creations — and it is why those surfaces are sandboxed, visually framed as generated output, and kept out of the paths where the product itself takes consequential action.

The design guidance is straightforward: use the least authority that accomplishes the job, and never let generated markup be the surface through which a consequential action is confirmed. A model-authored button that says “Confirm transfer” carries no guarantee about what it does. Approvals belong to application chrome the model cannot compose.

Design implications

Predictability is a feature, not a limitation

The instinct is to treat flexibility as the point. In use, the opposite tends to hold: people work faster in a surface whose repertoire they recognize. If the same kind of question reliably produces the same kind of view, a user learns where to look. If every response invents a layout, every response has to be read from scratch, and the cognitive cost lands on the person exactly when they are trying to evaluate whether the answer is any good.

Practical consequence: define a small set of response shapes and bind them to intent classes. Let the model choose the shape, not invent one. Keep persistent elements — the input, the run controls, the history, the stop button — in fixed positions across every generated view, so at least the frame is stable while the contents vary.

Mental models of a shifting surface

Users build expectations from repetition. A generated interface undermines that unless the system gives them something stable to hold onto. Three things help: consistent naming for the same concept across views, visible causality between the request and the resulting layout (so the surface feels responsive rather than arbitrary), and persistence — if a user pinned, filtered, or edited something, the next generated view should honor it rather than silently reset.

Also worth stating plainly: users cannot discover capability by looking at a generated surface, because what is on screen reflects this request, not the system’s repertoire. Discoverability has to be provided somewhere else — suggestions, examples, an explicit capability view.

Accessibility cannot be delegated to the model

A model asked to produce an interface will produce something that looks right in a screenshot. Heading order, focus management, label associations, contrast, and keyboard reachability are not reliably preserved by generation, and they are invisible in exactly the review most teams perform.

  • Put accessibility in the components, not the prompt. In a selection-based system the library carries semantics, focus behavior, and contrast, and the model cannot degrade them.
  • Own the document structure. Let the application assign heading levels and landmarks by position in the composition rather than accepting whatever the model emitted.
  • Manage focus and announcements on the application side when content streams in — a surface that rewrites itself mid-read is hostile to screen reader and keyboard users unless someone decided where focus goes.
  • Run automated accessibility checks against generated output as part of evaluation, not only against static component stories.

Testing and QA when output is nondeterministic

You cannot snapshot-test a screen that is different every run, but you can test everything around it. The practical decomposition:

  • Components are tested conventionally. The finite, human-authored library is where normal visual, unit, and accessibility testing applies — and it is why keeping the library finite matters.
  • Selection is evaluated, not asserted. Build a set of representative requests with expected component or shape choices, and track the hit rate across model and prompt changes like any other eval.
  • Validate at the boundary. Treat model output as untrusted input: schema-validate props, reject unknown components, clamp array lengths and string sizes, and design a graceful degradation path for malformed output rather than rendering whatever arrives.
  • Test the invariants. Regardless of what the model composed, the stop control exists, provenance is shown, the layout does not overflow, and no consequential control appears inside generated content.
  • Watch the tail. Empty results, one result, five hundred results, missing fields, very long strings, and multiple languages break generated layouts more often than the happy path that gets demoed.

Trust and provenance

A generated interface looks as authoritative as a designed one. That is precisely the problem: the visual language of software implies that someone checked. Users need to be able to tell what was generated, from what, and how confident they should be.

  • Distinguish generated regions from application chrome. A consistent visual treatment for model-composed content is worth more than a disclaimer, because it works every time without being read.
  • Attribute the data, not just the answer. A generated table should say where its rows came from — which tool, which source, retrieved when — and let a user reach the underlying record.
  • Mark staleness. Generated views are snapshots. If the data behind one has moved, the surface should say so rather than presenting an old composition as current.
  • Never render untrusted content as interface. Text retrieved from a page or a document is data to display, not instructions to build UI from. Where fetched content influences what is rendered, that provenance should be visible — the same reasoning that makes prompt injection an interface problem and not just a security one.
  • Make generated surfaces inspectable. Users should be able to see the underlying data or the request that produced a view, and correct it. A generated interface that cannot be questioned cannot be trusted for anything that matters.

The short version

Give the model a rich vocabulary and a narrow grammar. Design the components, constrain the composition, validate the output, keep consequential controls out of generated regions, and make provenance visible by default. Almost every generative UI failure in production traces back to granting the model more layout authority than the job required.

Stay Updated

Analysis of AI search, crawler policy and agent standards — sent when there is something worth reading, roughly twice a month. Unsubscribe anytime.

We store your email address only to send you this newsletter. See our privacy policy.