10 способов улучшить производительность систем усиления генерации поиска

10 способов улучшить производительность систем усиления генерации поиска' can be condensed to '10 способов улучшить производительность системы усиления поиска

Инструменты для перехода от прототипа к производству

Краткое руководство недостаточно

“Добавление извлеченной информации — это процесс дополнения ввода пользователя большой языковой модели (LLM), такой как ChatGPT, дополнительной информацией, которую вы (система) извлекли откуда-то еще. Затем LLM может использовать эту информацию для улучшения сгенерированного им ответа.” — Кори Зю

LLM – удивительное изобретение, но имеет одну ключевую проблему. Они выдумывают. RAG делает LLM гораздо более полезными, предоставляя им фактический контекст для использования при ответе на запросы.

С помощью быстрого руководства по использованию таких фреймворков, как LangChain или LlamaIndex, любой может создать простую систему RAG, например, чат-бота для ваших документов, всего лишь с помощью пяти строк кода.

Однако, чат-бот, построенный с помощью этих пяти строк кода, не будет работать очень хорошо. RAG легко прототипировать, но очень сложно внедрить в производство – то есть достичь такого уровня, который удовлетворит пользователей. Базовый учебник может заставить RAG работать на 80%. Но для заполнения следующих 20% часто требуется серьезное экспериментирование. Лучшие практики еще не установлены и могут варьироваться в зависимости от конкретной ситуации использования. Однако выяснение лучших практик стоит нашего времени, потому что RAG, вероятно, является самым эффективным способом использования LLM.

В этой статье будут рассмотрены стратегии для улучшения качества систем RAG. Она предназначена для тех, кто создает системы RAG и хочет сократить разрыв между базовыми настройками и производительностью на уровне производства. Для целей этой статьи улучшение означает увеличение доли запросов, для которых система: 1. Находит правильный контекст и 2. Генерирует соответствующий ответ. Я предполагаю, что читатель уже имеет представление о том, как работает RAG. Если нет, я бы порекомендовал прочитать эту статью Кори Зю для хорошего введения. Она также предполагает базовое знакомство с общими фреймворками, используемыми для создания этих инструментов: LangChain и LlamaIndex. Однако здесь обсуждаемые идеи являются независимыми от конкретного фреймворка.

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

10 способов улучшить производительность извлеченной генерации

1. Очистите свои данные.

RAG связывает возможности LLM с вашими данными. Если ваши данные запутаны, как по содержанию, так и по структуре, то ваша система будет страдать. Если вы используете данные с противоречивой или избыточной информацией, ваш поиск будет затруднен в поиске правильного контекста. И когда это произойдет, шаг генерации, выполняемый LLM, может быть неоптимальным. Предположим, вы создаете чат-бота для справочной документации своей стартап-компании, и вы видите, что он работает плохо. Первое, на что стоит обратить внимание, это данные, которые вы подаете на вход системы. Логически ли разделены темы? Покрыты ли темы в одном месте или во многих отдельных местах? Если вы, как человек, не можете легко определить, на какой документ вам нужно обратиться, чтобы ответить на обычные запросы, ваша система извлечения тоже не сможет.

Этот процесс может быть столь простым, как ручное объединение документов по одной теме, но вы можете пойти еще дальше. Одним из самых творческих подходов, которые я видел, является использование LLM для создания сводок всех предоставленных контекстных документов. Затем на этапе извлечения сначала выполняется поиск по этим сводкам, а в подробности погружаются только при необходимости. Некоторые фреймворки даже имеют это встроенным абстракцией.

2. Исследуйте различные типы индексов.

