Коротко. Schema.org-разметка не поднимает позиции и не «подключает» сайт к ИИ. Она делает страницу однозначной для машины: называет тип сущности, автора, дату и связи между узлами через @id. Для попадания в ИИ-ответы решают три вещи: разметка совпадает с видимым текстом, узлы связаны в один граф, дублей нет. Разметка, противоречащая тексту, вредит сильнее, чем её отсутствие.
Что разметка даёт ИИ-движку, а чего не даёт
У страницы два канала описания. Первый — видимый текст: заголовки, абзацы, таблицы. Он работает всегда и у всех потребителей. Второй — JSON-LD внутри <script type="application/ld+json">. Он работает только там, где его читают, и это принципиально разные ситуации.
Разделите потребителей по механике доступа:
- Индексные движки. Ответ собирается поверх поискового индекса. Структурированные данные в этот индекс попадают: их разбирает тот же конвейер, что готовит расширенные сниппеты. Здесь JSON-LD читается почти наверняка.
- Собственные индексы ассистентов. Бот обходит сайт, сохраняет HTML целиком и складывает во внутренний индекс. Разметка сохраняется вместе с остальным HTML, но что именно из неё используется при генерации ответа — публично не описано ни одним вендором.
- Живая загрузка по ссылке. Пользователь дал ассистенту URL, тот скачал страницу и превратил HTML в текст. Здесь всё зависит от экстрактора: типовые библиотеки очистки контента выбрасывают содержимое
scriptцеликом — вместе с JSON-LD.
Из третьего пункта следует практический вывод, который экономит недели работы: если факт важен — он должен быть в видимом тексте. Дата обновления, имя автора, цена, шаги инструкции, единицы измерения. Разметка дублирует и уточняет эти факты для машины, но не заменяет их. Как именно ассистенты превращают HTML в текст, разбираем в материале как ИИ-краулеры читают сайты и в гайде по извлекаемости контента.
Разметка — не рычаг ранжирования, а способ снять неоднозначность. Страница без разметки, но с чистым текстом и внятной структурой, цитируется чаще, чем страница с идеальным JSON-LD и кашей в вёрстке.
Доступ ботов — отдельная тема со своими решениями: она разобрана в соседней статье про robots.txt и ИИ-ботов. Разметка бесполезна, если бота не пустили на страницу.

