Одно из важнейших направлений нашего бизнеса — разработка программ для автоматизации бизнес‑процессов, управления и учёта предприятий и организаций. А одна из наших главных обязанностей перед пользователями наших продуктов — предоставлять им техподдержку, отвечать на вопросы — как использовать наши продукты для различных бизнес‑процессов и в соответствии с текущим законодательством и нормативами. Для этого у нас есть сервис с базой знаний, называется ИТС (информационно‑технологическое сопровождение).
На сегодня у нас есть 30+ программных продуктов и документация по ним. А ещё есть постоянно пополняемая база нормативных документов. Идеальная схема процесса:
-
Пользователь задает вопрос в привычной ему форме, например:
Как в 1С драйв начислить бонусные баллы покупателю
Налоговая реформа 2025
Розница 2.3 настроить продажу разливного пива
-
И получает ответ
При необходимости — пошаговую инструкцию: что и как нужно сделать в программном продукте для работы требуемой функциональности.
Выдержки из нормативных документов, относящихся к заданному вопросу, со ссылками на исходный текст этих документов.

На заре времен все подобные вопросы решались на уровне телефонной техподдержки с живым экспертом на нашем конце провода. Потом поддержка в основном перешла в онлайн‑чат с тем же экспертом у монитора‑клавиатуры.
С появлением и взрослением ИИ логичным шагом стал переход с живого эксперта на ИИ‑бота.
Как мы его сделали, как обучали, как организовали интеллектуальный поиск по базе документов, почему и как задействовали векторный поиск — ниже.
Все вы, конечно, слышали про интеллектуальных ассистентов, которые помогают решать различные прикладные задачи. Мы также разработали собственное решение, которое является дополнением нашего портала знаний ИТС и позволяет пользователям быстрее находить нужную информацию, получая ответы на свои вопросы.
Наш бот находится по адресу https://portalchat.1c.ai/ (требует для работы аккаунт на сайте ИТС). Бот отвечает на вопросы по продуктам 1С, к ответам также прикладываются ссылки на исходные документы, по которым можно перейти и посмотреть исходный текст документа. Поддерживается взаимодействие в виде чата, в ходе диалога можно скорректировать вопрос и посмотреть историю предыдущих сообщений.

У бота есть ограничения: он может отвечать только на вопросы, ответы на которые содержатся в материалах, размещённых на сайте ИТС. При ответе бот не использует «собственные» знания и не может выполнять произвольные задачи; то есть его предметная область ограничена содержанием нашего портала.

Остановимся на документах, на основании которых бот отвечает на вопросы. В качестве базы знаний мы используем документы с нашего портала: это официальная платформа, на которой содержится документация по нашим программным продуктам, а также рекомендации по налогообложению, новости по вопросам учёта и другие материалы которые могут быть полезны нашим пользователям. Ориентировочно это десятки тысяч статей.

Если посмотреть на распределение вопросов, с которыми к нам обращаются пользователи, то видно, что большая часть вопросов связана с выполнением типовых операций в продуктах 1С, с настройкой и администрированием системы, со стоимостью программного обеспечения, а также вопросы, связанные с нюансами законодательства, правилами ведения учёта и так далее

Ниже — примеры реальных пользовательских вопросов. Хорошо видно, что формулировки вопросов могут сильно различаться. Пользователь может задать вопрос так, как он бы задавал его в поисковой системе, например, «налоговая реформа 2025», или сформулировать его более естественным образом — «как работает переход на новый тариф 1С:Распознавание первичных документов». Во всех случаях нам нужно корректно обработать вопрос и выдавать релевантную информацию.

Остановимся на архитектуре бота. Поскольку ответы предполагается снабдить ссылками на документы (а их база постоянно пополняется), то использовать готовую языковую модель было бы недостаточно. Вместо этого у нас реализован сложный многошаговый алгоритм, в ходе которого мы анализируем запрос пользователя, извлекаем его ключевые части, подбираем релевантные документы и только после этого формируем ответ. Такой подход позволяет нам уменьшить количество «галлюцинаций» и повысить вероятность правильного ответа.

Зачем нам нужна такая сложная процедура для обработки запросов?
Ниже — два примера ответа на один и тот же запрос «цифровые деньги учёт в 1С». Слева — модель, которой не предоставлены документы для ответа, отвечает, что для учёта цифровых денег в 1С есть модуль 1С:Криптовалюта, и даёт развёрнутый ответ, исходя из этой информации. По факту же модуля для учёта криптовалюты в 1С нет, и эта информация являются галлюцинацией модели.
Справа — ответ нашей системы, которая использует знания из документов портала. Видно, что она корректно определила, что учёт цифровых рублей ведётся на счёте 53 «Счёт цифрового рубля» и дала ссылку на соответствующий документ из базы знаний.

