Skip to content
EN
← Все статьи

Schema.org для AI-поиска: типы, @id и частые ошибки

Коротко. Schema.org-разметка не поднимает позиции и не «подключает» сайт к ИИ. Она делает страницу однозначной для машины: называет тип сущности, автора, дату и связи между узлами через @id. Для попадания в ИИ-ответы решают три вещи: разметка совпадает с видимым текстом, узлы связаны в один граф, дублей нет. Разметка, противоречащая тексту, вредит сильнее, чем её отсутствие.

Что разметка даёт ИИ-движку, а чего не даёт

У страницы два канала описания. Первый — видимый текст: заголовки, абзацы, таблицы. Он работает всегда и у всех потребителей. Второй — JSON-LD внутри <script type="application/ld+json">. Он работает только там, где его читают, и это принципиально разные ситуации.

Разделите потребителей по механике доступа:

  • Индексные движки. Ответ собирается поверх поискового индекса. Структурированные данные в этот индекс попадают: их разбирает тот же конвейер, что готовит расширенные сниппеты. Здесь JSON-LD читается почти наверняка.
  • Собственные индексы ассистентов. Бот обходит сайт, сохраняет HTML целиком и складывает во внутренний индекс. Разметка сохраняется вместе с остальным HTML, но что именно из неё используется при генерации ответа — публично не описано ни одним вендором.
  • Живая загрузка по ссылке. Пользователь дал ассистенту URL, тот скачал страницу и превратил HTML в текст. Здесь всё зависит от экстрактора: типовые библиотеки очистки контента выбрасывают содержимое script целиком — вместе с JSON-LD.

Из третьего пункта следует практический вывод, который экономит недели работы: если факт важен — он должен быть в видимом тексте. Дата обновления, имя автора, цена, шаги инструкции, единицы измерения. Разметка дублирует и уточняет эти факты для машины, но не заменяет их. Как именно ассистенты превращают HTML в текст, разбираем в материале как ИИ-краулеры читают сайты и в гайде по извлекаемости контента.

Разметка — не рычаг ранжирования, а способ снять неоднозначность. Страница без разметки, но с чистым текстом и внятной структурой, цитируется чаще, чем страница с идеальным JSON-LD и кашей в вёрстке.

Доступ ботов — отдельная тема со своими решениями: она разобрана в соседней статье про robots.txt и ИИ-ботов. Разметка бесполезна, если бота не пустили на страницу.

Два канала описания страницы: видимый текст и JSON-LD, и три типа потребителей
Видимый текст читают все потребители, JSON-LD — только часть из них. Отсюда правило: важное дублируется в тексте.

Какие типы разметки реально влияют на извлекаемость

В словаре 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:

  1. Дубли сущностей. Каждая страница порождает новую «организацию» с тем же именем. Вместо одного сильного узла — сотня слабых.
  2. Нет переиспользования. Издателя приходится описывать заново в каждом блоке, поля со временем расходятся: где-то логотип старый, где-то имя с другой пунктуацией.
  3. Ломается склейка бренда. Без общего @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 на страницу лучше, чем шесть независимых блоков: связи внутри одного блока очевидны, между блоками — нет.
Граф сущностей: организация, сайт, страница, статья, автор и хлебные крошки связаны через @id
Связный граф: один узел организации, к которому крепятся сайт, страницы и статьи. Без @id вместо графа получается россыпь анонимных узлов.

Как выглядит разрыв графа: разбор реального случая

На одном из проектов, который мы разбирали, на странице каталога оказалось два узла 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 на каждый деплойГейт, который валит сборку при пустом графе
Разбор типовых ошибок разметки: дубли узлов, разметка без контента, штампованная дата
Три ошибки, которые валидатор считает нормой: дубли без @id, FAQPage без FAQ и dateModified из времени сборки.

Как проверить разметку: команды и валидаторы

Начните с того, что реально отдаёт сервер, а не с того, что видно в браузере: разница между ними — самая частая причина «разметка есть, но её не видят».

Выгрузка всех узлов со страницы с типами и идентификаторами:

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, поля подтверждены видимым текстом, узлы связаны одним графом.

Чеклист перед деплоем

  • Разметка — 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 — стратегический слой.

Проверить Schema.org-разметку страницы →

Проверьте ваш сайт прямо сейчас

Проверить SEO своего сайта →
Другие статьи: SEO
SEO
Open Graph: как настроить превью ссылки в Telegram, VK и соцсетях
21.07.2026 · 476 просм.
SEO
Sitemap XML: структура карты сайта, лимиты, генерация и проверка
16.03.2026 · 398 просм.
SEO
SEO-аудит сайта: чеклист из 20 пунктов
14.03.2026 · 225 просм.
SEO
Цепочки редиректов: как они влияют на SEO и скорость
11.03.2026 · 206 просм.