Селлер на маркетплейсах — это человек с тремя личными кабинетами и вечным долгом перед отзывами. Утром посмотреть заказы за ночь. Проверить, что ничего не кончилось на складе. Ответить на вопросы покупателей, пока их не увидел конкурент. Поднять цену на то, что уходит слишком быстро, и понять, почему реклама съела дневной бюджет к обеду. На Wildberries, Ozon и Яндекс Маркете это одна и та же работа в трёх разных интерфейсах.

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

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

Что менеджер должен уметь с первого дня

Мы не стали начинать с «умного советника». Начали с того, на что селлер тратит время каждый день:

  • заказы и продажи за сегодня, вчера, неделю, месяц;

  • остатки на складах и когда пора везти поставку;

  • цены и акции площадок;

  • карточки товаров и их названия;

  • реклама — пока только посмотреть;

  • воронка: показы, переходы, корзины, заказы;

  • вопросы и отзывы покупателей;

  • отчёт в Excel одной командой;

  • утренняя проверка: если что-то срочное, менеджер сам пишет в чат.

Всё это работает через официальные API площадок по ключу владельца. Селлер подключает кабинет, а дальше просто пишет в чат обычными словами.

Как устроен прототип: фраза, правило, API

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

Фраза сначала проходит через набор правил, и на выходе получается намерение: какая операция, какая площадка, за какой период.

Выглядит это так (сильно сокращено):

def words(q: str) -> dict:
    """Без модели: намерение по словам. Порядок проверок — от изменения к чтению."""
    low = q.lower().replace("ё", "е")
    p = {"op": "ask", "goods": q, "day": "", "days": 0}
    if re.search(r"сегодн", low):
        p["day"] = "today"
    elif re.search(r"вчера", low):
        p["day"] = "yesterday"
    m = re.search(r"(\d{1,3})\s*(дн|день|сут)", low)
    p["days"] = int(m.group(1)) if m else 30 if "месяц" in low else 7 if "недел" in low else 0
    # ... дальше — ответы покупателям, цены, акции, остатки, заказы
    return p

Обратите внимание на строку в docstring: проверки идут от изменения к чтению. Сначала ищем, не просят ли что-то поменять, и только потом — показать. Ошибиться в сторону «показал лишнюю таблицу» не страшно. Ошибиться в сторону «поменял цену» — очень.

Площадку определяет такое же правило. Тут сразу нашлись грабли русского языка: «маркетплейсы» — это не Яндекс Маркет.

asked = [k for k, w in (("ozon", r"ozon|озон"),
                        ("ym",   r"маркет(?!плейс)|market(?!place)"),
                        ("wb",   r"\bwb\b|\bвб\b|wildberries|вайлдберр"))
         if re.search(w, low)]

Если площадку не назвали, менеджер отвечает по всем подключённым. Если назвали ту, что не подключена, — по первой, которая есть.

Дальше всё прямолинейно. Операция зовёт свой обработчик, обработчик ходит в API нужной площадки, разделы WB, Ozon и Маркета запрашиваются параллельно, ответ собирается в таблицу. Свежий снимок кабинета кладём в базу и обновляем в фоне, чтобы второй вопрос подряд не ждал площадку заново.

Где здесь нейросеть

Правила хороши, пока человек пишет предсказуемо. Поэтому, если модель подключена, фраза уходит и ей — вместе со списком операций и одной строкой описания к каждой:

def parse(q: str) -> dict:
    p = words(q)                      # сначала правила
    if not llm.available():
        return p
    ai = llm.complete_json(_PARSE + "
".join(f"{k} — {v}" for k, v in OPS.items()),
                           json.dumps({"фраза": q}, ensure_ascii=False),
                           SCHEMA, effort="low", max_tokens=400) or {}
    if ai.get("op") in OPS:           # чужую операцию не примем
        p.update({k: v for k, v in ai.items()
                  if k in SCHEMA["properties"] and v not in (None, "")})
    return p

Модель здесь — классификатор. Она может уточнить, что имел в виду человек, но выбирает только из того, что мы ей разрешили. Ответила что-то вне списка — её ответ просто выбрасывается, остаётся разбор правилами. Не ответила вовсе — тоже остаётся разбор правилами, менеджер работает дальше.

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

Деньги — только кнопкой

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

Это правило появилось в первый же день, и отменять его мы не собираемся. Что бы ни менялось в устройстве менеджера, тратить деньги владельца без его явного согласия он не будет.

Почему мы начали именно так

Можно было сразу дать модели инструменты и сказать «разбирайся». Мы сознательно пошли от правил, и причины были вполне практические.

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

Скорость. Модели нужен один короткий ответ — название операции, а не рассуждение. Без модели правила отвечают сразу.

Проверяемость. Мы написали подставные WB, Ozon и Маркет, которые работают без сети. Весь менеджер прогоняется смоук-тестом без единого запроса наружу: заказы, остатки, цены, ответы, отчёты, кнопки.

Цена. Модель вызывается коротко и по мелочи.

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

Как будем тестировать

Прототип мы выпустили в два места.

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