Какие типы разметки реально влияют на извлекаемость
В словаре Schema.org больше восьмисот типов. На обычном сайте работающих — меньше десяти. Остальное либо не поддерживается потребителями, либо описывает сущности, которых у вас нет.
Article, BlogPosting, TechArticle — атрибуция и свежесть
Article — базовый тип, BlogPosting и TechArticle — его подтипы. Разница не косметическая: подтип точнее описывает жанр, а значит помогает отличить обзорный пост от технической инструкции. Обязательный минимум для любого из них:
headline— совпадает с видимым заголовком страницы. Исторически Google рекомендовал держать его коротким (порядка сотни символов); длинный заголовок обрезается.datePublishedиdateModified— в формате ISO 8601 с часовым поясом.author— узелPersonилиOrganizationс собственным@idиurl, а не строка.publisher— ссылка на узел организации.mainEntityOfPage— ссылка на узелWebPage, чтобы статья и страница не выглядели двумя разными сущностями.
Формулировки заголовков и описаний — отдельная дисциплина, она в материале про title и description.
HowTo и FAQPage — самые цитируемые и самые рискованные
Оба типа отдают модели готовые фрагменты: пронумерованные шаги и пары «вопрос — ответ». Это буквально тот формат, в котором ассистент хочет выдать ответ, поэтому такие блоки цитируются охотнее прочих.
Честная оговорка: по объявлениям Google 2023 года показ FAQ-расширенных результатов сократили до узкого круга авторитетных ресурсов, а HowTo-сниппеты свернули. Это не повод снимать разметку — машиночитаемая структура остаётся, а расширенный сниппет никогда не был единственной целью. Но и ждать от FAQPage «звёздочек в выдаче» больше не стоит.
Главная ошибка на практике одна и та же: FAQPage стоит на странице, где никакого FAQ нет, — блок сгенерировал шаблон CMS «на всякий случай». Это прямое нарушение правил по структурированным данным.
Product, Offer, AggregateRating — где начинается риск ручных мер
Product с Offer — нормальная разметка карточки товара: цена, валюта, наличие, срок действия предложения. Проблемы начинаются с AggregateRating: агрегированный рейтинг без реальных, видимых на странице отзывов — одна из самых частых причин ручных санкций.
Показательный случай из практики: на главной одного проекта долго стоял aggregateRating с красивыми цифрами — рейтингом и количеством отзывов, которые не подтверждались ни одной видимой публикацией. Формально валидатор молчал. Блок вырезали при аудите: выгоднее не размечать ничего, чем размечать то, чего на странице нет.
Organization, WebSite, BreadcrumbList — скелет сайта
Эти три типа отличаются от остальных тем, что описывают не текст страницы, а сам сайт, и потому не требуют контентной поддержки:
Organization— узел бренда:name,url,logo,sameAsсо ссылками на подтверждаемые профили. К нему крепятся все статьи черезpublisher.WebSite— узел сайта, к нему черезisPartOfкрепятся страницы.BreadcrumbList— иерархия; единственный тип, который почти всегда стоит ставить на каждой вложенной странице.
| Тип | Где ставить | Что даёт машине | Чем рискуете |
|---|---|---|---|
| Article / BlogPosting / TechArticle | Статьи, гайды, новости | Автор, даты, жанр, атрибуция источника | Расхождение headline и H1; штампованная дата |
| HowTo | Пошаговые инструкции | Шаги как упорядоченный список | Шагов в разметке больше, чем на странице |
| FAQPage | Реальный блок вопрос-ответ | Готовые пары для дословной цитаты | Разметка без видимого FAQ — нарушение |
| Product / Offer | Карточка товара | Цена, валюта, наличие | Цена в разметке не совпадает с ценой на странице |
| AggregateRating | Только при видимых отзывах | Сводная оценка | Ручные меры за выдуманный рейтинг |
| Organization | Каждая страница (один узел) | Идентификация бренда, sameAs | Разные @id на разных страницах — «разные бренды» |
| WebSite | Каждая страница | Привязка страниц к сайту | Дубли узла в нескольких блоках |
| BreadcrumbList | Любая вложенная страница | Иерархия и контекст раздела | Порядок position не совпадает с видимыми хлебными крошками |
Что из разметки читают ИИ-движки, а что только поисковые роботы
Публичной спецификации «какой движок какие поля читает» не существует — ни один вендор её не публикует. Но механику доступа разложить можно, и этого достаточно для проектных решений.
| Механизм | Как получает страницу | Видит ли JSON-LD | Что решает исход |
|---|---|---|---|
| Поисковый индекс | Штатный обход поискового робота | Да — разбирается конвейером индексации | Точные типы, связный граф, sameAs |
| Собственный индекс ассистента | Обход ботом ИИ-сервиса, HTML сохраняется | Скорее да, но использование не документировано | Полнота HTML без JS-рендера, доступность для бота |
| Живая загрузка по ссылке | Пользователь дал URL ассистенту | Часто нет: экстрактор выбрасывает script | Видимый текст, заголовки, порядок блоков |
| Обучающий обход | Массовая выкачка в корпус | Данные попадают в корпус целиком | Ничего не гарантирует для конкретного ответа |
Проектируйте разметку так, будто её прочитает только половина потребителей. Тогда вторая половина ничего не потеряет — а первая получит бонус.
Зачем нужен @id и почему разрозненные узлы хуже связанных
@id — устойчивый идентификатор узла в графе. Узел без @id анонимен: парсер не может понять, что автор этой статьи и человек со страницы «Об авторе» — одно лицо, а издатель здесь и издатель на соседней странице — одна организация.
Три следствия отсутствия @id:
- Дубли сущностей. Каждая страница порождает новую «организацию» с тем же именем. Вместо одного сильного узла — сотня слабых.
- Нет переиспользования. Издателя приходится описывать заново в каждом блоке, поля со временем расходятся: где-то логотип старый, где-то имя с другой пунктуацией.
- Ломается склейка бренда. Без общего
@idиsameAsу машины нет оснований считать упоминания одной сущностью.
Правильная форма — один блок JSON-LD на страницу с контейнером @graph, где узлы ссылаются друг на друга по @id:
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#organization",
"name": "Example",
"url": "https://example.com/",
"logo": {
"@type": "ImageObject",
"@id": "https://example.com/#logo",
"url": "https://example.com/logo.png",
"width": 512,
"height": 512
},
"sameAs": [
"https://www.wikidata.org/wiki/Q00000000"
]
},
{
"@type": "WebSite",
"@id": "https://example.com/#website",
"url": "https://example.com/",
"name": "Example",
"publisher": { "@id": "https://example.com/#organization" },
"inLanguage": "ru-RU"
},
{
"@type": "WebPage",
"@id": "https://example.com/guide/schema/#webpage",
"url": "https://example.com/guide/schema/",
"name": "Разметка для ИИ-поиска",
"isPartOf": { "@id": "https://example.com/#website" },
"breadcrumb": { "@id": "https://example.com/guide/schema/#breadcrumb" },
"datePublished": "2026-03-04T09:00:00+03:00",
"dateModified": "2026-08-11T14:20:00+03:00"
},
{
"@type": "TechArticle",
"@id": "https://example.com/guide/schema/#article",
"headline": "Разметка для ИИ-поиска",
"description": "Какие типы Schema.org влияют на извлекаемость.",
"datePublished": "2026-03-04T09:00:00+03:00",
"dateModified": "2026-08-11T14:20:00+03:00",
"author": { "@id": "https://example.com/team/ivanov/#person" },
"publisher": { "@id": "https://example.com/#organization" },
"mainEntityOfPage": { "@id": "https://example.com/guide/schema/#webpage" },
"proficiencyLevel": "Expert",
"inLanguage": "ru-RU"
},
{
"@type": "Person",
"@id": "https://example.com/team/ivanov/#person",
"name": "Иван Иванов",
"url": "https://example.com/team/ivanov/",
"jobTitle": "SRE",
"worksFor": { "@id": "https://example.com/#organization" }
},
{
"@type": "BreadcrumbList",
"@id": "https://example.com/guide/schema/#breadcrumb",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Главная",
"item": "https://example.com/" },
{ "@type": "ListItem", "position": 2, "name": "Гайды",
"item": "https://example.com/guide/" },
{ "@type": "ListItem", "position": 3, "name": "Разметка для ИИ-поиска" }
]
}
]
}
Соглашения, которые стоит зафиксировать в команде один раз:
@id— абсолютный URL с фрагментом:#organization,#website,#webpage,#article,#person,#breadcrumb. Фрагмент делает идентификатор уникальным и при этом человекочитаемым.- Идентификатор организации — один на весь сайт и никогда не меняется. Смена
@idравносильна появлению нового бренда. - Повторная ссылка на узел — это
{ "@id": "..." }без дублирования полей. - Один блок с
@graphна страницу лучше, чем шесть независимых блоков: связи внутри одного блока очевидны, между блоками — нет.

