Command Palette

Search for a command to run...

Hectal
PHASE 4Intermediate ~21 min· topic 7 of 8

Topic 4.7

Extraction and Classification

In one line

Extraction pulls fields out of text and classification picks one label from a list. Both go wrong the same way: a model asked to fill every field will invent a value. Give it an honest way out (null or unknown), and check values against the source.

Think of it like this

A form clerk copying details from a letter. The form has a phone number box, the letter has no phone number. A good clerk leaves the box empty. A clerk under pressure to "fill every box" writes a number that looks plausible. The second clerk's forms look complete and are quietly wrong. A model behaves like the second clerk unless you tell it, and check, otherwise.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

Extraction
Pulling specific fields (such as name or date) out of free text.
Classification
Choosing one label from a fixed list for a piece of text.
Hallucination
A confident, fluent statement from a model that is not true or not in the source.
Null
The JSON value meaning "no value". Different from an empty string or a missing key.
Unknown option
An allowed label such as unknown that the model can choose when no real label fits.
Evidence check
Checking that an extracted value really appears in the source text.
Confidence
A number the model gives for how sure it is. Rough, often too high.
Threshold
The cut-off that decides which answers are accepted and which go to a person.

Step by step

01Step 1: the text with a missing field

The source email gives a name, a company and an invoice number, but no phone number. The task asks for four fields, one of which does not exist in the text. This is the situation that tempts a model to invent.

02Step 2: a model that fills every field

The first scripted reply writes phone: "555-0100". The JSON is valid, the schema is satisfied, a validator would pass it. Only a check against the source shows the problem.

03Step 3: the evidence check

keep_only_evidence looks at each non-null value and asks whether it appears in the source. 555-0100 does not, so it is set to null and reported. The second reply, from a model told to use null, passes without any removal.

Step 3: the evidence checkdiagram
Rendering diagram…

04Step 4: classification with exits

The second example classifies tickets. The model may answer a label from the list, unknown, or something outside the list. The decide function turns each case into an outcome: a label, unknown (with the reason), or needs review when the confidence is below 70. It never passes on a label that is not in the list.

05Step 5: the lab

The lab asks a real model to extract the four fields from the same email, with instructions to use null for anything missing. Goals check the keys, that phone is null, and that the invoice is right. Try removing the "never guess" sentence and see whether the model invents a phone number.

Try it yourself

  1. 1

    Predict the removal

    Change the invoice in the first reply to "4472". Predict what invented and removed says, then run.

  2. 2

    Normalise before comparing

    Change the source to say phone 555 0100 and the reply's phone to "555-0100". The check removes a real value. Fix keep_only_evidence to compare after removing spaces and dashes from both.

  3. 3

    Move the threshold

    In the classification example change THRESHOLD to 90. Which cases move to needs review? Then change it to 50. What is the trade-off in reviewer workload?

  4. 4

    The lab

    Run the lab at temperature 0 five times, then change it to 1.5 and run five more. Count how often phone stays null.

Code & diagrams

Remove invented values with an evidence check New tab

A substring check is a crude evidence test. Real systems normalise spaces, case and number formats first.

Sign in to run this example in your browser.

Expected output

model that fills every field
  name: Priya
  company: Acme
  phone: (missing)
  invoice: 4471
  invented and removed: phone
model told to use null
  name: Priya
  company: Acme
  phone: (missing)
  invoice: 4471
  invented and removed: none
Classification with unknown, a threshold and a reason New tab

Confidence is an integer from 0 to 100, so the output is the same in every language.

Sign in to run this example in your browser.

Expected output

I was charged twice              -> billing
The app crashes on start         -> bug
Maybe dark mode, or fix login?   -> needs review (feature, confidence 55)
hello                            -> unknown (the model said so)
Refund me                        -> unknown (label "refund" is not allowed)
???                              -> unknown (reply was not JSON)
Extraction challenge: do not invent a phone numberreal model

Try: Send as it is. Does phone come back as null? Then delete the sentence "If a field is not in the text, use null. Never guess." from the system message and send a few times: does the model start inventing a number? Put the sentence back and make all four goals pass.

user

Goals

  • It has the keys name, company, phone and invoice
  • phone is null (nothing invented)
  • invoice is 4471
  • company is Acme

Sign in to send this request to a real model (free).

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Skip the evidence check

In the Python extraction example change the test value not in source to False (so nothing is ever removed) and run it.

