Skip to main content
A search assistant is asked how automotive technicians get paid. It finds three passages and writes, among other things:
The specific amount of pay varies by location, with the highest average pay in Alaska ($23.70 per hour or $49,400 per year) and the lowest average pay in Mississippi ($18.60 per hour or $38,900 per year).
Alaska is in the passages, with exactly those figures. Mississippi is not in them at all. The model made up a state and two numbers, in the same calm voice as the true ones. How would your code tell?
This happens wherever a model answers from text it retrieved: search, support bots, assistants over internal documents. Retrieval and writing are yours. hunch is for the last step, deciding whether the answer stays inside its sources.

Try it first

Read the passages, then the answer. Is everything it says somewhere in the passages? Then see what hunch said, and what the people who annotated the answer marked. Some are easy once you look: a line number or a peppermint oil tip appears from nowhere. Others are a matter of taste. Is turning 79°F into 26°C adding a fact? That question comes back at the end.

1. One row per answer

A row holds what the assistant saw and what it said. The example uses 900 answers from RAGTruth, a public dataset in which people marked every part of an answer the passages don’t support. Here is the Mississippi answer as a row: gold_unsupported is the known answer. The check never reads it; it is what the check is tested against.

2. Write the question

One file says what to ask about each answer, and what the model may read:
answer_support.yml
state is all the model sees: the question, the passages and the answer, never the annotators’ mark. act is the rule for what happens next, and step 4 is about it.

3. Run it

All 900 answers took 15 seconds and about three cents. Every answer is kept, so running it again is free. For the Mississippi answer the check says yes, something is unsupported, and it is 0.93 sure.

4. Pass only what it’s sure is supported

act has two sides. On the no side, 0.7 means an answer the check is at least 0.7 sure is supported goes straight to the user. On the yes side, 1.0 is a bar no answer reaches, so the check never blocks an answer by itself. Everything it isn’t sure about goes to a person. On these 900, a little over half go straight through, and 4 of them hold something the annotators marked. The rest wait for a person, and they include 156 of the 160 marked answers.

Which model to ship

Group the same answers by the model that wrote them: Without seeing a single mark, the check puts the six models in the annotators’ order (the two middle Llamas are one answer apart either way), so it can compare a new model or retrieval setup on your own questions before you switch.

Stricter than the annotators

Look again at the bars: the teal one is longer for every model. When the check says an answer is unsupported, the annotators agree only about half the time. Its most confident disagreement, at 0.96, is an answer about how the body’s systems work together. It summarises the three passages faithfully, then adds a list of its own: “The skeletal system provides support and structure for the body”, the digestive system breaks food down into nutrients, the nervous system coordinates movement and thought. All of it is textbook biology. None of it is in the passages. The annotators let textbook knowledge pass. The question, which asks about the passages only, does not. Neither is wrong; they answer different questions, and whether your assistant may add what everyone knows is a product decision. That is why the dial is lopsided. When the check is sure an answer is supported, it is almost always right. When it says unsupported, it is often only being strict. So pass what it’s sure of and show the rest to a person. Their verdicts, saved by hunch review, become the known answers, and the next hunch test measures the check against your rule instead of RAGTruth’s.

Use it on your data

This copies the spec, the 900 answers, two pinned examples and the measured results into rag_answers/. Replace the rows with your own questions, retrieved passages and answers, review a few dozen, and hunch test tells you how the check does on your data. In an app, ask before an answer is shown:

How it was measured

RAGTruth (MIT licence, Copyright (c) 2023 ParticleMedia), its QA test split: 900 answers that six models wrote to MS MARCO search questions from the passages they were given, 150 per model, with every unsupported span marked by human annotators. ragtruth_qa.csv is built from dataset/response.jsonl and dataset/source_info.jsonl (split test, task QA); gold_unsupported is yes when any span was marked, which is 160 of the 900. The CSV keeps only whether something was marked, not which span. The longest passages are 2,405 characters, so clip cuts none of them. Seven rows repeat another row’s question, passages and answer, so the 900 rows are 893 distinct requests.
hunch test prototype/examples/rag_answers/answer_support.yml, trimmed:
AUROC is the chance that a marked answer gets a higher p(unsupported) than an unmarked one. The calibration table shows the strictness: of the answers it gives 0.7–0.8, about 30% were marked.
At act: {yes: 1.0, no: 0.7} the check passes 489 answers (54.3%) as supported, and 4 of them (0.8%) had something the annotators marked. The other 411 (46%) go to a person; they hold 156 of the 160 marked answers. The check leans yes on 270 answers, and 142 of those were marked. At the 0.5 line it disagrees with the annotators on 146 answers (754 of 900 agree, 83.8%): 128 it calls unsupported that they left unmarked, and 18 the other way.
150 answers per model. Flagged means the check leans yes; passed means it clears act on no.By the share passed, the order matches the annotators’ exactly. By the count flagged, Llama 2 13B and 70B swap places, one answer apart, as they are one answer apart the other way in the annotators’ marks.
All twelve of its most confident disagreements, at 0.90 to 0.96, are answers it calls unsupported that the annotators left unmarked. They answer how the body’s systems work together (twice; the first is the one above), how to make ribs, how a transistor works, the benefits of clove tea (twice), cooking a frozen pork loin, what children learn from water play, cooking pollock, how the colonists responded to the Stamp Act (twice), and elements, compounds and mixtures. These were not reviewed, so how many are strictness and how many are marks the annotators missed is not measured.
The same battery (src/hunch/recipes/rag_answers/, results in its results*.json), from the benchmark:
hunch compile on an empty store estimates 808,794 input tokens and $0.034 for the 900 rows. The 893 answers in the store were written between 16:44:44 and 16:44:59 on 26 September 2026: 15 seconds. The numbers for jev-1.13.0 on this page come from those cached answers; make_rag_answers_data.py rebuilds the widgets from them with HUNCH_MAX_COST=0, asking nothing.