Снижение галлюцинаций в конвейере медицинского чат-бота на основе RAG
Узнайте, как гибридный поиск, переранжирование и строгая политика отказа от фальсификаций совместно способствуют созданию более надежного чат-бота для медицинских исследований типа RAG.
Проект начинался с простой цели.
Нужно было создать чат-бота, способного отвечать на вопросы на основе медицинских научных статей.
Это должно было быть довольно просто, верно?
Однако оказалось иначе.
При первой реализации использовалась довольно традиционная схема RAG: загрузка документов, генерация эмбеддингов, хранение их в векторной базе данных, извлечение релевантных фрагментов и передача их в LLM.
Это сработало.
Только не надежно.
А в медицинской сфере «ненадежность» — это серьезный недостаток.
Чат-бот, который уверенно, но неверно отвечает, гораздо опаснее того, который признается: «У меня недостаточно информации, чтобы ответить на этот вопрос».
Это осознание привело к тому, что процесс поиска информации вошел в фазу постоянной отладки.
Первая проблема: галлюцинации
Самой насущной проблемой, с которой нужно было бороться, являлись галлюцинации.
Языковые модели обладают поразительным умением генерировать ответы, звучащие убедительно, иногда даже слишком убедительно.
Когда в документах не было ответа, модель часто заполняла этот пробел с помощью собственных внутренних знаний, вместо того чтобы признать неопределенность.
Это поведение требовало изменений.
Ответы чат-бота должны были исходить исключительно из предоставленных исследовательских материалов, а не из воображения модели.
Поэтому основополагающая философия изменилась.
Вместо того чтобы рассматривать ЯЗЫКОВУЮ МОДЕЛЬ как источник фактов, реальным источником правды стали полученные документы.
Роль ЯЗЫКОВОЙ МОДЕЛИ свелась к интерпретации этих документов и преобразованию полученного контекста в связный ответ.
А что делать, если контекста недостаточно?
Система должна отказываться делать догадки.
Начало с базового RAG
Первая версия этой архитектуры казалась простой:
Это соответствует стандартной схеме RAG.
Большой документ разделяется на меньшие фрагменты, каждый из которых встраивается и хранится в векторной базе данных.
Каждый раз, когда пользователь задаёт вопрос, он также встраивается в базу данных.
Затем система ищет фрагменты, эмбеддинги которых семантически близки.
В теории всё просто.
Но быстро выявилась одна проблема.
Семантическая близость не гарантирует фактической релевантности.
Почему векторный поиск оказался недостаточным
Представьте, что пользователь задаёт вопрос:
«Каковы последствия инсулинорезистентности?»
Семантический поиск хорошо справляется с пониманием общей цели такого вопроса.
Это полезно.
Однако медицинские тексты полны точной терминологии.
Такие термины, как:
- инсулинорезистентность
- HbA1c
- гипергликемия
- метформин
- толерантность к глюкозе
Эти конкретные термины имеют большое значение.
Иногда нужно понимание общего смысла.
В других случаях требуется возможность найти именно конкретный термин.
Зачем ограничиваться лишь одной функцией?
Решением стало сочетание обеих.
Гибридный поиск
Именно здесь гибридный поиск стал ключевой частью дизайна.
Вместо использования исключительно поиска на основе векторов был применён семантический поиск в сочетании с поиском по ключевым словам.
Логика, стоящая за этим, довольно интуитивна.
Семантический поиск по сути задаёт вопрос:
«Какой контент имеет схожий смысл?»
Поиск по ключевым словам в свою очередь задаёт вопрос:
«Где на самом деле встречаются ключевые термины?»
У каждого метода есть свои сильные стороны.
У каждого также есть свои слабые места.
В совокупности они покрывают более широкий спектр запросов.
Результативный процесс выглядел следующим образом:
User Query
↓
┌─────────┴─────────┐
↓ ↓
Vector Search Keyword Search
↓ ↓
└─────────┬─────────┘
↓
Combined Results
↓
Reranker
↓
Best Context
↓
LLM
↓
Answer
Это изменение повлияло на подход к поиску в дальнейшем.
Однако проблема осталась.
Получение информации не означает, что это лучший вариант
Предположим, что шаг гибридного поиска возвращает 20 фрагментов.
Это звучит многообещающе.
Но действительно ли каждый из этих фрагментов полезен?
Не обязательно.
Некоторые фрагменты могут быть в высокой степени связаны с темой.
Другие могут просто иметь совпадающую лексику.
Ещё другие могут быть косвенно связаны, но не отвечать на поставленный вопрос.
Подача всего этого напрямую в LLM — не идеальное решение.
Увеличение объема полученного контекста не обязательно приводит к лучшим ответам.
На самом деле это может негативно повлиять на результат.
Это добавляет больше токенов, больше нерелевантного шума и увеличивает задержку.
Поэтому была введена еще одна стадия.
Переупорядочивание.
Почему переупорядочивание изменило ситуацию
Роль механизма поиска можно свести к следующему:
Выявление возможных кандидатов.
Роль механизма переупорядочивания отличается:
Определение того, какие из этих кандидатов действительно релевантны.
Таким образом, вместо простой цепочки:
Query → Search → LLM
процесс превратился в:
Query
↓
Hybrid Search
↓
20 Candidate Chunks
↓
Reranker
↓
Top Relevant Chunks
↓
LLM
Такое разделение обязанностей имеет большое значение.
На первой стадии поиска можно сосредоточиться на охвате, используя широкий диапазон кандидатов.
На стадии переупорядочивания можно затем сосредоточиться именно на релевантности и точности.
Для чат-бота в медицинских исследованиях это различие оказалось особенно ценным, поскольку фрагмент, содержащий лишь соответствующую терминологию, не всегда является тем фрагментом, который действительно отвечает на вопрос пользователя.
Самый важный аспект: отказ от фальсификации
Помимо поиска и переупорядочивания информации, на этапе генерации были введены строгие ограничения.
Основная инструкция сводилась к следующему:
Use the provided context to answer.
Do not invent information.If the context doesn't contain enough information,
say that there isn't enough information available.
Это кажется слишком простым, чтобы иметь значение.
Однако это заметно меняет поведение чат-бота.
Вместо того чтобы заставлять модель выдавать ответ в любом случае, этот подход предоставляет ей возможность уклониться, когда информации просто нет.
Этот способ уклонения оказывается необходимым.
Иногда честный ответ выглядит примерно так:
«Я не смог найти достаточно информации в предоставленных исследовательских материалах».
Не каждый вопрос заслуживает уверенного ответа.
Так полностью ли устранены галлюцинации?
Не совсем.
Это стало ясно в процессе создания системы.
RAG действительно снижает количество галлюцинаций и позволяет ответам более тесно связываться с реальными источниками.
Но утверждать, что галлюцинации полностью отсутствуют, было бы преувеличением.
Остается множество точек возможных сбоев.
Механизм поиска может выбрать неправильный фрагмент текста.
Сам процесс разбиения текста на фрагменты может устранить важный контекст.
Механизм ранжирования может неправильно оценить важность элементов.
У основных документов может с самого начала отсутствовать необходимая информация.
Даже когда все предыдущие этапы работают корректно, большая языковая модель всё равно может неправильно интерпретировать полученный материал.
Поэтому настоящая цель не в том, чтобы:
«Создать чат-бота, который никогда не ошибается».
Она ближе к тому, чтобы:
«Создайте систему с меньшим количеством возможностей для ошибок и такую, которая осознаёт пределы своих знаний».
Это гораздо более достижимая цель.
Оказалось критически важным дизайн блоков
Одно важное открытие: разделение документов на блоки — это не просто временный шаг предобработки, настраиваемый один раз.
Слишком большие блоки включают в себя нерелевантный контент.
Слишком маленькие блоки могут удалять окружающий контекст, от которого зависит тезис.
Полезно рассматривать каждый блок как самостоятельную единицу знаний, а не просто произвольный фрагмент текста.
Хорошо спроектированные блоки напрямую способствуют более эффективному поиску информации.
А более эффективный поиск, в свою очередь, приводит к лучшим итоговым ответам.
Ускорение обработки
Правильность была лишь половиной проблемы; другой половиной было время отклика.
Одна запрос к RAG может запустить несколько разных операций:
User Query
↓
Embedding
↓
Vector Search
↓
Keyword Search
↓
Merge Results
↓
Reranking
↓
LLM
Выполнение всех этих операций строго по порядку замедляет весь процесс.
Чтобы решить эту проблему, шаги по получению данных были преобразованы в асинхронные операции там, где это возможно.
Изменённый алгоритм выглядел примерно так:
User Query
↓
┌──────┴──────┐
↓ ↓
Vector Search Keyword Search
↓ ↓
└──────┬──────┘
↓
Rerank
↓
LLM
Это сократило время ожидания между шагами, которые на самом деле не зависели друг от друга.
Точность сама по себе — не единственный критерий хорошей системы RAG.
Пользователи не хотят сидеть и ждать ответа.
Результативная архитектура
После нескольких раундов усовершенствований процесс принял примерно такой вид:
Medical Research Documents
↓
Document Processing
↓
Chunking
↓
Embeddings
↓
Vector Database
↓
User Query
↓
┌──────────┴──────────┐
↓ ↓
Semantic Search Keyword Search
↓ ↓
└──────────┬──────────┘
↓
Result Fusion
↓
Reranker
↓
Relevant Context
↓
Grounded Prompt
↓
LLM
↓
Final Response
Каждый компонент на этой диаграмме выполняет свою конкретную функцию.
Такое разделение стало одним из самых ценных уроков проекта.
База векторных данных предназначена не для ответов на вопросы.
Механизм поиска не предназначен для генерации ответов.
LLM по умолчанию не обладает знаниями всего.
Каждый компонент выполняет свою функцию.
И в идеале он выполняет её хорошо.
Уроки, полученные в процессе разработки
Основной вывод из всего этого эксперимента заключается в том, что подход RAG — это гораздо больше, чем просто сочетание LLM с базой векторных данных. Существует множество компонентов, каждый из которых требует внимания.
Качество поиска — нечто само собой разумеющееся
Даже самая сильная модель языка не может компенсировать плохой контекст. Если предоставить ей слабые результаты поиска, она вернёт слабые ответы. Это простой пример правила «что входит, то и выходит».
Гибридный поиск оправдывает себя
Семантический поиск отлично справляется с пониманием смысла и намерений. Поиск по ключевым словам эффективен тогда, когда важна точность терминологии. Поскольку медицинские исследования полны точных терминов и специфических формулировок, сочетание обоих подходов оказалось правильным решением.
Повторная оценка заслуживает большего признания
Получение двадцати кандидатских результатов — это одна из проблем. Ограничение их числа до пяти лучших — совершенно отдельная проблема. Повторная оценка находится между этими двумя шагами и преодолевает разрыв между ними.
Более большие окна контекста не гарантируют лучших ответов
Изначально существовало предположение, что большее количество полученного контента естественным образом улучшит результаты. Это предположение оказалось неверным. На практике пять тесно связанных фрагментов часто демонстрируют лучшие результаты, чем двадцать посредственных.
Признание неопределенности — это сила, а не слабость
Возможно, это самый важный урок из всех. Надежная система не должна чувствовать себя обязанной давать ответ в любом случае. Когда соответствующая информация просто отсутствует, система должна быть готова это признать.
Что дальше?
Ещё много возможностей для улучшений. Среди областей, которые стоит исследовать дальше, — это:
- Более эффективные методы оценки результатов поиска
- Переписывание запросов
- Фильтрация метаданных
- Усовершенствованные модели переранжирования
- Ответы с цитатами
- Оценка уверенности и логика воздержания от ответа
- Лучшая возможность наблюдения за процессом поиска
- Автоматизированные наборы данных для оценки
- Дополнительные меры кэширования и снижения задержек
Создание надлежащей системы оценки имеет особое значение, поскольку ручный анализ нескольких ответов чат-бота — это не строгий способ оценки качества. К числу вопросов, которые стоит измерять, относятся: была ли вообще получена правильная информация, действительно ли сгенерированный ответ основан на этой информации, и как часто система вообще не может предоставить нужный контекст. Эти показатели гораздо важнее субъективного мнения о том, звучит ли ответ «правильно».
Заключение
То, что начиналось как простой чат-бот на основе технологии RAG, превратилось в гораздо более глубокое изучение того, как на самом деле работают системы поиска информации. Обсуждения прикладных решений в области ИИ часто сосредотачиваются на языковой модели, но в конфигурации RAG именно система поиска выполняет большую часть работы в фоновом режиме.
Минимальная конфигурация может выглядеть так: документы поступают в векторную базу данных, а затем — в LLM. Более надежная версия предполагает обработку документов с помощью разбиения на фрагменты, последующего гибридного поиска и переранжирования, после чего они становятся основанным на фактах контекстом перед тем, как попасть в LLM. Даже такая схема всё ещё имеет возможности для развития.
Именно это в конечном итоге делает создание систем RAG привлекательным: речь идёт не просто о том, чтобы заставить языковую модель генерировать текст. Речь идёт о том, чтобы убедиться, что текст основан на правильной информации до того, как модель начнёт говорить.
Примечание: этот проект предназначен исключительно для технических исследований и экспериментов. Он не заменяет профессиональные медицинские советы, диагностику или лечение.
Связанная литература
- Иерархическая карта концепций инженерии ИИ и ситуаций, когда они важны — Узнайте, какие концепции инженерии ИИ определяют работоспособность системы, какие важны при разработке для производства и какие можно отложить.
- Second Brain: Преобразование стенограмм собраний в поисковую знаниевую сеть — Объясняется, как агентная система извлекает сущности из стенограмм собраний и хранит их в Cosmos DB для возможности поиска с использованием естественного языка и исследования знаниевой сети.