A million pages, about 60 Claude calls.
Sending every page of a large site to a language model would cost thousands of dollars per audit. This tool runs code and ML on everything, and only shows Claude a small, well-chosen sample, then checks Claude's answers before they reach the report.
The pipeline
Cheapest tool first. Each step narrows what the next, more expensive step has to look at.
- 01
Read robots.txt, llms.txt and the sitemaps
CodeFollows sitemap indexes and samples files from every family (numbered files, per-city files and so on), then scales the counts back up.
Why · A 1.3M-page site has hundreds of sitemap files. Reading a fair sample gets the page count within about 1%; “Count every page” reads them all when you need the exact number.
- 02
Group URLs into page types
MLTurns URLs into patterns like /building/{slug}, then fetches a few pages per pattern and compares their structure (tag paths and heading outline) with MinHash. HDBSCAN clusters pages that share a layout.
Why · URLs alone over-split or under-split. One pattern can hide two layouts, and two patterns can be the same page. Structure settles it, with no labels to train on.
- 03
Fetch samples and run 24 rule checks
CodeAbout 6 pages per page type: titles, canonicals, headings, JSON-LD and its required properties, placeholders like “-%”, freshness, internal links and broken links.
Why · Pages built from one template share its bugs, so a handful of samples shows the problem for all of them. Rules are free, fast and exact, so they go first.
- 04
Render with and without JavaScript, measure Core Web Vitals
BrowserHeadless Chromium compares what a crawler that doesn't run JavaScript sees against the full page. Core Web Vitals come from Chrome field data via PageSpeed Insights.
Why · Most AI crawlers don't run JavaScript. If the facts only appear after hydration, they don't exist for ChatGPT or Claude.
- 05
Claude reads the sample pages
ClaudeClaude Haiku, one call per sample page: which key facts a page of this type should state, whether this page states them in text and in JSON-LD, whether there's one quotable summary sentence, and which questions it answers.
Why · Rules can't tell whether “Rated 4.2 by 38 renters” is a fact or a placeholder, or whether a page answers what people actually ask. A small, fast model is enough for this reading task.
- 06
Ask real questions with web search
ClaudeClaude Haiku with the web search tool answers the questions people ask about your page types and records which sites it cites. It keeps asking until it has 8 answers that actually searched.
Why · This is the closest free signal to “does AI search quote us?”. Answers given from memory, without a search, are marked and not scored.
- 07
Judge everything once and write the fixes
ClaudeClaude Sonnet reads a digest of every finding, ranks the fixes by pages covered and severity, and writes the code for each page type: JSON-LD, a summary block, a title pattern.
Why · Ranking trade-offs across the whole site needs judgement, so the bigger model runs here, once, not once per page.
- 08
Score, compare and alert
CodeSEO, AI readiness and GEO scores per page type, compared with the last saved audit. Scheduled monitors post to Slack when a deploy breaks a template.
Why · Comparisons use only the deterministic checks, so the alert means the site changed, not that a model answered differently.
Model routing
The small model does the many repetitive reads. The bigger model is called once, where judgement matters.
| Step | Model | Calls per audit | How | Typical cost |
|---|---|---|---|---|
| Page checks | Claude Haiku 5.5 | ~60 calls | Structured output, low effort | ~$0.05 |
| AI visibility | Claude Haiku 5.5 + web search | 8–16 calls | $0.01 per search | ~$0.10 |
| Judge and fixes | Claude Sonnet 5.5 | 1 call | Structured output, medium effort | ~$0.05 |
Everything else (sitemaps, clustering, rules, rendering, scoring) costs $0. Each report's “Under the hood” view shows the real numbers for that audit.
Guardrails
A model's answer is treated as a claim to check, not a fact.
Structured output only
Every Claude call returns a fixed schema (Pydantic). A malformed answer is rejected, never parsed by guesswork.
Quotes must exist on the page
When Claude says “this is the quotable sentence”, the sentence is searched for in the page text. If it isn't there, it's thrown away.
Generated JSON-LD is validated
Placeholders are filled with sample values, then it must parse, have a schema.org @type, and include the required properties. Failing fixes aren't shown.
Unsearched answers aren't scored
If the model answers from memory instead of searching, the answer is kept for reference but left out of the visibility score. The score shows its confidence.
A hard budget per audit
Before each call, the worst-case cost (full output length) must fit in what's left of the $0.50 cap. Every call records model, tokens, cost and time.
Show the evidence
Each Claude finding has a “Why?” button: what Claude was shown, what it answered, and whether the guardrail passed.
Measured, not assumed
The pipeline runs on generated sites where the right answer is known (3 synthetic sites, 1315 pages, 14 true page types). The tests fail if these scores drop.
What it doesn't do
- —It samples pages per page type. A bug that hits one page in a thousand of the same template can be missed.
- —AI visibility uses Claude's web search. ChatGPT, Perplexity and Gemini need your own keys when you self-host.
- —Search Console, Bing and AI referral traffic need you to connect your accounts.
- —Page types are found without labels. Two URL sections that share one layout (/neighborhood/… and /area/…) stay separate, and two near-identical layouts can be merged. The report shows the clustering so you can check.
See it on your site
Run an audit, then open “Under the hood” in the report.