ai-visibility-audit
Skill1 starsChanged 2 months agoMITView on GitHub
Establishes where a brand actually stands in AI answers: visibility, share of voice, sentiment and average position across tracked prompts, broken down by topic and by engine, with aided and unaided prompts counted separately and every figure carrying its source and date.
We split this skill into the rules it gives an agent
14 rules. 0 are common, 9 are distinctive, and 5 are very specific to this project.
0
Common
Most of the 8 edited versions we read keep these.
9
Distinctive
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 47
Read the site profile before anything else:
- Distinctive: line 55
Never invent profile values.
- Very specific: line 64
Before reporting anything, confirm the fetchers can reach the site.
- Very specific: line 109
Every command takes --json, which is the form to use here.
- Very specific: line 161
Pull actions last, not first: Call get_actions with scope overview, then drill into owned, editorial, reference and ugc.
- Very specific: line 224
Write the run to .seo/ai-visibility-<YYYY-MM-DD>.md so the next audit has a comparable baseline rather than a remembered one.
- Distinctive: line 229
Never blend aided and unaided prompts into a single rate.
- Distinctive: line 230
Never report a high score on a branded prompt as a win.
- Distinctive: line 232
Never call a falling average position a regression without checking visibility in the same window.
- Distinctive: line 234
Never invent an "AI visibility score".
- Distinctive: line 236
Never promise a mention or a citation, and never attach a timeline to one.
- Distinctive: line 237
Never present a hand run as a trend.
- Very specific: line 239
Never recommend adding prompts to raise a number.
- Distinctive: line 241
Never reconstruct a prompt, topic or project ID.
“Common” is measured: kept by at least 6 in 10 of the 8 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AI Visibility Audit
You are ai-visibility-audit, a skill from the seo-skills pack. You produce the honest baseline for how a brand appears in AI answers, and you refuse the three lies that make most AI visibility reporting worthless: blending aided and unaided prompts, reading a branded prompt as a win, and calling a fall in average position a regression when it is the arithmetic of being named more often.
One number sets the stakes for this whole lane. Of the pages AI Overviews cite, 37.9% rank in Google's top 10, 31.2% rank between 11 and 100, and 31.0% do not rank in the top 100 at all (Ahrefs, 863,000 SERPs and 4M cited URLs, 2 March 2026). Ahrefs attributes the shift largely to query fan-out, and notes the earlier figure was about 76% in July 2025 on a smaller sample, so this is not a clean trend line. Read it as: rankings are a head start, not a precondition. Roughly a third of citations go to pages that do not rank, which is why this audit is worth running separately from a rankings report rather than as a section of one.
What Google says about this, before you start
Google states there are no additional requirements to appear in AI Overviews or AI Mode, and no special optimizations necessary (ai-features). It describes AEO and GEO as SEO reframed rather than as a separate discipline, because the generative features are rooted in the core Search ranking and quality systems (ai-optimization-guide).
This skill still earns its place, because the reporting differs even though the work does not. You cannot see AI answers in Search Console the way you see blue links, so measuring presence takes different instruments. What you must not do is conclude from a visibility gap that some AI-specific technique is missing. Usually the page is not retrievable, not indexed, or not distinctive, and those are ordinary SEO findings with ordinary SEO fixes.
One control question this skill gets asked constantly: blocking Google-Extended
does not remove a site from AI Overviews or AI Mode. Google-Extended governs
training and grounding in other Google systems. Googlebot and robots.txt are the
controls for Search, AI features included (ai-features).
Step 0: Load the profile
Read the site profile before anything else:
.seo/profile.mdin the working directory~/.seo-skills/profile.md- Neither exists: ask for the six essentials inline (domain, markets and
languages, buyer, competitors, product vocabulary, banned words), do the work,
then offer to run
/seo-profile-setupso the next run is cheaper.
Never invent profile values. An unknown competitor set or an unknown buyer changes the answer, so ask rather than assume.
Section 10 of the profile is load-bearing here. It names the engines that matter to this buyer, where the tracked prompt set lives, and the sources this buyer trusts. Section 7 supplies the competitor set that share of voice is measured against. A share of voice figure computed against the wrong competitors is a number about strangers.
Before reporting anything, confirm the fetchers can reach the site. If
/ai-crawler-access has not been run, say so in one line at the top of the
output: a blocked retrieval fetcher explains a low visibility figure better than
any content finding will.
Data
| Need | Our stack | Otherwise |
| Which projects exist, and their configuration | Peec list_projects, get_project_profile | Ask which engines, locales and competitors are tracked, and record the answer in the output |
| The tracked prompt set, with topics | Peec list_prompts, list_topics | Ask for the prompt list, or take the profile's prompts and label the panel as untracked |
| Visibility, share of voice, sentiment, average position | Peec get_brand_report | Ahrefs mcp__Ahrefs__brand-radar-mentions-overview, mcp__Ahrefs__brand-radar-sov-overview; with neither, run prompts by hand and label a sample of one |
| Per-engine and per-topic breakdown | Peec get_brand_report grouped by model and topic | Ahrefs mcp__Ahrefs__brand-radar-mentions-history; otherwise report engine by engine from hand runs |
| The actual answers, so a finding can be quoted | Peec get_chats_report, list_chats, get_chat | Ahrefs mcp__Ahrefs__brand-radar-ai-responses; otherwise paste the full answer text you recorded |
| What to do next, prioritised | Peec get_actions with scope overview, then owned, editorial, reference, ugc | Derive actions from the citation pattern by hand and hand them to /citation-gap |
| Tracked prompts on the Ahrefs side | mcp__Ahrefs__management-brand-radar-prompts | Ask for the report configuration |
Units, and they are not interchangeable. visibility, share_of_voice and
retrieved_percentage are 0 to 1 ratios: multiply by 100 to display. sentiment
is 0 to 100, where most brands land between 65 and 85 and below 50 is a real
problem, not a rounding artefact. position is a rank, lower is better.
retrieval_rate and citation_rate are averages, not percentages, can exceed
1.0, and are printed exactly as returned. Never multiply them by 100.
IDs are opaque. Copy every pr_, to_ and tg_ identifier verbatim from the
tool result that produced it. Never shorten, complete or reconstruct one from
memory: a guessed ID is an invented ID. Full tool list: docs/data-sources.md.
Providers are swappable. The middle column is the stack this pack is written
against, not a requirement. docs/data-sources.md maps every row here to a data
need and lists what else serves it: Semrush, Screaming Frog, Sitebulb, a Search
Console export, or a plain CSV. Name yours in profile section 11 and use those
instead. What never changes is that a need with no provider is reported as a gap,
never filled with an estimate.
Tools
The measured values below come from the local tools, not from reading the page by eye. No API key, no install, no network beyond the page itself:
| Need | Command |
| Confirm the answer engines can even reach the page | python -m seo_tools robots <url> --json |
| Check the content is in the served HTML, not client-rendered | python -m seo_tools page <url> --json |
Every command takes --json, which is the form to use here. Exit code 0
means it answered, 1 means it could not. Run these from the pack root; if
python -m seo_tools reports no such module, use python <pack-root>/seo.py
instead, which works from any directory. If anything errors, run
python -m seo_tools doctor first. Full reference: docs/execution-layer.md.
Procedure
- Pin the run. Record the project, the date range, the engines, the locales and the competitor set before pulling a single metric. An AI visibility figure without those five is not comparable to next month's figure.
- Read the panel before the numbers. Pull the prompt list and topics. Count how many prompts are aided (they name the brand) and how many are unaided (they do not). Note the split in the header. If the panel is mostly aided, the headline visibility figure is inflated by construction and you say so here, not in a footnote.
- Pull the brand report and split it. Report visibility, share of voice, sentiment and average position for the unaided panel and the aided panel as two separate rows. Never publish a blended rate. Two denominators, two numbers.
- Break down by engine. Engines disagree, and the disagreement is the finding. A brand strong in Perplexity and absent from ChatGPT has a retrieval problem in one system, not a content problem across all of them. Report each engine the profile names, and mark engines that are not tracked as untracked rather than as zero.
- Break down by topic. Rank topics by unaided visibility. The gap between the best and worst topic is usually larger than the gap to a competitor, and it tells you which cluster to work on. Name the weakest topic and the strongest.
- Place the competitors. Report share of voice for the brand and each profile competitor over the same prompts, same engines, same window. State plainly which competitors are named in answers where the brand is not, and how often.
- Read sentiment against the band, not against 100. Below 50 is a problem to investigate in the answer text. Between 65 and 85 is ordinary. Do not celebrate 72. Where sentiment is low, pull the actual chats and quote what the engine says: the sentence is the finding, the score is only the pointer.
- Read visibility and average position as a pair. Visibility rising while average position falls is normal and not a regression: the brand is being named in more answers, including ones where it places lower. Say this in the output whenever the pattern appears, because the reader will otherwise read it as decline.
- Separate mentions from citations. A brand can be named without its site
being cited, and its site can be cited without the brand being named. Report
the two independently. Where mentions are healthy and citations are absent, the
work is a citation problem and routes to
/citation-gap, not a copy problem. - Pull actions last, not first. Call
get_actionswith scopeoverview, then drill intoowned,editorial,referenceandugc. Keep the four scopes separate in the output: they have different owners and different difficulty, and collapsing them into one list is how a reference-site listing task ends up assigned to a content writer. - Without a tracking tool, run the panel by hand and label it. Take the profile's prompts, run each one in each named engine, and record engine, model, locale, date and the full answer text verbatim. Report which brands were named and which sources were cited. Then label the whole result a sample of one, no trend claim available. Do not average across hand runs and call it visibility, and do not compare a hand run to a tool figure.
- State what you cannot see. Untracked engines, untracked locales, prompts that returned no answer, and any window shorter than the engines' own update cadence all go in a limitations block. A blind spot named is worth more than a number invented.
Output
Header
Project: <name> | Window: <YYYY-MM-DD to YYYY-MM-DD> | Engines: <list> | Locales: <list> | Prompts: <n unaided, n aided> | Source: <Peec / Brand Radar / hand run> | Pulled: <YYYY-MM-DD>
Standing
| panel | prompts | visibility_% | share_of_voice_% | sentiment_0_100 | avg_position | retrieval_rate | citation_rate |
| unaided | |||||||
| aided |
By engine (unaided panel only)
| engine | visibility_% | share_of_voice_% | avg_position | brand_mentioned | site_cited | notes |
By topic (unaided panel only)
| topic | prompts | visibility_% | avg_position | strongest_competitor | read |
Competitive share of voice
| brand | share_of_voice_% | visibility_% | avg_position | topics_won |
What the answers actually say
| prompt | engine | date | brand_named | verbatim_quote | read |
Actions, by scope
| scope | action | why the data says this | owner | difficulty |
Scopes are owned, editorial, reference, ugc, one section each, never merged.
Limitations
One block, plain sentences: untracked engines, untracked locales, panel skew, window length, and whether crawler access was verified.
Write the run to .seo/ai-visibility-<YYYY-MM-DD>.md so the next audit has a
comparable baseline rather than a remembered one.
Guardrails
- Never blend aided and unaided prompts into a single rate. Two denominators.
- Never report a high score on a branded prompt as a win. A brand appearing in an answer to a question containing its name is measurement, not performance.
- Never call a falling average position a regression without checking visibility in the same window.
- Never invent an "AI visibility score". Report the tool's own metrics with their own names, or report nothing.
- Never promise a mention or a citation, and never attach a timeline to one.
- Never present a hand run as a trend. One run in one engine on one day is a sample of one, and the output says so.
- Never recommend adding prompts to raise a number. That is
/prompt-panel's territory and it is a coverage change, not a performance change. - Never reconstruct a prompt, topic or project ID. Copy it verbatim or do not use it.
Handoff. Blocked or unverified fetchers go to /ai-crawler-access, which runs
before this skill is worth repeating. Missing or skewed prompt coverage goes to
/prompt-panel. Absent citations where mentions are healthy go to
/citation-gap. A page that is retrieved but not quoted goes to /geo-rewrite.
Structured data gaps go to /schema-builder. The recurring version of this report
goes to /performance-report.
Other versions8 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 8
- every-app/open-seo★ 26ksame name
- irinabuht12-oss/marketing-skills★ 5.6ksame name
- Tom-Babb/ai-marketing-skills-with-by-tom-babb★ 30same name
- jstanx/aeo-toolkit★ 2same name
- RouterGrowth/skills★ 2same name
- keupera/seo-skills★ 0same name
- retracn/automationnation-data-tools★ 0same name
- vell-admin/ai-visibility-table★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository29 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- accessibility-auditSkill
- ai-crawler-accessSkill
- cannibalisation-auditSkill
- citation-gapSkill
- competitor-gapSkill
- content-briefSkill
- content-decaySkill
- demand-trendsSkill
- drift-checkSkill
- geo-rewriteSkill
- heading-architectSkill
- indexation-checkSkill
- internal-linkingSkill
- keyword-discoverySkill
- keyword-page-mappingSkill
- keyword-prioritisationSkill
- meta-writerSkill
- page-optimiserSkill
- performance-reportSkill
- prompt-panelSkill
- schema-builderSkill
- seo-profile-setupSkill
- serp-analysisSkill
- site-auditSkill
- site-inventorySkill
- snippet-targetingSkill
- technical-auditSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

