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
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 byhunch 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
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
The data
The data
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.The test, in full
The test, in full
hunch test prototype/examples/rag_answers/answer_support.yml, trimmed:What the dial does on these 900
What the dial does on these 900
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.By the model that wrote the answer
By the model that wrote the answer
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.
Where the check and the annotators disagree
Where the check and the annotators disagree
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.
Other engines
Other engines
The same battery (
src/hunch/recipes/rag_answers/, results in its results*.json), from the benchmark:Cost and time
Cost and time
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.