cd /news/ai-agents/how-to-stop-an-llm-from-inventing-nu… · home › topics › ai-agents › article
[ARTICLE · art-164954] src=dev.to ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

How to stop an LLM from inventing numbers: evidence containment and numeral tracing

Ali Ahmed built a research-to-LinkedIn automation pipeline that uses deterministic code, not the LLM, to decide what counts as true: every STATED claim must carry a verbatim quote found in the source paper via normalized substring matching, and every numeral in the final draft must trace back to a verified number or the source text, with a single unmatched figure failing the draft. An LLM fact-checker runs in parallel but is overridden by the code checks, following the design rule that "if a check can be decided in code, code decides it.

by read2 min views1 publishedNov 5, 2026

You can't prompt an LLM out of inventing statistics, but you can make an invented number impossible to publish. In my Research-to-LinkedIn Automation project, which turns a researcher's new papers into LinkedIn posts, the model extracts and drafts, while deterministic code decides what counts as true. Every "stated" claim needs a verbatim quote that is actually in the paper, any number without one is thrown away, and every numeral in the final draft must trace back to the source. If code says no, the draft fails, whatever the model thinks.

Posting about someone's research under their name means one wrong number is a public misquote of their own work. A vague sentence is embarrassing. A fabricated "37% reduction" is a correction request. So the design treats invented statistics as the highest-severity failure, and spends its strictest checks there.

Extraction is schema-driven (Zod plus the provider's structured-output mode), so there's no free-text parsing. Each claim carries a provenance:

STATED`` evidence must be a verbatim quote.INFERRED`` ABSENT Two structural choices do most of the work:

After the model answers, code checks every STATED claim:

function containsEvidence(source: string, evidence: string): boolean {
  const norm = (t: string) => t.toLowerCase().replace(/\s+/g, " ").trim();
  return norm(evidence).length > 0 && norm(source).includes(norm(evidence));
}

It's plain substring matching after normalising case and whitespace. That's crude, and that's the point: a quote either appears in the paper or it doesn't, and no model gets a vote.

The drafting model writes from the extraction, not the paper, so errors can creep back in. The draft then goes through two independent checks in parallel, and both must pass:

A. An LLM fact-checker labels each claim SUPPORTED, HEDGED_OK, UNSUPPORTED or CONTRADICTED, and flags overstatement and anything that reads like medical advice.

B. Deterministic checks, which override the LLM:

12.5% or 3×) must appear in the verified important numbers or literally in the source text. One unmatched number fails the draft. The rule from the design doc: if a check can be decided in code, code decides it. An LLM judge is good at nuance and bad at reliably noticing that 0.37 became 37%.

Being honest about the gaps matters as much as the checks:

Related: writing tool errors that AI agents understand, and building an OAuth 2.1 MCP server.

Written by Ali Ahmed · Original article

── more in #ai-agents 4 stories · sorted by recency
── more on @ali ahmed 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-to-stop-an-llm-f…] indexed:0 read:2min 2026-11-05 · —