Tender Radar
площадок разобрано в разведке: 6Заказчик поставляет медицинские изделия и живёт с государственных закупок. Имя не называем: проект под NDA, снимков и адреса тоже не будет. Показываем то, что показать можно, — разбор предмета и устройство решения.
Рамка та же, что в кейсе таможенного калькулятора. Задача звучала просто: закупки размазаны по десятку площадок, на трёх языках, без единого API. Пока человек обойдёт их руками, половина сроков подачи истечёт. Нужен агент, который обходит площадки сам, решает по правилам, подходит ли закупка под профиль компании, и готовит черновики документов.
Сразу о рамке. Наша часть — разведка источников, проектирование и техническое задание; всё, что ниже, лежит в проектных документах и проверяется по ним. Собирали систему дальше по этим документам, и доступа к её показателям у нас нет — поэтому в кейсе не будет ни одной цифры результата. Будет то, за что мы отвечаем.
Ожидание перед разведкой обычное: шесть сайтов — шесть парсеров, разница в мелочах. Реальность оказалась другой: шесть разных устройств, и ни одно не похоже на соседнее.
- Первая — самая приветливая: за одностраничным приложением лежит открытый JSON-API без авторизации, к нему есть опубликованная схема, а сверх того — канал живых обновлений. То есть по ней можно не опрашивать листинг, а слушать изменения.
- Вторая — того же оператора, но собрана из отдельных сервисов, каждый на своём хосте и за защитой: без правильных заголовков запроса отвечает отказом. Карту сервисов пришлось снимать с живого приложения в браузере, а не с документации.
- Третья оказалась приятным сюрпризом наоборот: гипотеза была «там API», а листинг отдаётся обычной страницей с разметкой — сотня карточек за раз, с предметом закупки, заказчиком и сроком. Читать можно без единой строчки JavaScript. Зато детальная карточка на любой неизвестный адрес возвращает одну и ту же заглушку весом около десяти мегабайт — одинакового размера, с кодом «всё хорошо». Парсер, который на такое поведётся, будет исправно «работать» и не приносить ничего.
- Четвёртая — приложение, а настоящий сервер за ним на анонимный запрос отвечает «не авторизован». Путь внутрь есть, но лежит он через разбор мобильного приложения, а не через сайт.
- Пятая — единственная в международном стандарте открытых контрактов, и стратегически самая ценная: она сводит все стадии, от плана закупки до исполнения договора. И она закрыта по географии — с не-узбекского адреса просто не отвечает. Это не «сложно спарсить», это «нужен сервер в стране», то есть требование к инфраструктуре, а не к коду.
- Шестая открыта настежь, отдаёт больше ста тысяч лотов постранично — но это конфискат и залоговое имущество, а не закупки. Записали и отложили: источник хороший, к предмету заказчика отношения не имеет.
Вывод, ради которого это всё перечислено: «написать парсер» — это шесть разных работ разной цены, и узнать их цену можно только разведкой. Сроки, посчитанные до неё, — выдумка.
Площадка уже сама всё разложила
Первым делом напрашивается разбор текста: читать название лота, вытаскивать из него смысл, обучать что-нибудь. Дорого, долго и неточно.
Оказалось, что этого не нужно. Площадка публикует свой справочник категорий — тридцать пять штук, и он доступен без входа. Из них семь медицинских: изделия медицинского назначения, медикаменты, медтехника, лабораторные приборы, протезно-ортопедические изделия, стоматологическое сырьё, БАДы.
Значит грубый вопрос «это вообще медицина?» решается выбором категории, а не разбором текста: детерминированно, мгновенно, бесплатно и объяснимо. А разбор текста остаётся там, где он действительно нужен, — на тонком вопросе «нужен ли этому клиенту именно этот товар».
Разница между двумя подходами — месяцы работы и стоимость модели на каждом лоте.
«Ведомственные площадки» оказались витринами
Вторая гипотеза была не менее естественной: у каждой крупной госкомпании свой раздел закупок, значит нужны десятки сборщиков.
Разведка показала, что закон сводит поток в центральные площадки, а ведомственные разделы — по большей части витрины с переадресацией на них же. Крупные госкомпании публикуются на центральной бирже.
Следствие: десятки заказчиков закрываются одним фильтром по ИНН, а не десятками отдельных коннекторов. Каждый несделанный коннектор — это ещё и то, что потом не сломается.
И один отрицательный результат
Портал открытых данных выглядел очевидным источником — и им не оказался: там статистика ведомств, а не поток закупок. Записали прямо, чтобы следующий читатель не пошёл туда снова.
Побочная выгода от разведки всё же нашлась: справочники. Товарный классификатор почти на полмиллиона позиций — тот же самый, которым пользуется сама площадка, — коды регионов, реестр юрлиц по ИНН и реестр недобросовестных исполнителей. Это уже не поток, а обвязка, которой поток обогащают.
Установка заказчика была сформулирована жёстко: нужен объяснимый механизм правил, где ИИ — учитель словаря, а не судья. Под это и спроектировано.
Слой 0 — то, что площадка сказала сама. Категория, регион, цена, срок, тип процедуры, метод закупки. Пересечение с профилем компании отсекает основную массу — детерминированно и без единого обращения к модели. Он же работает дешёвым предфильтром: до дорогого разбора доходит малая часть.
Слой A — правила клиента. Это не «список ключевых слов», как обычно рисуют в презентациях:
- у каждого ключа вес от минус ста до плюс ста — то есть бывают анти-ключи, которые уводят лот из выдачи, а не приводят в неё;
- есть стоп-слова. Живой пример из документов: «перчаточный бокс» — это не «перчатки». Ключ на перчатки срабатывает, лот к делу не относится, и без глушилки поставщик каждый раз читает мусор;
- есть лемматизация, потому что русский и узбекский склоняются, а подстрока этого не знает;
- есть требуемое соседнее слово: ключ считается сработавшим только в нужном окружении.
Решение принимается по порогу, а не по «да/нет». Выше верхнего порога — сразу в подписку, ниже нижнего — сразу мимо, между ними — человеку на разметку. Пороги подбираются по размеченному набору, а не на глаз.
Очередь на разметку строится по неуверенности, а не по времени. Наверх поднимаются лоты у самого порога, конфликты (слой 0 говорит «медицина», правила говорят «нет»), незнакомые формулировки и случаи, где недавняя оценка клиента разошлась с автоматическим решением. Час работы человека тратится там, где он больше всего меняет систему.
И дальше главное: каждый размеченный лот становится тестом. Добавили ключ — прогон по всему размеченному корпусу показывает, что улучшилось и что сломалось. Точность становится измеряемой, а не предметом веры.
По каждому решению хранится происхождение: какие правила сработали, на каком куске текста, с каким вкладом. Клиент видит, почему лот попал к нему — и может сам подкрутить профиль, а не жаловаться подрядчику.
Где здесь ИИ
На входе и на выходе, но не в середине:
- на входе — приведение потока к трём языкам, чтобы узбекский лот ловился на русский ключ, и извлечение текста из вложенных документов, потому что суть закупки часто лежит в приложенном техзадании, а не в названии;
- в цикле разметки — ИИ предлагает оператору ключи-кандидаты и их варианты: синонимы, словоформы, транслитерацию, анти-ключи. Оператор принимает или отклоняет в один клик. Словарь растёт быстро, но растёт под подтверждением человека;
- на выходе — черновики документов и расчёт «участвовать по такой цене или отказаться»;
- в середине, где принимается решение, — правила.
Отдельно про догадку модели там, где правил ещё не хватило. Она разрешена как запасной вариант — но её доля объявлена метрикой здоровья, и эта метрика должна падать к нулю. Это редкая для ИИ-проектов постановка: успех измеряется тем, как меньше становится ИИ в рантайме.
Мониторинг отвечает «вот подходящий лот». Следующий вопрос поставщика — «а стоит ли в него идти», и на него без склада не ответить.
Позиции закупки сопоставляются с остатками клиента: по коду товара, по штрихкоду или нечётко по имени — но нечёткое совпадение обязательно подтверждает человек, и подтверждение запоминается, чтобы не разбирать одно и то же дважды.
А дальше начинается то, что в презентациях обычно опускают, — грабли, которые превращают красивую формулу маржи в неверное число:
- себестоимость часто в долларах, а закупка в сумах — нужен курс на дату, иначе маржа врёт на величину колебания;
- единицы измерения не совпадают: упаковка против штуки, коробка против упаковки. Нужен коэффициент пересчёта, иначе ошибка кратная;
- остаток — не свободный остаток: часть зарезервирована, часть в пути. Продать можно только свободное;
- одна позиция лота — это часто несколько наших артикулов, а не один;
- НДС надо считать в одной базе с обеих сторон;
- номенклатура дрейфует, поэтому сопоставления хранятся, а не пересчитываются с нуля.
Ни один из этих пунктов не про программирование. Все они про то, как устроена торговля у заказчика, — и каждый найденный до кода дешевле найденного после.
- Ставки конкурентов увидеть нельзя — их скрывают намеренно, чтобы не было сговора. Значит оценка «по какой цене идти» строится на истории цен победителей, а не на «мы видим, кто сколько поставил». Обещать второе было бы враньём.
- Площадки меняются, и это главный операционный риск, а не мелочь. Поэтому в проекте заложена канарейка: адаптер проверяет, на месте ли ожидаемые поля, и при расхождении поднимает тревогу «источник сломался». Молча отдавать пустоту система не должна — это худший вид отказа, тот, который выглядит как работа.
- Подача заявки остаётся за человеком. Электронная подпись — его, ответственность — его. Система готовит документ, отправляет его он сам. Ровно как с ИИ-декларантом: убираем перепечатывание, а не специалиста.
Заказчик пришёл не за сайтом и даже не за парсером. Ему нужно было перестать пропускать закупки, в которых он мог бы выиграть.
Работа началась с того, что мы разобрали шесть площадок до устройства каждой, нашли, что часть задачи уже решена самой площадкой, честно записали тупик и только потом спроектировали отбор — так, чтобы через год его можно было объяснить словами, а не сослаться на модель. Так же мы разбирали маркировку товара и таможенные ставки: сначала понять предмет до уровня расчёта, потом уже строить.
Оставьте номер, и мы перезвоним
Одно поле. Расскажете задачу — как удобно: звонком, в Telegram или голосовым. Сразу назовём срок и вилку цены, а на следующий день пришлём три концепции. Бесплатно.