Как выглядит разрыв графа: разбор реального случая
На одном из проектов, который мы разбирали, на странице каталога оказалось два узла CollectionPage: их вставляли два разных места шаблона — общий слой и блок раздела. Имена отличались, @id не было ни у одного:
[
{
"@context": "https://schema.org",
"@type": "CollectionPage",
"name": "Инструменты",
"url": "https://example.com/tools/"
},
{
"@context": "https://schema.org",
"@type": "CollectionPage",
"name": "Все проверки сайта — каталог инструментов",
"url": "https://example.com/tools/"
}
]
Формально это не ошибка: валидатор такое пропускает зелёным. Фактически парсер получает две сущности с одним URL и разными именами и вынужден выбирать, какое из описаний считать настоящим. Ни один из вариантов не усиливается — они конкурируют друг с другом. Починка простая: свести к одному узлу с @id, а имя брать из одного источника — того же, что рисует видимый H1.
Второй случай из той же серии: у всех статей блога тип был Article. Он валиден и безопасен, поэтому такое живёт годами. Но Article — самый безликий вариант: он не отличает пошаговую инструкцию от обзора и от справочной заметки. После того как определение типа переписали — гайды в TechArticle, пошаговые в HowTo, обзорные в BlogPosting, — в данных появилась жанровая разница, которой раньше просто не было.
Валидатор не ловит смысловые ошибки. Два узла без @id, безликий тип, дата обновления из времени сборки — всё это проходит проверку зелёным и всё это ухудшает данные.
Типовые ошибки разметки: симптом, причина, проверка, фикс
| Симптом | Причина | Как проверить | Фикс |
|---|---|---|---|
| Валидатор зелёный, эффекта ноль | Разметка не подтверждается видимым текстом | Сравнить headline с H1, поля — с содержимым страницы | Свести к одному источнику данных в шаблоне |
| Две сущности на одну страницу | Несколько блоков без @id из разных мест шаблона | Выгрузить все узлы командой из следующего раздела | Один блок с @graph, у каждого узла @id |
| FAQ-разметка ничего не даёт | FAQPage на странице без видимого FAQ | Поискать текст вопроса в HTML страницы | Либо убрать разметку, либо добавить реальный блок |
dateModified всегда «сегодня» | Дата берётся из времени сборки или запроса | Сверить с заголовком Last-Modified и историей правок | Писать дату фактического изменения текста |
| Блок игнорируется целиком | Невалидный JSON: висячая запятая, «умные» кавычки из визуального редактора | Прогнать через парсер (см. CI-гейт ниже) | Никогда не редактировать JSON-LD в WYSIWYG |
| Автор не распознаётся | "author": "Иван Иванов" строкой вместо узла | Проверить тип значения поля | Узел Person с @id и url |
| Валидатор видит ноль узлов | Разметку вставляет клиентский JS после загрузки | Сравнить исходный HTML (curl) и DOM в браузере | Рендерить разметку на сервере |
| Бренд распознаётся как несколько разных | Разные @id организации на разных страницах, нет sameAs | Сверить @id организации на трёх-четырёх страницах | Один @id и один набор sameAs на весь сайт |
| Разметка пропала после релиза | Шаблон перевыпустили без блока, никто не заметил | Проверка в CI на каждый деплой | Гейт, который валит сборку при пустом графе |

