Design an Extraction Schema Before You Extract
AI extraction returns clean JSON that quietly means something different each run. Design the extraction schema first — each field's meaning, type, allowed values, missing-value rule, and required evidence — and review it before a single record is pulled.
Build an Extraction Schema PromptWhen the JSON parses but the data doesn't mean anything
You have a stack of documents — vendor security reviews, contracts, support tickets — and you ask the AI to pull the important fields into a table. It returns clean JSON: vendor, risk, date, owner, next step. It parses, it looks structured, and for about a minute it looks like you're done. Then you read it against the source. The "risk" is "medium" — rated by whom, against what? The "date" is one date, but the document had three: submitted, reviewed, renewed. The "owner" is "Security" — but that word isn't in the document, so the model inferred it. Run the same prompt on the next file and the fields come back subtly renamed and differently interpreted. The output is parseable. It just isn't trustworthy, and it isn't the same twice.
The mistake almost always happens before the extraction, not during it: you asked the model to extract before anyone defined what the fields mean. A list of field names is not a schema. A schema says what each field is, what type it holds, which values are allowed, what happens when the document doesn't contain it, and what evidence has to come back with it — and it exists, reviewed, before the first record is pulled. This guide is how to design an extraction schema before you extract: field by field, with an explicit missing-value policy and a source reference, drafted with AI and approved by you. NewPrompt helps you build that schema prompt — the Extraction Prompt Generator builds it from your field list — but it's honest about the edges: it doesn't upload or parse your documents, run the extraction, validate the schema, or check that a value is right. You run the prompt on your own source in your own AI tool, and what comes back — both the schema and, later, the data — is a draft you review, not a result you trust on sight.
Why a list of field names is not a schema
The reason "extract vendor, risk, date, owner, next step" fails isn't that the model is weak — it's that every one of those words is a question the prompt left unanswered, so the model answers it, differently, for each document. "Risk" — the rating the document assigned, or your read of the issues it lists? "Date" — which of the several in the file? Field names carry a meaning in your head that the model can't see, and it will fill the gap with a plausible guess every time. A schema is the difference between naming a field and defining it. For each field, it pins down:
- Meaning — what this field actually is, in one sentence the model can't reinterpret. Not "risk" but "the overall risk rating the review explicitly assigned."
- Type — string, number, date, enum, list — so the same field doesn't come back as "3" in one record and "three people" in the next.
- Allowed values — for anything from a closed set, the exact options (low | medium | high | critical), so the model picks from your list instead of inventing a scale.
- Example — one valid value, because a concrete example constrains the model more reliably than a paragraph of description.
- When to fill it, and when not to — the condition under which the field applies, so an optional field left blank is a decision, not an oversight.
- Missing-value policy — what comes back when the document doesn't contain it, covered in its own step because it's the setting that most often turns extraction into silent garbage.
- Evidence — the quote or location the value came from, so a reviewer can check it against the source instead of trusting it.
Step 1: Design the schema first, and stop before extracting
Make the schema its own request, and end it before any extraction happens. The instinct is to ask for the data — "extract these fields" — and let the schema be implicit in the field names. Invert it: ask the model to design the extraction schema and output only the schema, explicitly not the data yet. Give it the source type (what kind of document this is), the goal (what the extracted table is for — that shapes which fields matter), and your rough field list. Then have it return, for each field, the meaning, type, allowed values, example, fill conditions, missing policy, and evidence requirement. The instruction that does the work is the one that holds it back: output the schema first; do not extract yet.
The Extraction Prompt Generator is built for this — you give it fields and it writes the per-field extraction rules, the missing-data behavior, and the ambiguity policy, so the schema comes back structured instead of as a loose paragraph. If you want to see that structure before you build your own, the Information Extraction Prompt lays out the six sections a reliable extraction prompt needs — source guidance, field definitions, per-field rules, missing-data, ambiguity policy, and a worked example — on a real extraction you can read and adapt. Both give you a prompt you run on your own source.
Step 2: Define each field so the model can't reinterpret it
With the schema as its own artifact, go field by field and close every gap the name leaves open. The test for a good field definition is simple: could two careful people, reading it, disagree about what belongs in the field? If yes, it isn't defined yet. "security_risk_level" isn't "the risk" — it's "the overall risk rating the review explicitly assigned, not inferred from the issues it lists," with allowed values low | medium | high | critical, and an example. "follow_up_action" isn't "next steps" — it's "an action the document explicitly requests," with a rule that the model does not invent a recommended action of its own. The definition is where you separate what the document says from what the model would like to add.
Two distinctions carry most of the weight. The first is extracted versus inferred: a field should say, in its definition, whether it captures something stated in the text or something the model is allowed to conclude — and for most extraction, the answer is "stated only, do not infer." The second is output shape versus field meaning: getting valid JSON back is a different job from getting the right field to hold the right thing. The JSON Output Prompt Builder is the tool for the shape — types, nullability, a parseable contract — and it's genuinely necessary, but a perfectly-shaped record can still be meaningfully wrong. This guide is about the meaning layer, which is the one that decides whether the data is true.
Step 3: Decide what "missing" means before the model does
The single most consequential line in an extraction schema is what happens when the field isn't in the document — because eventually it isn't. Leave it undefined and the model improvises: it blanks one field, writes "N/A" in another, and quietly invents a plausible value in a third, and now your data has three different meanings for "absent" and one of them is fiction. Decide it up front, per field or as a default: an absent value returns a specific, agreed marker — an empty string, a null, or a literal "not_stated" / "unknown" / "not_applicable" — and the rule "never infer or guess a value for a missing field" is stated and non-negotiable. The point isn't which marker you pick; it's that absence has one consistent, visible representation instead of several accidental ones.
The markers aren't interchangeable, and the right one depends on who reads the output: a literal "unknown" string is loud — a human scanning a column can't miss it — while a null keeps keys stable for code that parses the result, and "not_applicable" says something different again: the field doesn't apply to this document, which is not the same as present-but-not-found. The Missing Data in AI Extraction resource lays out the four behaviors — leave empty, null, unknown, skip — and when each is right, with the contract language that enforces it. Whichever you choose, the rule underneath is the one that matters: a field the document doesn't support stays empty or flagged, never filled with a guess. Getting that rule into the schema is most of what separates reviewable extraction from confident nonsense.
Step 4: Make the values that matter carry their evidence
A value you can't trace back to the source is a value you have to take on faith, and at scale nobody re-reads the documents. So build the evidence requirement into the schema: for each field that matters, the extraction returns not just the value but where it came from — the exact quote, and the section, page, or line if the source has them. A "security_risk_level" of "high" backed by the sentence that assigned it is checkable in seconds; the same value with no quote is a claim. For high-impact fields especially, make evidence mandatory: no supporting quote means the field comes back as not_stated or flagged for review, not filled from the model's best guess.
Two honest limits keep this from becoming false confidence. First, the model produces the quote and the location from the text you gave it — it isn't looking up a verified source, and it can misattribute or approximate a line number, so the reference exists to make your review fast, not to prove the value is right. A quote next to a value means "here's where I got this, go check" — not "this is confirmed." Second, evidence makes wrong values easier to catch, but it doesn't make them fewer; a confident extraction with a slightly-misread quote is exactly the kind of error the review exists to find. Evidence is what makes the data reviewable. You are still the one who reviews it.
Step 5: Review the schema, extract a sample, then scale
The schema the AI drafts is a candidate, not a spec, so the review is yours and it comes before extraction, not after. Read each field definition and ask the questions the model can't: is "risk" really the assigned rating in your documents, or did you mean your own assessment? Does "owner" exist in these files, or are you asking for something that isn't there? Are the allowed values actually the ones your source uses? Edit the definitions until they match your documents and your intent — this is the step that makes every later extraction consistent, because the model stops guessing meanings and starts following yours.
Then test before you trust. Run the approved schema on a small sample — a handful of representative documents, including an awkward one — and read the output against the source, not just for shape but for meaning: did the fields capture what you intended, did missing values behave, did the evidence line up? Where it drifted, the fix is usually the schema, not the extraction: a definition that was still ambiguous, a missing case the policy didn't cover, an allowed-value list that was too narrow. Adjust the schema, re-run the sample, and only scale to the full set once the small one is boring. And treat what finally comes out as candidate data: the extracted values are a draft you verify against the source, and for anything legal, financial, medical, security, or compliance-related, that verification belongs with the domain owner, not the model. NewPrompt gives you the structure to design and review; running the extraction, reading your documents, and confirming the values happen on your side.
Common mistakes
The habits that produce parseable, unreliable extraction:
- Handing the model a field list and calling it a schema. Names carry meaning you can see and the model can't; define each field or watch it get reinterpreted per document.
- Asking for the data before defining the fields. Design and approve the schema first, as its own step; extraction comes after the definitions are settled, not instead of them.
- Leaving "missing" undefined. An absent value should return one agreed marker with a never-infer rule — not a mix of blanks, "N/A", and quietly invented values.
- Confusing valid JSON with good data. Parseable is the shape; correct is the meaning — a record can pass a parser and still hold the wrong thing in the wrong field.
- Letting the model infer owners, risks, and actions. If it isn't stated in the source, the field is not_stated; a definition that says "do not infer" is what stops the helpful guess.
- Trusting extracted values because they came with a quote. Evidence makes review fast, not unnecessary — the value, and the quote, are a draft you check against the source, not something NewPrompt verified.
A worked example: vendor security reviews into a reviewable table
Watch a one-line extraction request produce ambiguous data, then a schema-first prompt define the fields — and stop, deliberately, before extracting.
A one-line "extract these fields" returns ambiguous, per-file-inconsistent data; a schema-first prompt defines each field's meaning, type, missing policy, and required evidence — and stops before extracting, so you approve the schema, run it on a sample, and verify the values yourselfTHE SOURCE:
A stack of vendor security review documents (free text, varied formats).
Goal: a reviewable table of vendor security status and open follow-ups.
THE WEAK ASK, AND WHAT IT GIVES BACK:
ask: "Extract vendor name, risk, dates, owner, and next steps."
one record it returns:
{ "vendor": "AcmeCloud", "risk": "medium", "date": "2026-04-02",
"owner": "Security", "next_step": "Review contract" }
why it isn't trustworthy:
- risk "medium" -- assigned by the review, or inferred from the issues?
- date -- submitted, reviewed, or renewal date? the file had all three
- owner "Security" -- that word isn't in the document; the model guessed
- next_step -- extracted from the doc, or the model's own suggestion?
- no evidence, no missing-value policy -- the next file parses differently
A SCHEMA-FIRST PROMPT (design only, do not extract yet):
Before extracting, design the extraction schema. Output the schema only.
Source type: vendor security review documents.
Goal: reviewable table of vendor security status and open follow-ups.
For each field, return:
field_name | definition | type | allowed_values | example
when_not_to_fill | missing_value_policy | evidence_required
Rules:
- Do not infer owners, risks, or next steps unless explicitly stated.
- If a value is not stated, use "not_stated".
- If a field does not apply to this document, use "not_applicable".
- Every value must carry a source_quote (and location if available).
- Do not extract yet. Wait for my approval of this schema.
PART OF THE SCHEMA IT DRAFTS:
field_name: security_risk_level
definition: overall risk rating the review explicitly assigned,
NOT inferred from the issues listed
type: enum allowed_values: low | medium | high | critical | not_stated
when_not_to_fill: issues are listed but no overall rating is stated
missing_value_policy: not_stated
evidence_required: quote containing the rating
needs_review: true when issues imply risk but no rating is stated
field_name: follow_up_action
definition: an action the document explicitly requests
type: string
when_not_to_fill: do NOT invent a recommended action
missing_value_policy: not_stated
evidence_required: quote with the action language
THE EXTRACTION STEP (only after you approve the schema):
Extract using only these fields. Do not add fields during extraction.
If the schema can't hold a document, stop and propose a schema change.
NEXT: you edit the definitions to match your documents, run the approved
schema on a few files, and check each value against the source. The schema
is a candidate draft and the extracted data is candidate data -- you run
every step in your own AI tool; NewPrompt designs neither for you.
Where this fits in NewPrompt
Designing the schema is the front half of reliable extraction, and NewPrompt gives you the structure for it, not the extraction. The Extraction Prompt Generator derives each field's extraction rule from the name you give it and assembles the schema prompt; the Information Extraction Prompt shows the six-section anatomy that prompt follows, on a worked example you can adapt; and the Missing Data in AI Extraction resource goes deep on the one setting — empty, null, unknown, or skip — that most often decides whether absence is visible or silent. One layer down from meaning sits shape: the JSON Output Prompt Builder makes the output parseable, a necessary and separate job from making the fields mean the right thing. Each builds a prompt you run on your own source in your own AI tool.
This guide sits at the start of the extraction work, before its neighbors pick up. Extracting from documents without losing evidence is about doing the extraction well once you're in it; keeping AI from inventing missing data is one rule — a critical one — that this schema encodes as an explicit missing-value policy; and getting valid JSON is the output shape, which a good schema needs but isn't. What this guide adds is the step that comes first: deciding what each field means, what it may contain, and what has to travel with it, before the model extracts a single record. Get the schema right and those other problems shrink; skip it and no amount of downstream cleanup makes inconsistent extraction consistent.
An extraction schema is a row of labeled, empty jars you prepare before you start pouring. Decide up front what each one is for, what kind of thing goes in it, and what to do when there's nothing to pour — and every document fills the same jars the same way, with a note on each of where its contents came from. Skip the labeling and you pour first and sort later, from memory, hoping each batch landed in the right container. The AI can help you design the jars and it fills a first batch fast; whether the labels are right, and whether what landed in each jar actually belongs there, is the part you check — before you pour the whole shelf.