Extraction and verification with Jev
Jev answers a fixed question with a choice, a score or a probability, so to extract a date or an amount from a document you give it the candidates. It picks one from a list your code built, and it can say whether a statement is true of a document. That makes extraction a two-step job: code over-finds candidates with a parser or a regular expression (a text pattern), and a Choice question selects the right one or none. This page covers that pattern from TypeSafe's cookbooks, date extraction done as parts with the arithmetic in code, citation checking against a source, entity matching across 450 catalogue pairs, and the counting and date weaknesses that shape all of it.
Published September 22, 2026. Editorial.
Key takeaways
- Extraction with a decision model is selection: code finds every candidate, the model picks one or says none.
- Dates are read as text, so ask for month, day and year as separate Choice questions and do the calendar arithmetic in code, as TypeSafe's date cookbook does.
- A citation check is a string match in code followed by one Choice question: supports, contradicts, or says nothing.
- Entity matching uses one Score question for the overall verdict and one Noul per field, with the numeric field compared in code.
- Jev does not count reliably and cannot judge whether two numbers are near each other; every count and comparison stays in code.
The first thing an engineer tries with a decision model is "extract the invoice total from this email", and the first thing they learn is that the response holds a choice from options you gave it, a score on a scale you defined, or a probability that a statement is true, and nothing else [1]. A value the model found on its own has nowhere to go.
So extraction becomes selection, and that turns out to be a better design than the one it replaces. The candidates come from code that you can test, the model does the one thing a regular expression cannot (understand which candidate the sentence is about), and the answer comes with a probability you can gate on.
Pre-parse in code, select with a Choice
TypeSafe's pre-parsed value extraction cookbook is the reference [2]. It uses three regular expressions, one each for email addresses, phone numbers and money amounts, to over-find every candidate in the text, then deduplicates them in document order. Those candidates become the options of a Choice question, plus a "none" option. The question is written in the language of the task: "Which email address does the sender want their receipt sent to?" The cookbook's worked examples return confidence between 0.98 and 1.00 on the email selection, 1.00 on picking the mobile number, and 1.00 on the invoice total; a follow-up Noul, "Is the amount a credit or refund?", returned probabilities of 0.01 and 0.99 on the two examples, gated at 0.5 [2]. Those are TypeSafe's own three worked examples, and the page gives no dataset size, so they show the shape rather than a measured accuracy.
The reason to over-find is that a missed candidate can never be selected. A regular expression that is too loose produces extra options the model can reject; one that is too tight produces a "none" answer for a value that was on the page. Write the parser loose and let the Choice question be strict. The 255-option cap on a Choice question applies [3], so a document with more candidates than that needs a first pass to shortlist, the same two-stage shape as intent routing.
A second benefit is that the state can be small. The question needs the sentence around each candidate, and the jaggedness page says accuracy falls as the state grows with content unrelated to the decision [4]. A parser that returns each candidate with a window of text around it gives the model what it needs and nothing else.
Dates: parts as choices, arithmetic in code
Dates are the case where the naive design fails hardest, because the jaggedness page says the model reads dates as plain text with no sense of order and is unreliable for ordering, duration or whether a date falls in a window, especially with mixed formats and relative references [4].
TypeSafe's date extraction cookbook designs around that rather than through it [5]. For an absolute date it asks seven Choice questions that each read one component: which month, which day, which year, and whether each part is present in the text. No question asks the model to compute anything. For a relative date ("next Tuesday", "the day after tomorrow") it asks a Choice for the anchor (today, tomorrow, the day after, or a named weekday) and resolves the calendar in code from a fixed reference date. An assemble step in code then validates the parts, fills a missing year with the current one and moves it forward if the result is more than 31 days in the past, rejects impossible dates such as 30 February, and flags years outside 1900 to 2050 rather than guessing [5].
The confidence of the assembled date is the lowest confidence among the parts that went into it, and the cookbook routes anything below 0.60 to review. On its six test cases across four documents, TypeSafe reports five accepted at 0.91 to 0.97 and one flagged at 0.46 for an incomplete absolute date [5]. Six cases is a demonstration, and we cite it for the design, which is the part that generalises: the model reads, the code calculates.
The same rule covers every numeric comparison. The jaggedness page says the model cannot reliably judge whether two numeric values are near each other, and that it does better on semantic representations than numeric ones (a colour name rather than a hex code) [4]. So a question like "is the quoted price within 10 percent of the list price" is two code steps and no model call. If a threshold has to be judged by the model, convert the number to a category in code first ("above the limit", "within the limit") and ask about the category.
Counting stays in code
The jaggedness page is direct: Jev "does not count reliably", whether the count is characters in a word, occurrences of a term or items in a long list, and the error grows with size [4]. Its suggested design is to ask one question per item and sum the answers in code. A Noul per line item ("this line is a shipping charge") with the total done in code is reliable; "how many shipping charges are there" is a question the model is not built to answer.
That is also the general shape for a list: iterate in code, ask a narrow question per element, and combine. Because questions run in parallel, the per-element questions can share one request up to the context limit of 64k tokens per request, with 32k for the state plus the longest question [6].
Verifying a citation against a source
Verification is the case where a decision model is at its most natural, because "is this statement true of this document" is a Noul or a Choice question with no extraction involved.
TypeSafe's citation check cookbook does it in two steps [7]. First, code: the quoted text is normalised (whitespace collapsed, curly quotes straightened) and searched as a substring of the source. A quote that is not in the source is marked fabricated without a model call. Second, for the quotes that survive, one Choice question asks how the cited section relates to the claim, with three options: supports, contradicts, or says nothing. The verdicts map to verified, contradicted and unsupported, and anything below an auto-accept confidence of 0.8 goes to a person.
The cookbook's test is eight citations against RFC 7519, a 58,365-character document in 45 numbered sections. TypeSafe reports four verified at confidence 0.93 to 0.99, one fabricated caught by the string match, one contradicted at 0.99, and two unsupported at 0.27 and 0.56, both of which fell below the 0.8 gate and were flagged for review [7]. Eight citations is a small test; the design is what matters, and the design is that code catches the mechanical failure and the model judges the semantic one.
We use this exact shape to check a language model's output against its source before it is shown to a user, and TypeSafe's coding-agents page lists it as one of the three core uses inside an application: "Check whether a statement is true of a document, message, or record before taking an action" [8].
Matching entities with a Score and three Nouls
Deciding whether two records describe the same thing is the last common extraction-adjacent task, and TypeSafe's entity alignment cookbook shows the combination of question types that fits it [9].
The data is 450 candidate pairs from two beer catalogues in the Magellan benchmark collection, each with a name, a brewery, a style and an alcohol percentage. One Score question with three levels gives the overall verdict: 0 for two different products, 1 for closely related products that may or may not be the same, 2 for one and the same product. Three Noul questions ask about the fields the model can read: same name, same brewery, same style. The alcohol percentage is compared in code, because that is a numeric comparison [9].
The decision rule is the nearest level: below 0.5 leave the pair unlinked, above 1.5 merge, and between them send to a curator. On the 450 pairs with jev-1.12, TypeSafe reports 40 merged (8.9 percent), 50 sent to the curator queue (11.1 percent) and 360 left unlinked (80.0 percent), with most scores clustering near 0.25 and 47 pairs within 0.1 of the 0.5 threshold [9]. The example the cookbook highlights is a pair scoring 1.10 at confidence 0.77: same brewery and same alcohol percentage, but one is a variant with a different name, and it went to the curator. That is the middle band doing what confidence-gated routing describes.
The per-field Nouls are what make the verdict explainable. When a merge is wrong, the log shows which field the model thought matched, and the fix is a field question rather than a mystery.
The rules, collected
Over-find candidates in code and let the Choice be strict. Always include a none option. Ask for date parts, never date arithmetic. Compare numbers in code, or convert them to categories first. Count by asking per item and summing. Verify with a string match first and one Choice second. Match with one Score for the verdict and one Noul per readable field. Gate every result on confidence and send the uncertain band to a person, whose label you keep.
Where Reveneau uses this
Reveneau builds these steps into the agents and pipelines it delivers, and grades its own eval suite the same way: whether a diff stays in scope, whether generated text follows an instruction and whether an agent's trace followed the plan are each a Noul or a Score question with the rubric written into the criteria, while every check with a deterministic answer stays deterministic and never reaches the model. Evals with Jev covers that grader. For the agent-level view of verification, how to evaluate an AI agent before you trust it is the page in our agents guide, and Jev and System One models has the full definition of each question type.
Best for
- Picking the right value among candidates a parser already found.
- Checking a claim or a quote against a source before it is shown or acted on.
- Deciding whether two records are the same thing, with a curator queue for the middle.
Avoid if
- The value has to be written out and no parser can find the candidates.
- The task is a count, a date comparison or a numeric closeness check; those belong in code.
- The source document plus question would exceed 32k tokens without a first pass to trim it.
Check before you decide
- The parser is tested on its own and over-finds rather than under-finds.
- Every Choice has a none option and the none rate is tracked.
- Dates are assembled in code from part answers with validation for impossible dates.
- Results below the confidence gate reach a person and the person's answer is kept.
Common questions
Can Jev extract a value from a document?
Only by selecting it from candidates your code found. Jev returns a choice, a score or a probability and has no field for a value it discovered, so TypeSafe's pre-parsed extraction cookbook uses regular expressions to over-find every email, phone number and money amount, then asks a Choice question to pick the right one or none. Write the parser loose, so nothing is missed, and let the Choice question be the strict step.
Why should the parser over-find candidates?
Because a candidate that was never found can never be selected. A loose regular expression produces extra options that the model can reject at low probability; a tight one produces a none answer for a value that was on the page, and that error is invisible. Over-find, deduplicate in document order as TypeSafe's cookbook does, and keep the count under the 255-option limit of a Choice question, shortlisting in a first pass if needed.
How should dates be extracted with a decision model?
As parts, with the arithmetic in code. TypeSafe's jaggedness page says Jev reads dates as plain text with no sense of order, so its date cookbook asks seven Choice questions for month, day, year and presence, resolves relative dates from an anchor choice in code, validates impossible dates and fills a missing year by rule. The assembled date's confidence is the lowest of its parts, and anything under 0.60 goes to review.
Can Jev tell whether two numbers are close or whether one date is before another?
No. TypeSafe's jaggedness page says the model cannot reliably judge whether two numeric values are near each other and is unreliable on date ordering, duration and window containment. Do every comparison in code. If the model must judge something numeric, convert the number to a category first (within the limit, above the limit) and ask about the category, because the page also says the model does better on semantic representations than numeric ones.
How do I count things in a document with Jev?
Ask one question per item and sum in code. TypeSafe's jaggedness page says Jev does not count reliably, whether characters, occurrences of a term or items in a list, and the error grows with size. Iterate over the candidates your parser found, ask a Noul per candidate (this line is a shipping charge), and add up the yes answers. The per-item questions can share one request, since they run in parallel, up to the 32k-token state limit.
How does a citation check with Jev work?
Two steps. Code normalises the quote and searches for it in the source; a quote that is absent is marked fabricated with no model call. For quotes that survive, one Choice question asks how the cited section relates to the claim: supports, contradicts or says nothing, mapped to verified, contradicted and unsupported. TypeSafe's cookbook auto-accepts at 0.8 confidence and sends the rest to review; on its eight-citation test both unsupported cases fell below the gate.
What question types suit entity matching?
One Score for the verdict and one Noul per readable field. TypeSafe's entity alignment cookbook scores 450 beer catalogue pairs on a three-level scale (different, related, same) and asks three Nouls on name, brewery and style, with the alcohol percentage compared in code. The nearest level decides: below 0.5 unlinked, above 1.5 merged, between them a curator. The per-field Nouls make a wrong merge traceable to the field the model misjudged.
What share of pairs went to a person in the entity alignment cookbook?
On 450 pairs with jev-1.12, TypeSafe reports 40 merged (8.9 percent), 50 sent to the curator queue (11.1 percent) and 360 left unlinked (80.0 percent), with 47 pairs within 0.1 of the 0.5 threshold. The highlighted middle case scored 1.10 at confidence 0.77: same brewery and alcohol, different name, a variant of the same beer. Budget a review queue of that order when the pairs are hard, and expect it to shrink as field questions improve.
How large can the document be?
TypeSafe's models page gives 64k tokens per request and 32k for the state plus the longest question. Beyond that, split the document and ask per section, or use a first pass in code to select the sections that contain candidates. Smaller is also more accurate: the jaggedness page says accuracy falls as the state grows with content unrelated to the decision, so give each question the sentence around its candidate rather than the whole file.
Should extraction results below the confidence gate be discarded?
No, they should go to a person and the person's answer should be kept. TypeSafe's date cookbook reviews below 0.60, the citation cookbook below 0.8, and the entity cookbook sends the middle score band to a curator. Each reviewed case becomes a labelled example, and the labelled set is what you re-run when the model version changes or when you rewrite a question. Discarding them loses the only confirmed answers the pipeline produces.
How does Reveneau use selection and verification in its own work?
Reveneau builds these steps into the pipelines it delivers and uses the verification shape in its own eval suite: whether a diff stays in scope, whether generated text follows an instruction and whether an agent's trace followed the plan are Noul or Score questions with the rubric in the criteria. Checks with a deterministic answer, such as a schema validating, never reach the model. A grade in the uncertain band goes to a person and that label is kept.
References
- [1] TypeSafe docs, System One concepts: output is a typed answer per question with probabilities; Jev does not generate text.
- [2] TypeSafe docs, Pre-parsed value extraction cookbook: regex for emails, phone numbers and money amounts over-finds candidates; a Choice selects one or none; examples at confidence 0.98 to 1.00; a credit-or-refund Noul at 0.01 and 0.99 gated at 0.5; no dataset size given.
- [3] TypeSafe docs, Choice: accepts up to 255 options.
- [4] TypeSafe docs, Model jaggedness jev-1.13: reads dates as text with no sense of order; does not count reliably; cannot reliably judge whether two numeric values are near each other; accuracy falls as the state grows with unrelated content.
- [5] TypeSafe docs, Date extraction cookbook: seven Choice questions read date parts; relative dates resolved in code from an anchor; review below 0.60; six test cases, five accepted at 0.91 to 0.97 and one flagged at 0.46; impossible dates rejected and years outside 1900 to 2050 flagged.
- [6] TypeSafe docs, Models: 64k tokens per request, 32k for state plus the longest question.
- [7] TypeSafe docs, Citation check cookbook: normalised substring match first, then one Choice (supports, contradicts, says nothing); auto-accept at 0.8; eight citations against RFC 7519 (58,365 characters, 45 sections): four verified at 0.93 to 0.99, one fabricated, one contradicted at 0.99, two unsupported at 0.27 and 0.56 flagged for review.
- [8] TypeSafe docs, Coding agents: Check whether a statement is true of a document, message, or record before taking an action.
- [9] TypeSafe docs, Entity alignment cookbook: 450 pairs from two beer catalogues; one three-level Score plus three Nouls (name, brewery, style) with alcohol compared in code; nearest level decides at 0.5 and 1.5; 40 merged (8.9%), 50 to the curator (11.1%), 360 unlinked (80.0%) on jev-1.12; pair c428 at 1.10 with confidence 0.77.
Related reading
AI evaluation and guardrails for production: how to know your AI actually works
"It seems to work" is not a production standard. Here is how we turn that feeling into a number, and how we stop the system from doing damage on the days the number is bad.
Never let the model grade its own work
When the same run writes the code and the tests, a passing build proves only that the code is consistent with itself. That is not verification, and it is the most common way an AI-built codebase becomes confidently wrong.
How to write an acceptance test a machine can run
Most acceptance criteria are written for a human reader who will add the missing details. A machine adds nothing. Here is how to write the sentence so an automated check can enforce it.
More in Patterns
Intent routing with Jev
Intent routing sends each incoming request to the handler that should take it: a piece of deterministic code, a specialist model or a person. With Jev it is one Choice question whose options are the handlers, returning a choice, a probability per option and a confidence number. This page covers how to write the options, what to do when the list is longer than the 255-option limit, how TypeSafe's skill-suggestion cookbook picks one of 182 skills in two stages, how to handle the request that fits none of the options, and what a route costs at the public price.
Confidence-gated routing: act, confirm, or escalate
A decision model returns two things: the answer, and how concentrated the probability was behind it. Confidence-gated routing uses the second as its own axis. TypeSafe's bands are the starting point: act automatically at 0.9 and above, send anything below 0.5 to a person or another system, and proceed with caution in between. This page turns those bands into a gate per action, sized by what a wrong answer would cost, shows the pattern of escalating to an expensive reasoning model only in the uncertain band, and lists what to log so the gates can be tuned from real outcomes.