Для одного из клиентов собрал упоминания бренда в ответах ChatGPT. Как обычно — на 20 вопросов, но теперь тремя разными способами. Бренд без подсказки прозвучал на одном вопросе из 19 в первом съёме и ни разу в двух других. А теперь к деталям.
Что я измерял и на каких вопросах
Раньше я описывал общую схему замера видимости бренда в ответах шести нейросетей. Здесь только ChatGPT. Данные взяты из мониторинга, который я собирал для одного из клиентов: ему помогали растить видимость в ответах ИИ-моделей. ChatGPT я снял трижды за одну неделю, каждый раз новым способом и на одних и тех же 20 вопросах. Вопросы из одной ниши, продвижения бизнеса в нейросетях, от «где заказать» и «сколько стоит» до «как сделать, чтобы нейросети рекомендовали мой бренд». В 19 вопросах имени бренда клиента нет. Двадцатый брендовый и сравнительный: «бренд X или конкурент Y — кто лучше».
Каждый ответ ложится в JSON-лог: текст, признак поиска, источники, отметки об упоминании бренда и шести конкурентов, дефекты записи. Конкурентов я отобрал по ответам Алисы AI и Perplexity. Лог заполняет парсер, мой код, который вытаскивает из текста ответа ссылки и имена. От мониторинга мне нужны были доля ответов, где ИИ-модель называет бренд без подсказки, и список сайтов, на которые она опирается.
Задумано было просто. На деле мониторинг несколько раз врал не потому, что врёт ChatGPT, а потому, что врал мой парсер.
Три способа снять ответы ChatGPT на одних 20 вопросах

API — программный доступ к ИИ-моделям OpenAI: запрос отправляет код, ответ приходит в виде данных для программы. Два съёма из трёх шли через шлюз, платного посредника к API OpenAI со своим балансом. Интерфейс, то есть обычное окно чата, я снимал поштучно через сторонний сервис.
первый съём (API) | второй (интерфейс) | третий (API) | |
|---|---|---|---|
Как снят | через шлюз | окно чата, поштучно через сторонний сервис | через шлюз |
ИИ-модель | gpt-4o, поиск опцией | та, что отвечает в интерфейсе | gpt-5.5, поиск инструментом |
Запросов | 60 (20 × 3 повтора) | 20 (по одному) | 60 (20 × 3) |
Ответов | 60 | 20 | 43, ещё 17 запросов вернули ошибку 402 |
Признак поиска | не записан, поле пустое у всех 60 | неизвестен, такого поля нет | поиск отработал в 33 из 43 |
Ответов с источниками | 37 из 60 | 19 из 20 | 33 из 43 |
Медиана длины ответа | 1 497 знаков | 5 137 знаков | 3 935 знаков |
Цена ответа | 25–36 ₽ через шлюз | 10 ₽ | 25–36 ₽ через шлюз |
Ошибка 402 в третьем съёме значит, что у шлюза кончились деньги на балансе. Баланс иссяк посреди прогона, все 17 ошибок пришлись на третий повтор, и он потерян целиком.
Поиск опцией и поиск инструментом — два способа подключить ИИ-модели веб-поиск через API. У gpt-4o поиск включался параметром запроса web_search_options: ИИ-модель сама решает, искать ли, а по ответу не видно, искала ли она. Отсюда пустое поле признака у всех 60 записей первого съёма, хотя источники есть в 37 ответах. У этих источников нет и пометки, пришли они от API или вытащены из текста ответа, так что ответ из поиска по такому логу не отличить от ответа по памяти даже там, где ссылки есть. У gpt-5.5 поиск подключён инструментом: вызов поиска и ссылки-аннотации приходят отдельными полями ответа, и их можно проверить. Как это устроено, описано в документации OpenAI о веб-поиске в API.
ИИ-модели в двух API-съёмах разные, gpt-4o в первом и gpt-5.5 в третьем. Эти два столбца я считаю порознь и динамику между ними не ищу. Медианы 1 497 и 3 935 знаков по двум точкам тоже не объяснить: разницу могла дать смена ИИ-модели, смена механизма поиска или случай на небольшой выборке.
В третьем съёме поиск отработал в 33 ответах из 43. На трёх вопросах ChatGPT не вышел в поиск ни в одном повторе: «как заказать аудит видимости бренда в нейросетях», «как управлять репутацией компании в ответах ИИ» и «можно ли гарантировать попадание в ответы нейросети». Ещё у четырёх вопросов поиск отработал не во всех повторах. Всего в логе 10 записей с дефектом «поиск не отработал».
Как часто ChatGPT называет бренд без подсказки
первый съём (API) | второй (интерфейс) | третий (API) | |
|---|---|---|---|
ответов на 19 небрендовых вопросов | 1 из 57 | 0 из 19 | 0 из 41 |
небрендовых вопросов, где бренд прозвучал хотя бы раз | 1 из 19 | 0 из 19 | 0 из 19 |
ответов на брендовый вопрос | 3 из 3 | 1 из 1 | 2 из 2 |
Единственное небрендовое упоминание — в первом съёме: вопрос про аудит видимости, один ответ из трёх повторов. ChatGPT сослался в нём на статью бренда клиента о ручной проверке видимости. На брендовом вопросе имя звучит во всех ответах, его задаёт сам вопрос. Ответ из интерфейса на него вышел длиной 27 098 знаков, с таблицей сравнения.
Число 57 здесь означает 19 вопросов, каждый из которых снят трижды. По ответам доля выходит 1 из 57, меньше 2%. По вопросам 1 из 19: хотя бы раз бренд прозвучал на одном вопросе из девятнадцати. Данные одни и те же, а цифры отличаются в три раза.
Шесть отслеживаемых конкурентов ChatGPT назвал хоть раз только в 3 ответах из 43 третьего съёма. Других игроков на коммерческих вопросах он называет. Кого именно, по этим логам не сказать: лог отмечает только бренд и шестёрку, отобранную по ответам Алисы AI и Perplexity.
Интерфейс и API ChatGPT на одних вопросах: 17 общих доменов из 49 и 68

