Skip to content

Jev Practices & Patterns

Numbers, dates, and units in decision states

Counting, date arithmetic, and currency belong in code. How to extract components with Choice, copy amounts verbatim, and keep units normalized.
Published
Category
Jev Practices & Patterns
Resources cited
9
Reading time
5 min
Tags#decisions#extraction#dates#state

Ask a decision model for a total and you may get a confident number that is slightly wrong. Ask it to compare two dates and it may treat them as text. Ask it for a currency amount and it may return a plausible value with no decimal. These are not model bugs in the usual sense. They are the boundary between what a fast, non-generative decision model is good at and what belongs in ordinary code.

The practical rule is simple: let the model read and classify, and let code compute. The interesting part is designing the questions so that rule survives contact with real inputs.

Counting is a code job

The jaggedness notes list counting as unreliable, with error growing as the number of items grows. The guardrail is not a better prompt. It is one Noul question per item, then a sum in code. The cookbook example counts per-item booleans rather than trusting a single “how many?” answer.

That pattern generalizes. If you need to know how many line items are missing a field, ask one Noul per line item and count the true answers. If you need a total, ask for the components and add them yourself. If you need to compare magnitudes, ask for the level and compare in code.

Dates are text until you make them components

The date-extraction cookbook is the template. It asks seven Choice questions about a date's shape and parts (mode, month, day, year from 1900 to 2050, and weekday) and does no arithmetic in the model. Code resolves the parts against a pinned TODAY and infers missing years. On the cookbook's six examples, five were auto-accepted. An absent kickoff date returned none at 0.46 confidence, with a note that the absolute date was incomplete.

The conventions matter as much as the questions. Bare weekdays mean the next occurrence on or after today; “next” means the following calendar week. Anything under 0.60 confidence goes to a person. Those are policy decisions, and they belong next to the code that resolves the date, not in a prompt the model may reinterpret.

The same logic applies to durations, ages, deadlines, and reporting periods. Extract the components, then compare or subtract in code.

Amounts and units need a verbatim source

The pre-parsed extraction cookbook solves a different half of the problem. Regex finds candidate emails, phone numbers, and amounts; Jev picks the requested span. Because the model only chooses among spans that code already found, the returned value is copied verbatim and cannot be invented. In the cookbook, a receipt email was picked at 0.98, a cell number normalized to +14155550177, and an invoice total read as $1,315.50. A $50.00 courtesy credit was flagged at P(credit) 0.99. Amounts parse to Decimal in code.

That is the strongest pattern for numeric values: do not ask the model to produce the number. Ask it to identify which candidate is the one you want, then copy the candidate.

The caveats are practical. Choice caps at 255 options, and candidates without a regex (names, for example) need a roster, NER, or an LLM to generate them. The model is doing selection, not extraction from free text. That is exactly why the value is trustworthy.

Score levels are not a ruler

The jaggedness notes warn that Score levels are weak at numeric calibration. If you ask for a severity score from 1 to 5, you can use the level as an ordinal judgment, but you should not interpolate an exact magnitude between levels. “3.7” is not a measurement; it is a number the model produced because the interface allowed it.

The composite-scoring pattern handles this well. It asks four Score questions in one parallel request, normalizes each score by dividing by len(criteria) - 1, and combines them with weights in code. The weights are policy, not model output. That keeps the model on the part it does well (placing a candidate on an ordered scale) and keeps the arithmetic where it can be tested.

The primitives guide is the reference for which primitive to use. Choice for a label, Score for an ordered level, Noul for a yes/no or a probability. If the decision needs a magnitude, ask whether the magnitude is really a level in disguise. If it is, use Score and treat it as ordinal. If it is a count or a total, use code.

Normalize the units before the state

A model sees what is in the state. If one field is in cents and another in dollars, the model has no reliable way to know. Normalize units before the request: currency to a single base, durations to a single unit, dates to ISO components, and measurements to the unit the policy uses.

The advanced structure guide allows structured JSON in criteria and instructions, which helps. You can give the model a legend or a schema that says what each field means. But a legend does not replace normalization. It documents the convention; it does not enforce it.

For mixed inputs, include the raw value and the normalized value in the state, and ask the question about the normalized field. The state design guide calls this out as a general rule: include the material the model cannot infer, and leave out conclusions. A normalized number is material. A verdict about whether the number is acceptable is a conclusion.

A short checklist

  • Count in code, one Noul per item, then sum.
  • Extract date components with Choice, then resolve and compare in code.
  • Find candidate amounts with regex, ask Jev to pick, and copy the span verbatim.
  • Parse money to Decimal; never trust a float from a language model.
  • Treat Score levels as ordinal, not as a calibrated ruler.
  • Normalize units before the request, and document the convention.
  • Send low-confidence dates and amounts to review rather than guessing.

The pattern is consistent across all of them: the model reads and chooses, and code owns the math. Once that boundary is explicit, the numeric failures become testable instead of mysterious.

From the Jev directory

The resources behind this article.

A maintained list of jev-1.13's known failure modes, literal reading, unreliable counting, dates as text, indirection, context rot, and contradictory criteria, each with a guardrail.
Jev Practices & PatternsDocs#official#docs#evaluation
Official
Extract dates by asking seven Choice questions about a date's shape and parts, then resolving them in code: five of six examples auto-accepted and missing dates flagged at 0.46 confidence.
Jev CookbooksDocs#official#cookbook#extraction
Official
Regex finds candidate emails, phone numbers, and amounts; Jev picks the requested span so code copies a verbatim value that cannot be invented, with no free-text extraction required.
Jev CookbooksDocs#official#cookbook#extraction
Official
Reconstruct Markdown from unformatted text in two requests: 16 Noul line-pair questions stitch split sentences, then 62 questions classify each block's type and companions.
Jev CookbooksDocs#official#cookbook#formatting
Official
Rate content against 2 to 10 ordered levels. Returns a probability-weighted score that can land between levels, per-level probabilities, and confidence, with the arithmetic left to code.
Jev Practices & PatternsDocs#official#primitives#score
Official
The yes/no primitive: one probability from 0 to 1, where the value is the answer and no separate confidence is needed. True and false criteria pin down subtle boundaries.
Jev Practices & PatternsDocs#official#primitives#noul
Official
Instructions, option descriptions, score levels, and noul criteria all accept JSON, so you can label question parts, pass schemas and taxonomies, and keep candidate paths alive.
Jev Practices & PatternsDocs#official#primitives#architecture
Official
How to shape what Jev evaluates: a string, a named object, or an array of messages. Every question in a request sees the same state and is evaluated independently.
Jev Practices & PatternsDocs#official#docs#state
Official
A 14-Noul claims-triage rubric over one insurance claim, repeated 15 times: mean probability standard deviation of 0.0102 at 111 ms per call, with a 0.30 to 0.70 band for human review.
Jev CookbooksDocs#official#cookbook#consistency
Official
Back to all articles

Related Jev articles

Language changes accuracy, calibration, and error ranking. What the Indonesian, Arabic, and Chinese evaluations show, and how to design a multilingual deployment.
Jev Practices & Patterns#decisions#multilingual#calibration
Read article
Jev cannot count, reads dates as text, and takes instructions literally. These are not bugs to work around quietly; they are design constraints with known guardrails.
Jev Practices & Patterns#evaluation#state#dates
Read article

From the Jev AI model community

Posts from builders shipping with Jev right now.

Follow @typesafeai