# SEO Audit Geo

> seo-audit-geo — Analyse GEO (visibilité IA générative)

- Skill: `lcrvl2/seo-audit-geo` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add lcrvl2/seo-audit-geo`
- Raw SKILL.md: https://api.skillmd.com/api/skills/lcrvl2/seo-audit-geo/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Marketing & Growth
- Author: lcrvl2 (https://skillmd.com/u/lcrvl2)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/lcrvl2/seo-audit-geo

---


# seo-audit-geo — Analyse GEO (visibilité IA générative)

Couvre **l'intégralité de la méthode GEO** (`references/process.md`, copie fidèle de la spec phase 5). Produit `findings/geo.json`.

## Architecture hybride — deux couches, aucun process omis

1. **Couche script** (`scripts/analyze.py`) : tout le mécanisable — matrice d'accès bots LLM (5.1-5.5), llms.txt (5.6), FAQ/glossaire par URL + FAQPage schema (5.12-5.14), Organization/Person completeness (5.16-5.17), Wikidata (5.19), cohérence de marque (5.20). Écrit `facts` + `findings`.
2. **Couche agent** (CE SKILL.md) : les **jugements sur le contenu réel** que le crawl ne porte pas — structure AEO sur 20 pages (5.8-5.11), contenu caché par JS (5.7), liens d'identité externes (5.18). Listés dans `to_judge` avec rubrique exacte. Plus la visibilité LLM (5D-5F) quand DataForSEO AI sera branché.

> Le script ne fabrique pas de proxy. Il ne sait pas si une page a des `<ul>`/`<table>` (le crawl DFS OnPage n'expose pas le HTML) → il inscrit l'évaluation AEO dans `to_judge` avec le barème, et l'agent va WebFetch les pages pour scorer réellement.

## Procédure de l'agent

### Étape 1 — Lancer le socle script
```bash
python seo/skills/seo-audit-geo/scripts/analyze.py <slug>
python seo/skills/seo-audit-geo/scripts/analyze.py <slug> --offline   # sans HTTP (réserve seule)
```

### Étape 2 — Exécuter chaque évaluation de `to_judge`

**5.7 — Contenu caché par JS** (échantillon 10 pages) : pour chaque page, comparer le rendu **sans JS** (HTTP brut / `curl`) vs **avec JS** (WebFetch rendu). Title, H1, word count. WC sans JS=0 & avec JS>0 → contenu caché (critique pour les LLM). >1.5× → contenu majoritairement JS. **JS_dependency_score = pages avec issue / total × 100**. Seuils : <5% bon, 5-15% surveiller, >15% risque élevé.

**5.8-5.11 — Structure AEO** (20 pages clés : home, pricing, features, top blog) : pour chaque page (WebFetch HTML), scorer → réponse/résumé en tête (les ~100 premiers mots répondent au sujet) **+20**, listes `<ol>`/`<ul>` **+15**, tableaux `<table>` récap **+15**, hiérarchie H2/H3 claire **+15**, section FAQ **+20**, définitions de termes **+15**. **AEO Score/page = somme (max 100)**. Confirmer que les listes numérotées sont de vrais how-to instructionnels (5.11). Renvoyer la **moyenne sur 20 pages** + les pages faibles. Seuils (thresholds.geo.aeo_score) : >70 bon, 50-70 moyen, <50 faible.

**5.18 — Liens d'identité externes** : WebFetch about/home, chercher des liens vers Wikidata, Wikipedia, Crunchbase, LinkedIn entreprise, profils sociaux officiels. Compter les liens d'autorité, vérifier qu'ils sont officiels et pertinents.

### Étape 3 — (Quand DataForSEO AI est branché) Visibilité LLM 5D-5F

Tant que `collecte_a_brancher`, ces findings sont affichés "à venir". Quand la collecte est branchée, exécuter le process complet :
- **5.21-5.22** : générer 20-30 prompts (JTBD / transactionnels / comparaison / problème) depuis GSC + feature pages + concurrents, faire valider par l'utilisateur.
- **5.23-5.26** : `ai_opt_llm_ment_search` par prompt → marque mentionnée/position/contexte/concurrents ; `ai_opt_llm_ment_agg_metrics` → mention rate, share of voice ; `ai_opt_llm_ment_top_domains` / `top_pages` → domaines et pages cités.
- **5.27-5.30** : `chat_gpt_scraper` pour vérifier exactitude ; sentiment (positif/neutre/négatif/mixte) ; exactitude de la description produit sur 5 dimensions (catégorie, features, audience, prix, différenciation) ; mentions négatives à corriger.
- **5.31-5.34** : query fan-out (sources qui influencent les réponses), pages concurrentes les plus citées, pages à créer, pages à optimiser (avec gains AEO estimés).

### Étape 4 — Write-back des jugements (OBLIGATOIRE)

Une fois les `to_judge` évalués, **réintègre les résultats dans `findings/geo.json`** via le module partagé — sinon le rapport ne voit pas tes scores et l'audit n'est pas comparable d'un run à l'autre :

```bash
python seo/seo-os/scripts/judgment.py <findings/geo.json> \
  --results '{"aeo_score": <moyenne 20 pages>, "js_dependency_score": <pct>, "lists_pct": <%>, "tables_pct": <%>, "external_authority_links": <n>}' \
  --rule geo_aeo
```
Cela hydrate `facts.aeo.content_depth_score` (via la clé `judged`) et émet `geo.aeo.weak_structure` si le score AEO moyen < seuil (thresholds.geo.aeo_score.warning_min). Ajoute aussi manuellement `geo.js.hidden_content` (via un 2e appel write-back avec un finding construit) si JS_dependency_score > 15%. Les id sont stables pour la comparaison entre audits.

## Données requises

- Crawl (raw.json) : obligatoire (microdata pour schema, URLs).
- robots.txt / llms.txt live : HTTP direct (sauf `--offline`).
- Contenu HTML des pages (WebFetch) : pour les `to_judge` AEO/JS. L'agent le récupère.
- DataForSEO AI Optimization : pour 5D-5F. Non collecté → `collecte_a_brancher`.

## Contrat

Entrée : `data/crawl/<date>/raw.json` + robots/llms live. Sortie : `findings/geo.json` (facts + to_judge + findings). Voir `references/process.md` et `seo-os/references/data-contract.md`.

## Sur Hermes

Profil-worker `seo-geo`, carte `parents=[seo-collect]`, parallèle aux autres analyses. La couche agent (WebFetch des pages pour l'AEO) tourne dans le worker.

