Un site e-commerce de 22 000 pages produit. Googlebot crawle 8 000 pages par jour. GPTBot en visite 1 200. Pourtant, sur les 150 requêtes commerciales testées dans ChatGPT et Perplexity, le site n'est cité que 3 fois. Le contenu existe, il est crawlé, mais il est systématiquement ignoré par les moteurs de recherche IA. Le problème ne se situe pas là où vous pensez.
L'article récemment publié par Search Engine Journal, sponsorisé par Siteimprove, pose la bonne question : pourquoi un contenu indexé par Google peut-il être invisible pour les LLM ? Mais la réponse mérite d'aller bien au-delà du diagnostic de surface. Il y a un pipeline technique complet entre le crawl d'un bot IA et la citation effective dans une réponse générée, et chaque étape est un point de rupture potentiel.
Le pipeline de visibilité IA : 5 étapes, 5 points de rupture
La visibilité dans les moteurs de recherche IA (ChatGPT Search, Perplexity, Gemini, Copilot) repose sur un pipeline fondamentalement différent de celui de Google Search. Voici les étapes, dans l'ordre :
- Crawl — Le bot IA (GPTBot, PerplexityBot, ClaudeBot) accède à la page
- Extraction — Le contenu textuel est extrait du HTML rendu
- Chunking — Le contenu est découpé en segments sémantiques
- Embedding — Chaque chunk est vectorisé dans un espace sémantique
- Retrieval + Citation — Lors d'une requête utilisateur, le système RAG (Retrieval-Augmented Generation) sélectionne les chunks les plus pertinents et décide de les citer ou non
Un contenu peut passer l'étape 1 (le bot crawle la page avec succès) et échouer à l'étape 3 (le contenu est mal découpé car la structure HTML est ambiguë) ou à l'étape 5 (le chunk est récupéré mais jugé redondant avec une source plus autoritaire).
Le diagnostic technique consiste à identifier précisément à quelle étape votre contenu décroche.
Étape 1 : vérifier que les bots IA crawlent réellement vos pages
Analyser les logs serveur
La première vérification est triviale mais souvent négligée. Vous devez confirmer que GPTBot, PerplexityBot et les autres accèdent effectivement à vos pages stratégiques — pas seulement à votre homepage et vos pages "À propos".
# Extraire les hits GPTBot des 30 derniers jours, groupés par URL
grep "GPTBot" /var/log/nginx/access.log \
| awk '{print $7}' \
| sort \
| uniq -c \
| sort -rn \
| head -50
# Même chose pour PerplexityBot
grep "PerplexityBot" /var/log/nginx/access.log \
| awk '{print $7, $9}' \
| sort \
| uniq -c \
| sort -rn \
| head -50
Ce que vous cherchez : la distribution des pages crawlées. Si GPTBot visite principalement vos pages de catégories et ignore vos pages produits ou vos articles de fond, le problème est un problème de découverte. Les bots IA suivent les liens de la même manière que Googlebot — votre maillage interne dicte ce qu'ils trouvent.
Le piège du robots.txt mal configuré
Une analyse de 68 millions de visites de crawlers IA a montré que la distribution de crawl varie massivement d'un bot à l'autre. Certains sites bloquent GPTBot par précaution sans réaliser qu'ils se coupent de la visibilité ChatGPT Search.
Vérifiez votre robots.txt avec précision. Google a d'ailleurs récemment étendu sa documentation sur les règles robots.txt non supportées, ce qui complexifie encore la gestion multi-bots.
# robots.txt — Configuration recommandée pour les bots IA
# Autoriser le crawl tout en bloquant les sections non pertinentes
User-agent: GPTBot
Allow: /blog/
Allow: /guides/
Allow: /produits/
Disallow: /compte/
Disallow: /panier/
Disallow: /api/
Crawl-delay: 2
User-agent: PerplexityBot
Allow: /blog/
Allow: /guides/
Allow: /produits/
Disallow: /compte/
Disallow: /panier/
Crawl-delay: 2
User-agent: ClaudeBot
Allow: /blog/
Allow: /guides/
Allow: /produits/
Disallow: /compte/
Disallow: /panier/
Crawl-delay: 5
User-agent: Bytespider
Disallow: /
Notez la distinction : autoriser les bots des systèmes que vous voulez cibler (GPTBot pour ChatGPT, PerplexityBot pour Perplexity), bloquer ceux qui n'apportent rien (Bytespider de ByteDance consomme du bandwidth sans retour mesurable pour la plupart des sites occidentaux). La hausse récente de l'activité de crawl d'OpenAI rend cette configuration d'autant plus critique.
Codes de réponse et temps de réponse
Les bots IA sont moins tolérants que Googlebot sur les temps de réponse. GPTBot abandonne une requête plus rapidement. Si votre serveur met 3 secondes à répondre (acceptable pour Googlebot), GPTBot peut timeout et passer à la suite.
Dans vos logs, filtrez les réponses 5xx et les temps de réponse supérieurs à 2 secondes pour les user-agents IA. Un taux d'erreur de 15% sur GPTBot signifie que 15% de vos pages ne sont jamais ingérées.
Étape 2 : ce que le bot IA voit vs ce que vous pensez qu'il voit
C'est le point de rupture le plus sous-estimé. Les bots IA ne rendent pas le JavaScript de la même manière que Googlebot (qui utilise un moteur Chromium complet). GPTBot et PerplexityBot se comportent davantage comme des crawlers headless basiques — ils récupèrent le HTML initial et extraient le texte.
Tester le rendu sans JavaScript
# Comparer le contenu visible avec et sans JS
# 1. Récupérer le HTML brut (ce que GPTBot voit probablement)
curl -s -A "GPTBot/1.0" https://votre-site.fr/guide-technique \
| python3 -c "
import sys
from html.parser import HTMLParser
class TextExtractor(HTMLParser):
def __init__(self):
super().__init__()
self.text = []
self.skip = False
def handle_starttag(self, tag, attrs):
if tag in ('script', 'style', 'noscript'):
self.skip = True
def handle_endtag(self, tag):
if tag in ('script', 'style', 'noscript'):
self.skip = False
def handle_data(self, data):
if not self.skip and data.strip():
self.text.append(data.strip())
e = TextExtractor()
e.feed(sys.stdin.read())
print('\n'.join(e.text))
" > content_nojs.txt
# 2. Récupérer le contenu rendu via Puppeteer/Playwright
npx playwright screenshot https://votre-site.fr/guide-technique \
--wait-until networkidle
# 3. Comparer les deux fichiers
wc -w content_nojs.txt # Si < 200 mots, le contenu dépend du JS
Si la version sans JavaScript ne contient que le header, le footer et un <div id="app"></div> vide, votre contenu est invisible pour les bots IA. Ce scénario est extrêmement fréquent sur les SPA React/Vue sans SSR.
Le cas concret : migration SPA vers SSR
Prenez un média tech de 8 000 articles construit sur une SPA React. Après audit :
- Googlebot : indexe 7 200 pages (rendu JS côté Google)
- GPTBot : crawle 3 500 pages, mais n'extrait du contenu substantiel que sur 400 (les pages dont le contenu est dans le HTML initial — pages statiques legacy)
- Résultat Perplexity : le site est cité sur 2 requêtes parmi 80 testées
Après migration vers Next.js avec SSR (Server-Side Rendering), le contenu est présent dans le HTML initial. En 6 semaines :
- GPTBot extrait du contenu sur 3 200 pages
- Les citations Perplexity passent de 2 à 17 sur le même panel de requêtes
Le SSR n'est pas une option pour la visibilité IA — c'est un prérequis. Et les régressions SSR silencieuses (un déploiement qui casse le rendu serveur sans que personne ne s'en aperçoive) sont le type exact de problème qu'un monitoring continu comme Seogard détecte avant que l'impact ne se matérialise.
Étape 3 : la structure sémantique détermine le chunking
Les systèmes RAG ne lisent pas votre page comme un humain. Ils la découpent en chunks — des segments de 200 à 500 tokens en général — puis vectorisent chaque chunk indépendamment. La qualité de ce découpage dépend directement de votre structure HTML.
Pourquoi la hiérarchie H1-H6 compte (vraiment, cette fois)
En SEO classique, la hiérarchie des headings est un signal parmi d'autres. Pour les systèmes RAG, c'est le squelette du chunking. Un H2 suivi de 3 paragraphes = un chunk cohérent. Un mur de texte de 2 000 mots sans aucun heading = un chunk qui mélange 4 sujets différents et dont l'embedding vectoriel ne matche aucune requête précise.
<!-- ❌ Structure anti-chunking : tout le contenu dans un seul bloc -->
<article>
<h1>Guide complet de la migration HTTPS</h1>
<p>La migration HTTPS implique le changement de protocole...
[2000 mots sans aucun sous-titre, mélangeant certificats SSL,
redirections 301, HSTS, mixed content, impact SEO, monitoring...]</p>
</article>
<!-- ✅ Structure optimisée pour le chunking RAG -->
<article>
<h1>Guide complet de la migration HTTPS</h1>
<section>
<h2>Choisir et installer le certificat SSL</h2>
<p>Le choix du certificat dépend de votre architecture.
Un certificat wildcard (*.example.fr) couvre tous les sous-domaines...</p>
<h3>Certificat DV vs OV vs EV : quel impact réel ?</h3>
<p>Pour le SEO, aucun. Google ne distingue pas les types
de certificats. Le choix est purement une question de confiance
utilisateur dans la barre d'adresse...</p>
</section>
<section>
<h2>Configurer les redirections 301</h2>
<p>Chaque URL HTTP doit rediriger vers son équivalent HTTPS
avec un code 301 permanent...</p>
<pre><code>
# Nginx — Redirection HTTP vers HTTPS
server {
listen 80;
server_name example.fr www.example.fr;
return 301 https://$server_name$request_uri;
}
</code></pre>
</section>
<section>
<h2>Activer HSTS et gérer le mixed content</h2>
<p>Le header Strict-Transport-Security empêche les navigateurs
de revenir en HTTP après la première visite...</p>
</section>
</article>
La deuxième structure produit des chunks thématiquement cohérents. Quand un utilisateur demande à Perplexity "comment configurer les redirections 301 pour une migration HTTPS", le chunk de la section 2 aura un embedding beaucoup plus proche de la requête que le même contenu noyé dans un bloc monolithique.
Les balises sémantiques HTML5 comme signaux de découpage
Les <section>, <article>, <aside>, <nav> ne sont pas décoratifs. Les extracteurs de contenu des systèmes RAG les utilisent comme délimiteurs. Un <aside> sera probablement exclu du contenu principal. Un <nav> sera ignoré. Un <section> dans un <article> sera traité comme une unité logique.
C'est un aspect que les signaux de visibilité IA incluent de plus en plus : la clarté structurelle de votre HTML est un facteur de sélection en amont du modèle de langage lui-même.
Étape 4 : le contenu est extrait mais jamais sélectionné — le problème d'autorité topicale
Votre contenu est crawlé, rendu correctement, bien structuré, et pourtant jamais cité. Le problème se situe alors à l'étape 5 du pipeline : le retrieval. Le système RAG récupère plusieurs chunks candidats pour une requête, puis le LLM sélectionne ceux qu'il va utiliser et citer.
Comment fonctionne la sélection des sources dans un système RAG
Un système RAG typique (celui de Perplexity est le mieux documenté) fonctionne ainsi :
- La requête utilisateur est vectorisée
- Les N chunks les plus proches dans l'espace d'embedding sont récupérés (typiquement 20-50)
- Un re-ranker évalue la pertinence fine de chaque chunk
- Le LLM génère sa réponse en utilisant les top chunks comme contexte
- Le LLM décide quelles sources citer (et peut ignorer un chunk qu'il a pourtant utilisé)
L'étape 3 (re-ranking) et l'étape 5 (décision de citation) sont celles où l'autorité perçue de la source intervient. Le re-ranker n'utilise pas le PageRank, mais il utilise des signaux corrélés :
- La cohérence thématique du domaine : un site qui publie 200 articles sur la cybersécurité sera préféré à un site généraliste qui a 1 article sur le sujet
- La fraîcheur du contenu : un article daté de 2024 sera préféré à un article non daté
- La densité informationnelle du chunk : un paragraphe qui contient des données factuelles, des chiffres, des noms propres sera préféré à un paragraphe vague
C'est exactement ce qu'analyse en profondeur l'article sur pourquoi le bon contenu ne suffit plus : les LLM ne cherchent pas le "meilleur contenu" au sens éditorial, ils cherchent la source la plus fiable pour une affirmation spécifique.
Le diagnostic pratique
Utilisez Perplexity en mode "Focus: Academic" ou "Focus: All" sur vos requêtes cibles. Examinez les sources citées. Si vos concurrents sont cités et pas vous, analysez la différence structurelle :
- Leurs pages contiennent-elles des données originales (études, benchmarks, chiffres propriétaires) ?
- Leurs chunks sont-ils auto-suffisants (compréhensibles hors contexte) ?
- Leur domaine a-t-il une couverture thématique plus profonde sur le sujet ?
La question de la réputation est centrale ici : les LLM héritent des biais de leurs données d'entraînement. Si votre marque n'est pas associée à votre domaine d'expertise dans le corpus d'entraînement, le re-ranker vous pénalise implicitement. La manière dont les modèles IA comprennent votre marque détermine votre plafond de visibilité.
Étape 5 : le diagnostic technique complet — checklist actionable
Voici le processus de diagnostic complet, étape par étape, applicable à un site de 5 000+ pages.
Phase 1 : Audit de crawlabilité IA (semaine 1)
// Script Node.js pour auditer la crawlabilité IA d'un sitemap
import { parse } from 'node-html-parser';
interface CrawlResult {
url: string;
status: number;
contentLength: number;
wordCount: number;
hasH1: boolean;
headingStructure: string[];
hasStructuredData: boolean;
responseTime: number;
}
async function auditUrl(url: string): Promise<CrawlResult> {
const start = Date.now();
const response = await fetch(url, {
headers: {
'User-Agent': 'GPTBot/1.0 (+https://openai.com/gptbot)',
},
signal: AbortSignal.timeout(5000),
});
const html = await response.text();
const responseTime = Date.now() - start;
const root = parse(html);
// Extraire le texte visible (hors script/style)
const scripts = root.querySelectorAll('script, style, noscript');
scripts.forEach(s => s.remove());
const textContent = root.textContent.replace(/\s+/g, ' ').trim();
const wordCount = textContent.split(' ').filter(w => w.length > 2).length;
// Analyser la structure des headings
const headings = root.querySelectorAll('h1, h2, h3, h4, h5, h6');
const headingStructure = headings.map(
h => `${h.tagName}: ${h.textContent.trim().substring(0, 60)}`
);
// Vérifier la présence de structured data
const jsonLd = root.querySelectorAll('script[type="application/ld+json"]');
return {
url,
status: response.status,
contentLength: html.length,
wordCount,
hasH1: root.querySelector('h1') !== null,
headingStructure,
hasStructuredData: jsonLd.length > 0,
responseTime,
};
}
async function auditSitemap(sitemapUrl: string) {
const response = await fetch(sitemapUrl);
const xml = await response.text();
const root = parse(xml);
const urls = root.querySelectorAll('loc').map(l => l.textContent);
console.log(`Auditing ${urls.length} URLs...`);
const results: CrawlResult[] = [];
for (const url of urls.slice(0, 500)) { // Limiter pour le test
try {
const result = await auditUrl(url);
results.push(result);
// Alertes immédiates
if (result.wordCount < 100) {
console.warn(`⚠️ LOW CONTENT: ${url} (${result.wordCount} words)`);
}
if (result.responseTime > 2000) {
console.warn(`⚠️ SLOW: ${url} (${result.responseTime}ms)`);
}
if (!result.hasH1) {
console.warn(`⚠️ NO H1: ${url}`);
}
} catch (e) {
console.error(`❌ FAILED: ${url} — ${e.message}`);
}
// Rate limiting
await new Promise(r => setTimeout(r, 1000));
}
// Résumé
const avgWords = results.reduce((a, r) => a + r.wordCount, 0) / results.length;
const lowContent = results.filter(r => r.wordCount < 100).length;
const slow = results.filter(r => r.responseTime > 2000).length;
const noStructuredData = results.filter(r => !r.hasStructuredData).length;
console.log(`\n--- RÉSUMÉ ---`);
console.log(`Pages auditées: ${results.length}`);
console.log(`Mots moyens (sans JS): ${Math.round(avgWords)}`);
console.log(`Pages < 100 mots (contenu JS-dépendant probable): ${lowContent}`);
console.log(`Pages > 2s de réponse: ${slow}`);
console.log(`Pages sans structured data: ${noStructuredData}`);
}
auditSitemap('https://votre-site.fr/sitemap.xml');
Ce script simule ce que GPTBot voit réellement. Les pages avec moins de 100 mots en HTML brut sont quasi certainement des pages dont le contenu dépend du JavaScript côté client — elles sont invisibles pour les bots IA.
Phase 2 : Analyse de la couverture topicale (semaine 2)
Utilisez Screaming Frog avec l'extraction custom pour mapper votre couverture thématique :
- Crawlez votre site avec extraction des H1, H2, et du premier paragraphe de chaque page
- Exportez en CSV
- Classez par cluster thématique (manuellement ou via embeddings)
- Identifiez les trous : quels sous-sujets de votre domaine ne sont couverts par aucune page ?
Les LLM préfèrent les sources qui démontrent une couverture exhaustive d'un sujet. Si vous avez 3 articles sur "migration cloud" mais aucun sur "migration cloud sécurité données sensibles", "migration cloud coûts cachés", ou "migration cloud réversibilité", votre autorité topicale est perçue comme superficielle.
C'est la logique décrite dans l'analyse sur comment produire plus de contenu ne suffit plus : la profondeur prime sur le volume.
Phase 3 : Test de citation (semaine 3-4)
Il n'existe pas encore d'API publique pour mesurer la visibilité dans les réponses LLM à grande échelle. La méthode manuelle reste la plus fiable :
- Constituez un panel de 50-100 requêtes représentatives de votre domaine
- Testez chaque requête dans ChatGPT (mode recherche web), Perplexity, et Gemini
- Notez si votre site est cité, à quelle position dans les sources, et quel contenu est extrait
- Comparez avec vos concurrents directs
Des outils comme ceux analysés par DebugBear commencent à automatiser ce processus. Bing Webmaster Tools teste également un rapport de citations IA qui devrait faciliter ce suivi.
Les structured data : pas un facteur de ranking, mais un facteur de compréhension
Les données structurées (JSON-LD) ne sont pas directement utilisées par les systèmes RAG pour le ranking. Mais elles influencent la compréhension du contenu lors de l'extraction. Un Article avec author, datePublished, dateModified et about donne au système RAG des métadonnées exploitables pour le re-ranking.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "TechArticle",
"headline": "Migration HTTPS : guide technique pour sites e-commerce",
"author": {
"@type": "Person",
"name": "Marie Laurent",
"jobTitle": "Lead Security Engineer",
"url": "https://votre-site.fr/equipe/marie-laurent"
},
"datePublished": "2026-04-15",
"dateModified": "2026-05-01",
"about": {
"@type": "Thing",
"name": "HTTPS Migration",
"sameAs": "https://en.wikipedia.org/wiki/HTTPS"
},
"isPartOf": {
"@type": "WebSite",
"name": "VotreSite Tech Blog",
"url": "https://votre-site.fr"
},
"speakable": {
"@type": "SpeakableSpecification",
"cssSelector": ["article h1", "article > section:first-of-type"]
}
}
</script>
Le champ speakable est particulièrement intéressant : bien que conçu initialement pour Google Assistant, il indique explicitement quelles parties de la page sont les plus "citables". C'est un signal que les systèmes RAG pourraient exploiter — et que Perplexity semble déjà prendre en compte selon les observations de plusieurs praticiens. Consultez la documentation Google sur les Speakable pour les détails d'implémentation.
Le point soulevé par l'article de SEJ est que votre site doit fonctionner comme une source, pas un mégaphone. Les données structurées transforment votre page d'un document HTML en une entité compréhensible par les machines.
Les faux positifs du diagnostic : ce qui ne cause PAS le problème
Il serait malhonnête de ne pas mentionner les fausses pistes courantes.
Le Domain Authority n'est pas le facteur principal
Des expériences ont montré qu'une fausse marque peut gagner en AI search. L'autorité de domaine au sens Moz/Ahrefs n'est pas directement utilisée par les systèmes RAG. Ce qui compte, c'est la pertinence et la densité informationnelle du chunk, combinées à la cohérence thématique du domaine.
La fréquence de publication n'est pas un levier direct
Publier un article par jour ne vous rendra pas plus visible dans ChatGPT si chaque article manque de profondeur technique. Les LLM évaluent la qualité à l'échelle du chunk, pas à l'échelle du domaine. Un seul article technique exhaustif sur un sujet précis vaut plus que 20 articles superficiels.
Les meta descriptions ne sont pas utilisées par les LLM
Les systèmes RAG extraient le contenu <body>, pas les <meta>. Vos meta descriptions n'ont aucun impact sur votre visibilité IA. Concentrez votre effort sur le contenu visible, les headings, et la structure sémantique.
Cela dit, comme l'analyse des retombées CTR des AI Overviews l'a montré, les meta descriptions restent essentielles pour les résultats classiques qui coexistent avec les réponses IA.
Le monitoring continu comme filet de sécurité
Le diagnostic ponctuel ne suffit pas. Les régressions SSR, les changements de structure HTML après un déploiement, les blocages robots.txt accidentels — tout cela arrive en continu sur un site actif.
Le scénario classique : un développeur ajoute un lazy-loading agressif sur les images et le contenu below-the-fold. L'impact sur Googlebot est nul (il attend le rendu complet). L'impact sur GPTBot est immédiat — tout le contenu sous le premier écran disparaît du HTML initial. Le site perd 40% de son contenu visible pour les bots IA, et personne ne s'en aperçoit pendant 3 mois.
Un monitoring technique automatisé qui vérifie quotidiennement le contenu visible dans le HTML brut (sans rendu JS) permet de détecter ce type de régression en quelques heures. C'est le type de surveillance que Seogard automatise : comparer le HTML rendu côté serveur avec le contenu attendu, et alerter immédiatement quand un delta significatif apparaît.
La visibilité dans les moteurs de recherche IA n'est pas un nouveau canal marketing à "optimiser" — c'est un ensemble de contraintes techniques à satisfaire. Diagnostiquez chaque étape du pipeline (crawl, extraction, chunking, embedding, retrieval), identifiez votre point de rupture spécifique, et corrigez chirurgicalement. Le contenu qui est compris comme de la donnée structurée par les LLM, pas comme de la