Как проверить разметку: команды и валидаторы
Начните с того, что реально отдаёт сервер, а не с того, что видно в браузере: разница между ними — самая частая причина «разметка есть, но её не видят».
Выгрузка всех узлов со страницы с типами и идентификаторами:
curl -sSL -A 'Mozilla/5.0 (compatible; audit/1.0)' https://example.com/guide/schema/ \
| python3 -c '
import sys, re, json
html = sys.stdin.read()
pat = r"<script[^>]*application/ld\+json[^>]*>(.*?)</script>"
blocks = re.findall(pat, html, re.S | re.I)
print("blocks:", len(blocks))
for i, b in enumerate(blocks, 1):
try:
data = json.loads(b)
except json.JSONDecodeError as e:
print(i, "BROKEN JSON:", e)
continue
nodes = data.get("@graph", [data]) if isinstance(data, dict) else data
for n in nodes:
print(i, n.get("@type"), "|", n.get("@id") or "NO @id")
'
Если blocks: 0, а в браузере разметка видна — её дорисовывает JavaScript. Для ботов, которые не выполняют скрипты, такой разметки не существует.
Сверка заголовка и даты между разметкой, видимым текстом и заголовками ответа:
# видимый H1
curl -sSL "$URL" | tr -d '\n' | grep -o '<h1[^>]*>[^<]*' | sed 's/.*>//'
# headline из разметки
curl -sSL "$URL" | python3 -c '
import sys, re, json
html = sys.stdin.read()
for b in re.findall(r"ld\+json[^>]*>(.*?)</script", html, re.S):
d = json.loads(b)
for n in (d.get("@graph", [d]) if isinstance(d, dict) else d):
if "headline" in n:
print(n["headline"], "|", n.get("dateModified"))
'
# что о свежести говорит сам сервер
curl -sSI "$URL" | grep -i '^last-modified'
И гейт для CI, который валит сборку, если на странице битый JSON или узлы без идентификаторов:
curl -sSL "$URL" | python3 -c '
import sys, re, json
html = sys.stdin.read()
bad = 0
found = 0
for b in re.findall(r"ld\+json[^>]*>(.*?)</script", html, re.S):
try:
d = json.loads(b)
except Exception as e:
print("BROKEN JSON:", e)
bad += 1
continue
for n in (d.get("@graph", [d]) if isinstance(d, dict) else d):
found += 1
if "@id" not in n:
print("NO @id:", n.get("@type"))
bad += 1
if found == 0:
print("NO STRUCTURED DATA AT ALL")
bad += 1
sys.exit(1 if bad else 0)
' && echo "schema OK"
Из внешних инструментов работают два: валидатор Schema.org — проверяет соответствие словарю без привязки к требованиям конкретной поисковой системы, и тест расширенных результатов Google — показывает, какие фичи поддерживаются именно им. Первый строже к словарю, второй — к требованиям конкретных сниппетов; они не заменяют друг друга.
Как проверить на enterno.io
- Проверка Schema.org-разметки — вытаскивает все блоки JSON-LD со страницы, показывает типы, идентификаторы и синтаксические ошибки ровно так, как их увидит парсер.
- Проверка готовности к ИИ — оценивает страницу комплексно: доступность для ботов, структуру, разметку, наличие карты контента.
- SEO-аудит — заголовки, единственность
H1, канонические адреса, метаописания. - Проверка HTTP-заголовков —
Last-Modified, кэширование, редиректы: если страница отдаётся с неожиданным статусом, разметка не дойдёт ни до кого. - Проверка robots.txt — убедиться, что страница вообще открыта для ботов.
- Мониторинг — чтобы узнать о пропаже разметки после релиза не через месяц из отчёта, а сразу.
Чего разметка не даёт
Список короткий, но его стоит прочитать до того, как закладывать разметку в план работ:
- Не поднимает позиции. Структурированные данные — не фактор ранжирования. Они меняют представление и понимание, а не вес документа.
- Не гарантирует сниппет. Показ расширенных результатов — решение поисковой системы, а не следствие корректного JSON-LD.
- Не заменяет текст. Если факта нет на странице, его нет и для тех потребителей, кто отбрасывает
script. - Не защищает контент. Ни от копирования, ни от использования в обучении моделей — это область robots.txt и серверных правил.
- Не чинит недоступность. Закрытая в robots.txt страница, отдача 403 боту или разметка, дорисованная клиентским JS, обнуляют всю работу.
- Не даёт «места в ИИ-выдаче». Такого места не существует: ответ собирается заново на каждый запрос.
Если задача звучит как «внедрить разметку, чтобы попасть в ИИ-ответы» — задача поставлена неверно. Верная постановка: «сделать страницу однозначной для машины и убедиться, что машина до неё доходит».

