Архив рубрики ~Лента новостей~

Вопросы RAG тоже нуждаются в анализе: преобразуйте строку пользователя в краткие описания для поиска и генерации.

Вопросы RAG тоже нуждаются в анализе: преобразуйте строку пользователя в краткие описания для поиска и генерации.
Вопросы RAG тоже нуждаются в анализе: преобразуйте строку пользователя в краткие описания для поиска и генерации.

Enterprise Document Intelligence [Том 1 #6a] – Почему вопрос пользователя заслуживает такого же анализа, как и документ, и как он разделяется на запрос на поиск и запрос на генерацию до начала выполнения каждого из них.

Делиться

Фотография Кристофа Жоржа, Pexels.

Эта статья является основой для анализа вопросов в рамках серии статей Enterprise Document Intelligence, которая строит корпоративную систему RAG из четырех компонентов: анализа, анализа вопросов, поиска и генерации.

Разбор вопросов — это второй блок. Это первая из трёх его частей:

  • Почему оно существует, что оно производит и какой раскол мотивирует все остальное.
  • В следующей части рассматривается , что именно парсер извлекает из пользовательской строки (статья 6 B, извлечение) и
  • как обработанная строка направляется на извлечение и генерацию (статья 6 C, отправка).
132e289a919f3becb497aa454d373de4
Место данной статьи в серии: Статья 6 (анализ вопросов), часть II (четыре кирпича) – Изображение предоставлено автором

В статье 1 (минимальный RAG) была показана основная схема: взять вопрос пользователя, отправить его специалисту по управлению знаниями и получить ответ.

В сериале этот подход был усовершенствован за счет использования подсказок, требующих от программы LLM возвращать JSON-объект с ответом и использованными фрагментами текста. Благодаря хорошо структурированному документу и правильному выводу, найти источник ответа больше не составляет труда.

Это отправная точка. Остается только сам вопрос, и именно здесь в конечном итоге сосредоточена большая часть работы в реальном конвейере RAG. В корпоративных проектах выделяют три уровня «работы над вопросом», и они, как правило, возникают в таком порядке.

1. Естественные вопросы от пользователей. Пользователь вводит все, что приходит ему в голову: «Каков максимальный размер ответственности?», «Расскажите об исключениях», «Как это соотносится с политикой прошлого года?». Система должна осмыслить строку, которую она не создавала, используя терминологию, которая не обязательно совпадает с терминологией документа. Именно этот случай демонстрируется в большинстве демонстраций, и именно он показывает наибольшую вариативность на стороне ввода.

2. Шаблоны, которые разработчик создает заранее. Довольно быстро команда замечает, что одни и те же вопросы повторяются снова и снова. Для каждого контракта кто-то хочет знать, кто клиент, кто страховщик, годовой взнос, гарантии, исключения, дату продления. Вместо того чтобы ждать, пока пользователи введут эти данные по одному, разработчик создает их один раз совместно с бизнес-командой, которая отвечает за документы, и запускает их для всего корпуса. В результате получается JSON-запись для каждого документа. На практике большинство компаний создают это в первую очередь; свободный чат обычно появляется позже, на этой основе.

3. Помощь пользователям в формулировании. Эта закономерность проявляется, когда система оказывается перед реальными пользователями: бизнес-команды знают, чего хотят, но им трудно сформулировать это четко. Вопрос «Каков лимит?» оставляет много вопросов без ответа. Система может вмешаться и спросить: «Вы имеете в виду ответственность, возмещение убытков, франшизу или премию?» Тот же механизм, что и на двух предыдущих уровнях (типизированный объект с именованными полями), но теперь пустые поля инициируют небольшой диалог с пользователем.

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

Пользователь вводит в чат одну строку: «Какова максимальная сумма страхового покрытия? Не путайте её с франшизой, они часто указываются вместе».

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

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

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

1. Анализ вопросов аналогичен анализу документов.

1.1 Аналогичный подход: реляционный набор таблиц

В результате анализа документа формируется реляционный набор данных: line_df с одной строкой на каждую текстовую строку, page_df с одной строкой на каждую страницу, toc_df с одной строкой на каждую запись в оглавлении, а также несколько вспомогательных данных.

Задача синтаксического анализа вопроса та же: преобразовать неструктурированные входные данные в структурированную форму перед выполнением следующих шагов. Результатом является то же самое: реляционное множество.

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

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

Наиболее распространенным является экспертный словарь ключевых слов проекта, разделенный на две части: concepts_df (одна строка на каждую концепцию с ее определением) и concept_keywords_df (одна строка на каждый (concept, language, keyword) ). Вместе они содержат специфические для предметной области синонимы: premium → prime, cotisation, tarif annuel; non-compete → restrictive covenant; side effects → adverse events. Другой словарь, с которым мы столкнемся позже, — answer_types_df , который регистрирует типы ответов, которые могут ожидаться в вопросах ( amount , date , iban , …).

Реальные проекты обычно развиваются быстрее:

  • файл regulations_df , сопоставляющий правовые кодексы с их текстами для юридического RAG.
  • entity_alias_df для вариантов названий компаний в корпоративном корпусе
  • файл unit_conversions_df в научном формате

Столбцы вопроса связаны с этими спутниками так же, как line_df связан с image_df при разборе документа.

Такая реляционная структура имеет значение на практике. Как только вопросы становятся строками в таблице, вы можете использовать для них SQL-запросы: «сколько вопросов типа amount задали пользователи в прошлом месяце?», «какие вопросы вызвали запрос на уточнение?», «какие записи в экспертном словаре использовались чаще всего?». История вопросов становится оперативными данными, а не просто файлом журнала. В последующей главе, посвященной хранению данных, рассматривается структура, которая делает таблицу question_df первоклассной.

Несколько слов о терминологии. Обычно это называют «пониманием запроса» и «пониманием вопроса». Оба термина расплывчаты: они предполагают, что система понимает вопрос, что мало о чём говорит. «Синтаксический анализ вопроса» описывает, что происходит: принимает строку и возвращает обогащенную реляционную строку.

1.2 Где это находится в pdf_qa

В статье 1 (минимальный RAG) был представлен вызов верхнего уровня в виде единой функции: result = pdf_qa(contract_pdf, question="What is the maximum coverage amount?") . Пользователь передает путь к PDF-файлу и вопрос, а в ответ получает структурированный JSON-ответ. Имя соответствует соглашению _ : pdf — формат, qa намерение. Том 2 открывает обе оси ( excel_qa , pdf_translate , …) с помощью диспетчера doc_qa ; Том 1 вызывает обработчик напрямую.

Внутри pdf_qa последовательно связывает четыре блока: parse_pdfparse_question(question, doc_profile=...)retrievegenerate , а затем оборачивает ответ блоком аудита _meta . В сопроводительном документе к извлечению (статья 6_b) подробно описывается, какие столбцы парсер заполняет из пользовательской строки; в сопроводительном документе к отправке (статья 6_c) подробно описывается, как каждый столбец направляется к блоку, который его обрабатывает.

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

2. Два запроса от потребителей из одной разобранной строки.

Строка вопроса в question_df содержит все, что может понадобиться конвейеру обработки данных, но для извлечения и генерации не требуется один и тот же набор данных. Парсер выдает два производных представления строки, каждое из которых адаптировано под этап обработки: RetrievalQuery и GenerationBrief . Зачем разделять их, а не передавать всю строку целиком обоим?

2.1 Разделение между извлечением и генерацией

Потому что эти два потребительских устройства обладают совершенно разными преимуществами:

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

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

Наиболее распространенная ошибка — отправлять все данные на оба этапа. Сторона, осуществляющая поиск, путается с принципом «не путать с вычетом» (у нее нет возможности реагировать на отрицание); сторона, осуществляющая генерацию, путается с rewrites (она должна отвечать в терминах пользователя, а не документа). Два производных представления позволяют каждому этапу сосредоточиться на том, что он может сделать.

2.2 Почему исключения относятся к процессу генерации, а не извлечения.

Естественная реакция пользователя, когда он говорит «не включайте X», — это отфильтровать X при поиске. Не делайте этого. Это почти всегда неправильное решение.

Рассмотрим конкретный пример. Пользователь задает вопрос:

«Каков лимит по каждому страховому случаю, а не сумма франшизы, указанная в этом договоре?»

Наивный подход заключается в удалении из результатов поиска любого фрагмента, в котором упоминается «франшиза». Три проблемы, по одной для каждого уровня, который вы можете попытаться исключить:

Проблема 1: исключение на уровне строк: Предположим, вы исключаете все строки, содержащие слово «франшиза». Тогда вы теряете такие строки, как:

«Максимальная сумма страхового возмещения по одному случаю составляет 1 500 000 евро, а франшиза — 1000 евро».

Эта строка — ответ. Исключение просто удалило её. Лимит и франшиза часто указываются рядом именно потому, что они связаны: именно поэтому пользователь предупредил вас о путанице.

Проблема 2: исключение на уровне страницы: Еще хуже. Страница, содержащая лимит, также содержит и франшизу (в той же таблице, в том же разделе). Исключение страницы полностью лишает нас ответа.

Проблема 3: исключение на уровне раздела: Хуже всего. Раздел «Лимиты и франшизы» по названию точно соответствует тому разделу, который содержит ответ. Исключение его лишает всего необходимого.

Помимо детализации, существует более серьезная проблема. Эмбеддинги не выполняют исключение. Добавление «NOT deductible» к строке запроса не работает. Эмбеддинги игнорируют отрицание, этот режим отказа был рассмотрен с помощью измерений в статье 2 (режимы отказа эмбеддингов). Вектор для «limit per claim NOT deductible» практически идентичен вектору для «limit per claim deductible». Вы ничего не исключили. Вы просто добавили слово. BM25 с отрицательными запросами тоже ненадежен. В некоторых поисковых системах можно написать query = "limit per claim" AND NOT "deductible" . Но это исключает любой фрагмент, где встречаются оба слова, включая точные фрагменты, содержащие ответ вместе с его контрастом.

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

Схема повторяется: обнаружение сигнала для уточнения в парсере, передача его в брифинг для генерации, затем применение его модулем LLM.

Как только это разделение станет понятным, та же логика будет применяться практически к любой отрицательной инструкции: «…не из предыдущей версии» → получить все версии, отфильтровать при генерации. «…кроме необязательных предложений» → получить все, отфильтровать при генерации. «…без маркетинговой терминологии» → получить все, четко резюмировать при генерации.

Поиск должен быть широким. Генерация должна быть избирательной.

3. Что будет дальше?

Вопрос проанализирован. Два обзора потребительских предпочтений готовы. Две последующие статьи завершают работу над оставшимся блоком:

  • Статья 6 B (извлечение) описывает , что парсер извлекает из пользовательской строки. Ключевые слова (с объединением нескольких источников), ожидаемая форма и тип ответа, подсказки области действия, декомпозиция для составных вопросов и поле уточнения для нечетких входных данных. Каждое из них становится столбцом в question_df .
  • Статья 6 C (диспетчеризация) описывает, как маршрутизируется проанализированная строка . Решения о диспетчеризации (стратегия фрагментации, модель, контекст ответа), которые принимает парсер на основе того, что сказал пользователь, используя профиль документа. Флаги активации, которые адаптируют конвейер к документу. И блок _meta , который записывает каждое решение для повторного воспроизведения.

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

4. Источники и дополнительная литература

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

В том же направлении, что и в статье:

  • Эмбеддинги — это не магия: предсказуемые режимы сбоев при поиске RAG. Эмпирическое обоснование того, почему поиск не может использовать исключение: эмбеддинги игнорируют отрицание, BM25 с отрицательными запросами неустойчив, и правильное место для применения «не X» — это вызов LLM, а не сам поиск.

Другой ракурс:

  • В большинстве обучающих материалов по RAG-in-a-day вопрос рассматривается как «черный ящик», передаваемый встраивающему программисту дословно. Здесь же тезис прямо противоположный: вопрос имеет структуру (тема, область применения, форма, разрешение неоднозначностей), которую этапы поиска и генерации должны читать отдельно. Именно такой подход и обеспечивает существование «кирпича».

Ранее в серии:

  • Документальная разведка: введение к серии. Что представляет собой серия, кирпичик за кирпичиком, и в каком порядке.

Часть I:

  • Базовая модель Enterprise RAG: от PDF-файла до выделенного ответа. Четырехэтапный конвейер от начала до конца: PDF-файл на входе, выделенный ответ на выходе.
  • Эмбеддинги — это не магия: предсказуемые сбои в поиске RAG. Где сходство эмбеддингов приносит пользу (синонимы, опечатки, перефразирование), где оно предсказуемо дает сбой (неизвестные термины, отрицание, релевантность термина и ответа) и как его все равно использовать.
  • Переранжировщики тоже не волшебство: когда слой кросс-кодировщика оправдывает затраты. Что добавляет кросс-кодировщик по сравнению с встраиванием на основе двух кодировщиков (измеренные показатели) и когда оправдана задержка.
  • RAG — это не машинное обучение, и инструментарий машинного обучения решает не ту задачу. Почему оптимизация по размеру фрагментов и тонкая настройка оптимизируют не то, что нужно; вместо этого следует ориентироваться на тип вопроса.
  • От регулярных выражений до моделей компьютерного зрения: какой метод RAG подходит для какой задачи? Две оси — сложность документа и контроль вопросов — определяют, какой метод подходит для каждого конкретного случая.
  • 10 распространенных ошибок RAG, которые мы постоянно видим на производстве. Десять производственных ошибок, расположенные по пунктам, с указанием способа их исправления.

Часть II:

  • Помимо функции extract_text: два слоя PDF-файла, определяющие качество RAG. Первая половина блока анализа: характер документа, сигналы и резюме.
  • Прекратите возвращать плоский текст из PDF-файла: необходима реляционная структура RAG. Вторая половина блока парсинга: реляционные таблицы, которые считывает каждый последующий блок.

Анджела Ши. Все материалы от Анджелы Ши.

Источник: towardsdatascience.com

❌ Нет похожих статей с такими тегами

Оцените материал:

Читайте также
Новости робототехники Интернет Архив рубрики ~Обо всем~ Китайские материаловеды разработали санскрин для перовскитных солнечных элементов. Больше всего от излучения страдал тонкий транспортный слой Архив рубрики ~Обо всем~ Формула-1 в Испании: Стратегическая борьба в старом стиле по-прежнему может быть захватывающей. Новости робототехники Морские хищники: новейшие российские БЭКи и подводные дроны представили в Кронштадте Архив рубрики ~Обо всем~ Прошивка AMD AGESA 1.3.0.1b прилично снижает напряжение оперативной памяти Новости робототехники Компания Mobileye, поставщик технологий для беспилотных автомобилей, хочет снова стать частью революции роботакси. Архив рубрики ~Обо всем~ Голландская крайне правая партия выплатила компенсацию художнику, изменившему изображение с помощью ИИ. Архив рубрики ~Полезное~ Передовая платформа для создания видео с искусственным интеллектом Magic HourAI Архив рубрики ~Коротко из Telegram~ Cursor улетает в космос Сегодня SpaceX подписал обязывающее соглашение о… Архив рубрики ~Коротко из Telegram~ АСУ под прицелом   Лаборатория Касперского опубликовала большой отчет по… Архив рубрики ~Коротко из Telegram~ Для 6G уже печатают «зеркала» Ученые не только экспериментируют с… Архив рубрики ~Обо всем~ Ученые уточнили времена существования древних культур Придонья: Гуманитарные науки Архив рубрики ~Обо всем~ AMD объяснила приличную задержку выхода FSR 4.1 для видеокарт на RDNA 2 Архив рубрики ~Обо всем~ Индия ввела временный запрет на использование Telegram из-за опасений по поводу мошенничества на экзаменах. Новости робототехники Интернет Архив рубрики ~Обо всем~ Китайские материаловеды разработали санскрин для перовскитных солнечных элементов. Больше всего от излучения страдал тонкий транспортный слой Архив рубрики ~Обо всем~ Формула-1 в Испании: Стратегическая борьба в старом стиле по-прежнему может быть захватывающей. Новости робототехники Морские хищники: новейшие российские БЭКи и подводные дроны представили в Кронштадте Архив рубрики ~Обо всем~ Прошивка AMD AGESA 1.3.0.1b прилично снижает напряжение оперативной памяти Новости робототехники Компания Mobileye, поставщик технологий для беспилотных автомобилей, хочет снова стать частью революции роботакси. Архив рубрики ~Обо всем~ Голландская крайне правая партия выплатила компенсацию художнику, изменившему изображение с помощью ИИ. Архив рубрики ~Полезное~ Передовая платформа для создания видео с искусственным интеллектом Magic HourAI Архив рубрики ~Коротко из Telegram~ Cursor улетает в космос Сегодня SpaceX подписал обязывающее соглашение о… Архив рубрики ~Коротко из Telegram~ АСУ под прицелом   Лаборатория Касперского опубликовала большой отчет по… Архив рубрики ~Коротко из Telegram~ Для 6G уже печатают «зеркала» Ученые не только экспериментируют с… Архив рубрики ~Обо всем~ Ученые уточнили времена существования древних культур Придонья: Гуманитарные науки Архив рубрики ~Обо всем~ AMD объяснила приличную задержку выхода FSR 4.1 для видеокарт на RDNA 2 Архив рубрики ~Обо всем~ Индия ввела временный запрет на использование Telegram из-за опасений по поводу мошенничества на экзаменах.

Оставить комментарий