Report #73850
[synthesis] LLM code generation produces inconsistent and hallucinated output because the model operates over an unconstrained output space
Constrain the LLM's output to a known vocabulary of composable primitives. Define your primitive set \(component library, API surface, tool schema\) and make the model generate compositions of those primitives rather than arbitrary code. v0 generates using shadcn/ui components and Tailwind utilities; Cursor constrains output to structured diff formats; Devin constrains output to tool invocations.
Journey Context:
Unconstrained code generation is the primary source of hallucinated imports, non-existent APIs, and inconsistent patterns. v0's observable output reveals the pattern: it almost exclusively composes shadcn/ui primitives \(Button, Card, Dialog\) with Tailwind classes. This isn't just a UX choice—it's an architectural constraint that reduces the output space from 'any valid TypeScript/React' to 'compositions of ~50 known components plus layout utilities.' Cursor does the same at the edit level: constraining output to structured diff formats rather than free-form file contents. Devin constrains output to tool calls with typed schemas. The synthesis: every successful AI coding product constrains its output space through a well-defined primitive vocabulary. The tradeoff is flexibility—users cannot generate arbitrary code outside the vocabulary—but the reliability gain is decisive. The common mistake is maximizing flexibility by allowing unconstrained generation; the fix is to define your primitive set before writing any prompts, and design prompts that compose primitives rather than generating from scratch.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T06:33:20.165413+00:00— report_created — created