Как можно добавлять новые знания в языковую модель? Самый очевидный способ — это дообучение, берём базовую языковую модель и дообучаем её на специализированном датасете вопросов и ответов. Преимущество этого способа в том, что мы можем потенциально достичь высокого качества генерации ответов, но при этом есть ряд серьёзных недостатков.
Во‑первых, нужен большой объём размеченных данных, относящихся нашей предметной области.
Далее, нужны достаточно серьёзные ресурсы для первоначального обучения модели и дальше, при каждой итерации обновления знаний в нашей базе придётся заново создавать набор обучающих данных и заново обучать модель. Это достаточно трудоёмкий процесс, и не совсем очевидно, принесёт ли он значимое улучшение. Такое дообучение не является универсальным и не подходит для областей, где происходит быстрое и постоянное обновление базы знаний.
Альтернативой дообучения является использование поиска по документам. Это подход у нас сочетает два механизма: сначала система выполняет семантический поиск по базе документов, чтобы найти документы, связанные с запросом пользователя, а затем система передаёт найденные фрагменты документов в языковую модель, которая формирует итоговый ответ.
Основным преимуществом является актуальность ответов. Можно обновлять базу знания без переобучения моделей и модель даёт обоснованные ответы, потому что опирается на реальные источники знаний, которые есть в нашей базе.
У такого подхода есть и недостатки. Требуется достаточно качественный поиск релевантных документов, потому что каждый документ влияет на качество ответа. Если мы предоставим нерелевантный документ при ответе на вопрос, то есть шанс, что языковая модель будет генерировать некорректную информацию.

Чтобы этот подход работал эффективно и поиск был качественным, важно понимать, какие существуют типы поиска и в чём разница между ними.
Есть классический полнотекстовый поиск. Для того, чтобы он хорошо работал, в запросе должен быть текст, точно совпадающий с текстом документа, в котором находится интересующая пользователя информация. Если же в запросе есть опечатки, неточности, или отсутствуют слова, которые есть в искомом документе — в таком случае документ может быть не найден полнотекстовым поиском, и мы не сможем дать хороший ответ.
Второй способ — это векторный поиск. Он позволяет лучше справляться с различными формулировками, понимает синонимы, допускает опечатки. Также плюсом является то, что он поддерживает мультиязычность «из коробки», то есть мы можем не знать, на каком языке написан исходный запрос и составлены документы, в которых проводится поиск.

Как работает векторный поиск?
Сначала мы преобразуем все документы в векторы с помощью специальной нейросетевой модели. Каждый документ превращается в числовое представление (от 512 до 2048 чисел, в зависимости от конкретной используемой нами модели), после чего числовые представления документов отправляются в базу данных. Этот «подготовительный» этап происходит при начальной загрузке данных либо при обновление данных для каждого обновляемого документа. Когда пользователь задаёт вопрос, его запрос прогоняется через ту же самую векторную модель, сервис получает вектор запроса и ищет в базе документ, который находится ближе всего к заданному пользователем вектору (то есть максимально похожий по смыслу). На выходе мы получаем набор релевантных документов, отвечающих запросу пользователя.

Для генерации векторов мы используем специальную векторную модель; есть разные виды векторных моделей, они отличаются по размеру, по качеству работы по скорости, по требованиям к ресурсам. Для нашего проекта мы выбрали модель multilingual‑e5-large. Это open source модель, которая показала хорошие результаты и на открытых бенчмарках, и на наших внутренних тестах. При этом она является относительной легковесной и имеет нативную поддержку мультиязычности. Т.е. можно использовать одну и ту же модель как для документов на русском, так и на других языках.

В сервисе есть отдельный компонент, отвечающий за хранение документов, преобразованных в вектора. В качестве базы данных для этого компонента мы используем PostgreSQL и расширение pgVector. У нас есть опыт в администрировании PostgreSQL, у этой базы достаточно хорошая отказоустойчивость, поэтому мы решили использовать её.
Поиск по документам может выполняться значительное время. Чтобы ускорить его, мы используем приближённый алгоритм векторного поиска HSNW (Hierarchical navigable small world). Это алгоритм, который строит граф из векторов, где каждый узел графа связан с соседними. Мы не обращаемся непосредственно в БД для поиска релевантных документов, а находим ближайший к узлу документ, после чего идём к соседним с ним документам и ищем только среди соседей. Такое решение показало хорошие результаты на наших данных. Отдельным плюсом является быстрое обновление данных при загрузке новых документов. Качество поиска (то есть релевантность ответа запросу) также является достаточно высоким.

