06 AI и автоматизация
B2B медтех · AI 2025 — н.в. Архитектор и разработчик системы

Price Monitor: LLM-экстракция цен дилеров

Ежемесячный контроль MAP по всему рынку дилеров Samsung Medison в РФ. Трёхуровневый pipeline (JSON-LD → LLM → эвристика) на Claude Haiku 4.5 и SerpAPI.

Коротко

  • Задача — контроль Minimum Advertised Price (MAP) по 6 моделям УЗ-сканеров Samsung на всём рынке дилеров РФ. Раньше — ручной обход сайтов раз в месяц.
  • Подход — 3-уровневый pipeline экстракции цены: JSON-LD schema.org → контекстная LLM-экстракция на Claude Haiku → regex-эвристика как fallback.
  • Объём — 6 моделей × 6 query-шаблонов × 2 поисковика × 5 страниц выдачи = ~1 000 уникальных URL за прогон. 30–45 минут до Excel-отчёта.
  • Экономика — ~$5 за полный прогон. SerpAPI ≈ $3–4, LLM ≈ $2–4. 2–3 прогона в месяц укладываются в квоту 1 000 SerpAPI-запросов.

Цифры, которые можно сверить

Моделей сканеров под контролем
6
URL за один прогон
~1 000
Время прогона
30–45 мин
Стоимость одного прогона
~$5
SerpAPI-вызовов за прогон
360
Уровней в pipeline экстракции
3

Зачем это бизнесу

У дистрибьютора есть утверждённая ценовая политика: дилер не может рекламировать скидку больше 45% от прайса. Без контроля эта политика быстро размывается — один дилер демпингует, остальные подстраиваются, маржа уходит, головной офис в Корее задаёт вопросы.

Контролировать вручную не получится. Только на 6 активных моделях — сотни дилерских сайтов, у каждого свой шаблон карточки товара, у каждого свой язык. И цены меняются между прогонами.

Нам нужно было собрать систему, которая раз в месяц делает то же самое, что ответственный сотрудник, — только быстрее, точнее и с воспроизводимым результатом.

Это одна из тех систем, про которые не надо громко говорить. Она просто работает каждый месяц и экономит дистрибьютору часы ручной работы и десятки процентов маржи.

Как это работает — за один прогон

  1. Поиск. Для каждой из 6 моделей (V6, V7, V8, W9, W10, Z20) — 6 поисковых запросов × 2 движка (Google и Yandex, включая Yandex Market) × 5 страниц выдачи. Итого 60 вызовов SerpAPI на модель, 360 на прогон.
  2. Пре-фильтры. Выбрасываем заведомо «шумные» страницы: прайс-листы, каталоги, страницы «б/у / демо / восстановленный», мультибрендовые витрины, страницы без упоминания целевой модели.
  3. Экстракция цены по 3-уровневой схеме. Первый уровень, который вернул валидную цену, — выигрывает.
  4. Сравнение с прайсом. Берём курс EUR/RUB с CBR РФ, прибавляем 2% надбавки, считаем допустимый минимум: list_price × (1 − 0.45). Если цена ниже — ALARM. Если выше прайса × 1.3 — возможно, собрано с датчиками в комплекте (аномалия).
  5. Отчёт. Excel с тремя листами: «Нарушители», «Все результаты», «Сводка». В «Все результаты» цветовая разметка: зелёное — норма, красное — нарушение, оранжевое — аномалия, серое — цены нет.

3-уровневый pipeline экстракции

Это сердце системы. Почему именно три уровня — каждый закрывает свои случаи.

Уровень A — JSON-LD schema.org (бесплатно)

Читаем <script type="application/ld+json"> на странице. Ищем Product / Offer с price и priceCurrency. Если магазин корректно размечен — это авторитетный источник, цена попадает в отчёт без привлечения LLM. Покрывает 30–50% e-commerce-сайтов.

SEO-ghost guard. Отдельный защитный слой: принимаем JSON-LD-цену только если то же число встречается в видимом тексте страницы. Многие дилеры зашивают в микроразметку «SEO-цену» для ранжирования в Google, а на самой странице показывают «Запросить цену». Без проверки такие страницы давали бы ложные ALARM.

Уровень B — LLM-экстракция (Claude Haiku 4.5 через OpenAI-совместимый proxy)

Если JSON-LD не дал результата — отправляем текст страницы, URL и курс EUR/RUB в модель со строгим системным промптом. Модель возвращает {"price": int|null, "reason": "..."}.

Что умеет промпт:

  • Отличать цену целевой модели от цен других Samsung-моделей в блоках «Похожие товары».
  • Отбрасывать цены конкурирующих брендов (Mindray, GE, Philips, Esaote и десятки других) — у них общие страницы сравнения встречаются регулярно.
  • Игнорировать цены датчиков, принтеров, расходников.
  • Не путать лизинговые платежи («первый взнос», «в месяц») с ценой аппарата.
  • Выбрасывать б/у и демо-оборудование.
  • Корректно конвертировать EUR → RUB по переданному курсу.
  • Возвращать null, если на странице «цена по запросу» или нет числа для целевой модели.

