Финал серии. К первой статье GEO vs SEO вы, вероятно, пришли с вопросом «ну и что мне конкретно делать с сайтом»; вторая дала словарь метрик (Метрики AI-видимости), третья — технику и приоритет гигиены (llms.txt и краулеры), четвёртая — автоматический счётчик того, что модель реально говорит (Трекинг бренда в LLM). Здесь всё это сводится в один прогон: аудит — это не ещё один дашборд, а чек-лист, который вы прогоняете скриптом и который заканчивается приоритизированным списком «что править первым».
Главный честный тезис всей статьи, и он же — вывод серии: «полезно модели» почти полностью совпадает с «полезно человеку и quality-SEO», но не тождественно ему. Аудит нужен ровно чтобы поймать те несколько пунктов, где они расходятся, — и не потратить вечер на правки, которые моделью всё равно не считываются. Ниже: трёхслойная рамка (доступность → извлекаемость → видимость), готовый PHP-скрипт, который проверяет первые два слоя автоматически и подхватывает третий из снимка четвёртой статьи, формат отчёта и правило приоритизации.
Все числа в примерах — иллюстрации на условных данных, домены условные (example.test); реальные значения зависят от вашей ниши и движков.
Часть I. Рамка: три слоя, и порядок проверок не произволен
GEO-аудит — это не чек-лист «включите schema, включите llms.txt». Это конвейер из трёх слоёв, каждый из которых — условие следующего. Проверять их не по порядку — типичная ошибка: мерить «почему меня не цитируют», когда вас в принципе не ползают.
| Слой | Вопрос | Чем проверяется | Это статья |
|---|---|---|---|
| 1. Доступность (crawlability) | Доступен ли ваш контент ботам, из которых собирается ответ | robots.txt, HTTP-статусы, server-render | №3 + скрипт ниже |
| 2. Извлекаемость (extractability) | Можно ли из вашей страницы вытащить утверждение и указать источник | заголовки-тезисы, самодостаточные абзацы, schema, числа/даты | №3 + №2 |
| 3. Видимость (visibility) | Что модели в итоге говорят про вас и ссылаются ли | трекер: 4-way события, prominence, SoV | №4 |
Слой 3 — это то, что вы не можете починить прямо из админки: модель может узнавать о вас из чужих обзоров (Часть IV первой статьи). Но слои 1 и 2 целиком на вашей стороне, и они детерминированы: если retrieval-бот закрыт или текст рендерится за JS, вас физически нет в candidate-пуле, и никакой «креативный контент-план» не поможет. Поэтому аудит и идёт снизу вверх: сначала убедиться, что вы можете быть процитированы, потом — хотят ли вас цитировать.
Формально слои соотносятся так: слой 1 — бинарный (открыт/закрыт), слой 2 — оценочный (насколько страница удобна для извлечения), слой 3 — статистический (доли и интервалы из метрик). Аудит склеивает их в один отчёт: «закрыто» → красный флаг; «плохо извлекается» → жёлтый; «не виден при открытом и извлекаемом» → это уже задача не к редактору, а к third-party-присутствию.
Часть II. Слой 1 — доступность: проверяем, что вас ползают
Здесь почти всё уже разобрано в третьей статье; для аудита важно не пересказывать, а превратить в проверяемые утверждения с бинарным исходом:
- A1. Отдают ли серверы
/robots.txt,/sitemap.xml,/llms.txt(последний — опционален, и отсутствие не красный флаг; красный — когда он есть и вводит в заблуждение). - A2. Открыты ли retrieval-боты (
OAI-SearchBot,PerplexityBot,Claude-SearchBotи др.) — это главный рубильник: одинDisallow: /для всех вырезает вас из ответов. Разделение «обучение»/«ответ» — сердце Части IV третьей статьи. - A3. Рендерится ли основной текст на сервере (а не только за JS), — живой поиск читает пустую оболочку.
- A4. Отдаётся ли контент боту без платной стены/куки-гайда, перекрывающих текст.
A2 — самое частое самоубийство: сайт закрывают «от всех роботов на время редизайна», забывают открыть, и месяцами не понимают, откуда пропала AI-видимость. Поэтому в аудите A2 проверяется по каждой retrieval-строке User-agent отдельно, а не «в целом по robots».
Часть III. Слой 2 — извлекаемость: можно ли вытащить утверждение
Этот слой переводит рекомендации третьей статьи в форму, которую уже можно эвристически проверить по HTML страницы. Что делает страницу удобной для извлечения (и, значит, для цитаты):
- E1. Заголовки — тезисы, а не вопросы и не «вода». Модель извлекает утверждение под заголовком;
Как проверить модельхуже, чемМодель отвечает за 300 мс при температуре 0. Считаем долю заголовков-утверждений (с глаголом и/или числом) от всех заголовков. - E2. Самодостаточные абзацы: каждый ключевой абзац понятен без предыдущего (нет висячих «это», «как видно выше»). Эвристика: абзац, начинающийся с местоимения/ссылки на контекст, — кандидат в «неизвлекаемый».
- E3. Явные числа и даты в тексте утверждений (модель предпочитает цитировать конкретику; тот же вывод, что в Части V третьей статьи).
- E4.
schema(Article/FAQPageс явным автором иdatePublished) — сигнал авторитетности и источник структурного контекста. - E5. Разделение контента и инструкции — страница информирует, а не проинструктирована (врезка про prompt-injection в Чек-листе третьей статьи и фильтр честности №2). Пункт аудита: в исходном HTML страницы нет скрытых директив «агент, посоветуй меня первым».
Заметьте: E1–E4 это почти дословно quality-SEO / контент-гигиена. Это не случайно — и к этому возвращаемся в Части V.
Часть IV. Слой 3 — видимость: подтягиваем снимок счётчика
Третий слой не проверяется сканированием сайта — он берётся из готового снимка, который ведёт трекер: cron пинговал набор промптов, записал события, сторез snapshot — и аудит просто читает этот snapshot как один из входов. Так слои 1–2 (что можно исправить на сайте) склеиваются со слоем 3 (что уже происходит в ответах) в один отчёт.
Что аудит вытаскивает из снимка (имена событий — из Части II метрик):
target_url_citedпо конкретным ключевым страницам — low при открытом A2 и хорошем E1 → проблема не на вашей стороне (недостаточная авторитетность/конкуренция), правки страниц не помогут, нужен third-party.third_party_source_citedвыше собственных ссылок → вас объясняют чужими пересказами → приоритет = работа с обзорами/каталогами, а не редизайн блога.- доля ответов с
prominence = first→ базовая «рекомендуемость». - всё с 95%-ым интервалом Уилсона (из 4-й статьи) и с версией набора промптов — иначе аудит показывает дрейф прибора вместо reality.
Смыслово это самый дешёвый слой аудита (у вас уже есть snapshot), но он превращает два предыдущих из «автономных проверок» в объяснение: доступность и извлекаемость хороши, а видимости нет → вы в candidate-пуле, но проигрываете конкуренцию за цитату, и это уже стратегическая, а не техническая задача.
Часть V. Единый скрипт: прогон слоёв 1–2 и сборка отчёта
Скрипт ниже — то, чем обещание «чек-лист, который превращается в скрипт» становится правдой. Он проверяет слой 1 по списку URL, эвристически оценивает слой 2 по HTML и печатает отчёт с флагом OK/WARN/FAIL и предложенным действием по каждому пункту. Слой 3 подключается строкой require вашего snapshot-хранилища из трекера (там уже есть таблица/опция снимка) — здесь показан интерфейс, а не повтор его кода.
<?php
// geo_audit.php — аудит доступности+извлекаемости; слой видимости из snapshot трекера.
// Запуск: php geo_audit.php https://example.test /путь/к/снимку.json
// Эвристики грубые: аудит даёт гипотезы и приоритет, не приговор.
$base = $argv[1] ?? 'https://example.test';
$snapPath = $argv[2] ?? null;
$pages = ['', '/blog', '/docs', '/about']; // ключевые шаблоны страниц
function fetch(string $url, int $timeout = 8): array {
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_TIMEOUT => $timeout,
CURLOPT_USERAGENT => 'GeoAudit/1.0',
]);
$body = (string) curl_exec($ch);
$code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return [$code, $body];
}
$rows = [];
// --- Слой 1A: отдают ли инфраструктурные пути ---
foreach (['/robots.txt', '/sitemap.xml', '/llms.txt'] as $p) {
[$code,] = fetch($base . $p);
$ok = $code === 200;
$rows[] = ['A1', $p, $ok ? 'OK' : ($code === 404 ? 'WARN' : 'FAIL'),
$ok ? '' : ($p === '/llms.txt' ? 'факультативно' : 'проверить отдачу')];
}
// --- Слой 1A/1E: retrieval-боты открыты? ---
[$rc, $robots] = fetch($base . '/robots.txt');
$retrieval = ['OAI-SearchBot', 'PerplexityBot', 'Claude-SearchBot'];
foreach ($retrieval as $bot) {
$blocked = false; $named = false;
if ($rc === 200 && $robots) {
foreach (preg_split('/\n\s*\n/', $robots) as $blk) {
if (preg_match('/user-agent:\s*' . preg_quote($bot, '/') . '\b/i', $blk)) {
$named = true;
if (preg_match('/disallow:\s*\/\s*$/im', $blk)) { $blocked = true; }
}
}
}
$rows[] = ['A2', $bot,
$blocked ? 'FAIL' : ($named ? 'OK' : 'WARN'),
$blocked ? 'открыть в robots.txt — вырезает из ответов'
: ($named ? '' : 'нет явного блока — проверить микс директив')];
}
// --- Слой 1C/2: текст на сервере + извлекаемость по ключевым страницам ---
foreach ($pages as $pg) {
[$code, $html] = fetch($base . $pg);
if ($code !== 200 || $html === '') {
$rows[] = ['A3', $pg, 'FAIL', 'страница не отдаётся боту'];
continue;
}
// server-render proxy: есть ли substantial text в <body>, а не только каркас
$textLen = 0;
if (preg_match('~<body\b[^>]*>(.*?)</body>~is', $html, $m)) {
$textLen = strlen(trim(strip_tags($m[1])));
}
$rendered = $textLen > 800 ? 'OK' : 'FAIL';
// E1: доля заголовков-тезисов (есть глагол-маркер или число)
preg_match_all('/<h[1-3][^>]*>(.*?)<\/h[1-3]>/is', $html, $hs);
$hCount = count($hs[1]); $thesis = 0;
foreach ($hs[1] as $h) {
$t = trim(strip_tags($h));
if ($t === '') continue;
if (preg_match('/\d/', $t) || preg_match('/\b(есть|являет|работает|делает|стоит|нужно|важен|нравится|составляет|падает|растёт)/iu', $t)) {
$thesis++;
}
}
$e1 = $hCount ? sprintf('%.0f%%', 100 * $thesis / $hCount) : '—';
// E4: schema
$hasSchema = (stripos($html, 'application/ld+json') !== false
|| preg_match('/itemtype=[^>]*Article/i', $html) || preg_match('/FAQPage/i', $html));
// E5: подозрение на скрытую инструкцию агенту
$suspectInstruction = (bool) preg_match('/ignore\s+(previous|all)|системн\w+\s+под\w*каз|prompt\s*inject/iu', $html);
$rows[] = ['A3', $pg, $rendered, $rendered === 'OK' ? '' : 'рендерить текст на сервере'];
$rows[] = ['E1', $pg, ($hCount && $thesis / $hCount < 0.6) ? 'WARN' : 'OK', "доля тезисов: $e1"];
$rows[] = ['E4', $pg, $hasSchema ? 'OK' : 'WARN', $hasSchema ? '' : 'добавить Article/FAQPage'];
$rows[] = ['E5', $pg, $suspectInstruction ? 'FAIL' : 'OK',
$suspectInstruction ? 'убрать директивы агенту — риск демупа и prompt-injection' : ''];
}
// --- Слой 3: снимок из трекера (интерфейс, не повтор кода) ---
if ($snapPath && is_readable($snapPath)) {
$snap = json_decode((string) file_get_contents($snapPath), true);
// ожидаем ключи из geo-treking: url_cited_pct, third_party_pct, prominence_first_pct, n
if (is_array($snap)) {
$rows[] = ['S3', 'url_cited', ($snap['url_cited_pct'] ?? 0) < 15 ? 'WARN' : 'OK',
sprintf('deep-link %s%% из %d ответов', $snap['url_cited_pct'] ?? '?', $snap['n'] ?? 0)];
$rows[] = ['S3', 'third_party', ($snap['third_party_pct'] ?? 0) > ($snap['url_cited_pct'] ?? 0) ? 'WARN' : 'OK',
'вас чаще цитируют чужие — см. third-party'];
}
}
// --- Отчёт, отсортированный по приоритету: FAIL > WARN > OK ---
$rank = ['FAIL' => 0, 'WARN' => 1, 'OK' => 2];
usort($rows, fn($a, $b) => $rank[$a[2]] <=> $rank[$b[2]]);
printf("GEO-аудит %s\n%s\n", $base, str_repeat('=', 60));
foreach ($rows as [$sec, $target, $flag, $note]) {
printf("%-3s %-22s %-5s %s\n", $sec, $target, $flag, $note);
}
$fail = count(array_filter($rows, fn($r) => $r[2] === 'FAIL'));
$warn = count(array_filter($rows, fn($r) => $r[2] === 'WARN'));
printf("\nИтог: FAIL %d · WARN %d · OK %d. Начинать сверху списка (FAIL по слоям 1–2).\n",
$fail, $warn, count($rows) - $fail - $warn);Скрипт нарочито эвристический и честен в этом: реальная оценка server-render и «самодостаточности абзаца» сложнее одной регулярки, как и разбор robots.txt. Это не «приговор сайту», а генератор приоритетного списка гипотез: он за минуту отделяет «вас физически не ползают» (красный A2 — чинится одним редактором robots.txt) от «вас читают, но неудобно извлекать» (жёлтый E1/E4) и от «вас читают и цитируют чужие» (жёлтый S3/third_party — это уже не скрипт правит). Прогоняйте его по своим ключевым шаблонам страниц; pages подставьте реальные пути, а в retrieval добавьте ботов, актуальных на момент прогона (списки меняются — сверяйте по источнику, как в №3).
Как выглядит отчёт (условный вывод, иллюстрация формата):
GEO-аудит https://example.test
============================================================
A2 PerplexityBot FAIL открыть в robots.txt — вырезает из ответов
A3 /docs FAIL страница не отдаётся боту
E5 / FAIL убрать директивы агенту — риск демупа и prompt-injection
A1 /sitemap.xml WARN проверить отдачу
E1 /blog WARN доля тезисов: 41%
E4 /about WARN добавить Article/FAQPage
S3 third_party WARN вас чаще цитируют чужие — см. third-party
A2 OAI-SearchBot OK
...
Итог: FAIL 3 · WARN 4 · OK 6. Начинать сверху списка (FAIL по слоям 1–2).
Верх списка и есть «что править первым»: сначала FAIL по доступности (дешевле всего, сильнее всего бьёт), потом FAIL по честности (E5), затем WARN по извлекаемости, и только в конце — стратегические WARN слоя 3, которые скриптом не чинятся.
Часть VI. Где GEO совпадает с quality-SEO, а где расходится — и приоритет
Тезис серии, до которого мы дошли: почти весь аудит — это то, что вы и так делаете в хорошем SEO, только теперь это читает ещё и синтезирующий движок. Полезно не «для ИИ», полезно человеку, который через ИИ; механика извлечения просто награждает ровно те качества, что награждали и люди.
| Пункт аудита | В SEO | В GEO | Расхождение |
|---|---|---|---|
| Интент, качество, авторитет | да | то же | нет |
schema Article/FAQPage | полезно | полезно (структурный контекст) | нет |
| Заголовки-тезисы, самодостаточные абзацы | полезно людям | критично для извлечения | усилено |
| Числа и даты в утверждениях | полезно | модель предпочитает конкретику | усилено |
| Server-render основного текста | полезно | обязательно (живой поиск читает HTML) | уникально |
| Разделение retrieval/training-ботов | нет аналога | главный рубильник | уникально |
Директивы агенту в тексте (E5) | неактуально | риск prompt-injection / демупы | уникально и опасно |
Практический вывод: не нужно осваивать отдельную «GEO-профессию» — аудит в основном обслуживает то, что уже умеет SEO-специалист. Уникальны ровно три вещи: открыть retrieval-ботов, убедиться, что текст рендерится на сервере, и не засовывать в страницу инструкции агента. Всё остальное — quality-SEO, которое теперь ещё и цитируется.
Правило приоритизации: влияние × выполнимость, а не «всё сразу»:
- FAIL по A2 (закрыт retrieval-бот) — огромное влияние, правка за минуту. Делать первым, всегда.
- FAIL по A3/E5 — влияние высокое, выполнимость средняя (редизайн рендера/очистка текста). Вторым.
- WARN по E1/E4 (извлекаемость) — влияние среднее, выполнимость растянутая (переписывать статьи неделями). Идти точечно по топ-страницам, не по всему блогу.
- WARN по S3 (видимость/third-party) — часто не решается сайтом вообще; это отдельная стратегическая задача (обзоры, каталоги, упоминания — см. №1), и в тех же правках редактора не нуждается.
Перепутать порядок 1 и 4 — типовая ошибка: «оптимизировать контент», когда вас не ползают, или «чинить third-party», когда deep-link низкий из-за закрытого бота. Отчёт, отсортированный по флагу и слою, эту ошибку не даёт совершить.
Инструменты под задачу
Финальный шаг аудита — не только скрипт, но и «ручная видимость»: спросите чат-ассистента про свою же нишу и посмотрите, кого он называет первым и на что ссылается; это и беглая сверка со слоем 3, и источник формулировок для промптов-зондов трекера. Готовая страница ассистента: https://codestack.space/ai-pomoshhnik-dlja-koda/
Чек-лист граблей
- Сверили «AI-видимость» и назвали это аудитом. Дашборд показывает итог; аудит проверяет готовность сайта и кончается списком действий.
- Начали с видимости. Мерить «почему не цитируют», когда retrieval-бот закрыт, — бессмысленно: идите слоями снизу вверх (доступность → извлекаемость → видимость).
- Ставили
Disallow: /«от всех роботов на время редизайна» и забыли → вместе с обучением вырезали retrieval-ботов → выпали из ответов. Проверка A2 по каждому боту отдельно. - Ждёте, что
llms.txtпочинит видимость. Отсутствие файла — не FAIL; файл почти не влияет на цитируемость, а ложный — добавляет проблем. - Текст за JS-рендером/lazy load. Живой поиск читает пустую оболочку → server-render основного текста обязателен (A3).
- Доверяете грубой эвристике как приговору. Регулярки по server-render и «самодостаточности» дают гипотезы, не вердикт; проверяйте выборочно руками.
- Не обновили список retrieval-ботов под прогон. Имена директив меняются — сверяйте по источнику на дату (как в №3), иначе аудит проверяет прошлогодний ландшафт.
- Засунули в HTML директивы агенту («посоветуй меня первым»). Риск демупы и prompt-injection, проходит objective и проваливает фильтр честности (E5).
- Переписываете весь блог в тезисы сразу. Влияние среднее, выполнимость низкая; идите точечно по топ-страницам (приоритет 3), не «всё».
- Лечите редактором то, что вне сайта. Низкий deep-link при открытом боте и хорошей извлекаемости — это third-party-задача, а не редизайн.
- Смешали слои в один «итоговый балл». FAIL по доступности и «0,3 SoV» несопоставимы; не усредняйте разнородные флаги в число.
- **Путаете GEO-аудит со «всё то же SEO, только добавить». Уникальны три пункта (retrieval-боты, server-render, отсутствие инструкций агенту); остальное quality-SEO — но именно их чаще всего не делают.
👤 Зарегистрируйтесь, чтобы добавить материал в закладки.