При работе с векторной моделью есть существенное ограничение: документы могут быть сколь угодно длинными, но у векторной модели есть ограничение окна контекста в 512 токенов. Если передать текст длиннее этого лимита — он будет отрезан, и мы потеряем релевантную информацию. Чтобы с этим справиться, мы нарезаем документы на фрагменты, после чего сохраняем в базе фрагменты документов (со ссылкой на исходный документ) и осуществляем поиск по этим фрагментам.
Токеном может быть отдельное слово, но, если слово длинное — модель может разбить слово на несколько токенов.

Этот подход ставит перед нами задачу — как по найденным фрагментам определить наиболее релевантные документы. Эту задачу мы решаем в два этапа.
Сначала из векторной базы мы получаем 100 фрагментов‑кандидатов и затем ранжируем эти фрагменты таким образом, что вверх попадают документы, для которых было извлечено больше всего фрагментов из векторной базы (то есть они более релевантны запросу и их оценка векторной модели достаточно высока). Из упорядоченного набора фрагментов мы получаем упорядоченный набор исходных документов, у каждого из которых будет выставлена релевантность на основании оценок векторной модели.

Чтобы иметь возможность объективно оценивать качество поиска, мы собрали набор тестовых запросов, приближённых к реальным вопросам, которые задают пользователи. Это были специально отобранные запросы, на которых полнотекстовый поиск сработал плохо. Мы хотели, чтобы бот искал документы более качественно, и такой набор сложных запросов позволяет нам точнее измерять эффективность поиска. Для каждого запроса мы определили релевантный документ, в котором содержится корректный ответ, и ключевые слова, которые должны присутствовать в ответе. На таком датасете мы сравнили качество полнотекстового поиска и векторного поиска и выяснили, что векторный поиск практически в два раза лучше. Это подтвердило нашу гипотезу, что векторную модель использовать более эффективно.
Алгоритм поиска |
Качество (сложные вопросы) |
Полнотекстовый поиск |
20% |
Векторный поиск |
39% |
Для дальнейшего повышения качества мы решили дообучить векторную модель, чтобы она лучше понимала терминологию, используемую в документах. Для этого мы сгенерировали набор синтетических данных, используя языковую модель: на вход языковой модели подавались документы, на выходе языковая модель генерировала вопросы, ответы на которые могут находиться в этих документах. В результате мы получили пары вопрос‑документ, на которых мы дообучили языковую модель, и в результате получили рост количество поисков кандидатов на 8%.
(1С:ЗУП — программный продукт «1С:Зарплата и Управление Персоналом»).

Следующим шагом мы реализовали улучшение алгоритма переранжирования. На первом этапе мы использовали для ранжирования ту оценку, которую вернула векторная модель, но из‑за того, что вектор не всегда отражает семантический смысл вопроса, оценки могут быть не совсем точными. Например, векторная модель считает запросы «Как пойти в отпуск» и «Как не пойти в запланированный отпуск» очень близкими, но их значение диаметрально противоположно.
Поэтому мы переоцениваем 50 кандидатов, которых мы получили после обращения к векторной модели, с помощью языковой модели (LLM). LLM лучше понимает языковые нюансы и, таким образом, исправляет ошибки векторной модели.

После того, как мы получили набор кандидатов, мы повторно отправляем каждого из этих кандидатов в языковую модель, снабжая кандидата дополнительной информацией (в частности, из какого документа этот кандидат взят, какой заголовок у этого документа). После чего языковая модель возвращает нам оценку от 1 до 10, что позволяет нам принять более обоснованное решение — действительно ли этот документ нам подходит или он просто похож «в векторном смысле» на релевантный документ, но на самом деле не отвечает на запрос пользователя.

После оценки на нашем тестовом датасете выяснилось, что такая доработка даёт нам существенный прирост в качестве поиска — с 47% точность увеличилась до 61%, что является очень существенным улучшением.
Алгоритм поиска |
Качество (сложные вопросы) |
Полнотекстовый поиск |
20% |
Векторный поиск (базовая) |
39% |
Векторный поиск (дообученная) |
47% |
Векторный поиск (дообученная + переранжирование) |
61% |
Пользователи часто задавали боту вопросы следующего характера. В запросе может быть явно указан программный продукт 1С или сервис 1С, к которым относится вопрос, но найденные в базе документы относятся к другому продукту или сервису. С точки зрения языковой модели текст документа может быть релевантен запросу, но при этом мы заранее знаем, что этот документ относится к другой предметной области. При этом на сайте есть разметка — какие документы относятся к какому программному продукту/сервису.

