Un fichier unique, hébergé à la racine de votre domaine, qui déclare aux systèmes d'IA l'ensemble des entités que votre organisation maîtrise, avec les preuves associées. C'est la proposition d'EntityMap, un standard ouvert porté par Dixon Jones et présenté en détail sur Search Engine Journal. Au-delà du buzz, la question technique est sérieuse : comment structurer un graphe d'entités complet sans créer un monstre de maintenance, et surtout, quel impact réel sur la façon dont les LLM et les moteurs de réponse consomment votre contenu ?
Ce que propose EntityMap — et pourquoi c'est différent du schema.org classique
Le schema.org embarqué dans vos pages HTML décrit le contenu de cette page. Un Article, un Product, un LocalBusiness — toujours contextuel, toujours fragmenté. Pour reconstituer la vue d'ensemble de ce qu'une organisation "sait", un crawler doit parcourir des milliers de pages, interpréter des centaines de blocs JSON-LD hétérogènes, et tenter de résoudre les co-références entre entités.
EntityMap prend le problème à l'envers. Au lieu de distribuer les déclarations d'entités à travers le site, vous publiez un fichier centralisé — /.well-known/entitymap.json — qui expose un graphe d'entités complet avec, pour chaque entité, les URLs qui servent de preuve.
Le modèle conceptuel est simple :
- Entity : une chose identifiable (personne, concept, produit, lieu) avec un URI stable (idéalement un Wikidata QID, un DUNS, un ISNI, ou un URI interne).
- Claim : une affirmation que votre organisation fait sur cette entité.
- Evidence : l'URL de la page de votre site qui étaye cette affirmation.
Ce n'est pas un remplacement du schema.org inline. C'est une couche de méta-description au niveau du domaine entier, pensée pour les agents IA qui ont besoin de comprendre l'expertise d'ensemble d'une organisation avant de décider si elle est une source fiable sur un sujet donné.
La philosophie est comparable à celle de robots.txt (déclaratif, à la racine, convention de nommage) ou de llms.txt (un fichier texte qui guide les LLM), mais avec une ambition de granularité bien supérieure grâce au format JSON-LD et à l'ancrage dans le web sémantique.
Anatomie d'un fichier entitymap.json
La spécification (encore en draft au moment de l'écriture) s'appuie sur JSON-LD avec le vocabulaire schema.org étendu par des propriétés spécifiques. Voici un exemple concret pour un éditeur SaaS spécialisé en cybersécurité avec un catalogue de 3 000 articles de blog et 45 pages produit :
{
"@context": [
"https://schema.org",
{
"entitymap": "https://entitymap.org/ns/",
"claims": "entitymap:claims",
"evidence": "entitymap:evidence",
"confidence": "entitymap:confidence",
"topicAuthority": "entitymap:topicAuthority"
}
],
"@type": "entitymap:EntityMap",
"publisher": {
"@type": "Organization",
"@id": "https://cyberguard.io/#organization",
"name": "CyberGuard",
"url": "https://cyberguard.io",
"sameAs": [
"https://www.wikidata.org/wiki/Q119283746",
"https://www.linkedin.com/company/cyberguard-io"
]
},
"dateModified": "2026-05-30T14:22:00Z",
"entities": [
{
"@type": "DefinedTerm",
"@id": "https://www.wikidata.org/wiki/Q3510521",
"name": "Zero Trust Architecture",
"topicAuthority": "expert",
"claims": [
{
"@type": "entitymap:Claim",
"text": "Zero Trust requires continuous verification of every access request regardless of network location",
"evidence": [
{
"url": "https://cyberguard.io/blog/zero-trust-architecture-complete-guide",
"datePublished": "2025-11-12",
"contentType": "Article"
},
{
"url": "https://cyberguard.io/whitepapers/nist-800-207-implementation",
"datePublished": "2026-01-08",
"contentType": "ScholarlyArticle"
}
]
}
]
},
{
"@type": "Product",
"@id": "https://cyberguard.io/products/sentinel-xdr/#product",
"name": "Sentinel XDR",
"claims": [
{
"@type": "entitymap:Claim",
"text": "Sentinel XDR correlates telemetry from endpoint, network, and cloud in under 200ms",
"evidence": [
{
"url": "https://cyberguard.io/products/sentinel-xdr",
"contentType": "ProductPage"
},
{
"url": "https://cyberguard.io/case-studies/fortune-500-soc-deployment",
"contentType": "Case Study"
}
]
}
]
}
]
}
Quelques points techniques à relever :
- L'ancrage sémantique via
@id: lier chaque entité à un identifiant Wikidata, DBpedia, ou un URI interne stable. C'est ce qui permet la désambiguïsation — "Mercury" n'est pas la même entité si le QID pointe vers la planète ou l'élément chimique. - Le champ
topicAuthority: une auto-déclaration du niveau d'expertise. Les LLM pourront (ou non) en tenir compte. C'est un signal, pas une garantie. - La séparation claim/evidence : chaque affirmation est adossée à une ou plusieurs URLs vérifiables. Un LLM ou un agent peut aller vérifier la source, exactement comme un fact-checker humain.
Implémentation technique : déploiement et automatisation
Servir le fichier via .well-known
Le standard utilise le répertoire .well-known (RFC 8615) — le même mécanisme que security.txt, change-password, ou assetlinks.json pour Android. La configuration serveur est triviale.
Pour Nginx :
location = /.well-known/entitymap.json {
root /var/www/cyberguard.io/public;
default_type application/ld+json;
add_header Cache-Control "public, max-age=86400";
add_header Access-Control-Allow-Origin "*";
add_header X-Robots-Tag "noindex";
}
Le Content-Type: application/ld+json est critique. Sans lui, un parser JSON-LD strict pourrait refuser le fichier. Le header CORS est nécessaire si des outils tiers (validateurs, crawlers d'agence) doivent pouvoir fetch le fichier cross-origin. Et le X-Robots-Tag: noindex évite que le fichier lui-même apparaisse dans les SERPs — ce n'est pas du contenu destiné aux humains.
Génération automatique à partir du CMS
Sur un site de 3 000 articles, maintenir un entitymap.json à la main est impensable. L'approche viable : un script de build qui extrait les entités depuis votre CMS ou votre base de données de contenu.
Voici un exemple en TypeScript pour un site Next.js qui tire ses contenus d'un headless CMS (Strapi, Sanity, ou similaire) :
// scripts/generate-entitymap.ts
import { getAllArticles, getAllProducts } from '../lib/cms-client';
import { writeFileSync } from 'fs';
import { resolve } from 'path';
interface EntityClaim {
'@type': string;
text: string;
evidence: Array<{
url: string;
datePublished?: string;
contentType: string;
}>;
}
interface Entity {
'@type': string;
'@id': string;
name: string;
topicAuthority?: string;
claims: EntityClaim[];
}
async function buildEntityMap(): Promise<void> {
const articles = await getAllArticles(); // retourne ~3000 articles
const products = await getAllProducts(); // retourne ~45 produits
// Regrouper les articles par entité principale (tag/topic)
const entityIndex = new Map<string, Entity>();
for (const article of articles) {
// Chaque article a un champ "primaryEntity" avec un wikidataId
const entityKey = article.primaryEntity?.wikidataId;
if (!entityKey) continue;
if (!entityIndex.has(entityKey)) {
entityIndex.set(entityKey, {
'@type': 'DefinedTerm',
'@id': `https://www.wikidata.org/wiki/${entityKey}`,
name: article.primaryEntity.label,
topicAuthority: computeAuthority(articles, entityKey),
claims: [],
});
}
const entity = entityIndex.get(entityKey)!;
entity.claims.push({
'@type': 'entitymap:Claim',
text: article.metaDescription || article.excerpt,
evidence: [
{
url: `https://cyberguard.io/blog/${article.slug}`,
datePublished: article.publishedAt,
contentType: 'Article',
},
],
});
}
// Ajouter les produits comme entités distinctes
for (const product of products) {
entityIndex.set(product.sku, {
'@type': 'Product',
'@id': `https://cyberguard.io/products/${product.slug}/#product`,
name: product.name,
claims: [
{
'@type': 'entitymap:Claim',
text: product.valueProposition,
evidence: [
{
url: `https://cyberguard.io/products/${product.slug}`,
contentType: 'ProductPage',
},
],
},
],
});
}
const entityMap = {
'@context': [
'https://schema.org',
{
entitymap: 'https://entitymap.org/ns/',
claims: 'entitymap:claims',
evidence: 'entitymap:evidence',
confidence: 'entitymap:confidence',
topicAuthority: 'entitymap:topicAuthority',
},
],
'@type': 'entitymap:EntityMap',
publisher: {
'@type': 'Organization',
'@id': 'https://cyberguard.io/#organization',
name: 'CyberGuard',
url: 'https://cyberguard.io',
},
dateModified: new Date().toISOString(),
entities: Array.from(entityIndex.values()),
};
const outputPath = resolve(process.cwd(), 'public/.well-known/entitymap.json');
writeFileSync(outputPath, JSON.stringify(entityMap, null, 2), 'utf-8');
console.log(`EntityMap generated: ${entityIndex.size} entities, written to ${outputPath}`);
}
function computeAuthority(
articles: Array<{ primaryEntity?: { wikidataId: string } }>,
wikidataId: string
): string {
const count = articles.filter(
(a) => a.primaryEntity?.wikidataId === wikidataId
).length;
if (count >= 20) return 'expert';
if (count >= 5) return 'knowledgeable';
return 'familiar';
}
buildEntityMap().catch(console.error);
Ce script tourne dans le pipeline CI/CD (GitHub Actions, GitLab CI) à chaque déploiement. Le fichier est régénéré, versionné, et servi statiquement. Pas de runtime, pas de latence additionnelle.
Validation et debugging
Avant de pousser en production, validez la structure JSON-LD. Le JSON-LD Playground du W3C reste l'outil de référence pour vérifier l'expansion des contextes. Pour les gros fichiers (le nôtre pèse 2,4 Mo pour 3 000 articles), jq en CLI est plus adapté :
# Vérifier la structure de base
cat public/.well-known/entitymap.json | jq '.entities | length'
# => 847 (entités uniques après regroupement)
# Lister les entités sans wikidataId (à corriger)
cat public/.well-known/entitymap.json | jq '[.entities[] | select(."@id" | startswith("https://www.wikidata.org") | not)] | length'
# => 45 (les produits — normal, ils ont des URIs internes)
# Vérifier que toutes les URLs d'evidence sont en HTTPS
cat public/.well-known/entitymap.json | jq '[.entities[].claims[].evidence[].url | select(startswith("https://") | not)]'
# => [] (aucune URL non-HTTPS — OK)
Scénario concret : un média tech de 12 000 pages
Prenons le cas de TechPulse, un média tech français avec 12 000 articles publiés depuis 2018, couvrant le cloud, la cybersécurité, et l'IA. Leur Knowledge Panel Google est instable — il apparaît sur certaines requêtes brandées mais pas d'autres. Les citations dans les AI Overviews de Google et dans les réponses de Perplexity sont incohérentes : parfois le média est attribué, souvent il est synthétisé sans attribution.
Avant EntityMap :
- 12 000 pages avec du schema.org
Articleen inline, mais sansaboutstructuré sur 80% des articles (les anciens). - Aucun graphe d'entités centralisé. Le knowledge graph interne existe dans la tête du rédacteur en chef, pas dans les données.
- Google Search Console montre 9 200 pages indexées — cohérent. Mais les rich results ne couvrent que 2 100 articles (ceux publiés après la refonte de 2023).
- Screaming Frog détecte 3 400 articles sans aucune donnée structurée JSON-LD.
Implémentation EntityMap :
- Export des 12 000 articles depuis WordPress headless (WPGraphQL).
- Enrichissement automatique : un script NLP (spaCy + Wikidata Lookup API) extrait les entités principales de chaque article et les lie à des QIDs. Taux de match automatique : 73%. Les 27% restants sont revus manuellement par la rédaction sur 3 semaines.
- Regroupement : les 12 000 articles se mappent sur 1 240 entités distinctes. TechPulse a 15+ articles sur 89 d'entre elles →
topicAuthority: "expert". - Le fichier entitymap.json pèse 4,1 Mo. Servi avec gzip, il descend à 380 Ko.
- Déploiement en
.well-known/entitymap.jsonavec les headers appropriés.
Résultat attendu (suivi sur 3 mois) : Ce standard étant encore en phase d'adoption, les résultats directs sur les rankings Google classiques sont nuls — Google n'a pas annoncé de support d'EntityMap. En revanche, l'exercice de structuration a un bénéfice collatéral massif : en mappant chaque article à une entité Wikidata, l'équipe de TechPulse a identifié 340 articles orphelins (sans lien interne thématique), 87 doublons sémantiques (deux articles couvrant la même entité sans canonical croisé), et 12 entités "expert" sans page pillar dédiée.
Ce qui compte ici, ce n'est pas que les LLM lisent le fichier demain. C'est que l'exercice de construire un EntityMap force une hygiène sémantique que la plupart des sites de cette taille n'ont jamais faite.
Relations avec les autres signaux machine-readable
EntityMap ne vit pas dans le vide. Il s'inscrit dans un écosystème croissant de fichiers déclaratifs destinés aux agents IA et aux crawlers.
robots.txt, llms.txt, et maintenant entitymap.json
robots.txt contrôle l'accès — qui peut crawler quoi. llms.txt (proposé par Jeremy Howard, co-fondateur de fast.ai) fournit un résumé textuel de votre site pour les LLM. EntityMap va plus loin : il structure le savoir de votre organisation, pas juste la permission d'accès ou un résumé narratif.
Ces trois fichiers sont complémentaires, pas concurrents :
| Fichier | Fonction | Format | Consumer principal |
|---|---|---|---|
robots.txt |
Contrôle d'accès crawlers | Texte plat | Googlebot, Bingbot |
llms.txt |
Résumé narratif pour LLM | Markdown | ChatGPT, Claude, etc. |
entitymap.json |
Graphe d'entités + preuves | JSON-LD | Agents IA, knowledge graphs |
L'article de Cloudflare sur l'Agent Readiness Score (analysé ici) montre que la capacité d'un site à communiquer avec les agents IA devient un critère de qualité technique mesurable. EntityMap s'inscrit directement dans cette tendance.
Le lien avec le schema.org inline
EntityMap ne remplace pas votre JSON-LD inline. Il le complète. La bonne pratique : chaque page conserve son schema.org contextuel (Article, Product, etc.), et le fichier EntityMap fournit la vue d'ensemble qui relie toutes ces pages entre elles.
Un pattern intéressant consiste à utiliser les mêmes @id dans les deux contextes. Si votre page produit contient :
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"@id": "https://cyberguard.io/products/sentinel-xdr/#product",
"name": "Sentinel XDR",
"description": "Extended Detection and Response platform..."
}
</script>
...et que votre EntityMap déclare la même entité avec le même @id, un agent IA peut faire le lien entre la déclaration centralisée et le contenu de la page. C'est du linked data classique, mais appliqué à un use case nouveau.
Cela rejoint directement les enjeux de lisibilité machine des marques que nous avons explorés dans l'article sur ce qui rend une marque machine-readable pour l'AI search.
Limites et trade-offs — ce qu'EntityMap ne résout pas
Aucun engagement de consommation côté LLM
C'est le point critique. Aujourd'hui, aucun grand modèle de langage (GPT-4o, Claude, Gemini) n'a publiquement annoncé consommer le fichier entitymap.json. Google n'en fait pas mention dans sa documentation Search Central. Le standard est une proposition, portée par Dixon Jones (fondateur d'InLinks, figure reconnue du SEO sémantique), mais il n'a pas encore de RFC formelle ni d'adoption par un agent IA majeur.
Cela ne signifie pas que c'est inutile — la dynamique de robots.txt a suivi le même chemin (convention informelle avant d'être respectée par les crawlers). Mais il faut calibrer vos attentes : déployer EntityMap ne va pas, demain matin, améliorer vos citations dans les AI Overviews.
Le risque du fichier obèse
Pour un e-commerce de 50 000 SKUs, chacun mappé à des entités (marques, catégories, matériaux, normes), le fichier peut facilement dépasser 20 Mo. Même compressé, c'est un payload non trivial. La spécification ne prévoit pas de mécanisme de pagination ou de Sitemap-style split. C'est une lacune que la communauté devra adresser.
Une solution pragmatique : segmenter par sous-domaines ou par section du site, avec un fichier index :
{
"@type": "entitymap:EntityMapIndex",
"maps": [
{ "url": "https://cyberguard.io/.well-known/entitymap-blog.json" },
{ "url": "https://cyberguard.io/.well-known/entitymap-products.json" },
{ "url": "https://cyberguard.io/.well-known/entitymap-docs.json" }
]
}
Ce pattern n'est pas dans la spec actuelle, mais il est cohérent avec la logique des sitemaps index et sera probablement nécessaire pour les gros sites.
L'auto-déclaration d'expertise
Le champ topicAuthority est une auto-déclaration. Rien n'empêche un site spam de se déclarer "expert" sur n'importe quel sujet. Les consommateurs du fichier devront croiser cette déclaration avec des signaux externes (backlinks, mentions, E-E-A-T classique). C'est un signal parmi d'autres, pas une preuve.
La maintenance continue
Un EntityMap qui dérive de la réalité du site est pire que pas d'EntityMap du tout. Si vous supprimez 200 articles lors d'un content pruning et que les URLs d'evidence pointent toujours vers des 404, vous envoyez un signal de négligence aux agents qui vérifient les preuves.
C'est exactement le type de régression silencieuse qu'un outil de monitoring comme Seogard peut détecter automatiquement : des URLs référencées dans vos données structurées qui retournent un 404 ou un soft 404, sans que personne dans l'équipe ne s'en rende compte.
Stratégie d'adoption : quand et comment déployer
Pour qui c'est pertinent maintenant
- Sites avec une forte couverture thématique (médias, bases de connaissances, SaaS avec un blog éditorial conséquent) : l'exercice de structuration a une valeur intrinsèque, même sans consommation par les LLM.
- Organisations qui investissent déjà dans le knowledge graph interne : si vous avez une taxonomie d'entités (via InLinks, WordLift, ou un système custom), la génération d'EntityMap est quasi-gratuite.
- Early adopters qui veulent être prêts quand les agents IA commenceront à consommer ce type de fichier — et les signaux vont dans ce sens, comme le montrent les annonces de Google I/O 2026 sur la convergence search/agents/tools.
Pour qui c'est prématuré
- Sites de moins de 100 pages : le ratio effort/bénéfice est défavorable. Concentrez-vous sur votre schema.org inline et vos bases.
- Sites sans taxonomie d'entités : si vous ne savez pas quelles entités votre site couvre, commencez par ce travail de fond avant de penser au fichier de sortie.
Checklist de déploiement
- Inventorier vos entités principales via un crawl Screaming Frog + extraction des
aboutetmentionsdans votre JSON-LD existant. - Enrichir avec des identifiants Wikidata (l'API Wikidata Search est gratuite et bien documentée : https://www.wikidata.org/w/api.php).
- Regrouper les articles par entité et évaluer la couverture.
- Générer le fichier via un script de build intégré au CI/CD.
- Servir avec les bons headers (cf. config Nginx ci-dessus).
- Monitorer que les URLs d'evidence restent valides — un check hebdomadaire automatisé est le minimum.
Ce que cela signifie pour la visibilité IA en 2026
EntityMap est un pari sur l'avenir de la découverte d'information. Le postulat sous-jacent : les agents IA vont de plus en plus chercher à comprendre qui sait quoi avant de décider quelle source citer. Ce n'est plus une question de ranking sur 10 liens bleus, mais de visibilité dans un écosystème de réponses générées.
Les démonstrations de Google I/O 2026 (analysées ici) ont montré que le problème de visibilité des marques dans l'AI search est réel et croissant. Un fichier déclaratif qui dit "voici nos entités, voici nos preuves" ne résoudra pas tout, mais il pose les fondations d'une communication structurée entre votre site et les systèmes qui synthétisent l'information.
Le standard est jeune, les consommateurs sont rares, et les bénéfices immédiats sont surtout collatéraux (hygiène sémantique, détection de lacunes éditoriales). Mais l'histoire du SEO technique nous enseigne que les standards déclaratifs finissent par s'imposer quand ils résolvent un vrai problème — et la question "comment les agents IA découvrent-ils l'expertise d'un domaine ?" est un vrai problème. Déployez EntityMap comme vous auriez déployé schema.org en 2014 : sans attendre la preuve de ROI immédiat, mais avec la rigueur technique qui garantit que le jour où les agents le lisent, votre fichier est irréprochable.