- Главная
- Блог
- «Кабель ВВГ 3х2.5, не плоский» — как мы научили ИИ-агента попадать в справочник 1С с первого раза
«Кабель ВВГ 3х2.5, не плоский» — как мы научили ИИ-агента попадать в справочник 1С с первого раза

Знакомая ситуация: под вечер пятницы менеджеру оптового поставщика электрики падает письмо: «Здравствуйте, нужно 200 метров ВВГ 3х2.5, не плоский, с доставкой на склад до вторника». Менеджер открывает 1С, забивает «ВВГ 3х2.5» в поиск номенклатуры — получает несколько десятков позиций. «Кабель ВВГнг(А)-LS 3х2.5 ок-0.66 ГОСТ», «Кабель ВВГ-Пнг(А)-LS 3х2.5», «Провод ВВГнг 3х2.5 ТУ» и ещё пачка вариантов. Какой из них «не плоский»? Какой «ок-0.66», а какой «ок-1»? ГОСТ или ТУ — клиент не уточнил, но если ошибиться, поедет не то, и приёмка на стройке развернёт машину.
На такую заявку менеджер тратит несколько минут: уточнить, перепроверить, открыть карточку товара, посмотреть остатки. В заявке таких позиций пять. В день — пара десятков заявок. К концу пятницы человек смотрит уже не в номенклатуру, а в стену.
Это типичный B2B-сценарий, на котором ломаются «универсальные» ИИ-агенты. Расскажу, как мы у одного из заказчиков сопоставили свободный текст клиента со справочником 1С на двенадцать тысяч позиций, где вылезли первые грабли и почему пришлось переделывать архитектуру после первой недели в проде.
Почему регулярки и Левенштейн здесь сдаются первыми
Первый инстинкт инженера — написать парсер. Достать марку («ВВГ»), сечение («3х2.5»), исполнение («не плоский»), а дальше через ILIKE найти кандидатов в номенклатурной таблице. На бумаге работает. На живых заявках — нет.
Клиенты пишут как угодно: «кабель ВВГ-3*2,5», «провод ВВГнг 3 на 2.5», «ВВГ 3×2,5», «кабель силовой 3х2,5 квадрата». В одной заявке встретили «ВВГ 3х2,5 не круглый» — а в нашей терминологии «не плоский» означает как раз круглый, потому что плоский кабель — это ВВГ-П. Клиент сказал правильную вещь неправильными словами. Мы полдня сидели, спорили с товароведом, кто прав, пока не поняли: правы оба, просто на разных языках.
Левенштейн на таких данных даёт ложные совпадения: «ВВГ 3х2.5» и «ВВГ 3х4» отличаются на одну цифру, а это разные товары с разрывом в цене вдвое. Полнотекстовый поиск Postgres находит всё, что содержит подстроку, и приносит те же самые несколько десятков кандидатов — то же, что у менеджера в 1С. Мы не убрали проблему, мы её перенесли.
Архитектура: эмбеддинги отсеивают, GigaChat Pro выбирает
После пары неудачных заходов пришли к двухступенчатой схеме. Не потому что она красивая, а потому что каждая ступень закрывает то, на чём валится соседняя.
Шаг 1. Векторное сужение кандидатов. Прогоняем всю номенклатуру через эмбеддинг-модель и складываем в pgvector. Перед эмбеддингом нормализуем строки: убираем лишние пробелы, приводим «х» и «×» к одному виду, разворачиваем сокращения («ок» → «оболочка кабеля»), оставляем ГОСТ/ТУ маркеры. Запрос клиента проходит ту же нормализацию — иначе эмбеддинг «ВВГ 3*2,5» и «ВВГ 3х2.5» уплывают друг от друга сильнее, чем хотелось бы.
Поиск по косинусной близости возвращает топ-15 кандидатов. На этом шаге мы не пытаемся найти точный ответ — задача отсеять почти двенадцать тысяч заведомо не подходящих позиций и оставить короткий список, с которым уже можно работать по-взрослому.
SELECT sku, name, attributes,
1 - (embedding <=> $1) AS similarity
FROM nomenclature
WHERE is_active = true
ORDER BY embedding <=> $1
LIMIT 15;
Шаг 2. LLM-дешифратор. Топ-15 уходят в GigaChat Pro с промптом в духе: «Клиент написал X. Вот 15 позиций из нашего справочника с атрибутами. Выбери одну подходящую или верни null, если ни одна не подходит. Объясняй выбор по атрибутам, не по похожести строк».
Принципиальный момент — структурированный вывод через JSON Schema: {sku, confidence, reasoning, alternatives}. Модель не имеет права выдумать новый SKU, она выбирает только из присланного списка. Если клиент попросил «ВВГ-П» (плоский), а в топ-15 плоских нет — модель возвращает null, и заявка идёт менеджеру. Это тот случай, когда автономные ИИ-агенты обязаны уметь честно сказать «не знаю», иначе бизнес получает не ускорение, а тихий саботаж.
Где поставить границу для человека
Самая интересная инженерная работа была не с моделью, а с порогом уверенности. Про это редко пишут, а зря — именно там ИИ-агент превращается из демки в рабочий инструмент.
confidence от LLM — это не вероятность, это самоотчёт модели. Калибровать его пришлось эмпирически. Взяли выборку размеченных вручную заявок и посмотрели, на каких уровнях уверенности модель ошибается, а на каких — нет.
Картина получилась ожидаемая, но с сюрпризом: между «модель уверена» и «модель почти уверена» разрыв в точности заметный, а вот всё, что модель сама помечает как «серединка на половинку», в бой пускать нельзя — там ошибки идут пачками.
Порог автоподтверждения после нескольких итераций поставили на 0.90. Всё, что выше — летит в заявку без человека. Средняя зона — попадает в очередь «уточнить у менеджера» с подсветкой альтернатив: одной кнопкой либо подтверждаешь, либо выбираешь другой вариант. Всё, где модель откровенно плывёт — уходит в полноценный ручной разбор, и там же ИИ-агент сам пишет клиенту вежливое «уточните, пожалуйста, что именно нужно, вот варианты».
По ощущениям менеджеров, большая часть позиций теперь уходит в автомат, ощутимый кусок — в полуавтомат в один клик, и совсем небольшой хвост требует полноценного разбора. Точные проценты плавают от недели к неделе в зависимости от того, кто именно пишет заявки — розничники или прорабы со стройки.
Первый подход провалился. Почему
Стартовали мы с одной ступени: эмбеддинги без LLM, просто берём топ-1 по близости. На синтетических тестах работало неплохо. В проде посыпалось за первую же неделю: менеджеры начали присылать скриншоты в чат с подписью «оно что, серьёзно?».
Причина оказалась структурной. Эмбеддинги отлично ловят семантическую близость текстов, но не различают атрибуты, где одна цифра меняет смысл. Для модели «ВВГ 3х2.5» и «ВВГ 3х4» почти одно и то же: тот же кабель, то же количество жил, тот же тип. А для прайса это два товара с разной ценой и разной полкой на складе.
LLM-слой решил проблему потому, что мы прямо в промпте прописали приоритеты: «Сечение, количество жил и исполнение должны совпадать буквально. Тип изоляции — желательно. Производитель — опционально». Модель перестала путать 2.5 с 4 не потому что стала лучше «видеть», а потому что мы явно указали ей, на что смотреть в первую очередь. Это, кстати, общий принцип для новых ИИ-агентов на своих данных: без явной иерархии атрибутов модель по умолчанию ведёт себя как расслабленный стажёр — вроде похоже, ну и ладно.
Что изменилось в работе
Мерили на оптовом поставщике с плотным потоком заявок, в каждой — несколько позиций.
Разбор одной строки раньше занимал у менеджера несколько минут: перечитать, уточнить, полазить по 1С. Теперь на автоподтверждённой позиции — доли минуты, на полуавтоматической — минута с небольшим на подтверждение. По суммарному времени: то, на что раньше уходил полный день, укладывается в первую половину дня, и это без переработок.
Доля заявок, которые полностью закрываются в первые сутки, выросла заметно — с «половина висит на завтра» до «почти всё улетает в тот же день». Заявок, развернувшихся из-за ошибки в номенклатуре, стало сильно меньше — единичные случаи в месяц вместо стабильного потока. Менеджеры перестали работать по субботам — это не метрика, но в чате появилось много благодарных смайликов, а один сотрудник наконец-то съездил на дачу.
Отдельная приятная штука — освободившийся человек ушёл в повторные продажи по тёплой базе. Там деньги совсем другого порядка, чем экономия на обработке входящих.
Что забрать с собой
Сопоставление свободного текста с жёстким справочником — задача, на которой ломается интуиция «давайте просто прикрутим LLM». Один LLM-вызов на двенадцать тысяч кандидатов либо не влезет в контекст, либо будет стоить как чугунный мост. Один pgvector-поиск без LLM путает то, что нельзя путать.
Рабочая схема — эмбеддинги для грубой фильтрации, LLM для финального выбора, threshold для разделения автомата и человека. Промпт должен явно перечислять атрибуты по приоритету, иначе модель будет ловить «семантически похожее, но не то». И желательно, чтобы у вас была не одна модель в вакууме, а небольшая команда ИИ-агентов с разными ролями: один нормализует и ищет, другой выбирает, третий пишет клиенту уточнение. Дробить логику по ролям проще, чем потом ловить регрессии в одном большом промпте на всё сразу.
И главное: считайте качество не на синтетике, а на размеченных заявках из своего же потока. На наших синтетических тестах первая версия выглядела отличницей. Прод оценку поставил быстрее и честнее — за неделю.
Если в вашей номенклатуре заметная доля позиций различается «одной цифрой» — голый векторный поиск вас подведёт, проверено на живых людях и живых заявках. И ещё одно наблюдение напоследок: не пытайтесь сразу собрать личного ИИ-агента, который делает всё. Начните с одной узкой задачи, где ошибки видны глазом и легко размечаются. На ней и калибруйте — а дальше уже пристраивайте следующие ступени.
Похожие статьи
- Как мы научили ИИ-агента на GigaChat Pro не путать живого клиента с ночным батчем
- Как мы настроили ИИ-агента для поиска в 1С: MCP-сервер вместо метаний между окнами
- Один вопрос — три темы: как мы научили ИИ-агента разбирать составные запросы
- Text2SQL для 340 таблиц: как мы собирали ИИ-агента для анализа корпоративных данных на GigaChat Pro




