51 прайс от поставщиков. Часть — нормальные Excel-файлы. Часть — PDF. Часть — фотографии распечатки, снятые на телефон и присланные в WhatsApp.
Снабженец сводит это в одну таблицу руками. Потом сверяет каждую строку с номенклатурой в 1С. Потому что «Цемент М500 50 кг» и «Цемент портландский М-500, меш. 50кг» — это, вообще-то, одно и то же, а компьютер об этом не догадывается.
Мы такой сервис сделали, он работает в проде у отдела снабжения строительной группы компаний, и им пользуются каждый день. Расскажу, из чего он состоит и где мы набили шишки, — потому что закупки автоматизируются не там, где кажется.
Что реально съедает время
Спросите снабженца, на что уходит день. Ответ будет не «выбор поставщика». День уходит на другое:
- перебить чужие таблицы в свою;
- выяснить, та же это труба или другая;
- найти позицию, которая в 1С называется иначе;
- перенести итог в учётную систему руками.
Собственно решение — какой поставщик лучше — занимает минуты. Остальное рутина. Её и надо снимать.
Прайсы приходят как попало
Первое, что должен уметь сервис, — разбирать чужие файлы без предварительной подготовки. Шапка на четвёртой строке, объединённые ячейки, колонка «Цена» называется «Стоимость с НДС», а поставщик не указан нигде, кроме имени файла.
Парсер ищет шапку сам и понимает синонимы колонок:
- материал — наименование, номенклатура, позиция, товар, ТМЦ;
- цена — стоимость, прайс, цена с НДС, цена за единицу;
- срок — поставка, отгрузка, срок в днях, «под заказ»;
- поставщик — берём из колонки, а нет колонки — вытаскиваем из имени файла.
Звучит просто. На деле именно эта часть даёт больше всего мелких сбоев, и доводить её приходится недели две на живых файлах.
Отдельная боль — единицы измерения. Метр погонный, штука, упаковка на 6 метров, тонна. Сравнивать позиции в разных единицах нельзя, а поставщики про это не думают. Приводим всё к общей единице и помечаем, где пересчитали. Иначе сравнение врёт, причём не на проценты, а в разы.
Сканы: OCR нужен реже, чем думают
Про то, как ИИ читает сканы, любят рассказывать первым делом. По факту это самая переоценённая часть.
Мы прогнали архив из 51 отработанного лота — заявки, конкурентные листы, счета. OCR понадобился ровно двум счетам. Остальные PDF оказались текстовыми: текст в них лежит внутри файла, его надо просто вынуть библиотекой (PyMuPDF), и это быстро и точно.
Порядок такой. Сначала достаём текстовый слой. Не вышло — тогда зовём Tesseract. Русскую модель берём из набора tessdata_best. На tessdata_fast мы потеряли пару дней: движок молча спотыкается, откатывается на английский и выдаёт латинскую кашу. Ошибки в логах нет. Результат — мусор.
Фото с телефона надо подготовить, прежде чем скармливать движку:
- перевести в чёрно-белый;
- увеличить в два раза;
- прогнать автоконтраст.
Без этого мелкий шрифт в накладной читается наполовину. Числа после OCR всегда смотрит человек — цену и количество мы автоматом в закупку не пускаем ни при каких настройках.
Ловушка гомоглифов
Теперь про грабли, ради которых стоило писать эту статью. В выгрузке номенклатуры из 1С 571 позиция числилась как «нет у поставщиков». Товар у поставщиков был.
Оказалось, что названия набраны вперемешку кириллицей и латиницей:
| Как выглядит | Что внутри | Итог |
|---|---|---|
| Сгон | латинская C вместо русской «С» | поиск не находит |
| угольник | латинская y | позиция уходит в «не найдено» |
| PN16 | латинская N в русской строке | не совпадает с номенклатурой |
Глазами это не отличить вообще. Шрифт одинаковый, длина строки та же. А для компьютера «С» и «C» — разные символы, и любое сравнение проваливается молча: не ошибка, а пустой результат.
Появляются такие вещи естественно. Человек копирует кусок названия из письма, дописывает своё, переключает раскладку — и в базе навсегда остаётся гибрид. За годы работы 1С таких позиций накапливаются сотни.
Лечится это одной функцией. В словах, где встретились оба алфавита, латинские двойники переводим в кириллицу. Чисто латинские слова — VALTEC, COMPACT, PN — не трогаем, иначе сломаем нормальные названия. Гоняем её первой, до всякого поиска.
Мораль шире одной функции: перед тем как учить ИИ работать с вашими данными, данные надо посмотреть. Не «выгрузить и загрузить», а именно посмотреть — там будут дубли, пробелы в начале строк, «ё» вперемешку с «е» и номенклатура, заведённая тремя разными людьми по трём разным логикам.
Матчинг, который дообучается
Свести чужую строку с нашей позицией — сердце всей истории. Правила и нечёткое сравнение строк неплохо тянут трубы и метизы. На инструменте, электрике и расходке они сыплются. «Бита PH2x90» и «Бита РН-2 90мм» — человеку очевидно, что это одно и то же. Алгоритму нет.
Решение оказалось не в более умной модели, а в памяти. Мы взяли архив отработанных тендеров — папки с заявками, счетами и конкурентными листами — и вытащили оттуда пары «строка поставщика → наша позиция» в том виде, как их свёл живой снабженец. Стыковка шла по цене, которая в лоте уникальна, поэтому брак в память не попадал.
Из 51 лота получилось 1374 уникальные пары. Память сопоставлений выросла с 14 803 записей до 15 519 — плюс 716 новых, и почти все как раз в слабых категориях. Дальше система дообучается сама: каждая правка снабженца («нет, это не тот кабель») сохраняется и в следующий раз применяется автоматически.
Важная деталь про конфликты: когда одна и та же строка в разных лотах сведена к разным позициям, мы решаем голосованием, а спорные случаи не трогаем вовсе. Тихо «угадывать» в закупках нельзя.
Выбор поставщика: не только цена
Самое дешёвое предложение часто самое долгое. Мы считаем по каждой позиции балл, где цена весит 0.5, срок 0.3, надёжность поставщика 0.2. Веса настраиваются: у кого-то стройка горит, и срок важнее денег.
Что это даёт на реальных листах. На одном лоте выбор сервиса полностью совпал с протоколом отдела — приятно, но неинтересно. На двух других нашлись альтернативы дешевле на 82 720 ₽ и на 298 194 ₽ при сопоставимых сроках. Это не «ИИ умнее снабженца» — это человек физически не может каждый раз перепроверить 200 позиций по семи прайсам.
Разбор архива, кстати, показал любопытное: в 73% случаев отдел брал позицию у того, кто дешевле, а в 25% — консолидировал у лидера лота, чтобы не дробить поставку. Обе стратегии разумные, и система должна показывать оба варианта с разницей в деньгах, а не навязывать один.
Как результат попадает в 1С
Финал цепочки — не красивый отчёт, а данные в учётной системе. Сервис пишет JSON, в котором лежит всё, что нужно 1С:
- уникальный идентификатор позиции (уид) — чтобы 1С поняла, куда класть;
- ключ строки заявки;
- цена, срок поставки, ставка НДС;
- поставщик и дата, на которую цена актуальна.
Файл 1С забирает по таймеру. Никто ничего не перебивает руками.
Формат обмена согласуйте с вашим 1С-ником до начала работ. Этот пункт любят отложить «на потом», а потом он съедает три недели. Мы согласовывали поля до первой строчки кода — и не пожалели.
Как мы это провалили в первый раз
Первый движок, который сводил строки, вышел слишком самоуверенным. Мы взяли нечёткое сравнение, выставили порог похожести и разрешили применять совпадения автоматически. На демо смотрелось отлично.
На реальном лоте вылезли «Кран шаровой 1/2» против «Кран шаровой 1/2 с американкой» — разные вещи, разница в цене заметная, а строки похожи на 92%. Автомат их склеил.
Что мы поменяли:
- автоприменение выключили совсем. Движок предлагает, снабженец подтверждает — одним кликом;
- совпадения ниже уверенного порога уходят в отдельный список «посмотреть глазами», а не в результат;
- каждое подтверждение запоминается, и в следующий раз эта пара уже не спрашивается;
- разные типоразмеры и исполнения (с американкой, под приварку, оцинкованный) вынесли в признаки, по которым позиции нельзя сливать даже при высокой похожести.
Урок простой. В закупках лучше показать снабженцу десять пар на проверку, чем молча ошибиться в одной. Доверие теряется на первой же неверной склейке, и обратно его собирать долго.
Чек-лист перед пилотом
Что стоит проверить у себя до того, как звать подрядчика:
- Сколько поставщиков реально шлют прайсы каждый месяц? Меньше пяти — автоматизировать нечего, хватит нормального шаблона Excel.
- В каком виде приходят файлы: Excel, PDF, фото, письма в теле сообщения?
- Есть ли у вас справочник номенклатуры, или позиции заводят прямо в заявке?
- Прогоняли ли номенклатуру на гомоглифы и дубли? Это десять минут и часто объясняет «поиск ничего не находит».
- Кто у вас 1С-ник и готов ли он согласовать формат обмена? Без него финал цепочки не собрать.
- Сохранился ли архив прошлых закупок — заявки, счета, конкурентные листы? Это топливо для памяти сопоставлений, и чем его больше, тем быстрее система становится полезной.
Частые вопросы
Сколько это стоит? Честно: фиксированного прайса у нас нет, потому что объём работ зависит от состояния ваших данных. Пилот на одном участке считается после разбора: сколько поставщиков, какие форматы, есть ли справочник. Цифру называем после аудита, а не по телефону наугад.
Нужно ли менять 1С? Нет. Обмен идёт файлом, который 1С забирает по расписанию. Конфигурацию не трогаем — это принципиально, потому что доработка чужой конфигурации стоит дороже всего остального проекта.
А если поставщики шлют прайсы в теле письма, без вложений? Разбирается тоже, но хуже: в письме нет структуры таблицы. Обычно проще один раз попросить поставщиков присылать файл — они соглашаются чаще, чем кажется.
Сколько ждать первого результата? Две-три недели до рабочего сравнения на ваших прайсах, если файлы типовые. Дальше несколько недель на накопление памяти сопоставлений, и качество заметно подрастает.
Где это не работает
Не ждите результата, если у вас нет номенклатуры. Когда позиции заводят как попало прямо в заявке, сопоставлять не с чем: сначала наведите порядок в справочнике. И делают это ваши люди, а не подрядчик. Месяц-полтора минимум.
Не работает и на уникальных позициях. Оборудование под заказ, нестандартные изделия, услуги — там сравнивать нечего, решение принимает инженер. Автоматизация окупается на потоке: сотни повторяющихся строк каждый месяц.
Про качество матчинга скажу прямо: на старте, до накопления памяти, руками приходится править заметную часть позиций. Первые недели это выглядит как «а что тут автоматизировали». Кривая идёт вверх по мере правок — и вот тут важно, чтобы у снабженца была одна кнопка на исправление, а не форма на десять полей. Иначе он просто не будет её нажимать, и система не научится.
И последнее: цену ошибки в закупках держит человек. Система готовит сравнение, показывает варианты и считает разницу. Подпись под решением ставит снабженец.
Первый шаг
Возьмите прайсы за последний месяц и посчитайте: сколько поставщиков, сколько позиций, сколько часов ушло, чтобы всё это свести. Отдельно посмотрите, какая доля файлов пришла сканами. Эти три цифры — уже готовое техзадание на пилот.
Заодно проверьте номенклатуру на гомоглифы, это делается скриптом за десять минут и часто объясняет, почему поиск «ничего не находит». Как выглядят похожие контуры на других участках — в кейсах; про то, откуда ИИ берёт правильные ответы, — в статье про базу знаний. А разбор вашего процесса закупок с оценкой, что даст эффект первым, — это AI-аудит, приходите с примерами файлов.