A page can rank on page one and still never get cited by an assistant, quoted in an answer box, or referenced by a chatbot. That’s not a contradiction — ranking and extraction are scored on different things — but it does mean a page can look successful in Search Console while being effectively invisible to whatever is reading it for an answer.
Five things that keep a good page out of AI answers names the faults behind most of that gap. This is the diagnostic version of that list: the same five, each with the check you run by hand, the command you run across a whole site, and the fix. None of them require a rewrite; four are reordering jobs.
Each check below comes in two forms: one you run in a crawler or a spreadsheet, and one you run in a terminal. They find the same faults. If you don’t work in a terminal, take the first route and skip the code blocks entirely — nothing in this list requires a shell, and the two checks that genuinely need engineering help are called out as such.
One caveat before the checks. Fixing these makes a page readable and liftable. It does not make anything cite you — that depends on competition, authority, freshness, and the question asked, none of which live on your page. What the list removes is the failure mode where the page never had a chance to be considered in the first place.
The five checks, and what each one catches
| Fault | Readiness signal it breaks | Cheapest fix |
|---|---|---|
| The answer is buried below the setup | Answer block (AEO, weight 20) | Reorder the section |
| Every passage depends on the one before | Extractability (AEO, 15) | Restate the referent |
| The entity is never named plainly | Entity clarity (GEO, 15) | Name it in the body |
| The markup and the page disagree | Answer-relevant schema (AEO, 10) | Edit both together |
| Nothing on the page is quotable | Answer block, lists and tables | State one figure plainly |
Weights are GEOBee’s, and they’re published so they can be argued with — the three lenses documents each signal and how the 0–100 scores are built. They rank how much of a page’s readiness each fault accounts for, not how much any engine’s output depends on it. The order below is the order these are worth checking in.
Check 1: Does the first sentence answer the heading?
The fault. The heading asks a question, and the paragraph underneath spends two or three sentences on setup before it answers.
Why it survives review. It reads well. A reader going top to bottom gets context first and the answer at the end of the paragraph, which is how most good prose works. Extraction doesn’t read top to bottom — it evaluates a heading plus the passage under it, scored against a question, so the opening sentence is what gets matched and what a short answer gets built from. What an answer engine reads covers the mechanism.
Check it by hand. Pull the first sentence under every ## and ### on a page and read the pairs as a list, prose removed. If a sentence doesn’t work as a standalone answer to the heading above it, that section fails. The failures are obvious once the surrounding paragraphs are gone.
Check it at scale, in a crawler. Two custom extraction rules — //h2 | //h3 for the heading and //h2/following-sibling::p[1] | //h3/following-sibling::p[1] for the passage under it — give you a two-column export, heading beside opening sentence. Skim that list instead of reading pages. Sort by the length of the second column and the buried answers rise to the top.
Check it at scale, in a terminal. If you own the markdown source, one line prints every heading-and-opening pair on a page:
awk '/^##+ /{h=$0; want=1; next} want && NF {print h" || "$0; want=0}' page.md
Run it across a content directory and you’re skimming the same two-column list.
The fix. Move the sentence that answers the heading to the front. It’s usually already there, in sentence three or four — you’re reordering, not writing. Two or three tight sentences is enough. The 40–60 word window we use is a heuristic rather than anyone’s published rule; Google states snippet length has no fixed value and the snippet “is truncated in Google Search results as needed, typically to fit the device width” (Google Search Central, retrieved 2026-07-30). The constraint underneath is that a passage quoted whole has to survive truncation and still stand without its neighbours.
Check 2: Does each passage survive being read alone?
The fault. A paragraph reads fine in sequence and falls apart the moment it’s read alone — “it” with no antecedent in the same chunk, “as mentioned above,” a table whose meaning lives in the paragraph before it.
Why it survives review. Nobody reads their own page out of order, so the dependency is invisible to the person most likely to catch it. The pipeline splits the page into passages, and a passage can be retrieved without the one that gave it its subject.
Check it by hand. Read the paragraphs of a page in random order. Anything that stops making sense is the finding.
Check it at scale, in a spreadsheet. Using the same first-paragraph extraction as check 1, flag the openers that start with a bare demonstrative:
=REGEXMATCH(TRIM(B2), "^(It|This|That|These|Those|As mentioned)[ ,]")
Filter to TRUE for the candidate list.
Check it at scale, in a terminal. The same test, run over the source:
grep -nE '(^|\. )(It|This|That|These|Those|As mentioned)[ ,]' page.md
Not every hit is a fault — “This crawler” carries its own noun. Anything reaching further back than the current paragraph is a chunk-boundary risk.
The fix. Restate the noun. “It” becomes “the crawler,” “as mentioned above” becomes the thing that was mentioned above. This costs a few words per instance and nothing else.
Check 3: Is the entity named in the body, not just the title?
The fault. A support page refers to “this solution” and “our tool” nine times and names the product exactly once, in the page title.
Why it survives review. House style, usually. Repeating a product name reads as marketing to an editor, and on a page a person is reading, the title and the nav have already established what “our tool” refers to. An extracted passage carries neither. Titles, nav, and header are among the parts that don’t make the trip — what AI crawlers extract has the element-by-element inventory. A passage that never names its subject is a passage about nothing identifiable.
Check it by hand. Open the page and use the browser’s find on your product name. Note the hit count, then repeat it for “our tool,” “the platform,” and “this solution.” If the generic terms outnumber the name, the page reads as anonymous — and the find bar’s own counter is the whole measurement.
Check it at scale, in a crawler. Most crawlers let you define a content search that counts a string per page. Set one for the product name and one for the generic substitutes, crawl, and compare the two columns in the export. Any URL where the second column exceeds the first is a candidate.
Check it at scale, in a terminal. Count how often the name appears in the body against how often a generic substitute takes its place:
grep -oiE 'YourProduct|our (tool|platform|solution)|the (tool|platform|product)' page.md \
| tr 'A-Z' 'a-z' | sort | uniq -c | sort -rn
If the substitute wins by a wide margin, the page reads as anonymous.
The fix. Name the entity in the body at least once per major section, in a sentence that also says what it is — “GEOBee, a desktop crawler, …” rather than “the tool.” One naming sentence per section is enough; you’re not writing the name into every paragraph.
Check 4: Does the markup still agree with the page?
The fault. JSON-LD states a price, a rating, an author, or a date that no longer matches the visible page, usually because one got updated and the other didn’t.
Why it survives review. Nobody edits schema. It stops being true on its own, when a price changes on the page but not in a template field, or a CMS value is updated that the body copy doesn’t read from. There’s no error and no alert.
What it costs. Google’s guidelines are direct: “Don’t mark up content that is not visible to readers of the page,” and markup “must be a true representation of the page content” (Google Search Central, retrieved 2026-07-30). For extraction the cost is simpler — a system now holds two conflicting claims about the same fact and no clean way to choose between them.
Check it by hand. Paste the URL into Google’s Rich Results Test or schema.org’s validator at validator.schema.org. Both parse the page’s structured data and show it as a readable tree, so you can put the price, author, and date fields next to the visible page and compare them line by line. Search Console’s URL Inspection reports the same detected items for a URL you own. None of this requires a terminal, and on your ten highest-traffic pages it is a fifteen-minute job.
Check it at scale, in a crawler. Crawlers that extract structured data will export the parsed fields as columns. Pull offers.price, datePublished, and author.name alongside the visible price and byline extracted with an XPath rule, then use a spreadsheet comparison — =EXACT(C2, D2) — and filter to FALSE. That is the whole drift report.
Check it at scale, in a terminal. Print the JSON-LD for a URL and read it against the visible text:
curl -s "$URL" | python3 -c '
import sys, re, json
for m in re.findall(r"<script[^>]*application/ld\+json[^>]*>(.*?)</script>", sys.stdin.read(), re.S):
print(json.dumps(json.loads(m), indent=2))
'
If the drift turns out to be more than a one-off, script the same comparison — key schema fields against the equivalent visible text, one row per URL, printing only disagreements — and rerun it whenever pricing or catalog content changes.
The fix. Update both in the same edit. Better, make the template render the visible value from the same field the schema reads, so the two can’t drift apart again.
Check 5: Is there a single quotable sentence on the page?
The fault. The page is accurate and well organized, but every sentence hedges — “response times can vary,” “pricing depends on your setup.”
Why it survives review. The hedges are frequently correct, and sometimes required. But a system looking for something to quote needs a sentence that resolves: a figure, a named requirement, or a plain yes or no. Accuracy without resolution gives it nothing to carry.
Check it by hand. Skim a page for sentences containing a concrete number, a named requirement, or a yes/no claim. A page with none of those has nothing for an extractor to lift, no matter how sound the surrounding prose is.
Check it at scale, in a crawler. Define a content search with the regular expression [0-9] scoped to the main content area, crawl, and sort the export by match count ascending. The pages at the top contain no figure anywhere in the body.
Check it at scale, in a terminal. Count the sentences on a page that contain a figure at all:
grep -oE '[^.!?]*[0-9][^.!?]*[.!?]' page.md | wc -l
A zero is the finding. A low count on a page that exists to answer a quantitative question is the same finding.
The fix. Add the bounded version of the true statement rather than removing the hedge: “Response times vary with payload size; the documented target is 200 ms, and anything over 1 MB exceeds it.” You keep the caveat and gain something liftable.
Doing this across a site
Five checks on one page is a diagnosis, not an audit. The honest question isn’t whether a given page has an answer block — it’s which of your URLs fail which of the five, and whether the important ones are in that set. Every at-scale check above produces the same shape of output: one row per URL, one column per fault. That table is the artifact worth having, because it’s also the thing you re-run after a fix to see whether anything moved.
Run them in the order above, though, not in parallel. Checks 1 and 5 are the ones that change a page’s readiness most and cost the least, and a page that fails check 1 will usually fail check 5 for the same underlying reason — the writing never commits to an answer anywhere. Checks 2 and 3 are cheap to fix and easy to regress, so they’re worth re-running after any template change. Check 4 is the only one where the fault can appear without anyone touching the page.
Two of the five resist automation, and it’s worth being clear about which. Passage independence needs a reader to decide whether an antecedent is genuinely missing or merely distant, and schema agreement needs someone to judge whether two differently-worded claims mean the same thing. A crawler can flag candidates for both; it can’t close them. The other three — answer block, quotable content, and an entity tied to an organization profile — are scored signals in GEOBee, evaluated per URL with published weights, and findings and fixes shows how one failing URL turns into a finding with a fix attached.
For the full set of signals these five sit inside, see Answer Engine Optimization: a page-level guide.