Индекс является основной составляющей LlamaIndex и LangChain. Это объект, который содержит вашу систему извлечения. Стандартный подход к RAG включает в себя вложения и поиск похожих элементов. Разделите контекстные данные на части, вложите все, когда поступит запрос, найдите похожие части из контекста. Это работает очень хорошо, но не является лучшим подходом для каждого случая использования. Будут ли запросы относиться к конкретным элементам, таким как продукты в интернет-магазине? Возможно, вам захочется исследовать поиск на основе ключевых слов. Это не означает, что нужно выбирать одно или другое, многие приложения используют гибридный подход. Например, вы можете использовать поиск на основе ключевых слов для запросов, относящихся к определенному продукту, но полагаться на вложения для общей поддержки клиентов.

3. Экспериментируйте со своим подходом к чанкингу.

Чанкинг контекстных данных является основной частью построения системы RAG. Фреймворки абстрагируются от процесса чанкинга и позволяют вам обойтись без его рассмотрения. Но вы должны об этом подумать. Размер чанков имеет значение. Вам следует исследовать, что лучше всего подходит для вашего приложения. В целом, меньшие чанки часто улучшают извлечение, но могут привести к тому, что генерация будет страдать от отсутствия окружающего контекста. Существует множество способов подхода к чанкингу. Единственное, что не работает, это подходить к этому слепо. В этом посте от PineCone описаны некоторые стратегии, которые следует учесть. У меня есть тестовый набор вопросов. Я подошел к этому, проведя эксперимент. Я пробежался по каждому набору один раз с маленьким, VoAGI и большим размером чанков и обнаружил, что маленький размер наилучший.

4. Поиграйте с базовым промптом.

Один из примеров базового промпта, используемого в LlamaIndex, выглядит так:

‘Информация о контексте приведена ниже. Учитывая информацию о контексте и отсутствие предварительных знаний, ответьте на запрос.’

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

‘Вы являетесь агентом службы поддержки клиентов. Ваша цель – быть максимально полезным, предоставляя только фактическую информацию. Вы должны быть дружелюбными, но не слишком болтливыми. Информация о контексте приведена ниже. Учитывая информацию о контексте и отсутствие предварительных знаний, ответьте на запрос.’

5. Попробуйте фильтрацию метаданных.

Очень эффективная стратегия для улучшения извлечения – добавить метаданные к чанкам, а затем использовать их для обработки результатов. Дата является обычным тегом метаданных, который позволяет фильтровать по актуальности. Представьте, что вы создаете приложение, которое позволяет пользователям запрашивать историю своей электронной почты. Скорее всего, более свежие письма будут более актуальными. Но мы не знаем, что они будут наиболее похожи, с точки зрения эмбеддинга, на запрос пользователя. Это поднимает общую концепцию, которую следует иметь в виду при создании RAG: похожий ≠ актуальный. Вы можете добавить дату каждого письма к его метаданным, а затем приоритезировать наиболее свежий контекст во время извлечения. LlamaIndex имеет встроенный класс Node Post-Processors, который помогает в этом.

6. Используйте маршрутизацию запросов.

Часто бывает полезно иметь более одного индекса. Затем вы маршрутизируете запросы в соответствующий индекс при их поступлении. Например, у вас может быть один индекс, который обрабатывает вопросы о резюме, другой, который обрабатывает конкретные вопросы, и еще один, который хорошо работает для вопросов, связанных с датой. Если вы пытаетесь оптимизировать один индекс для всех этих поведений, вы закончите тем, что ослабите его эффективность во всех случаях. Вместо этого вы можете маршрутизировать запрос в соответствующий индекс. Другой вариант использования – направлять некоторые запросы в индекс на основе ключевых слов, о котором говорится в разделе 2.

Как только вы создали свои индексы, вам просто нужно определить текстом, для чего каждый из них должен использоваться. Затем во время запроса LLM выберет соответствующий вариант. И LlamaIndex, и LangChain имеют инструменты для этого.

7. Изучите переранжировку.