После исправленного разбора ссылок-иконок второй съём, через интерфейс, дал 49 доменов-источников по всем 20 вопросам, третий, через API, дал 68. Общих доменов у них 17. Из 12 вопросов, где источники нашлись у обоих способов, в 6 не совпал ни один домен.
Одно это число ещё не доказывает, что дело в способе: источники меняются и между повторами одного способа. Поэтому я пересчитал те же логи парами ответов. Метрика — доля общих доменов в паре: общие домены делятся на все домены пары, суммарно по вопросам, где источники есть у обоих ответов. Служебные домены вроде google.com, openai.com и bing.com исключены одинаково во всех трёх парах.
Пара ответов | Вопросов | Общих / всех доменов | Доля общих | Вопросов без общих |
|---|---|---|---|---|
третий съём (API): повтор 1 против повтора 2 | 9 | 14 / 61 | 23% | 1 |
первый съём (API): повтор 1 против повтора 2 | 12 | 38 / 93 | 41% | 1 |
второй (интерфейс) против третьего (API), только повтор 1 | 8 | 8 / 70 | 11% | 3 |
Общих доменов у интерфейса и API вдвое меньше, чем у двух повторов самого API: 11% против 23%. Сравнение нечистое: интерфейс и API-съём отличаются сразу тремя вещами, способом съёма, ИИ-моделью и числом ответов на вопрос. Число ответов я выровнял, взяв из API только первый повтор, 20 ответов против 20. Способ и ИИ-модель на этих данных не разделить. В парах по 8–12 вопросов, так что это порядок величины, а не точная оценка.
Внутри одного способа список источников тоже плывёт. Даже у двух повторов первого съёма общих меньше половины доменов, и целиком список от повтора к повтору почти не совпадает. ИИ-модели в первом и третьем съёмах разные, так что 41% и 23% между собой я не сравниваю.
По восьми коммерческим вопросам я сверил оба способа с Алисой AI, ответы которой снимал в день третьего съёма. У Алисы AI на этих вопросах 39 доменов. Интерфейс ChatGPT дал 30, общих с Алисой 7. API дал 40, общих тоже 7. Каким способом ни снимай, с Алисой AI ChatGPT делит меньше четверти своих доменов. На вопросе «кто в России делает GEO-продвижение под ключ» (GEO — продвижение в ответах нейросетей) общих доменов нет совсем.
Вопрос p001, «как сделать, чтобы нейросети рекомендовали мой бренд», я смотрел отдельно: на нём ChatGPT объясняет, как попасть в его же ответы. Интерфейс сослался на bing.com, blogs.bing.com и help.openai.com. API в третьем съёме ссылался на developers.google.com четыре раза, на help.openai.com три раза и на support.google.com дважды. Отвечает он по документации OpenAI, Google и Bing, в том числе по рекомендациям Bing для вебмастеров. У OpenAI есть и страница о роботах, которые ходят по сайтам: GPTBot, OAI-SearchBot и ChatGPT-User.
Что ломает подсчёт источников в логах ChatGPT