terminal
$ Run
── what you'll see ──
model that fills every field
name: Priya
company: Acme
phone: 555-0100
invoice: 4471
invented and removed: none
model told to use null
name: Priya
company: Acme
phone: (missing)
invoice: 4471
invented and removed: none

Myth vs fact

Myth

A model only invents facts when it doesn't know the topic.

Fact

It invents when the format demands an answer. A required field with no matching text invites a guess even on an easy task.

Myth

A confidence number from the model is a probability.

Fact

It is the model's guess about itself, often too high. Use it as a rough filter, tuned on real data.

Myth

Adding "unknown" lowers accuracy.

Fact

It lowers the number of wrong answers by turning them into honest ones. Accuracy on the answers you do give goes up.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Measure both sides: how often the model says unknown when a human would have answered (too cautious) and how often it answers wrongly when it should have said unknown (too bold). Tune the prompt and threshold against both.

  • ▸

    For long texts ask for the supporting quote next to each value (phone_quote). The evidence check then becomes: is the quote in the source, and does the value appear inside the quote?

  • ▸

    Keep a labelled sample of real inputs, including ones where the true answer is null or unknown, and run it after every prompt or model change (Phase 9). Extraction regressions are quiet.

Remember this

  1. 1

    Why this exists. Extraction (pull the name, company, phone and invoice out of an email) and classification (billing, bug or feature request) are the two most common structured tasks. They are also where a model's urge to be helpful hurts most: if the schema says phone is a required string, the model must write a string, and it will make one up. The result is valid, well-formed and false. This is a hallucination (Topic 1.9) caused by the format, not by missing knowledge.

  2. 2

    Give the model an honest answer. For extraction, make the field nullable and say in the prompt: "If a field is not in the text, use null. Never guess." For classification, add an unknown (or other) option to the enum and say when to use it. Without those exits, the schema forces a wrong answer whenever the truth is "not there".

  3. 3

    Null is information. phone: null means "the model looked and the text has no phone number". A missing key means "the model skipped it". Strict provider modes often require all keys, so null becomes your marker for "not found" (Topic 4.4). Downstream code can then ask the customer for the phone number instead of calling a made-up one.

  4. 4

    Check against the source: the evidence check. For extraction of facts that should appear in the text (names, ids, amounts), check that each value actually occurs in the source. The first example runs a model that invents 555-0100: the check finds it isn't in the email and replaces it with null. It's crude (a phone number written "555 0100" would be rejected), so normalise before comparing, but it catches the most dangerous failure for almost no cost.

  5. 5

    Confidence, used carefully. You can ask for a confidence number, as an integer from 0 to 100, and send low-confidence answers to a person. Models are often overconfident, so the number is a rough signal, not a probability. Pick the threshold from data: collect real examples, see what confidence the wrong answers had, and choose a cut-off that gets the errors without drowning your reviewers. The second example shows the decisions: allowed label, "unknown" from the model, label outside the list, low confidence, and a reply that isn't JSON.

  6. 6

    Make the unsafe case the default. In a pipeline, the path with the least harm should be the one taken when anything is doubtful. unknown goes to a human queue. null fields are asked for again. Nothing is invented to keep a form looking complete. Add counters for how often unknown and nulls occur. A sudden rise or fall both mean something changed, and a fall can mean the model has started guessing.

Explain it without notes

01

Why does a required field in a schema encourage hallucination?

02

What is an evidence check, and what are its limits?

03

How would you design the label list for a classifier?

04

How do you use a confidence value responsibly?

Practice

01

Write normalise(s) that lowercases a string and removes spaces and dashes, and supported(value, source) that returns True when the normalised value is inside the normalised source.

02

Write route(label, confidence) that returns "auto" if the label is not unknown and the confidence is at least 70, and "human" otherwise.

Trade-offs

  • ↔

    A low confidence threshold automates more and lets more errors through; a high one sends more work to people.

  • ↔

    Evidence checks add a little code and reject some legitimate reformatted values; they save you from invented facts.

  • ↔

    An unknown option makes the pipeline honest and needs a place for unknowns to go.

Done when you can

  • Done when you can make a schema field nullable and write the prompt sentence that uses it.

  • Done when you can add unknown to a classification enum with a rule.

  • Done when you can write an evidence check for extracted values.

  • Done when you can choose a confidence threshold from real examples.

  • Done when you can explain why a valid reply can still be false.