Чтобы решить эту задачу, мы реализовали двухэтапный сценарий. Сначала языковая модель извлекает из запроса пользователя продукт или сервис 1С, а затем поиск идёт только среди тех документов, которые описывают указанный продукт или сервис. Это нехитрое, казалось бы, улучшение позволило нам поднять качество поиска на 11%.
Алгоритм поиска |
Качество |
Векторный поиск (базовая) |
39% |
Векторный поиск (дообученная) |
47% |
Векторный поиск (дообученная + переранжирование) |
61% |
Векторный поиск (то же + знания о конфигурации) |
72% |
Также мы столкнулись с тем, что языковые модели нередко неправильно интерпретируют термины и аббревиатуры, которые пользователи используют в запросах. Например, языковая модель придумывает некорректные расшифровки аббревиатур. Можно, конечно, использовать дообучение, но это достаточно трудоёмкий процесс, хотелось обойтись чем‑нибудь более простым. Мы предоставили языковой модели словарь терминов и аббревиатур (с корректными расшифровками аббревиатур). Это улучшило качество поиска ещё на 4%.

Алгоритм поиска |
Качество |
Векторный поиск (дообученная + переранжирование) |
61% |
Векторный поиск (то же + знания о конфигурации) |
72% |
Векторный поиск (то же + термины) |
76% |
Ещё у нас есть дополнительная логика, которая помогает правильно обрабатывать разные типы запросов. Не каждый вопрос требует полноценного поиска по базе документов. Чтобы определить такие запросы у нас реализован классификатор запросов. Если пользователь задал вопрос «Привет» или «Что ты умеешь?», то для ответа на такие вопросы нам не обязательно обращаться к поиску по документам; это не запрос к базе знаний, это запрос про функциональность самого ассистента. Мы добавили этап классификации запросов, на котором мы определяем, нужно ли нам использовать базу знаний для ответа или достаточно просто информации о самом чат‑боте. Во втором случае мы направляем пользователя на специальный промпт, в ходе которого выполняется генерация ответа напрямую, без запуска сложного пайплайна поиска.

Также в системе реализован отдельный модуль‑перефразировщик запроса. Бывает, что пользователи задают уточняющие сообщения в формате диалога. Например, текст от пользователя «Я не планировал отпуск что мне в таком случае делать» сам по себе — это уточнение, мы не можем просто отправить такой текст в поиск, потому что это даже не всегда вопрос, а просто уточняющий текст к предыдущему вопросу, вырванный из контекста.
Поэтому мы сделали отдельный механизм, который в ходе диалога «пользователь — бот» собирает историю переписки и на основании этой истории формулирует полный вопрос, который нужно отправить в поисковую систему. Далее, на основании этого полноценного поискового запроса, подбираются релевантные документы. Преимуществом такого подхода является то, что у нас унифицирован пайплайн поиска, на каждом этапе в поиск уходит чётко сформулированный запрос. Мы всегда обрабатываем некоторую историю, последние N сообщений, и генерируем полноценный ответ. Это значит, что мы не ограничены размером некоторого «окна» — пользователь может бесконечно продолжать диалог и в каждый момент получать корректные ответы. В чате есть ограничения — модель не может возвращаться к слишком старым диалогам, но мы считаем, что в нашем случае это достаточно редкий сценарий. Использование перефразировки также повышает качество ответов.

Для генерации финальных ответов мы используем открытые языковые модели, которые находятся в общем доступе (как as is, так и дообученные нами). Для каждого вида запросов (фактологический вопрос, мета‑вопрос и других) мы используем собственный промпт с возможностью его конфигурирования. При генерации ответа бот прикладывает к ответу ссылки на документы; чтобы корректно распарсить эти ссылки на фронтенде, они должны быть в определённом формате, который мы задаём для языковой модели. Мы столкнулись с тем, что языковая модель не всегда хорошо генерирует такие ссылки, поэтому мы применяем подход Few‑shot. Вместе с обычной инструкцией по тому, как нужно форматировать эти ссылки, мы «показываем» модели несколько примеров, в которых есть правильные ответы с корректно вставленными ссылками. Это позволяет добиться стабильного результата с корректными ссылками.

