When we first pointed an LLM at scientific papers for the Health Integrity Project, it looked great and roughly 95% of the numbers I spot-checked were wrong. Wrong p-values, wrong table references, section after section. All of it plausible enough that we almost didn’t check.
The fix wasn’t a better prompt alone. It took two layers working together: infrastructure that keeps the real PDF grounded every turn, and prompt rules that forbid guessing. Either one alone fails.
In practice that means uploading the PDF once with the Files API and reusing it across turns, so the model can’t claim it lost access and fall back on memory. It means prompt cache on from the first message, so keeping the paper present every turn is cheap and there’s no cost excuse to drop it. It means citations enabled, so every quote is page-anchored; if it can’t point to a page, it can’t cite. And it means strict skill rules re-sent every message: if you can’t find the exact string in the PDF, write “not reported.” A correct “I don’t know” beats a confident wrong answer.
The scientific numbers are right now, when I check them. What still slips through is the occasional wrong reference, pointing to the wrong table, not a fabricated statistic. It stays under $1 per review.
I wrote up the full setup with the config, what didn’t work, and the exact anti-hallucination wording on the Health Integrity Project blog:
If you’re building your own review agent, the failure modes are the same whether you read one paper or many. Keep being a scientist: check what the AI tells you against the source, every time it gives you a number or a citation.