Define Fields So AI Fills Them the Same Way Every Time
You ask AI to fill a table — issue_type, priority, reason — and the same column gets filled by different logic each row: priority as urgency here, sentiment there. Here's how to define each field's meaning, allowed values, and include/exclude rules so AI fills them consistently.
Build a Field-Definition PromptWhen the same column means five different things
You ask the AI to put a stack of support tickets into a table: issue_type, priority, reason, next_action. It returns a clean table — every row filled, nothing missing, parses fine. Then you read down a column. "priority" is "high" for a ticket that blocks payroll, and also "high" for a ticket where the customer is just angry — impact in one row, emotion in the next. "reason" quotes what the customer said in row one and states the AI's guess at the root cause in row two. "next_action" is an internal engineering task here and a customer-facing apology there. The columns line up; the logic behind them doesn't. Each row filled the same field by whatever made sense in that row, and now the table looks consistent and isn't.
That's the gap this guide closes. A field name is a label you understand and the model doesn't — "priority," "reason," "issue_type" each carry a precise meaning in your head that the column header never states, so the model supplies its own, and picks a different one whenever the row nudges it to. Getting valid JSON or a tidy table is a solved problem; getting the same field filled by the same logic in every row is a different one, and it's decided before the model fills anything — by field definitions written up front. This guide is how to write them: for each field, what it means, what counts and what doesn't, its allowed values, a good example and a bad one, and what to do when the answer isn't there. NewPrompt gives you the structure to build that field-definition prompt; it doesn't validate the values, enforce the schema as the model runs, or read your source — you run the prompt in your own AI tool, and the field definitions and the filled rows are drafts you check.
Why a field name isn't a definition
The reason "issue_type, priority, reason, next_action" drifts isn't that the model is careless — it's that each of those names is a question the prompt never answered, so the model answers it fresh for every row, by feel. "Priority" by what — business impact, urgency, how upset the customer sounds? "Reason" whose — the customer's stated reason, or the model's diagnosis? The label hides the choice, and an unstated choice gets made differently under different rows. Four gaps a bare field name leaves open:
- No decision rule. "priority" with no criteria lets each row weigh impact, urgency, and tone in whatever mix that ticket suggests — so "high" doesn't mean one thing.
- No source rule. "reason" doesn't say whether the value is quoted from the input or concluded by the model, so it's sometimes the customer's words and sometimes the model's inference — two different kinds of thing in one column.
- No allowed values. "issue_type" with no list lets the model mint a category per ticket — "login issue," "auth problem," "SSO bug" for three tickets that are the same type.
- No boundary. Nothing says what a field excludes, so "next_action" absorbs internal tasks, customer replies, and product suggestions interchangeably — all plausible, none consistent.
Step 1: Say what kind of field each one is
Before defining any single field, sort them by kind, because different kinds of field drift for different reasons and need different definitions. Most structured records mix a few types: a category field that picks from a fixed set (issue_type), a decision field that applies a rule to reach a verdict (priority), a source field that captures what the input actually says (customer_reason), a judgment field that holds the model's own read (suspected_cause), and an action field that states what to do (next_action). The trouble starts when a record treats them all the same — asks for five fields as if they were one kind of thing — because a category needs a list, a decision needs criteria, and a source field needs a quoting rule, and none of those substitutes for the others.
Naming the kind up front also catches the field that's secretly two fields. "reason" is the classic one: it wants to be a source field (what the customer said) and a judgment field (why it's happening) at the same time, so the model fills it as whichever fits the row. The fix is structural — split it into two clearly-typed fields — and it starts here, by refusing to write a definition for a field until you can say which single kind it is. A field you can't type yet isn't defined yet; it's a question with two answers.
Step 2: Define each field with include, exclude, and a counterexample
With the kind settled, write the definition that closes the gaps the name left open. The test for a good one: could two careful people, reading it, fill the same field differently? If yes, it isn't defined. A workable shape per field: a one-sentence plain-language meaning, what it includes, what it explicitly excludes, the allowed type or values, one good example value, and — the part that does the most work — one bad counterexample that would be easy to get wrong. "issue_type: the normalized category of the reported problem; includes the technical area affected; excludes the customer's emotion and the fix; allowed: login_access, billing, feature_request, bug_unknown, other; good: billing; bad: 'angry customer' (that's sentiment, not a type)."
The counterexample is what separates a definition that reads well from one that holds. A positive example shows the model a target; a bad example fences off the specific mistake the field invites, and every ambiguous field has one — the plausible wrong fill that a definition-by-inclusion-only never rules out. The Turn a JSON Schema into a Prompt resource shows the readable form these definitions take — one line per field with its type and a description that constrains the value, plus a realistic example — the format a model follows far better than a bare name or raw schema syntax. Write the meaning and the include/exclude yourself; that resource is the shape they travel in.
Step 3: Keep source fields and judgment fields apart
This is the distinction that quietly breaks the most tables, so it gets its own rule: a field that holds what the source says and a field that holds what the model concludes must never be the same field. When "reason" is allowed to mean both, one row gives you the customer's own words and the next gives you the model's theory of the bug — and downstream, nobody can tell which rows are reported fact and which are AI inference, because they share a column. Split them: customer_reason captures what the ticket states, quoting or closely paraphrasing, and never adds a diagnosis; suspected_cause, if you want it at all, holds the model's read and is explicitly labeled as inference, not report.
For the source field, the definition should say "from the input only — do not infer," and for the judgment field it should say the opposite plainly: "this is the model's conclusion, mark it as such, and if the input doesn't support one, leave it empty rather than guess." The point isn't that inference is forbidden — sometimes the model's read is exactly what you want — it's that report and inference are different kinds of claim and a reader has to be able to tell them apart. A table that blends them looks like data and behaves like opinion. Keeping the two in separate, clearly-typed fields is what lets you trust the reported column and weigh the inferred one, instead of taking the whole row on faith.
Step 4: Give decision fields criteria, and every field a missing rule
A decision field like priority or status is only consistent if the rule that sets it is written down, because "high / medium / low" without criteria is just three words the model assigns by feel. Spell out what earns each value: "priority is high when the ticket blocks a critical workflow today, or carries legal, security, or payment risk, or is an enterprise escalation — not high because the customer is angry." That last clause matters more than it looks: naming the tempting wrong basis — emotion, loudness, message length — is often what stops the model from using it. An enum field needs its criteria as much as its list; the list says which values are legal, the criteria say which one a given row earns.
Then decide, per field, what happens when the answer isn't in the input — because eventually it isn't, and an undefined absence is where consistency dies. Set one rule and state it: an absent value returns a specific marker — an empty string, a null, or a literal "not_stated" — and the model never fills a field it can't support from the source. This is especially strict for the judgment fields and the decision fields: a suspected_cause with no evidence gets the missing marker, not a guess; a priority that can't be determined is flagged for review, not guessed at. The Missing Data in AI Extraction resource lays out the handful of missing-value behaviors and when each is right — a visible, agreed marker in every row beats a mix of blanks, "N/A", and quietly invented values.
The JSON Output Prompt Builder is where these field definitions become a prompt: you give it each field with its type, its allowed values, and a one-line description, and it assembles the structured-output contract the model fills against. It carries the type and the allowed values into the output; the plain-language meaning, the include/exclude, and the criteria are the descriptions you write into each field. It assembles the prompt; you run it in your own AI tool, on your data.
Step 5: Define first, fill a sample, then check consistency
Field definitions are a draft, so review them before you fill anything, and test them before you trust them. Read each definition and ask what the model can't: is "priority" really impact-and-urgency in your world, or did you mean something else? Does "issue_type" cover the categories your tickets actually produce, or will half of them land in "other"? Edit until the definitions match your data and your intent — this is the step that makes every later row consistent, because the model stops filling by feel and starts filling by your rules. Then run the approved definitions on a small, deliberately awkward sample — a ticket that's angry but low-impact, one where the cause is unstated, one that fits two categories — and read the filled rows against the definitions, not just for shape but for logic: did priority follow the criteria, did customer_reason stay free of diagnosis, did the missing rule fire?
Where the sample drifts, the fix is almost always the definition, not the data: a criterion that was still fuzzy, an exclude you didn't state, a missing case the rule didn't cover. A structural check helps you see the drift — the Validate Structured Output from AI resource shows how to catch a missing field, an invented one, or prose creeping into the object — but be clear on what that catches and what it can't: it confirms the shape obeys the contract, not that a value obeys your definition or is correct. "priority: high" is valid structure and can still be the wrong call. So the final read is yours: the definitions are candidate rules you approve, the filled rows are candidate data you verify against the source, and for anything with legal, financial, medical, security, or compliance weight, that verification belongs with the domain owner, not the model.
Common mistakes
The habits that make a structured table look consistent without being consistent:
- Handing the model field names and expecting shared meaning. A name carries a definition you can see and the model can't; write it down or watch each row interpret it differently.
- Putting source text and model reasoning in one field. "reason" that means both the customer's words and the AI's diagnosis mixes report and inference in one column — split them into two typed fields.
- Leaving a decision field without criteria. "high / medium / low" with no rule is assigned by feel; state what earns each value, and name the wrong basis to rule it out.
- Defining only what a field includes. Every ambiguous field has a plausible wrong fill; a bad counterexample fences it off in a way an include-only definition never does.
- Leaving "missing" undefined. An absent value should return one agreed marker with a never-invent rule — not a mix of blanks, "N/A", and guessed values.
- Trusting valid structure as correct meaning. A record can parse, hit every allowed value, and still fill the wrong field with the wrong logic — the shape check isn't the meaning check.
A worked example: support tickets into a consistent table
Watch a one-line table request fill the same fields by different logic, then a field-definition-first prompt pin down what each field means before a single row is filled.
A one-line table request fills priority, reason, and next_action by different logic each row; defining each field's kind, criteria, and include/exclude first makes every row apply the same rulesTHE TICKETS:
1. "Login fails after SSO. Enterprise customer. Blocking payroll today."
2. "Can we get dark mode? Not urgent, but our team prefers it."
3. "Invoice total looks wrong. Customer is angry, threatens to cancel."
WEAK ASK, AND WHY THE TABLE ISN'T CONSISTENT:
ask: "Table these: issue_type, priority, reason, next_action."
issue_type priority reason next_action
Login issue High SSO failure Fix SSO
Feature request Low user prefers dark mode Add dark mode
Billing issue High customer angry Apologize, investigate
what's wrong:
- priority: ticket 1 is "high" for impact, ticket 3 for emotion -- two rules
- reason: "SSO failure" is the model's guess; "customer angry" is the source
- next_action: "Fix SSO" invents a fix; "Apologize" is customer-facing
- issue_type: free-form; no list, so categories won't match next batch
FIELD-DEFINITION-FIRST PROMPT (define before filling):
Define each field before filling any row. For each field give:
kind | definition | include | exclude | allowed_values |
good_example | bad_example | missing_rule
Rules:
- customer_reason is a SOURCE field: what the ticket says, no diagnosis.
- suspected_cause is a JUDGMENT field: mark as inference; empty if unsupported.
- priority is a DECISION field: business impact + urgency, NOT emotion.
- next_action is INTERNAL triage, not a customer-facing reply.
- If a value isn't supported by the ticket, use "not_stated" -- never invent.
PART OF THE FIELD DICTIONARY IT DRAFTS:
priority kind: decision
definition: urgency + business impact of the ticket
allowed: high | medium | low
high when: blocks a critical workflow today, or legal/security/payment
risk, or enterprise escalation
exclude: customer emotion alone (angry != high)
good: high (payroll blocked) bad: high ("customer is angry")
customer_reason kind: source
include: what the customer states; exclude: root-cause guesses
good: "invoice total looks wrong" bad: "rounding bug in billing"
missing_rule: not_stated
A ROW, FILLED TO THE DEFINITIONS:
ticket 1 -> issue_type: login_access | priority: high (payroll blocked,
enterprise) | customer_reason: "login fails after SSO, payroll blocked
today" | suspected_cause: not_stated | next_action: investigate SSO
login failure; escalate (payroll blocked)
CONSISTENCY CHECK:
ticket 3 -> priority is judged on impact (wrong invoice = payment issue),
not on "angry"; customer_reason quotes the ticket; suspected_cause stays
empty (cause unknown). Same rules, every row -- then you verify the values.
Where this fits in NewPrompt
Defining fields is the front half of any reliable structured output, and NewPrompt gives you the structure for it, not the filling. The JSON Output Prompt Builder turns your typed, described fields into the output contract the model fills against; the Turn a JSON Schema into a Prompt resource shows the readable field-line form those definitions take; the Missing Data in AI Extraction resource goes deep on the one rule — what "absent" returns — that most often decides whether a gap is visible or silently invented; and the Validate Structured Output from AI resource checks a filled record's shape against the contract. Each builds or checks a prompt you run on your own data in your own AI tool; none fills your fields, verifies a value, or enforces a schema as the model runs.
It's worth separating this from its neighbors, because they sit close. Designing an extraction schema is about which fields to pull out of a document and the evidence each must carry; classifying and tagging is about defining one closed set of labels for a single categorical field; getting valid JSON is about the output's shape and parseability. This guide is narrower and cuts across all three: whatever the fields are and however they're produced, it's about making each one mean the same thing in every row — the include and the exclude, the decision criteria, the line between what the source said and what the model concluded. Get the definitions right and those other jobs get easier; skip them and a perfectly-shaped table still fills the same column five different ways.
A field name is a question that every row answers a little differently; a definition is the answer key that makes them agree. Write down what each field means, what it excludes, which value a row earns and what to do when there's nothing to put there, and the model stops filling by feel and starts filling by your rules — so the second row and the two-hundredth follow the same logic. The model drafts the definitions fast and fills a sample faster; whether the rules match your data, and whether each value actually obeys them, is the part you check before you build anything on top of the table.