В нашей системе есть сбор обратной связи от пользователей. Это важная часть пайплайна, благодаря которой мы можем объективно оценивать работу ассистента и принимать решение о том, что именно нуждается в улучшении. Есть прямая связь от пользователей, они могут поставить лайк / дизлайк, выставить оценку ответа от одного до пяти, написать комментарий. Также мы можем оценивать качество ответа косвенно, через поведение пользователей. Если пользователь ответил боту‑ассистенту в чат, что ему не понравился ответ, или совсем перестал пользоваться нашим сервисом — мы анализируем, по какой причине это могло произойти. На основании всего перечисленного мы пополняем датасеты для тестирования, а также точечно исправляем возникающие у пользователей проблемы.

И в завершение хочется рассказать о тех открытых вопросах и задачах, которые стоят перед нами при разработке нашего бота.
Во‑первых, эта тема навыков языковых моделей. У себя в 1С мы используем языковые модели не только для генерации ответов на вопросы пользователей, но и для других задач. Хочется интегрировать в модели новые навыки, и здесь возникает несколько проблем.
Как добавить новый навык в языковую модель, чтобы это не «испортило» работу по старым навыкам?
Как добавлять новую функциональность, чтобы она негативно не сказалась на работе уже существующей функциональности? Например, если мы добавим в модель возможность узнать прогноз погоды у стороннего сервиса, не ухудшит ли этот факт качество ответов на вопросы, для которых прогноз погоды не нужен?
Это большая группа задач — как научить языковую модель чему‑то новому, не поломав при этом поведение на старых навыках.
Вторая большая группа задач — это работа с источниками данных. Сейчас мы используем только один источник данных — хранилище документов, но в будущем, вероятно, нам понадобится использовать несколько источников данных. Тут возникают задачи:
Как определять, на какие вопросы в нашей базе нет ответов?
Как правильно агрегировать данные от нескольких источников для ответа (если вопрос подразумевает ответ из нескольких источников данных)?
Как выбирать между разными источниками наиболее предпочтительные?
Что делать, если информация от разных источников будет конфликтовать между собой?
Есть также интересные задачи, связанные со структурой нашей базы данных «знаний». Сейчас мы используем базу векторных представлений документов, но, возможно, есть сценарии, для которых можно каким‑то образом предобработать документы, преобразовать их в другую форму, отличную от векторного представления. Возможно, это новое представление будет эффективней для поиска релевантной информации. Что это будет — графы знаний, что‑то ещё? Мы активно исследуем это направление, здесь большой простор для экспериментов.
CrushBy
А нельзя просто подключить к ИИ конфигурацию как MCP сервер, в котором будут возможности по считыванию кода, и запуска скриптов, чтобы ИИ сам бы разбирался в том, как это работает, и себя проверял ?
Для наглядности, вот пример. Подключил Claude к демо MyCompany , и задал простой вопрос :
Ответ Claude : https://claude.ai/chat/ea9a29f1-7c90-4930-9118-9f5c4fce1f4e
Ответ ChatGPT : https://chatgpt.com/share/6a85726f-e3e8-83eb-aaed-2687982c0db8
Они сами проанализировали код, проверили на реальных данных, нашли ошибки и даже предложили как исправить. Плюс такого подхода, что он будет работать и с модифицированными конфигурациями на основе сделанных там изменений, а не по официальной документации.
Кроме того, такой бот сможет сам проверять данные, и даже их изменять : https://claude.ai/share/bd0b0d12-75e5-4d6f-ade3-8e78f55984f3
PeterG Автор
А как ИИ будет искать в нормативных документах?
CrushBy
Что значит как ? Поиском в интернете :) Если очень надо, то можно их просто выложить рядом локально.
И речь же шла не столько о регламентной части учета, а просто обо всех конфигурациях на платформе. Бухгалтерия и регламентный учет - это небольшая часть всех бизнес-приложений.
PeterG Автор
Это не решается просто "поиском в интернете" )
Хотя для ваших целей, возможно, просто "поиска в интернете" - вполне достаточно.
CrushBy
Ну, смотря что считать "решается". Вот пример : https://chatgpt.com/c/6a858480-e944-83eb-86fc-c0b1db25f5bc
Но понятно, что можно подложить ему через MCP самому нужные документы, и он будет прекрасно искать в них.
CrushBy
Сорри, не та ссылка : https://chatgpt.com/share/6a858544-7010-83ed-abae-63c0dfa27d42
gennayo
Во многих крупных компаниях по соображениям безопасности не разрешено использование облачного ИИ, только локального. Но во если бы эту модельку от 1С можно было развернуть локально, с возможностью "прикрутить" туда код конфигурации, могло бы быть вполне интересно...