Переранжировка – это одно из решений проблемы различия между сходством и актуальностью. При переранжировке ваша система извлечения получает лучшие узлы контекста, как обычно. Затем они переупорядочиваются на основе актуальности. Для этого часто используется Cohere Rereanker. Эта стратегия часто рекомендуется экспертами. Независимо от конкретного случая использования, если вы работаете с RAG, вам следует экспериментировать с переранжировкой и посмотреть, улучшает ли она вашу систему. И LlamaIndex, и LangChain имеют абстракции, которые позволяют установить это легко.

8. Рассмотрите преобразования запросов.

Вы уже изменяете запрос пользователя, помещая его в базовый промпт. Иногда имеет смысл изменить его еще больше. Вот несколько примеров:

Перефразировка: если ваша система не находит актуального контекста для запроса, вы можете попросить LLM перефразировать запрос и попробовать снова. Два вопроса, которые кажутся одинаковыми для людей, не всегда выглядят такими же похожими в пространстве эмбеддингов.

HyDE: HyDE – это стратегия, которая берет запрос, генерирует гипотетический ответ, а затем использует оба для поиска по эмбеддингам. Исследователи обнаружили, что это может значительно улучшить производительность.

Подзапросы: LLM-ы обычно работают лучше, когда они разбивают сложные запросы. Вы можете внедрить это в свою систему RAG таким образом, чтобы запрос был разложен на несколько вопросов.

LLamaIndex имеет документацию, описывающую эти типы преобразований запросов.

9. Отрегулируйте свою модель смещения.

Схожесть на основе вложений является стандартным механизмом поиска для RAG. Ваши данные разбиваются и встраиваются внутри индекса. Когда поступает запрос, он также встраивается для сравнения с вложением в индексе. Но что делает встраивание? Обычно это предварительно обученная модель, такая как OpenAI’ text-embedding-ada-002.

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

Вы можете отрегулировать свою модель вложения для решения этой проблемы. Это может повысить показатели поиска на 5-10%. Это требует немного больше усилий, но может существенно повлиять на производительность вашего поиска. Процесс проще, чем вы думаете, так как LlamaIndex может помочь вам создать набор данных для обучения. Для получения дополнительной информации вы можете ознакомиться с этим сообщением Джерри Лю о том, как LlamaIndex подходит к настройке вложений, или с этим сообщением, в котором описывается процесс настройки.

10. Начните использовать инструменты разработки LLM.

Вероятно, вы уже используете LlamaIndex или LangChain для создания своей системы. Оба фреймворка имеют полезные инструменты отладки, которые позволяют вам определить обратные вызовы, увидеть, какой контекст используется, откуда получается ваш поиск и т. д.

Если вы обнаруживаете, что инструменты, встроенные в эти фреймворки, недостаточно функциональны, существует растущая экосистема инструментов, которые могут помочь вам разобраться во внутренней работе вашей системы RAG. Arize AI имеет инструмент внутри блокнота, который позволяет вам исследовать, какой контекст извлекается и почему. Rivet – это инструмент, который предоставляет визуальный интерфейс для создания сложных агентов. Он был только что опубликован компанией по юридическим технологиям Ironclad. Новые инструменты регулярно выпускаются, и стоит экспериментировать, чтобы узнать, какие из них помогают в вашем рабочем процессе.

Заключение

Работа с RAG может быть разочаровывающей, потому что она так легко запустить, но так трудно сделать хорошо. Я надеюсь, что вышеуказанные стратегии могут дать вам некоторую вдохновение по тому, как сократить разрыв. Ни одна из этих идей не работает всегда, и процесс является экспериментом, пробой и ошибкой. В этом сообщении я не углубился в оценку, как можно измерить производительность вашей системы. Оценка в настоящее время является больше искусством, чем наукой, но важно создать какую-то систему, на которую вы можете регулярно проверять. Это единственный способ узнать, какие изменения вы внедряете, имеют значение. Ранее я писал о том, как оценивать систему RAG. Для получения дополнительной информации вы можете изучить LlamaIndex Evals, LangChain Evals и действительно многообещающий новый фреймворк под названием RAGAS.