Ключевое архитектурное решение: если LLM сказал null, мы не проваливаемся в regex-fallback. Доверяем модели. Иначе эвристика уверенно подтягивает первую попавшуюся сумму из подвала с «запчасти от 15 000 ₽».

Уровень C — regex + DOM-эвристика (fallback)

Работает, когда LLM-этап выключен или ключ LLM не задан. Собственный парсер цен с набором правил: \b перед числом, чтобы iGo2 290 000 руб не читалось как 2 290 000 руб; разделители текстовых нод через separator=" ", чтобы Запросить КП и 4 773 627 ₽ не склеились в одну «4-миллионную» строку; фильтр по диапазону 500 тыс — 50 млн ₽.

Почему это вообще нетривиально

Если кажется, что «просто обход сайтов и regex», — нет. Вот несколько «маленьких» кейсов, которые съедают недели без LLM-этапа:

  • Похожие товары. На странице V7 карусель «Похожие» показывает V8 с ценой — нативный регекс не различает, о какой модели идёт речь.
  • Мультибрендовые витрины. На одной странице Samsung + Mindray + GE Logiq — без контекстного понимания моделями в отчёте всё смешается.
  • SEO-ghost. Микроразметка говорит «2 500 000», а на странице «Цена по запросу» — сайт получает преимущество в Google, а мы ловим ложный ALARM.
  • Лизинг. «Первый взнос 290 000 ₽» выдаётся за цену аппарата.
  • Б/у на той же странице. Сайт продаёт и новый, и б/у V6 в одной карточке — без проверки соседнего контекста выбирается первое число.

Для каждого из этих случаев в системе есть отдельное правило. Но чем больше таких «подкейсов» накапливается, тем хрупче становится чистый regex. Поэтому LLM-этап — не роскошь, а инструмент стабильности.

Экономика и масштаб

  • Полный прогон по 6 моделям — 360 SerpAPI-запросов, ~1 000 уникальных URL для скрапинга и анализа.
  • Время — 30–45 минут от запуска до готового Excel.
  • Стоимость — около $5 за прогон: $3–4 на SerpAPI, $2–4 на LLM. Месячная квота SerpAPI 1 000 = 2–3 полных прогона.
  • Защита от дорогих повторовrescrape_from_report.py: если нужно пересчитать только URL из предыдущего отчёта (например, после доработки правил), SerpAPI не дёргается вовсе.

Что делает система, кроме самой экстракции

  • Автоматически берёт курс EUR/RUB с CBR РФ и добавляет 2% надбавки к списочной цене.
  • Дедупликация: одна цена на дилера и модель (ключ domain|model).
  • Excel-отчёт с цветовой разметкой, отдельным листом нарушителей, листом всех результатов и сводкой по курсам и референсным прайсам.
  • PDF-спецификация по моделям для использования в согласованиях внутри компании.

Что здесь показательно как инженерный кейс

  • LLM не вместо правил, а как инструмент в правильном месте pipeline. Сначала — дешёвый и быстрый JSON-LD, потом дорогая модель, потом regex как последний рубеж.
  • Доверие к модели важнее формальной полноты. Если модель сказала «не знаю» — значит, не знаем и мы. Попытка «докрутить регексом» ломает точность.
  • Защиты от ложных срабатываний — отдельный пласт работы. SEO-ghost, мультибрендовые страницы, лизинг, б/у — каждый случай реальный и приходит с продакшна.
  • Экономика под квоту. Система не пытается «обойти интернет», она точно укладывается в месячную квоту SerpAPI и в разумный LLM-бюджет.

Что из этого кейса можно забрать себе

  • MAP-контроль, парсинг цен конкурентов, мониторинг дилеров — задача, которая почти в любой отраслевой B2B-компании есть, но почти нигде не решена системно.
  • Контекстная LLM-экстракция — хороший инструмент в любых случаях, где «данные есть, но в разметке их нет»: отзывы, описания товаров, характеристики, прайс-листы в PDF.
  • Формат Excel с цветовой разметкой — такие отчёты команда коммерции и бухгалтерия читают быстрее, чем любой дашборд.

Если у вас есть задача мониторинга цен, парсинга распределённых источников или извлечения структурированных данных из «грязного» текста — напишите мне в Telegram. Обсудим, укладывается ли ваша задача в похожую архитектуру.

Как со мной связаться

Расскажите задачу —
разберём, как её решать.

Первый разговор бесплатный, без презентаций и «а давайте я пришлю коммерческое». Смотрим, что есть, что мешает расти, и честно говорим, берём мы вашу задачу или нет. Если берём — собираем точечный план на ближайшие 60 дней.

Обычно отвечаю в течение рабочего дня. На часовых поясах от Калининграда до Владивостока проверено — пишите, когда вам удобно.