Papa BU: платформа перепродажи с Avito API и векторным поиском
Papa BU — платформа перепродажи. Она собирает поисковое ядро из Вордстата, пишет объявления, размещает их через Avito API, ищет по своей базе векторным поиском и следит за биллингом. Ниже — из каких узлов она собрана и как эти узлы связаны между собой.
Зачем платформе понадобилось поисковое ядро
Перепродажа держится на том, что товар находят. Найти его можно только по тем словам, которыми люди на самом деле ищут, а не по тем, которыми продавец привык называть вещь.
Поэтому первый узел платформы — сбор запросов из Вордстата. Система забирает частотность, отсекает мусор, группирует близкие формулировки и складывает результат в ядро, привязанное к категории товара.
Дальше это ядро работает не как справка для человека, а как вход для следующего узла. Объявление собирается из тех формулировок, которые набирают люди, и это меняет заголовок сильнее любых правок стиля.
Как собирается текст объявления
Второй узел берёт карточку товара и ядро запросов и собирает текст объявления: заголовок, описание, параметры.
Генерация здесь не свободное сочинение. Она ограничена: заголовок обязан уложиться в лимит площадки, описание обязано содержать характеристики из карточки, придумывать свойства товара запрещено.
Результат уходит не сразу на площадку, а в очередь на проверку. Человек видит список готовых объявлений и либо отправляет, либо правит. Полностью автоматическая публикация без просмотра — один из тех соблазнов, которые дорого обходятся при первой же ошибке в данных.
Размещение через Avito API и почему оно капризное
Размещение выглядит как одна кнопка, а внутри это самая капризная часть системы.
Внешний интерфейс площадки имеет ограничения по частоте запросов, свои коды ошибок и собственное представление о категориях и параметрах. Категория «шкаф» на площадке требует одних полей, «стол» — других, и эти требования меняются без предупреждения.
Поэтому узел размещения устроен как очередь с повторами. Задача на публикацию ставится в очередь, выполняется с учётом ограничений по частоте, при временной ошибке повторяется с увеличивающейся паузой, при постоянной — падает в список для человека с текстом ошибки.
Каждый запрос и каждый ответ пишутся в журнал. Когда объявление не появилось, ответ на вопрос «почему» занимает минуту, а не переписку с поддержкой площадки.
Узел поиска: почему обычный поиск не справился
В базе накапливаются тысячи позиций, и оператору нужно быстро находить похожее: чтобы не заводить дубль, чтобы взять описание за основу, чтобы понять, за сколько уходила такая же вещь.
Поиск по словам этого не даёт. «Кресло офисное на колёсиках» и «стул компьютерный с роликами» — про одно и то же, но не совпадают ни одним словом.
Поэтому в платформе стоит векторный поиск: каждая позиция превращается в набор чисел, отражающий смысл описания, и близость ищется по смыслу, а не по буквам. Оператор вводит фразу своими словами и получает похожие позиции, даже если формулировки разные.
Обычный поиск по словам при этом никуда не делся. Артикул, номер, точное название быстрее и надёжнее ищутся прямым совпадением, и два способа поиска работают вместе, а не вместо друг друга.
Деньги внутри платформы
У каждого действия внутри платформы есть себестоимость: обращение к внешнему сервису, генерация, размещение. Поэтому в платформе живёт учёт денег.
Баланс хранится не числом, а журналом операций: пополнение, резерв, списание, возврат, корректировка. Остаток — это сумма журнала, и любую цифру на экране можно разложить в список операций.
Списание двухшаговое. При запуске действия сумма резервируется, при успехе превращается в списание, при ошибке возвращается. Пользователь не платит за запрос, который упал по таймауту.
Как узлы связаны
Схема словами получается такая. Ядро запросов питает генерацию, генерация складывает объявления в очередь на проверку, проверенное уходит в очередь размещения.
Размещение отчитывается в журнал и дёргает биллинг. Векторный поиск стоит в стороне от этого конвейера: он смотрит на всю базу позиций и обслуживает человека.
Между узлами нет прямых вызовов «из страницы в страницу». Каждый узел получает задачу и отдаёт результат, и это позволяет останавливать любой из них на время без остановки остальных.
Права доступа разложены так же, как в остальных наших проектах: оператор работает с объявлениями и не видит финансовых настроек, владелец видит деньги и тарифы. Тот же принцип, что в магазине «Жук и Плут», где сборщик видит заказы, но не суммы.
Интерфейс: четыре экрана и ничего лишнего
Платформа снаружи — четыре экрана, и это сознательно мало.
Список позиций с фильтрами и поиском. Очередь объявлений на проверку, где видно, что сгенерировано и что ждёт отправки. Журнал размещений со статусами и текстами ошибок. Экран баланса с расходом и остатком.
Всё остальное происходит без участия человека и всплывает только тогда, когда что-то пошло не так. Интерфейс здесь не витрина возможностей, а место, куда система приносит исключения.
Что оказалось сложнее, чем ожидалось
Чужие правила. Ни одно ограничение внешней площадки не описано так подробно, как выясняется на практике. Часть узнаётся только по кодам ошибок в журнале.
Качество исходных данных. Генерация хороша ровно настолько, насколько заполнена карточка. Позиция без характеристик даёт объявление без характеристик, и никакая модель этого не исправит.
Терпение к очередям. Заказчику сначала хотелось, чтобы кнопка публиковала мгновенно. Мгновенно не бывает, когда на той стороне лимит по частоте; вместо этого пришлось делать честный статус задачи, чтобы человек видел, где именно она находится.
Кому такая платформа не нужна
Если позиций десятки и они меняются редко, ручное размещение дешевле. Платформа окупается на объёме и на повторяемости: сотни позиций, регулярное обновление, несколько человек в работе.
Если у вас нет структурированного каталога, начинать надо не с платформы, а с него. Автоматизация без данных превращается в дорогой способ размножать пустые карточки. Что входит в проекты такого размера и сколько это стоит — в разделе цены.
Коротко
Papa BU собрана из пяти узлов: сбор поискового ядра, генерация объявлений, размещение через Avito API с очередью и повторами, векторный поиск по базе и биллинг с журналом операций. Узлы связаны задачами, а не прямыми вызовами, поэтому любой можно остановить отдельно. Главные сложности оказались не в коде, а в чужих правилах площадки и в качестве исходного каталога.
Первый разговор — разбор задачи: нужна ли вам система или хватит одной страницы. Без обязательств и без счёта.
Частые вопросы
Сколько занимает разработка такой платформы?
Это не сайт и не магазин, а платформа: по нашим условиям от 150 000 ₽ и от 14 дней, причём реальный срок зависит от количества внешних систем. Каждая стыковка с чужим API — отдельный кусок работы со своими правилами и своими ошибками.
Что происходит, когда внешний сервис меняет правила?
Стыковка с каждым внешним сервисом вынесена в отдельный узел и не размазана по коду страниц. Изменение правил означает правку в одном месте и проверку по журналу запросов. Это одна из причин, по которой такие вещи не собирают из готовых надстроек.
Можно ли запустить платформу частями?
Да, и так дешевле. Мы обычно запускаем сначала сбор запросов и ручное размещение, потом генерацию, потом биллинг. Каждый кусок приносит пользу отдельно, и заказчик видит результат до того, как потрачен весь бюджет.
Те, что не помогают, мы переписываем — по этой кнопке и решаем, какие именно.
Ещё по теме
Что малому бизнесу от CRM реально нужно, чем готовая система отличается от своей внутри сайта и по каким признакам выбирать между ними.
тем, кто заказывает CRM купили, а работать в ней не стали: разбор причинШесть ошибок, из-за которых оплаченная CRM превращается в пустую базу, и что делать с каждой, пока подписка ещё действует.
тем, кто заказывает Freedom Gym: клубная система с абонементами и расписаниемИстория одного проекта: как из журнала на ресепшене выросла клубная система с абонементами, расписанием и правами тренеров, и что пошло не так.
тем, кто заказывает