В пятницу вечером менеджер получает письмо: нужно 200 метров ВВГ 3х2.5, не плоский. Открывает 1С, вбивает запрос и видит 47 позиций. Какой из них круглый, а какой плоский? Какой с оболочкой ок-0.66, а какой по ТУ? Ошибёшься и на стройке машину развернут.
На одну позицию уходит 4–7 минут. Пять позиций в заявке, двадцать заявок в день. К концу недели уже не в номенклатуру смотришь, а в стену.
Это классическая задача, на которой ломаются универсальные AI-агенты. Расскажу, как мы сопоставляем свободный текст клиента со справочником на 12 тысяч позиций.
Почему регулярки и Левенштейн сразу сдают Первый порыв написать парсер: вытащить марку, сечение, исполнение и через ILIKE найти кандидатов. На бумаге красиво, на реальных заявках нет.
Клиенты пишут как хотят: ВВГ-3*2,5, провод ВВГнг 3 на 2.5, ВВГ 3×2,5 не круглый. При этом «не плоский» у нас означает как раз круглый, потому что плоский — это ВВГ-П. Левенштейн путает 3х2.5 с 3х4 (разница в цене в два раза), а полнотекстовый поиск отдаёт те же 47 вариантов.
Двухступенчатая схема Шаг 1. Векторное отсеивание Прогоняем всю номенклатуру через эмбеддинг-модель, нормализуем строки (убираем лишние пробелы, приводим «х» и «×» к одному виду, разворачиваем сокращения) и складываем в pgvector. Запрос клиента проходит ту же обработку.
Ищем по косинусной близости, берём топ-15. Задача просто отсеять 11 985 заведомо не тех позиций.
Шаг 2. LLM как дешифратор Топ-15 отдаём GigaChat Pro с чётким промптом: Клиент написал X. Вот 15 позиций. Выбери одну или верни null. Объясни выбор по атрибутам, а не по похожести строк.
Важно, жёсткий JSON Schema. Модель не может придумать новый SKU, только выбирает из списка. Если ничего не подошло, заявка идёт менеджеру.
Порог уверенности Самое интересное было не с моделью, а с порогом confidence. Разметили 1200 реальных заявок и получили такую картину:
0.95+ — 98.4% точности (71% заявок) 0.80–0.94 — 91.2% 0.60–0.79 — 73% ниже 0.60 — 41.5% Порог автоподтверждения поставили на 0.90. В итоге 76% позиций уходит автоматически, 20% — в полуавтомат, 4% — на ручной разбор.
Почему первый подход провалился Сначала попробовали просто эмбеддинги и топ-1 по близости. На синтетике было 78%, в проде упало до 61%. Модель не различала, что сечение 2.5 и 4 это два разных товара.
Пришлось явно прописать в промпте приоритеты: Сечение, количество жил и исполнение должны совпадать буквально. После этого точность прыгнула до 94%.
Что получилось в цифрах Время на позицию: 4–7 минут — 15 секунд (при высоком confidence) Доля заявок за 24 часа: 64% — 97% Ошибок с “привезли не то”: 11 в месяц — 2
Главный вывод Одним LLM-вызовом на 12 тысяч позиций не обойдёшься — либо контекст не влезет, либо дорого. Один pgvector без LLM будет путать то, что путать нельзя.
Рабочая схема: эмбеддинги для грубой фильтрации + LLM для финального выбора + порог уверенности для разделения автомата и человека. И обязательно считайте метрики на реальных заявках, а не на синтетике.
ссылка на оригинал статьи https://habr.com/ru/articles/1057048/