A language model will happily write “a reserve of $85,000 is appropriate” about a claim it knows almost nothing about. The sentence is fluent, specific and invented. In claims, an invented number is worse than no number: it lands on a reserve, a letter or a board report, and somebody relies on it.

InsightCW lets the model reason over a claim — explain, weigh, question, draft — while making it structurally impossible for an invented figure to reach a person. This post describes how.

The rule, in one sentence

Every number in the model's text must already be one of the facts the agent gathered, or the model's text is thrown away and the rules' text stands.

flowchart TB F["Facts: each with a
label, value and source"] --> M["Model reads facts
and the file;
answers in a fixed shape"] M --> C{"Every number in
the answer is a fact?"} C -->|"yes"| K["Kept: findings shown
with their sources"] C -->|"no"| X["Rejected: the rules'
sentence stands;
status says why"] M --> J{"Valid shape?"} J -->|"no"| I["Invalid: fallback"] style X fill:#fdecec,stroke:#e57373 style K fill:#e8f8f4,stroke:#22c1a4

What the check looks at

  • Numbers, not words. The check is deliberately simple and strict: it extracts every number in the model's text and asks whether each appears among the facts (or in the rules' own text the model was asked to improve). Thousands separators and trailing punctuation are normalised.
  • Citations are not numbers. Citation markers the model uses to point at a fact are stripped before checking, and small section numbers are allowed.
  • Findings need a source. A finding the model states without citing a fact is dropped, even if it contains no number.
  • Names need to be in the file. A liable party the subrogation agent names must appear in the file.

Every outcome is recorded

StatusMeaning
ranThe model answered, the answer was valid and grounded, and it was kept
rejectedThe answer contained a number not in the facts; the rules' text stands
invalidThe answer did not parse or fit the shape; the rules' text stands
failedThe call failed; the rules' text stands
not_runNo model is configured or it is switched off; the rules' text stands

The status is on every agent step, with the model, tokens and cost, so a reviewer can see how often each agent's reasoning is kept and why it is not.

The coverage agent's page with recent runs and one run's trace, on demo data
The coverage agent's page (demo data): recent runs with model, tokens and cost, and one run's trace — what the file and the engines say, what the model reasoned, and what was prepared for a person.

The copilot uses the same idea, more generously

The claims copilot answers free-form questions, where people write “$152K” for 152,340. Its check understands rounding and abbreviation, and instead of throwing a whole answer away it gives the model one chance to repair it; a figure still unsupported after that is replaced with “‹not in the record›”. Both checks live in the shared insight_agents.grounded module, so every Insight product grounds numbers the same way.

What grounding does not guarantee

It guarantees that a figure came from the file. It does not guarantee that the reasoning around it is right. That is why agents prepare and people decide, and why every Change and Reject a person gives is recorded as evidence about the agent.

Keep reading