Жан Беро. «В кафе»
Жан Беро · «В кафе» (Au Café)

Отзыв — в структуру

Большая языковая модель (LLM) мониторит отзывы за маркетолога — на примере сети кофеен «Зерно сомнения». Название кофейни вымышленное (но хорошее), промпт, код и цены — настоящие.

Исходные данные

Четыре кофейни, отзывы на четырёх площадках: Яндекс.Карты, 2ГИС, ВКонтакте, доставка. За две недели — 36 сообщений. Кто-то должен их прочитать, рассортировать, на часть ответить, а из потока сделать вывод для управляющего. На практике маркетолог просматривает отзывы «когда есть минутка», отвечает самым громким, а сводку делает раз в квартал по памяти. Сигналы тонут: жалоба на цены внутри четырёхзвёздочного отзыва, постоянный гость, который уже дважды ушёл без покупки, три жалобы на очередь за неделю в одной и той же точке.

Анализ тональности

Классические методы определяют тональность по словарю «хороших» и «плохих» слов. Пропустив 36 отзывов через такой анализатор, получили только 44% совпадений с разметкой модели. Ошибки структурные:

«Ну спасибо за «быструю подачу» — всего 25 минут за одним капучино отстояла. Видимо, зерно собирали вручную прямо при мне. Отдельный комплимент кондиционеру, который дует ровно в очередь.»
Словарь
Позитивный+2/−1 слов
LLM
Негативныйскорость−, атмосфера−
Словарь увидел «спасибо» и «комплимент». Сарказм читается только смыслом.
«Отдельный респект за инновационную систему «один бариста на весь Невский в час пик». Бесплатная медитация в очереди, кофе за деньги. Дзен я обрела, капучино — минут через двадцать.»
Словарь
Позитивный+3/−1 слов
LLM
Негативныйскорость−
«Респект», «бесплатно», «дзен» — три позитивных слова в жалобе на очередь.
«Апдейт моего отзыва недельной давности: написали, извинились, вернули деньги. Сегодня заказала снова — приехало за 35 минут, горячее, стакан в новой плотной обойме, внутри открытка и печенька. Вот так надо работать с косяками!»
Словарь
Негативный+0/−1 слов
LLM
Позитивныйдоставка+, персонал+
Гостья хвалит работу с жалобой, но слово «косяки» утащило отзыв в негатив.
«Парковку у торгового центра перекрыли на ремонт, охрана хамит и разворачивает всех подряд. Полчаса кружил по кварталу. Кофейня, в общем-то, ни при чём, но настроение испорчено, звёзды снимаю.»
Словарь
Негативный+0/−2 слов
LLM
Не по адресу
Негатив про парковку ТЦ упал бы в метрики кофейни. LLM исключила его из KPI.
«Ребята, я к вам год хожу и всем вас советую. Но что случилось с эспрессо? После смены зерна в июле он стал заметно кислить. Уже два раза подходил к стойке, нюхал и уходил без покупки. Верните старый бленд или хотя бы дайте выбор!»
Словарь
Нейтральный+1/−1 слов
LLM
Смешанныйатмосфера+, напитки−
«Я вас всем советую» — а по сути постоянный гость уже дважды ушёл без покупки.
«Лучшая кофейня города!!! Всем советую!!! Обслуживание супер, кофе супер, всё супер!!! 5 звёзд!!!»
Словарь
Позитивный+5/−0 слов
LLM
Позитивныйшаблонный, без конкретики
Пять «супер» без единой детали: тональность позитивная, но в метрики качества такой отзыв идёт отдельно от содержательных.

И главное: даже угадав тональность, словарь выдаёт одну метку на отзыв. Бизнесу нужно другое — что именно хвалят и ругают, насколько это срочно, какие факты передать менеджеру и что ответить.

Что добавляет LLM

Языковая модель читает отзыв как внимательный сотрудник, а возвращает то, что нужно базе данных. Весь «интеллект» системы — один системный промпт со схемой ответа:

{
  "overall": "позитивный | негативный | смешанный | нейтральный",
  "aspects": [{"aspect": "скорость", "sentiment": "негатив",
               "quote": "25 минут за одним капучино"}],
  "urgency": "низкая | средняя | высокая",
  "sarcasm": true,
  "facts": ["только проверяемая конкретика"],
  "insight": "продуктовый вывод для команды",
  "reply_draft": "черновик ответа в тоне бренда"
}

