Как нейроответ Яндекса выбирает источники: прогнал 60 запросов через Search API и посчитал, что как

от автора

Наш любимый доходяга Яндекс частенько показывает вверху выдачи готовый ответ и ссылается в нём на три‑четыре сайта. При этом по такому же запросу в обычной выдаче сотни, а то и тысячи страниц. Позвольте спросить, по какому такому принципу нейроответ отбирает из этих сотен именно те самые избранные, которые собирают весь куш? Я решил проверить свои (бестолковые) гипотезы на реальных данных.

Гипотез, к слову, у меня хватало, проверенных цифр не было ни одной. Поэтому я собрал небольшой стенд, прогнал через него запросы по одной нише и посмотрел, что реально попадает в цитаты. Конкретная ниша тут вторична, методика повторяется на любой другой. Ниже разберу код, цифры и пару мест, где споткнулся, упал и разбил коленку.

Сразу про масштаб. Это одна ниша и всего 60 обращений, так что на вселенскую истину я не претендую, хотя очень хотелось бы. Но даже на таком объёме картинка получилась на удивление устойчивой, пусть и не такой, как мнение Греты Тунберг обо всём на свете.

Что такое нейроответ с точки зрения API

Сгенерированный ответ, который пользователь видит сверху выдачи, программно доступен через Yandex Search API в режиме generative. Работает он иначе, чем «голая» языковая модель в чате: сначала ищет по вебу, потом синтезирует ответ из найденного и возвращает список источников, на которые опирался. Именно этот список меня и интересовал.

Аналитики «Ашманова и сами знаете кого» описывают механику так: нейроответ попеременно задействует большую языковую модель и обычный органический поиск. Модель делает несколько запросов в поиск, отбирает страницы и синтезирует из них ответ. Значит, ссылки в ответе указывают на конкретные страницы из поиска, модель их не выдумывает.

Технически запрос уходит на эндпоинт /v2/gen/search. В ответ приходит текст и массив ссылок, на которые модель оперлась. Отвечает сервис долго, до пары минут, и это чувствуется: под капотом действительно идёт поиск и синтез. Первый прогон я поставил с таймаутом 30 и потерял половину запросов по этому самому таймауту, пришлось поднимать до 200 секунд.

Как я замерял

Логика стенда простая. Берём один и тот же набор запросов, прогоняем несколько раз, сохраняем сырые ответы вместе со списком источников, потом считаем частоты. Прогонять один раз смысла никакого, потому что ответ немного плавает от запуска к запуску. Я гонял каждый запрос по три итерации.

import requestsdef yandex_gen_search(query: str, folder_id: str, api_key: str) -> dict:    url = "https://searchapi.api.cloud.yandex.net/v2/gen/search"    payload = {        "messages": [{"content": query, "role": "ROLE_USER"}],        "folderId": folder_id,        "search_type": "SEARCH_TYPE_RU",    }    headers = {"Authorization": f"Api-Key {api_key}"}    r = requests.post(url, json=payload, headers=headers, timeout=200)    r.raise_for_status()    return r.json()

Дальше из ответа надо вытащить домены источников. Тут вылезли две мелочи, на которые я убил больше времени, чем на сам запрос. Первая: один и тот же сайт приходит то с www., то без него, и без нормализации эти штуки считаются двумя разными доменами. Вторая: на паре запросов массив источников оказывался пустым, потому что модель отвечала общими словами, без ссылок. Такие ответы я просто пропускал, чтобы не занижать частоты.

from collections import Counterfrom urllib.parse import urlparsedomains = Counter()for resp in all_responses:                 # сохранённые JSON-ответы    for src in resp.get("sources", []):        host = urlparse(src["url"]).netloc.replace("www.", "")        if host:                           # пустые/битые ссылки пропускаем            domains[host] += 1for host, n in domains.most_common(10):    print(f"{host:24} {n}")

Двадцать запросов по нише на три итерации дают 60 обращений. Всё сырьё я складывал в JSON на диск, чтобы пересчитывать метрики без новых обращений к API. Он платный, и дёргать его лишний раз ради опечатки в скрипте не хочется.

Что оказалось в данных

Картина получилась устойчивее, чем я ожидал. В топ цитируемых доменов по нише стабильно попадали площадки одного класса: крупные тематические блоги, агрегаторы и медиа.

Отдельно бросилось в глаза вот что. Сайты самих компаний из ниши в цитаты почти не попадали. Зато попадали площадки, где про эти компании написано. Чтобы тебя процитировали, свой сайт помогает мало, а внятная статья про тебя на крупной площадке работает хорошо.

Закономерность: цитируется то, что и так в топе органики

Самое интересное обнаружилось в связке с обычной выдачей. Я сверил процитированные URL с органическим топом по тем же запросам, и пересечение оказалось высоким: подавляющее большинство цитат приходит из верхней части обычной выдачи Яндекса по запросу.

То есть нейроответ не строит свой рейтинг с нуля, а берёт то, что уже считается релевантным в классическом поиске, и собирает из этого пула синтез. Чтобы попасть в нейроответ, сначала нужно попасть в топ органики. Дальше решает, насколько страница удобна для пересказа: есть ли там конкретика, структура, факты, которые модель может выдернуть и сжать.

Это сходится с замером «Ашманова и Ко»: за полгода доля сайтов не из топ‑10 Яндекса в ответах нейропоиска упала с 40% до 10%. Со временем нейроответ всё сильнее опирается именно на органический топ.

Что из этого следует и где я мог ошибиться

Если коротко, наблюдений три. На самом деле было семь, но четыре выкипели, пока я писал этот текст.

Первое. «Попасть в нейроответ» — никакая не отдельная магия. Это следствие нормального попадания в топ органики плюс структурности текста. Топ работает как необходимое условие, дальше решает пересказуемость.

Второе. Для большинства тем в цитаты чаще выходят площадки‑доноры: медиа, блоги, агрегаторы. Собственный лендинг проигрывает им вчистую. Если про вас написано на такой площадке, шанс попасть в цитату выше.

Третье. Список доноров устойчив. Один и тот же набор площадок всплывает из раза в раз, значит, его можно замерить и работать прицельно.

Теперь честно про дыры в методике, потому что их хватает. Ниша всего одна, и на другой тематике расклад доноров наверняка будет свой. Выборка маленькая: 60 обращений сглаживают шум, но доверительный интервал я на них не построю. Мерил я через API, а не парсил живую выдачу браузером, поэтому нет гарантии, что gen/search на 100% совпадает с тем, что видит пользователь в вебе. Так что это гипотеза с цифрами, которую ещё предстоит проверять на большем объёме.

Дальше интересно масштабировать: прогнать несколько разных ниш одним стендом и посмотреть, пересекаются ли списки доноров между тематиками или у каждой ниши свой замкнутый пул площадок. Если у вас есть свои наблюдения по отбору источников в нейроответах, поделитесь в комментариях, любопытно сверить картинку на других данных.

ссылка на оригинал статьи https://habr.com/ru/articles/1055922/