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.
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
| Status | Meaning |
|---|---|
ran | The model answered, the answer was valid and grounded, and it was kept |
rejected | The answer contained a number not in the facts; the rules' text stands |
invalid | The answer did not parse or fit the shape; the rules' text stands |
failed | The call failed; the rules' text stands |
not_run | No 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 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.