Ключевые правила промпта: фиксированный список из восьми аспектов (иначе агрегировать будет нечего), несколько аспектов с разной тональностью у одного отзыва, в факты — только то, что можно процитировать, каждый аспект подтверждается цитатой, тон бренда и запрет канцелярита для черновиков.

Как устроено

Ни одного экзотического компонента: сбор отзывов, один вызов LLM на отзыв со строгой JSON-схемой, валидация и обычная BI-витрина поверх.

  1. Источники. Яндекс.Карты, 2ГИС, VK, агрегаторы доставки
  2. Сбор. API площадок и выгрузки; новые отзывы — каждые 30 минут
  3. LLM-разбор. один вызов на отзыв, строгая JSON-схема, температура 0
  4. Валидация. проверка схемы; невалидный JSON — повторный запрос
  5. Витрина. база + BI-дашборд: тренды, аспекты, точки
  6. Действия. алерты в Telegram, очередь ответов с черновиками
Системный промпт целиком — главный «код» этой системы Скачать
Ты — аналитик отзывов сети кофеен «Зерно сомнения» (Санкт-Петербург, четыре точки: Невский, Васильевский, Петроградка, Московский). Твоя задача — превратить один отзыв гостя в структурированную запись для дашборда службы качества.

Верни СТРОГО один JSON-объект без пояснений и без markdown, по схеме:

{
  "type": "отзыв" | "вопрос" | "шаблонный" | "не_по_адресу",
  "overall": "позитивный" | "негативный" | "смешанный" | "нейтральный",
  "aspects": [
    {"aspect": "напитки|еда|скорость|персонал|чистота|атмосфера|цены|доставка",
     "sentiment": "позитив" | "негатив" | "нейтрально",
     "quote": "короткая цитата из отзыва, подтверждающая оценку"}
  ],
  "urgency": "низкая" | "средняя" | "высокая",
  "requires_reply": true | false,
  "sarcasm": true | false,
  "facts": ["только проверяемая конкретика: время, суммы, названия, события"],
  "insight": "продуктовый вывод для команды, если он есть, иначе null",
  "reply_draft": "черновик публичного ответа, если requires_reply, иначе null"
}

Правила разбора:
1. Аспекты выбирай ТОЛЬКО из списка: напитки, еда, скорость, персонал, чистота, атмосфера, цены, доставка. У одного отзыва может быть несколько аспектов с разной тональностью — это нормально и важно.
2. Сарказм и иронию оценивай по смыслу, а не по словам: «ну спасибо за быструю подачу — всего 25 минут» — это негатив по аспекту «скорость».
3. В facts выноси только конкретику, которую можно проверить или передать менеджеру (время ожидания, цены, имена, даты, события). Без интерпретаций и оценок.
4. type = "вопрос" — если это вопрос, а не отзыв; "шаблонный" — восторг или ругань без единой конкретной детали; "не_по_адресу" — текст не о работе кофейни (о ТЦ, парковке, соседях). Для "не_по_адресу" и "шаблонный" аспекты не заполняй. overall у "шаблонный" ставь по тональности текста: восторг — "позитивный", ругань и агрессия — "негативный". У "вопрос" и "не_по_адресу" overall ставь "нейтральный". В метрики качества записи с type ≠ "отзыв" всё равно не попадают — их отсекают по полю type.
5. urgency = "высокая": риск здоровья или безопасности, посторонние предметы в еде, конфликт с персоналом, публичная угроза репутации. "средняя": повторяемая проблема сервиса, вопрос с намерением визита, гость заявляет об уходе. "низкая": остальное.
6. requires_reply = true для: любого негатива, любого вопроса, отзывов с упоминанием сотрудников по имени, историй с риском репутации. Шаблонные и «не по адресу» отзывы тоже могут требовать ответа — реши по смыслу.
7. reply_draft пиши в тоне бренда: тепло, живо, конкретно, с лёгким юмором там, где это уместно. Запрещён канцелярит («приносим извинения за доставленные неудобства»). Признавай конкретную ошибку из отзыва, называй конкретное действие, которое сделаем. При серьёзной проблеме — приглашение в личные сообщения и промокод ZERNO. До 60 слов. На чистую ругань без единой детали — одна-две спокойные фразы без юмора, промокода и оправданий; в перепалку не вступай. При риске здоровья — без юмора: короткое честное извинение, что уже сделано, приглашение в личные сообщения.
8. Никогда не выдумывай факты, которых нет в отзыве. Если чего-то нельзя определить — ставь null или пустой список.

Результат

С 17 августа в отзывах точки на Невском стал повторяться аспект «скорость»: «один бариста на смене», «очередь до двери». По отдельности — обычные плохие дни. В агрегате — 8 негативных упоминаний за шесть дней против одного неделей ранее.

