Изучение процесса поиска информации в системах RAG путем экспериментирования с различными размерами фрагментов.
Делиться

Пользователь: «Что означает зеленая подсветка в этом документе?»
Система RAG: «Выделенный зеленым текст интерпретируется как параметры конфигурации».
Именно таких ответов мы сегодня ожидаем от систем генерации с расширенным поиском (Retrieval-Augmented Generation, RAG).
За последние несколько лет RAG стал одним из центральных архитектурных элементов для языковых моделей, основанных на знаниях: вместо того, чтобы полагаться исключительно на знания, хранящиеся в модели, системы RAG объединяют языковые модели с внешними источниками документов.
Этот термин был введен Льюисом и др. и описывает подход, широко используемый для уменьшения галлюцинаций, повышения прослеживаемости ответов и обеспечения возможности работы языковых моделей с конфиденциальными данными.
Мне хотелось понять, почему система выбирает один конкретный ответ вместо очень похожего варианта. Это решение часто принимается уже на этапе поиска, задолго до того, как в дело вступает LLM (Learning Learning and Materials).
По этой причине в данной статье я провел три эксперимента, чтобы исследовать, как разные размеры фрагментов (80, 220, 500) влияют на поведение при извлечении информации.
Оглавление
1. Почему размер фрагмента — это не просто параметр.
2. Как размер фрагмента влияет на стабильность результатов поиска в небольших системах RAG?
3 – Минимальная система RAG без генерации выходного сигнала
4 – Три эксперимента: Размер фрагмента как переменная
5 – Заключительные мысли
1. Почему размер фрагмента — это не просто параметр.
В типичном конвейере RAG документы сначала разбиваются на более мелкие текстовые сегменты, преобразуются в векторы и сохраняются в индексе. При выполнении запроса извлекаются семантически схожие текстовые сегменты, которые затем обрабатываются для получения ответа. Этот заключительный этап часто выполняется в сочетании с языковой моделью.
Типичные компоненты системы RAG включают в себя:
- Предварительная обработка документов
- Пошаговое изложение
- Встраивание
- Векторный индекс
- Логика поиска
- Необязательно: Генерация выходных данных
В этой статье я сосредоточусь на этапе извлечения данных. Этот этап зависит от нескольких параметров:
- Выбор модели встраивания:
Модель встраивания определяет, как текст преобразуется в числовые векторы. Различные модели улавливают смысл на разных уровнях детализации и обучаются на разных задачах. Например, для семантического поиска часто достаточно легких моделей преобразования предложений, в то время как более крупные модели могут улавливать больше нюансов, но требуют больших вычислительных затрат. - Метрика расстояния или сходства:
Метрика расстояния или сходства определяет способ измерения близости между двумя векторами. Обычно используются косинусное сходство, скалярное произведение или евклидово расстояние. Для нормализованных вложений часто используется косинусное сходство. - Количество полученных результатов (Top-k):
Количество полученных результатов определяет, сколько текстовых сегментов возвращается на этапе поиска. Небольшое значение Top-k может привести к потере релевантного контекста, в то время как большое значение Top-k повышает полноту поиска, но может внести шум. - Перекрытие между текстовыми сегментами:
Перекрытие определяет, какой объем текста является общим для последовательных фрагментов. Обычно оно используется для предотвращения потери важной информации на границах фрагментов. Небольшое перекрытие уменьшает избыточность, но увеличивает риск сокращения пояснений вдвое, в то время как большее перекрытие повышает надежность за счет хранения и обработки большего количества похожих фрагментов. - Размер фрагмента:
Описывает размер текстовых единиц, извлекаемых из документа и сохраняемых в виде отдельных векторов. В зависимости от реализации размер блока может определяться на основе символов, слов или токенов. Размер определяет, какой объем контекста представляет один вектор.
Небольшие фрагменты содержат очень мало контекста и носят узкоспециализированный характер. Большие фрагменты включают больше окружающей информации, но на гораздо более грубом уровне. В результате размер фрагмента определяет, какие части смысла фактически сравниваются при сопоставлении запроса с фрагментом.
Размер фрагмента информации неявно отражает предположения о том, сколько контекста необходимо для понимания смысла, насколько сильно может быть фрагментирована информация и насколько четко можно измерить семантическое сходство.
В этой статье я хотел исследовать именно это на примере небольшого эксперимента с системой RAG и задал себе вопрос:
Как разные размеры фрагментов влияют на поведение при извлечении информации?
Основное внимание уделяется не системе, предназначенной для использования в производственных целях. Вместо этого я хотел выяснить, как разные размеры фрагментов влияют на результаты поиска.
2. Как размер фрагмента влияет на результаты поиска в небольших системах RAG?
Поэтому я задал себе следующие вопросы:
- Как размер фрагмента влияет на результаты извлечения данных в небольшой, контролируемой системе RAG?
- Какие текстовые сегменты попадают в топ рейтинга, когда запросы идентичны, но размеры фрагментов различаются?
Для исследования этого вопроса я намеренно создал простую модель, в которой все условия (кроме размера фрагмента) остаются неизменными:
- Три документа в формате Markdown в качестве базы знаний
- Три одинаковых, фиксированных вопроса
- Та же модель встраивания используется для векторизации текстов.
Текст, использованный в трех файлах Markdown, основан на документации реального инструмента OneLatex. Чтобы эксперимент был сосредоточен на особенностях поведения пользователей при поиске информации, содержание было немного упрощено и сведено к основным пояснениям, имеющим отношение к вопросам.
Я использовал три вопроса:
«Вопрос 1: В чем главное преимущество разделения создания контента и форматирования в OneLatex?» «Вопрос 2: Как OneLatex интерпретирует текст, выделенный зеленым цветом в OneNote?» «Вопрос 3: Как OneLatex интерпретирует текст, выделенный желтым цветом в OneNote?»
Кроме того, я намеренно опустил LLM для генерации выходных данных.
Причина проста: я не хотел, чтобы LLM превращал неполные или плохо соответствующие фрагменты текста в связный ответ. Это значительно упрощает понимание того, что на самом деле происходит на этапе поиска, как взаимодействуют параметры поиска и какую роль играет преобразователь предложений.
3 – Минимальная система RAG без генерации выходного сигнала
Поэтому для экспериментов я использовал небольшую систему RAG, состоящую из следующих компонентов: документы Markdown в качестве базы знаний, простая логика сегментации с учетом перекрытия, модель преобразования предложений для генерации векторных представлений и ранжирование текстовых сегментов с использованием косинусного сходства.
В качестве модели встраивания я использовал модель all-MiniLM-L6-v2 из библиотеки Sentence-Transformers. Эта модель легковесна и поэтому хорошо подходит для локального запуска на личном ноутбуке (я запускал её локально на своём ноутбуке Lenovo с 64 ГБ оперативной памяти). Сходство между запросом и текстовым сегментом вычисляется с помощью косинусного сходства. Поскольку векторы нормализованы, скалярное произведение можно сравнивать напрямую.
Я намеренно сделал систему небольшой и поэтому не включил в нее историю чатов, память, логику работы агентов или генерацию ответов на основе LLM.
В качестве «ответа» система просто возвращает текстовый сегмент с наивысшим рейтингом. Это значительно упрощает определение того, какой контент действительно считается релевантным на этапе поиска.
Полный код мини-системы RAG можно найти в моем репозитории на GitHub:
→ 🤓 Полный код можно найти в репозитории GitHub 🤓 ←
4 – Три эксперимента: Размер фрагмента как переменная
Для оценки результатов я выполнил три приведенные ниже команды через командную строку:
#Эксперимент 1 — Базовый вариант: python main.py —chunk-size 220 —overlap 40 —top-k 3 #Эксперимент 2 — Малый размер фрагмента: python main.py —chunk-size 80 —overlap 10 —top-k 3 #Эксперимент 3 — Большой размер фрагмента: python main.py —chunk-size 500 —overlap 50 —top-k 3
Структура из раздела 3 остается неизменной: те же три документа, те же три вопроса и та же модель встраивания.
Размер фрагмента определяет количество символов в текстовом сегменте. Кроме того, в каждом эксперименте я использовал перекрытие, чтобы уменьшить потерю информации на границах фрагментов. Для каждого эксперимента я вычислял показатели семантического сходства между запросом и всеми фрагментами и ранжировал сегменты с наивысшими показателями.
Небольшие фрагменты (80 символов) – Потеря контекста
При использовании очень маленьких фрагментов (размер фрагмента 80) становится очевидной сильная фрагментация контента: отдельные текстовые сегменты часто содержат только обрывки предложений или изолированные утверждения без достаточного контекста. Объяснения разбросаны по нескольким фрагментам, так что отдельные сегменты содержат лишь части исходного контента.
Формально поиск по-прежнему работает корректно: семантически схожие фрагменты находятся и занимают высокие позиции в рейтинге.
Однако, если взглянуть на фактическое содержание, мы увидим, что результаты практически непригодны для использования:

