Copy
Trading Bots
Events
More

LLM in Editor: Schema Validation Lessons

2026/07/15 22:00Browse 0

When integrating an LLM generation step into a drag-and-drop editor, the model's output must be structurally valid, not just semantically correct. A hallucinated CSS class name can break styling, and an invalid prop key can silently render a component invisible. This article shares lessons from building WebDigitize, an AI-powered website generator for Nigerian small businesses using the Puck editor.

The Schema Representation Problem

Puck stores page state as a JSON document where each content entry maps to a registered React component with specific fields. If the LLM emits `headlineText` instead of `headline`, the component renders with `undefined` — no error, no warning. The naive approach of describing components in prose works for simple cases but fails when there are 15 components with 4–8 fields each, as the model drifts toward invented field names.

The solution was to represent component schemas as a compact formal notation in the system prompt. This notation uses pipe-separated enums (e.g., `"star" | "check" | "bolt"`), inline constraints like `max 60 chars`, and explicit notes such as "must match brief — do not invent." The model treats the enums as a closed set, preventing hallucinated values.

System Prompt vs User Message

Placement of the schema matters. In multi-turn conversations where the schema was placed in the user message, the critic pass occasionally invented prop names not in the original schema. Moving the schema to the system prompt — which is treated as persistent context across all turns — dropped schema violations to nearly zero. The model correctly understands that system prompt constraints are inviolable, while user message constraints can flex.

Validating Output at the Boundary

Even with strict prompting, a validation step is essential before storing generated content. The validator checks each block's type and prop keys against a whitelist. When validation fails, the raw output is logged and generation is retried with an amended prompt that includes the specific error. In practice, retries trigger for only about 2% of generations.

The Array Prop Problem

Arrays are the most reliably broken output format. The model may produce valid arrays initially, but on a retry or critic pass, it can wrap items in an object (e.g., `{"items": [...], "count": 2}`) or rename keys inside array items. The fix is to extend the validator to recurse into array items and check each key against a set of allowed keys.

Rich Text: The Unexpected Footgun

One block accepted a `body` field that was supposed to be a Puck rich text value — a Lexical editor serialized state, not a plain string. Exposing this to the LLM produced beautiful-looking text that was a plain string, causing a crash when the user tried to edit the block. The fix was to never ask an LLM to produce rich text editor state. Instead, the block accepts a `bodyText: string` prop, and a `useEffect` converts it to a Lexical initial state on first render.

Structuring the Puck Config for AI-Friendliness

After building this, the Puck config was restructured with AI consumers in mind. Consistent naming conventions were used: all text fields are string types named with a noun (e.g., `headline`, `subheadline`, `address`), and all boolean toggles start with `show` (e.g., `showCta`, `showImage`). The model learned these conventions quickly and stopped inventing alternatives. Array items were kept flat, and default prop values were provided in components to handle missing fields gracefully.

Disclaimer: This page may contain third-party information and does not necessarily reflect BYDFi's views or opinions. This content is for general reference only and does not constitute any representation, warranty, financial advice, or investment advice. BYDFi is not responsible for any errors, omissions, or any results arising from the use of such information. Virtual asset investments involve risks. Please carefully evaluate the risks of the product and your risk tolerance based on your financial situation. For more information, please refer to our Terms of Use and Risk Disclosure.