Reading AI output for claims
Day 7: Read for Claims, Not Flow
You read the whole AI answer, nodded and moved on. Now try to name one specific thing it claimed. Most people can't. AI writes a wrong claim in the same polished voice as a right one, so if you trust text because it reads smoothly, you'll approve mistakes without noticing. Today you get a 60-second reading drill that pulls out what the text actually claims, and shows you where the model hides its leaps.
The root-cause summary I almost approved
After an incident, I asked an assistant to summarise the logs and propose a root cause. What came back was clean and confident, with a timeline, a cause and a fix. I read it top to bottom, nodded and closed the tab. Then someone asked me what the cause was, and I couldn't name a single specific thing the summary had said. I'd taken in how it sounded and none of what it claimed.
When we checked later, every fact in it was true. The connection pool had been exhausted. A deploy shortly before had added a retry loop. But the summary joined those two facts with one word, 'so', and nobody checked that link. We shipped a fix for the retry loop, and the next day the pool ran out again for a different reason. Every fact was right and the conclusion was still wrong.
Why careful reading stopped working
Human writing used to show uncertainty in the prose. A colleague who wasn't sure would hedge ('I think it might be…'), write a clumsy sentence, or reach for a vague noun like 'the thing in the config'. Most of us learned to slow down at those rough spots without ever thinking about it.
An LLM doesn't leave rough spots. A guess and a verified fact come out in the same register, with the same confidence and the same polish. So 'careful' reading, the slow kind where you wait for something to feel off, is looking for a signal that isn't in the text any more. You need to read differently.
- ▹Old tell: rough prose meant the writer was unsure, so you slowed down there.
- ▹New reality: the prose is smooth everywhere, so it tells you nothing about which parts are true.
- ▹New tell: specific claims. That's where you slow down now.
Where this fits in the series
The last few days were about asking: what goes into the prompt and how you shape the request. Today is about reading. The output is in front of you, and you have to decide whether to act on it.
The method: a 60-second claims drill
- ▹1. Skim once, for shape only. Is it a timeline, an argument or a list of changes? Don't judge anything yet.
- ▹2. Re-read and pull out only the checkable claims: names, numbers, file/function/API references, dates, quotes, and anything with only, all, never or always in it. Highlight them or write them down.
- ▹3. Number them. There are usually fewer than you expected.
- ▹4. Mark each one 'I can verify' or 'I'm taking its word'.
- ▹Skip the glue: 'Additionally', 'It's worth noting', 'In summary', 'This improves maintainability'. These words keep the text moving but don't claim anything.
Live demo: a PR description, collapsed
Here's a realistic AI-written PR description, the kind you'd approve after one read:
This PR refactors session handling in `auth/session.py` to resolve the
intermittent logout issue. The root cause was that `refresh_token()` was
being called twice on page load, which caused a race condition with the
token store. Additionally, I've consolidated the expiry logic into a single
helper, `get_expiry_window()`, which is now the only place this calculation
happens. It's worth noting that `refresh_token()` is only called from
`middleware.py`, so this change has no impact on the mobile client. All
existing tests pass, and I've added three new tests covering the
double-refresh scenario. The token TTL remains unchanged at 15 minutes.
In summary, this is a low-risk change that improves the reliability and
maintainability of the session layer.Now strip out the glue and keep only the claims:
1. Root cause: refresh_token() is called twice on page load -> race condition. [taking its word]
2. get_expiry_window() is now the ONLY place expiry is calculated. [can verify: grep]
3. refresh_token() is ONLY called from middleware.py -> SO no mobile impact. [can verify part 1; part 2 is a leap]
4. All existing tests pass; 3 new tests added. [taking its word unless CI is linked]
5. TTL unchanged at 15 minutes. [can verify in diff]Over a hundred words of prose come down to five assertions. Line 3 is the risky one. It makes a universal claim ('only called from'), then uses 'so' to turn that into a safety guarantee. If a shared package or the mobile app reaches refresh_token() through another path, 'low-risk' and 'no mobile impact' are both wrong, and nothing in the prose would have warned you.
Which claims to check first
You won't verify everything. Start with these:
- ▹Universal claims (only, all, never, always, none). One counterexample breaks them, and models write them easily because they make the text sound decisive. A quick search of the codebase or the source usually settles them.
- ▹Things the AI couldn't have observed: the current state of your system, whether tests 'pass', what a colleague 'said', what's in production. Unless it ran a tool and showed you the output, these are guesses written up as reports. Coding agents with tool access sometimes did check, so look for the evidence in the transcript rather than trusting the sentence.
- ▹Precise-looking numbers with no source: '15 minutes', '37% faster', 'since version 4.2'. A precise number looks measured. If it has no source, treat it as a guess.
The twist: some connectives are claims
I told you to skip the connecting prose, and mostly you can. 'Additionally' and 'In summary' just carry you to the next sentence. Causal connectives are different. 'Because', 'so', 'therefore', 'which means', 'which caused', 'this ensures' and 'as a result' each assert that one thing produces another. Each one is a claim, and in my experience it's the kind most likely to have been written without being checked.
Back to my incident summary. Fact A (the pool was exhausted) was true. Fact B (a retry loop had been deployed) was true. The 'so' between them was the model's own invention. The timing made the link plausible, and that was enough for the model to write it. Language models are very good at producing plausible links between true statements. That's where the leaps hide. Each fact checks out on its own, which leaves you feeling that the whole thing checked out.
- ▹Rule: skip connectives that only move the text along. Every causal connective is a claim and gets its own line in your list.
- ▹At each 'so', ask one question: did it check this link, or just write it?
- ▹In the PR demo, two of the five lines depend on a causal link ('which caused', 'so'). Look hardest at those two.
Make the AI do half the work
You can have the model write the claims list for you. Add this to the end of any prompt where you'll act on the answer:
End with a numbered list of every checkable claim you made, including
every causal link (because / so / which means). Mark each one
verified / inferred / assumed, and give the evidence for each.Here's roughly what that adds to the PR description above:
1. refresh_token() is called twice on page load. VERIFIED: seen in the
network trace you pasted.
2. The double call causes the logout race. INFERRED: timing fits, no
reproduction run.
3. refresh_token() is only called from middleware.py. INFERRED: searched
web/src only; did not search mobile/ or shared packages.
4. No impact on mobile client. ASSUMED: follows from claim 3.
5. All existing tests pass. ASSUMED: I did not run the test suite.Compare that with the prose. 'All existing tests pass' read like a report, but the list says it was an assumption. 'Only called from middleware.py' read like a fact, but the list says the search skipped the one directory that matters. The prose hid those gaps, and the tags show them.
If you lead a team, this doesn't have to stay a personal habit. Put the claims-list requirement into your PR template, your agent's system prompt or your incident-summary prompt. Reviewers can then start at the list and go straight to the 'assumed' and 'inferred' lines. When agents write a lot of your PRs, this is a cheap way to keep human review on the parts that need it.
Where this breaks down
- ▹Creative and brainstorming output has nothing to check. Ten name ideas or a draft tagline are options, and picking one doesn't assert anything. Don't run the drill there.
- ▹The claims list can be wrong too. A model can tag something 'verified' without verifying it, especially when it has no tool access. Spot-check the 'verified' tags, at least on the claims you'll act on. Treat a 'verified' with no evidence as 'assumed'.
- ▹The list isn't always complete. Models leave claims out, and in my experience the causal ones go missing most often. Do your own quick pass for 'so' and 'because' anyway.
- ▹Don't overdo it. A summary you're skimming out of interest doesn't need a claims audit. Use the drill when you're about to approve, ship, forward or decide something.
Tomorrow morning
Take the next AI answer you'd normally skim and approve: a PR description, a policy summary, a research answer. Write its claims on five lines. Circle every 'so', 'because' and 'which means'. Then find the line you would have let slide. In my experience there's usually one.
Extend your knowledge
- ▹Daniel Kahneman's 'Thinking, Fast and Slow', the sections on 'cognitive ease' and processing fluency. They explain why fluent text feels more true, and that's the effect this lesson works against.
- ▹The Toulmin model of argument, specifically 'warrants'. A warrant is the unstated 'so' that connects evidence to a claim. It's the same thing you're circling in AI output.
- ▹Anthropic's prompt-engineering guidance on reducing hallucinations (ask for quotes and citations, let the model say 'I don't know'). Use it together with today's claims-list line.
- ▹This week, add the claims-list line to one real template, such as your PR template or incident-summary prompt. Then compare a week of reviews before and after.
Discussion
Chat with Chi Cong (AI) about this article. Your conversation is private to you — you can publish a summary for others when you're done.