Возвращаемые фрагменты тематически связаны, но не дают самодостаточного ответа. Система приблизительно определяет тему, но настолько сильно разбивает контент на части, что отдельные результаты сами по себе мало что говорят.
Средние фрагменты (220 символов) – Очевидная стабильность
При работе с фрагментами среднего размера (220 фрагментов) результаты заметно улучшились. Большинство возвращенных текстовых сегментов содержали полные пояснения и были правдоподобны с точки зрения содержания. На первый взгляд, поиск казался стабильным и надежным: он обычно возвращал именно ту информацию, которую ожидалось.
Однако при различении текста, выделенного зеленым и желтым цветом, выявилась конкретная проблема. Независимо от того, спрашивал ли я о значении зеленой или желтой подсветки, система в обоих случаях возвращала фрагмент текста, содержащий информацию о желтой подсветке, в качестве лучшего результата. Правильный фрагмент присутствовал, но не был выбран в качестве первого результата.

Причина кроется в очень схожих показателях сходства двух лучших результатов:
- Результат для лучшего игрока: 0,873
- Результат для двух лучших команд: 0,774
Система с трудом различает двух кандидатов семантически и в конечном итоге выбирает фрагмент с немного более высоким баллом.
В чём проблема? По содержанию это не соответствует вопросу и просто неверно.
Для нас, людей, это очень легко распознать. Для преобразователя предложений, такого как all-MiniLM-L6-v2, это, по-видимому, представляет собой проблему.
Здесь важно следующее: если мы будем рассматривать только результат Top-1, эта ошибка останется незаметной. Только сравнивая оценки, мы видим, что система в данной ситуации испытывает неуверенность. Поскольку в нашей конфигурации она вынуждена принимать однозначное решение, она возвращает фрагмент Top-1 в качестве ответа.
Большие фрагменты текста (500 символов) – Надежный контекст
При использовании больших фрагментов (размер фрагмента 500 символов) текстовые сегменты содержат гораздо более связный контекст. Кроме того, практически отсутствует фрагментация: пояснения больше не разбросаны по нескольким фрагментам.
И действительно, ошибка в различении зеленого и желтого цветов больше не возникает. Вопросы о выделении зеленым и желтым цветом теперь правильно различаются, и соответствующий фрагмент четко ранжируется как лучший результат. Мы также видим, что показатели сходства соответствующих фрагментов теперь более четко разделены.

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



