Чеклист перед деплоем
- Разметка — JSON-LD, отдаётся сервером в исходном HTML, не дорисовывается скриптом.
- Один блок на страницу, внутри —
@graph. - У каждого узла есть
@id; идентификатор организации одинаков на всех страницах. - Основной тип соответствует жанру страницы, а не выбран «по умолчанию».
headlineсовпадает с видимымH1; описание не противоречит первому абзацу.datePublishedиdateModified— реальные даты в ISO 8601, а не время сборки.authorиpublisher— узлы, а не строки; у автора есть страница на сайте.- Каждое поле подтверждено видимым содержимым: нет FAQ в разметке без FAQ на странице, нет рейтинга без отзывов, нет шагов без шагов.
- JSON валиден: проверка стоит в CI и валит сборку.
- Страница открыта для ботов и отдаётся со статусом 200 без JS-рендера.
Частые вопросы
Обязательна ли разметка, чтобы попасть в ИИ-ответ?
Нет. Ассистенты цитируют страницы без всякой разметки — им хватает чистого текста и внятных заголовков. Разметка повышает шанс, что вас поймут правильно: жанр, автора, дату, принадлежность бренду. Это про качество понимания, а не про допуск.
JSON-LD, microdata или RDFa?
JSON-LD. Он отделён от вёрстки, поэтому не ломается при редизайне, легко валидируется и переиспользует узлы через @id. Microdata цепляется за конкретные теги и умирает при первой же переработке шаблона. RDFa на обычных сайтах встречается редко и поддерживается хуже.
Сколько блоков разметки можно поставить на страницу?
Технически — сколько угодно, парсеры собирают их вместе. Практически один блок с @graph надёжнее: связи между узлами внутри одного блока очевидны, а несколько блоков из разных мест шаблона — прямая дорога к дублям без @id.
Нужен ли FAQPage, если расширенные результаты по нему почти не показывают?
Нужен, если FAQ на странице реально есть. Пары «вопрос — ответ» остаются самым удобным для цитирования форматом независимо от того, рисует ли поисковая система сниппет. Если FAQ нет — разметку ставить нельзя.
Что писать в dateModified?
Дату фактического изменения текста. Дата, которая меняется на каждой пересборке, обесценивает сигнал: если «обновлено сегодня» стоит на всех страницах сайта, это не отличает обновлённые материалы от нетронутых.
Помогает ли sameAs?
Это единственный дешёвый способ явно сказать машине, что бренд на вашем сайте и профиль в другом источнике — одна сущность. Ссылки в sameAs должны вести на страницы, которые действительно вам принадлежат и подтверждаемы; произвольный список ссылок сигналом не является.
Считается ли разметка, которую вставляет скрипт?
Только теми потребителями, которые выполняют JavaScript. Поисковые роботы это умеют с отложенным рендерингом, большинство ИИ-краулеров — нет. Разметку, добавленную на клиенте, надёжнее считать несуществующей.
Что дальше: структурированные данные и SEO — про обычную выдачу и расширенные сниппеты; как проверить разметку — пошаговая проверка; robots.txt и ИИ-боты — доступ для краулеров; llms.txt — карта контента для моделей; чеклист готовности к ИИ-поиску и GEO — стратегический слой.