Verification & Reflection

Deterministic-LLM Sandwich

Bracket every LLM call with deterministic checks on both sides.

Problem

Trusting the model's output unconditionally accepts hallucination at exactly the moment where mistakes are most expensive, and there is no signal at the boundary distinguishing a correct generation from a confidently wrong one. Banning the model entirely loses everything it was good at and forces the team back to brittle templated text. Simple downstream validation (a try/catch on the database call, for example) catches some failures but only after side effects have begun or only by failing loudly to the user. The team needs a way to keep the model in the loop while bounding what kinds of output it can land.

Solution

Three layers. Pre: deterministic check decides whether the LLM should run at all (e.g. AST parse must succeed). LLM: produces a candidate output with structured-output schema and frozen rubric. Post: deterministic re-validation (parse, type-check, run tests). If post fails, the original is returned unchanged.

When to use

  • LLM output must be checked deterministically before being trusted (e.g. AST parse, type-check, test run).
  • A pre-check can decide whether the LLM should run at all.
  • Returning the original input on post-check failure is acceptable behaviour.

Open the full interactive page

Diagram, neighbourhood map, code examples, related patterns and full provenance.

Related