Первые владельцы с живыми кабинетами. Тут всё по-настоящему: реальные товары, реальные покупатели, реальные деньги за кнопками.

Смотреть будем на три вещи:

  • сколько фраз не распознались и ушли в общий ответ;

  • где менеджер понял фразу, но показал не то;

  • какие правки владельцы готовят, но не подтверждают, и почему.


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

Комментарии (10)


  1. BladeConjuror
    27.10.2026 07:25

    Первое, на что обратил внимание, это работа с кешированными данными. У меня в одной из систем была довольно забавная проблема: агент уверенно отвечал пользователям на основании копий репозиториев, которые не обновлялись месяцами. Поэтому рекомендовал бы сразу предусмотреть контроль актуальности данных, особенно перед операциями изменения цен и остатков.
    Второй момент. Как у вас обрабатывается ситуация, когда пользователь подтвердил действие, запрос в API ушел, но система упала или получила таймаут до сохранения результата? Операция могла выполниться, а могла и нет. Была у меня такая ситуация, в итоге пришлось отдельно прорабатывать сохранение состояния операций и восстановление после неопределенного результата. Некоторые технические детали описывал здесь: https://habr.com/ru/articles/1095776/, если интересно можешь изучить
    Ну и немного смутило поведение с неподключенными площадками. Если пользователь запрашивает Ozon, а система подставляет WB, можно получить фактически неправильный ответ. Лучше явно сообщать об отсутствии подключения.
    Самое сложное в таких системах когда пытаешься гарантировать, что она не натворит плохих вещей при совершенно штатных сбоях)


    1. Haimi Автор
      27.10.2026 07:25

      Спасибо за подробный разбор — все три пункта по делу.

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

      Про таймаут после подтверждения. Здесь нас во многом спасает то, что правки пишутся абсолютными значениями: «поставить 1990 ₽», а не «поднять на 10%». Повторное нажатие после неясного исхода приводит к тому же состоянию, а не удваивает изменение. Если площадка вернула ошибку, менеджер её показывает, а кнопка остаётся. Там, где площадка сама работает асинхронно (создание карточки на WB), после действия появляется отдельный шаг «Проверить, создала ли площадка». Для правок в рекламных кабинетах рядом есть «Вернуть как было» со значениями, прочитанными до правки. А вот отдельного состояния «отправлено, исход неизвестен» с восстановлением после падения у нас действительно нет. За ссылку спасибо, посмотрим, как вы это сделали.

      Про неподключённую площадку — да, это ошибка, и вы её точно поймали в коде из статьи: next(..., on[0]). Правильно ответить «Ozon не подключён», а не молча показать WB. Исправим.

      Под последней фразой подписываемся. Штатные сбои страшнее нештатных: к ним никто не готовится.


  1. stas_makarov
    27.10.2026 07:25

    Сами регулярки вы же с ИИ писали, да? Это как раз то, что они делают практически идеально. В целом подход здравый — если что-то можно решить кодом, зачем тащить туда LLM?


    1. Haimi Автор
      27.10.2026 07:25

      Да, писали вместе с ИИ — и здесь он правда почти идеален: даёт регулярку, сам подбирает фразы, на которых она должна и не должна сработать, и не устаёт от пятидесятой проверки подряд. Мы оставили себе решать, что вообще считается операцией и в каком порядке проверять: сначала «изменить», потом «показать».

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


  1. alexed34-2022
    27.10.2026 07:25

    ссылка на сервис??



  1. Mdm3
    27.10.2026 07:25

    Два раза прочитал, и не понял ответ на вопрос "Что менеджер должен уметь с первого дня", чтобы понять, что такого предлагает сервис по сравнению с личным кабинетом маркетплейсов, которые достаточно развитые в аналитике, и за доп. подписки предлагаю возможности, которые вы никогда не получите сами через API.


    1. Haimi Автор
      27.10.2026 07:25

      Справедливо — в статье мы описали, что менеджер умеет, но не сказали, зачем это селлеру, если кабинет площадки показывает то же самое.

      Уникальных данных у нас нет, и мы с этим не спорим. Джем на WB или Premium на Ozon дают аналитику, которую через API не получить. Но кабинет — это цифры. Их все видят, все читают, а вот что с ними делать, кабинет не говорит.

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

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

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


  1. igrglvk
    27.10.2026 07:25

    Что-то несколько раз прочитал и не понял. Это какой-то телеграм бот получается, в который пишешь и он что-либо делает с инфой из маркетплейсов?


    1. Haimi Автор
      27.10.2026 07:25

      Почти, только не в Телеграме. Это чат с AI-менеджером в веб-кабинете на сайте. Вы подключаете кабинет продавца на WB, Ozon или Маркете ключом API, а дальше пишете обычными словами — что с остатками, сколько заказов за вчера, какие вопросы покупателей висят без ответа. Менеджер забирает данные из кабинета через официальный API и отвечает таблицей, а если нужно — готовит правку: цену, ответ покупателю, название карточки. Любая правка уходит в кабинет площадки только после того, как нажмёте кнопку.

      О срочном он пишет в этот же чат сам, утром: товар заканчивается, покупатели ждут ответа.