Ask a language model to read a discharge summary and return the medications as JSON, and it will. Ask it to do that ten thousand times for a hospital, and a different question moves to the front: not is the JSON valid — that's been solved five different ways — but is the JSON true. For a required field the model couldn't leave empty, did it read 4mg off the page, or did it produce a plausible number because the schema demanded one and blank wasn't an option?
Schema-constrained output has no answer to that. Instructor, Outlines, BAML, native structured-output modes — they all guarantee the shape. A validated object tells you the value is a number in the right field. It says nothing about where the number came from. And a well-formed lie is the most dangerous kind, because everything downstream trusts it precisely because it parsed.
Grounding is the feature, not the schema#
LangExtract, a Google library released under Apache-2.0, is built around the part the schema tools skip. For every value it extracts, it returns the exact character offsets in the source text where that value was found. Not "this document mentions a dosage" — this dosage came from characters 1,204 through 1,209, right here.
That one design choice changes what extraction is. With shape-only output, verifying a field means re-reading the source and hunting for the value yourself; at scale, nobody does it, so nobody catches the fabrications. With grounding, verification collapses to checking a highlighted span — the same instinct that makes citations in a RAG pipeline worth the trouble, pushed down to the level of the individual field. The library leans into this: it can emit a self-contained HTML file that renders thousands of extracted entities highlighted in their original context, so a human — or a reviewer, or an auditor — scans provenance instead of prose.
The quieter benefit is that grounding is a hallucination detector. If the extracted field says 4mg and the span it points to doesn't actually contain 4mg, that's a mismatch you can catch at extraction time, in a test, before the value ever reaches a database or a decision. The failure stops being silent. In every schema-only pipeline I've seen, fabricated-to-satisfy-the-schema values are found weeks later by a confused human staring at a record that doesn't match reality. Grounding turns that class of bug into an assertion you can write.
What it does with the boring 90%#
Extraction demos always use a paragraph. Production uses a forty-page contract, a novel-length deposition, a chart with a decade of notes — the needle-in-a-haystack regime where a single pass over a long context quietly drops recall as the relevant span gets buried. LangExtract does the unglamorous scaffolding that problem actually requires: it chunks the document, runs extraction passes in parallel, and makes multiple rounds to keep recall up, then reconciles the results into one schema. You steer it with a few worked examples rather than fine-tuning anything — the examples fix both the fields you want and the style of what counts as a match.
On the schema-guarantee side, LangExtract uses controlled generation, which is a first-class capability on Google's Gemini models — its default backend. It also runs against OpenAI models and local inference via Ollama, where schema adherence falls back to prompt-based coaxing rather than a hard constraint. The grounding — the offsets — is the throughline across backends, and it's the reason to reach for this over a general structured-output wrapper.
The honest limit#
Grounding is a dramatic narrowing of the trust surface, not its elimination. A model can return a span that's slightly misaligned or approximate, which is why the library does alignment work to map extractions back to real positions in the source. So a returned offset is still a claim — a much cheaper one to check than an ungrounded value, but a claim. In genuinely high-stakes settings, the right posture is to treat the offset as an assertion your pipeline verifies against the text, not as gospel.
And LangExtract extracts; it doesn't reason. It's built to find and structure what a document states — dosages, parties, dates, findings — not to infer what it implies or to answer questions the text doesn't directly contain. Point it at "what's the total exposure across these three overlapping clauses" and you're back in ordinary LLM territory, with ordinary LLM trust problems.
But for the enormous, dull, consequential category of work that is turn this pile of documents into a table someone will act on, the reframing is the whole point. "The model said 4mg" is a demo. "The model said 4mg, and here are the five characters where it read it" is a system an auditor will sign off on. The schema was never the hard part. Proving the value was there is.