В ответах из интерфейса источники приходят картинками-иконками: . Это сервис иконок Google: по адресу сайта он отдаёт его значок, фавикон, который браузер показывает на вкладке. Сам адрес спрятан в параметре domain= в закодированном виде, %3A вместо двоеточия и %2F вместо косой черты. Я проверил: на такой запрос сервис перенаправляет на gstatic.com/faviconV2. В 20 ответах второго съёма таких иконок оказалось 82.
Мой парсер брал любой адрес в круглых скобках. Так было:
import re def source_urls(text: str) -> list[str]: # так было: ловит и ссылки, и картинки-иконки return re.findall(r"\((https?://[^\s\)]+)\)", text)
Выражение ловит и ссылки, и картинки. Повторы одного адреса внутри ответа парсер отбрасывал, и из 82 иконок уникальных внутри своих ответов осталось 32. Все 32 легли в список источников как google.com: это 32 записи из 120, примерно каждая четвёртая, и иконки входят в эти 120.
Так стало:
import re from urllib.parse import urlparse, parse_qs, unquote def source_domains(answer: str) -> set[str]: """Домены источников из markdown-ответа, включая ссылки-иконки.""" domains = set() for url in re.findall(r"https?://[^\s)\]\"']+", answer): parts = urlparse(url) host = (parts.hostname or "").removeprefix("www.") if host == "google.com" and parts.path.startswith("/s2/favicons"): inner = unquote(parse_qs(parts.query).get("domain", [""])[0]) host = (urlparse(inner).hostname or inner).removeprefix("www.") if host: domains.add(host) return domains
Функция берёт любую ссылку и отдельно проверяет адреса сервиса иконок. Если хост google.com, а путь начинается с /s2/favicons, настоящий домен достаётся из параметра domain= и раскодируется. Без этой проверки иконки сливаются в один google.com, к ответу отношения не имеющий. Этой функцией и считаются источники интерфейса: отдельного поля с источниками, как у API, у него нет, есть только текст ответа.
Сторонний сервис съёма добавил своё расхождение. В 20 ответах он насчитал 382 ссылки, а в тексте тех же ответов видно 120, и расходятся цифры в 14 ответах из 20. Чей счётчик правее, я разбираться не стал: сервис мог считать ссылки из разметки вне текста или дублировать одну и ту же ссылку. Лог пишет это отдельным дефектом, «сервис насчитал N ссылок, в тексте видно M», и число сервиса на веру не берёт.
В третьем съёме, через API, на том же p001 в источники попали ваш-домен.ru, example.com и schema.org. Это домены из примеров кода и шаблонов внутри самого ответа, поиск такие страницы не открывал. Чёрный список доменов тут не спасает: сегодня example.com, завтра что-то ещё. Поэтому в API-съёме поиск засчитывается по источникам, которые пришли от API, и по его служебным полям: вызовам поиска и ссылкам-аннотациям, которые API прикладывает к ответу отдельно от текста. Медиана таких аннотаций в ответе третьего съёма равна 4.
def search_performed(channel_type, sources, extra): if channel_type == "model_bare": # канал без поиска return False if extra.get("search_calls") or extra.get("api_annotations"): return True if any(s.get("origin") == "api" for s in sources): return True # ссылка пришла от API, а не из текста if channel_type == "surface": # интерфейс отвечает поверх выдачи, return None # но подтверждения нет — «неизвестно» return False
Канал без поиска сразу получает False. Если API сообщил о вызовах поиска, приложил аннотации или хотя бы один источник помечен как пришедший от него, функция возвращает True. Ответ из интерфейса отдельного подтверждения не несёт, и для него функция возвращает None, то есть неизвестно. Три вопроса третьего съёма, где ChatGPT ни разу не вышел в поиск, не проходят ни одну проверку на True и получают False. В лог они уходят с дефектом «поиск не отработал».
Ошибки 402 из третьего съёма в логе записаны как ошибки. Запиши я их как ответы без бренда, ноль по бренду вырос бы на 17 записей, за которыми нет ни одного ответа.
Что мониторинг ChatGPT показывает и чего не показывает
На этих логах мониторинг показывает, как часто ChatGPT называет бренд без подсказки и на какие сайты опирается в ответе. Что увидит конкретный человек в окне чата, он не показывает: общих источников у API с интерфейсом вдвое меньше, чем у API с собственным повтором, а сам интерфейс снят одним ответом на вопрос. Одиночный ответ тоже ничего не доказывает: единственное небрендовое упоминание бренда клиента прозвучало в одном повторе из трёх.
Для кода мониторинга я вынес отсюда такие правила:
Один способ съёма на ряд. Интерфейс и API в одну цифру не смешиваю: подпись «доля упоминаний в ChatGPT» без способа съёма прячет два разных числа. Цена у выбора такая. Интерфейс стоит 10 ₽ за ответ и ближе к окну чата, но признака поиска у него нет. API через шлюз обходится в 25–36 ₽, признак поиска и источники приходят отдельными полями, но по источникам он расходится с окном чата. Какой из двух брать для ряда, три съёма одной недели не решают.
Счёт по вопросам при фиксированном числе повторов. 1 из 57 по ответам и 1 из 19 по вопросам получены из одних данных. Повтор показывает, устойчив ли ответ, и не добавляет вопросу веса, поэтому считаю по вопросам. Доля вопросов, где бренд прозвучал хотя бы раз, растёт с числом повторов, поэтому число повторов на вопрос я фиксирую и пишу рядом с цифрой. Ошибки вроде 402 идут отдельной строкой и в ноль не попадают.
Источники API-съёма берутся из поля API. Регулярное выражение по тексту ответа ловит иконки и примеры кода, поэтому в API-съёме в подсчёт идёт то, что API отдаёт отдельным полем. У интерфейса такого поля нет: его источники считаются по тексту с разбором иконок, как в
source_domains, а признак поиска остаётся неизвестным. Число ссылок от стороннего сервиса на веру не беру ни там, ни там.Серия повторов на каждый вопрос. Два повтора одного API-съёма делят 23% доменов в третьем съёме и 41% в первом, поэтому вывод я строю по нескольким запускам.
Эти правила пригодятся как вопросы к любому отчёту о видимости в ChatGPT: каким способом сняты ответы, считалась доля по вопросам или по ответам, сколько было повторов на вопрос и куда ушли ошибки. Без этих подписей одна и та же выборка даёт и 1 из 57, и 1 из 19. Нормальный отчёт отвечает так: один способ съёма на весь ряд, доля по вопросам, число повторов указано рядом с цифрой, ошибки вынесены отдельной строкой.
