«Сделайте, чтобы бот отвечал по нашим документам» — самая частая формулировка среди задач с ИИ, которые мы видим. Ожидания у заказчика простые: загрузили папку, бот всё выучил, дальше отвечает.
Работает это иначе, и разница объясняется за десять минут. Ниже — как такой сервис устроен внутри, из каких частей собирается и что в нём ломается.
Почему нельзя просто загрузить документы в модель
Языковая модель ничего не запоминает между разговорами. Всё, что она «знает» о вашей компании, помещается в одно сообщение: в тот текст, который вы отправили ей вместе с вопросом. Закрыли диалог, открыли новый — она снова не знает про вас ничего.
Первое, что приходит в голову, — дообучить модель на своих документах. На практике это слабый способ загрузить в неё факты: дообучение хорошо меняет манеру и формат ответа, но не гарантирует, что конкретный пункт регламента воспроизведётся дословно. А регламенты правят, и переучивать модель после каждой правки никто не станет.
Второй вариант: сложить весь архив прямо в сообщение. Объём одного запроса ограничен, оплачивается он по количеству текста, и качество ответов на большом ворохе документов падает: нужный абзац тонет среди тысяч ненужных.
Отсюда решение, к которому пришли почти все: документы держат снаружи, а в момент вопроса подкладывают модели только те куски, которые к вопросу относятся.
Что такое RAG
RAG расшифровывается как retrieval-augmented generation — «генерация с опорой на поиск». Механика в одном предложении: перед тем как ответить, система ищет в ваших документах подходящие фрагменты и отдаёт их модели вместе с вопросом пользователя.
Ближайшая аналогия — экзамен с открытой книгой. Отвечающий не помнит учебник наизусть, зато умеет быстро найти нужную страницу и сформулировать по ней ответ. Качество зависит от двух вещей: насколько точно найдена страница и насколько аккуратно пересказано найденное.
Для заказчика тут обычно сюрприз: основная работа над «умным ботом» приходится на поиск, а вызов модели оказывается последним и самым простым шагом.
Из каких частей он собирается
- Сбор документов. PDF, Word, таблицы, страницы внутренней вики, переписка поддержки. Всё приводится к тексту: сканы через распознавание, таблицы отдельной обработкой.
- Нарезка на фрагменты. Документ режут на куски такого размера, чтобы кусок оставался осмысленным и помещался в запрос. Режут с перехлёстом и тащат за собой заголовок раздела, иначе фрагмент теряет контекст.
- Эмбеддинги. Каждый фрагмент превращают в набор чисел, отражающий его смысл. Близкие по смыслу тексты дают близкие наборы — на этом и держится поиск.
- Хранилище. Векторная база. Расширение pgvector, если данных немного и PostgreSQL в проекте уже есть, либо отдельное хранилище вроде Qdrant.
- Поиск по вопросу. Вопрос превращают в такой же набор чисел и достают ближайшие фрагменты. Обычно поиск делают гибридным: по смыслу и по ключевым словам одновременно.
- Сборка запроса. Найденные фрагменты, вопрос и инструкция — отвечать только по приложенному, а при нехватке данных прямо сказать, что ответа нет.
- Ответ со ссылками. Рядом с ответом указано, из какого документа и какого раздела он собран.
Последний пункт заказчики почти никогда не заказывают, а пользуются им больше всего: без ссылки на источник сотрудник не может проверить ответ и перестаёт доверять всей системе после первой же ошибки.
Что в нём ломается чаще всего
Почти все проблемы приходят со стороны данных, а не со стороны модели.
Документы у заказчика редко бывают в приличном виде. Сканы без текстового слоя, из которых ничего не извлекается. Три версии одного регламента в разных папках, и никто не помнит, какая действующая. Таблица с объединёнными ячейками, которая при переводе в текст превращается в столбик чисел без подписей. Презентации, где половина смысла нарисована картинками.
Дальше нарезка. Если определение термина разорвано между двумя фрагментами, поиск принесёт половину, а модель уверенно достроит вторую. Поиск по смыслу сам по себе плохо работает с артикулами, номерами документов и фамилиями: «приказ 415-П» по смыслу похож на «приказ 415-Н», и без ключевого поиска система их путает.
Права доступа обычно вспоминают в конце. Бот, который отвечает любому сотруднику по любому документу, включая приказы по зарплате, — надёжный способ закрыть проект на первой неделе.
И поведение, которое надо проверять отдельно: что система делает, когда ничего не нашла. Без явной инструкции и проверки она соберёт правдоподобный ответ из ничего, тем же уверенным тоном, что и правильный. Проверяется это легко — задайте вопрос, ответа на который в документах заведомо нет, и посмотрите, что придёт.
Как понять, что он работает
Ощущение «вроде отвечает нормально» не годится: оно держится ровно до момента, когда бот выдаёт директору неверный пункт договора.
Рабочий способ — собрать несколько десятков реальных вопросов с заранее известными правильными ответами. У заказчика они уже есть: в переписке поддержки, в списке частых вопросов, в голове у сотрудника, которого все дёргают. Дальше прогоняем набор и смотрим на две разные вещи по отдельности. Первая — нашёлся ли вообще нужный фрагмент; это качество поиска. Вторая — правильно ли модель ответила по найденному; это качество генерации. Когда их меряют вместе, чинить нечего: непонятно, какая половина сломалась.
Отдельной строкой идёт доля отказов. Система должна говорить «в документах этого нет» ровно тогда, когда этого действительно нет, и не пользоваться этой фразой как удобной отговоркой на сложных вопросах.
Сколько это занимает и во что обходится
Срок определяется состоянием документов. Если материалы уже в текстовом виде и их немного, первая рабочая версия собирается за несколько дней. Если начинается со сканов, разнородных таблиц и вопроса «а где у нас актуальная версия», счёт идёт на недели, и большая часть уйдёт на подготовку данных.
Расходы на работающем сервисе складываются из трёх частей: вызовы модели, хранилище и сервер. Вызовы считаются по объёму текста, а объём тем больше, чем больше фрагментов подкладывается в каждый запрос, — то есть щедрая настройка поиска напрямую стоит денег каждый день. Конкретные тарифы меняются слишком часто, чтобы называть цифры в статье: считать надо на момент запуска.
Простая проверка перед стартом — прикинуть стоимость одного ответа и умножить на ожидаемое число обращений в месяц. После этого умножения иногда выясняется, что задачу закрывает нормальный поиск по сайту и пара статей в базе знаний.
Что нужно уметь, чтобы собрать такое
Python, работа с API, база данных, деплой и понимание того, как ведёт себя модель. По отдельности ни одна часть не сложная. Тяжесть в том, чтобы соединить их и удержать качество на чужих данных, которые меняются без предупреждения.
Полный набор навыков и остальные задачи этой профессии мы разобрали в статье о том, чем занимается ИИ-инженер.
Если выбираешь направление, сравни программы треков Quillon: в каждой расписано, что учишь и какие проекты делаешь.