21 августа сработал алерт. Причина оказалась операционной — из утренней смены ушли люди, — но заметил её не управляющий, а мониторинг отзывов.

Побочный продукт — поле insight: за две недели 19 заметок, от спроса на абонемент до просьбы вернуть облепиховый чай к осени. Раньше это тонуло в потоке; теперь — готовая повестка продуктовой встречи.

Экономика

Один отзыв ≈ 1300 токенов на входе и 350 на выходе.

МодельОдин отзыв1000 отзывов в месяц
Лёгкая модель≈ 25 коп.≈ 250 ₽
Модель классом выше≈ 50 коп.≈ 500 ₽
Лёгкая модель через Batch API≈ 13 коп.≈ 125 ₽

Капучино стоит 300–350 рублей: месяц мониторинга дешевле одной чашки. Считать нужно не токены, а время маркетолога — полчаса в день на чтение потока превращаются в пять минут на сводку.

Подводные камни

С чего начать: неделя до работающего контура

  1. Выгрузите отзывы за 2–3 месяца с двух главных площадок — хватит CSV.
  2. Возьмите промпт из демо, адаптируйте аспекты (8–10) и тон бренда.
  3. Прогоните массив через лёгкую модель, посмотрите 30 разборов глазами, зафиксируйте регресс-набор.
  4. Поставьте разбор на расписание: тренд по аспектам, очередь ответов, лента инсайтов.
  5. Добавьте один алерт: всплеск негатива по аспекту неделя к неделе.

Вопросы с задних рядов

А если модель выдумает то, чего в отзыве нет?
Три предохранителя: температура 0 и строгая JSON-схема (невалидный ответ автоматически перезапрашивается); правило «в facts — только то, что можно процитировать»; выборочный ручной контроль 5–10% разборов раз в неделю, как контроль качества у операторов кол-центра. Ошибки будут — вопрос в том, что их на порядок меньше, чем при ручной разметке потока, который иначе вообще никто не читает целиком.
Публичные ответы тоже пишет модель?
Модель пишет черновик, публикует человек. На объёме это меняет работу: маркетолог из «автора 20 ответов в день» превращается в редактора, который правит 3–4 черновика из 20. Ответы на критичные случаи (риск здоровья, юридические) — только после ручной проверки.
Что с персональными данными?
Отзывы публичны, но в промышленном контуре имена гостей и сотрудников стоит маскировать перед отправкой в API и хранить сырые тексты у себя. Плюс проверить условия площадок на автоматический сбор и требования 152-ФЗ к обработке.
А если в отзыве напишут инструкции для модели?
Такие попытки будут — это называется prompt-injection. Защита: текст отзыва подаётся строго как данные в фиксированном шаблоне, температура 0, ответ проходит валидацию по схеме, а цитаты сверяются с исходным текстом — «инструкция из отзыва» не добавит фактов и не сменит формат. Худший реалистичный исход — кривой разбор одного отзыва, который поймает выборочный контроль.
Почему не готовый сервис мониторинга?
Готовые системы хороши в сборе: они уже умеют забирать отзывы со всех площадок. Слабое место — разбор: тональность целиком и алерты по ключевым словам. Разумная схема — гибрид: сбор готовым сервисом, а поверх — свой промпт с вашей таксономией аспектов, тоном бренда и инсайтами.
Почему не дообучить маленькую модель классификации?
Можно, и при миллионах отзывов это окупится. Но классификатор надо обучать на каждую задачу отдельно (тональность — одна модель, аспекты — другая, ответы он не напишет вовсе), а LLM делает всё это одним промптом с первого дня, и «переобучение» — это правка текста промпта. Для 90% компаний с потоком до десятков тысяч отзывов в месяц LLM-вариант дешевле по совокупности.
Кто нужен, чтобы это запустить?
Прототип — вечер одного разработчика: сервис умещается в ~160 строк. Дальше промпт правит маркетолог как обычный документ, разработчик нужен эпизодически. Самое трудоёмкое — не код, а договориться о таксономии аспектов и собрать регресс-набор сложных отзывов.
А мониторинг Telegram-чатов и групп?
Тот же пайплайн, другой сбор: вместо API отзовиков — экспорт каналов или бот в чатах, плюс задача «найти упоминания бренда и тёплые лиды» в промпте. Юридически и этически сложнее (чужие сообщества, приватность участников), поэтому начинать лучше с публичных отзывов — а группы подключать вторым шагом.