Модель большого языка
Неизученные уроки анализа вопросов RAG: структура перед поиском
Enterprise Document Intelligence [Vol.1 #6ter] — Шесть позиций по блоку вопросов, которые противоречат основной книге RAG
Ангела Ши
2 июля 2026 года
11 мин читать
Поделиться
Фото Вадима Козы, через Pexels.
Эта статья является манифестом‑компаньоном к серии Enterprise Document Intelligence, философия которой изложена в Amplify the Expert.
Она масштабируется на кирпиче 2 (разбор вопросов) архитектуры из четырёх кирпичей и отображает уроки, которые большинство учебников пропускают.
Большинство учебников по RAG пропускают анализ вопросов. Строка пользователя идёт прямо к поиску, косинус работает сверху вниз, и модель получает всё, что возвращается. Мы не делаем этого по одной причине: вопрос пользователя — это не поисковый запрос. Относитесь к нему как к поисковому запросу — и вы получите неполные и невнятные ответы. В производстве, где активно используется RAG, система может тихо давать сбои.

где эта статья находится в серии: кирпич 6 (разбор вопросов) выделен — Изображение автора
Записные книжки‑компаньоны находятся на GitHub: doc-intel/notebooks-vol1.

Общедоступный репозиторий сопутствующего кода в doc-intel/notebooks‑vol1 — Изображение автора
Наивная основа, на которую опирается эта статья

Архитектурный контраст: строка, отправленная дословно, и типизированная строка question_df с двумя краткими комментариями — Изображение автора
Наивный конвейер вставляет пользовательскую строку и запрашивает у хранилища векторов k наиболее похожих фрагментов. Ничто в этой настройке не учитывает, что вопрос состоял из двух частей или что пользователь хотел получить точное значение, а не абзац. Поэтому мы добавляем один дополнительный элемент для самого вопроса: строку в question_df с пятью типизированными столбцами (ключевые слова, область применения, форма, декомпозиция, уточнение), а также вспомогательные таблицы и две производные сводки (RetrievalQuery для блока поиска, GenerationBrief для блока генерации).

От пользовательской строки к типизированной строке с пятью столбцами, затем к двум сводкам, на которые может воздействовать каждый последующий блок — Изображение автора
На диаграмме анатомии показаны пять основных столбцов, но в производственном question_df есть ещё два, которые определяют, насколько широкое окно поиска будет передано в генерацию. Контекстная дисциплина измеряется в строках (не в символах — слишком шумно; не в страницах — слишком грубо). В таблице ниже приведены три примерные строки: один поиск по фактам, один логический ответ «да»/«нет» и один вопрос‑перечисление. Каждая строка по‑разному определяет размер своего контекстного окна, учитывая форму ответа и шаблон декомпозиции.

По одной строке на запрос, семь типизированных столбцов, контекстное окно размером в строки вокруг обнаруженного изображения привязки, созданного автором
Два изумрудных столбца — это элементарная дисциплина, которую большинство конвейеров никогда не фиксируют. Поиск фактов (сумма страхового взноса, дата вступления в силу, размер франшизы) практически не требует дополнительного контекста: одной‑двух строк перед привязкой для проверки и нескольких строк после — для расстановки знаков препинания. Для вопроса со списком требуется нулевой контекст перед ним и широкое окно для переадресации, поскольку список может охватывать целый раздел. Синтаксический анализатор заполняет строки linesbeforeanchor и linesafteranchor на основе проанализированной формы и декомпозиции; при извлечении эти данные учитываются; никакого искусственного ограничения сверху‑k в конвейере не происходит.
Ниже приведены шесть неиспользованных уроков, которые скрепляют кирпичик воедино.
Урок 1 — Реляционная схема, симметричная по отношению к документу
В литературе есть разделы «понимание запроса» и «переписывание запроса», но в обоих случаях вопрос рассматривается как строка, преобразованная в другую строку. Моделирование вопроса как строки в questiondf плюс вспомогательные таблицы — это не то, как люди обычно формулируют его. Что делает его привлекательным, так это симметрия со стороны документа (linedf, tocdf, spandf): обе стороны являются относительными, обе объединяются, и поиск становится фильтром по ним.
Почему это важно. Большинство производственных конвейеров хранят вопрос в виде отдельной строки в шаблоне запроса LLM. Не существует понятия «вопрос имеет форму», «у вопроса есть область применения», «у вопроса есть декомпозиция». Когда команде требуется новая возможность (обрабатывать отрицания, сложные вопросы, диапазоны значений), единственное место, где её можно добавить, — это шаблон приглашения. Через шесть месяцев в приглашении появляется шестьдесят строк с оговорками об особых случаях, ни одну из которых аудитор не может отследить. Структурирование вопроса на границе синтаксического анализа, способ, которым синтаксический анализ структурирует документ на его границе, устраняет эту путаницу в его источнике.
Конкретный контраст. Пользователь спрашивает: «Какова сумма премии и срок продления?». Наивная базовая схема встраивает эту строку и ранжирует фрагменты. Серия заполняет одну строку questiondf: ключевые слова [«премия», «сумма», «продление», «крайний срок»], объём «контракта», форма (сумма, дата), декомпозиция «независимый» (два подвопроса). Теперь при извлечении есть строка, по которой нужно отфильтровать linedf, а при генерации — типизированная форма для заполнения.
Вторая форма. Юрисконсульт спрашивает: «Действует ли условие о возмещении убытков после прекращения действия, и если да, то на какой срок?». Наивный способ передаёт всю строку LLM; ответ часто содержит «да» или «нет» в отношении выживаемости и молча пропускает продолжительность. Серия заполняет question_df формой (логическое значение, длительность), декомпозиция «условная» (длительность имеет смысл только в том случае, если значение выживаемости равно True), и нижестоящие блоки точно знают, какой подвопрос каким образом задаётся.
→ Статья 6А: Разберите вопрос, прежде чем выполнять поиск по всему синтаксическому анализатору от начала до конца.
Урок 2 — Схема, а не ветвящийся код.
Большинство баз кода RAG расширяют логику обработки вопросов в виде ветвящегося кода, управляемого цепочками if intent == «...», которые окостеневают в течение нескольких месяцев. Вместо этого мы создаём «кирпичик» в виде схемы: новая возможность — это столбец, добавленный в question_df, отредактированный экспертом, а не новый путь к коду. Стоимость новой функции зависит от количества столбцов, а не от квадратичных комбинаций ветвей.
Конкретный контраст. Добавьте «обработку отрицания» к кирпичу. Наивный способ: новая ветвь в ассемблерном коде запроса, плюс тесты, плюс интеграционный тест для регрессии. Последовательный способ: добавьте столбец negation_present (логическое значение), добавьте строку в словарь токенов отрицания, задокументируйте последующее поведение, и диспетчер считывает этот столбец там, где ему нужно.
→ Статья 6B: Пять полей, которые RAG должен извлечь из любого вопроса, выстраивают пять столбцов один за другим.
Урок 3 — Два кратких изложения, по одному на каждый последующий блок.
По умолчанию используется одно приглашение, содержащее все данные, где поиск должен игнорировать поля, предназначенные только для генерации, а генерация должна повторно анализировать поля поиска. Мы разделяем их: блок поиска получает только то, с чем он может работать (ключевые слова, область действия, структурные подсказки), а блок генерации получает только то, что ему нужно (цель, форма вывода, исключения). Каждый последующий блок считывает краткое описание своей задачи, а не весь вопрос целиком.
Конкретный контраст. Чтобы ответить на вопрос «Какова сумма премии в долларах, а не в евро?», в поисковой выдаче используют ключевые слова [«премия», «сумма»] и область применения «контракт». Краткое описание для генерации — это форма «Сумма(значение, валюта="USD")» плюс исключения [«EUR»]. Поисковой системе не нужно знать об исключении валюты, генерации не нужно повторно извлекать ключевые слова.
→ В статье 6A вопрос разбит на две части, а в статье 6B приведены столбцы.
Урок 4 — Экспертный словарь, который превосходит вложения.
Стандартная история предлагает встраивания как способ обработки синонимов: пользователь вводит «премиум», модель «знает», что это относится к «ежемесячному взносу». На практике conceptkeywordsdf сопоставляет слово пользователя со словом документа перед любым поиском — за небольшую плату и без каких‑либо отклонений. Эксперт поддерживает словарь как wiki; модель внедрения не имеет мнения о том, какой псевдоним является каноническим в вашем корпусе.
Конкретный контраст. Пользователь вводит: «Сколько я плачу каждый месяц?». В Naive baseline это вводится, cosine возвращает типовые страницы «оплата». Сначала Series проверяет conceptkeywordsdf: «платить каждый месяц» соответствует [«премия», «ежемесячный взнос», «ежемесячный взнос в рассрочку»] для этого страхового пакета. Поиск запускает поиск по ключевым словам по этим трём терминам; фактическая строка («премия в размере 124 долларов США в месяц») высвечивается немедленно.
→ Статья 6B: пять полей, которые RAG должен извлекать из любого вопроса, объясняет механизм conceptkeywordsdf.
Урок 5 — Четыре шаблона составных вопросов, ни один из которых не содержит умолчаний.
На вопрос, состоящий из двух частей («сумма и крайний срок»), обычно отвечают по одной части, а о другой ничего не говорят. В серии даны названия четырём шаблонам (независимый, последовательный, унифицированный, условный), и синтаксический анализатор указывает, какой из них применим. Затем конвейер либо разлагается (и выполняется параллельно), либо соединяется в цепочки (и передаёт часть A в часть B), либо отказывается отвечать на ту половину, которую не смог охватить. Частичного ответа нет.
Конкретное отличие. Пользователь спрашивает: «Какова франшиза, если сумма претензии превышает предельный размер, и каков предельный размер?» — а это последовательное соединение*. Naive RAG отправляет и то, и другое в виде одной строки; LLM отвечает о лимите и забывает оговорку об условной франшизе. Series видит decomposition = «последовательный», разбирает часть A (ограничение?) и часть B (подлежащие вычету, если требование > ограничение?), выполняет их по порядку и отправляет ответ для каждого со своей цитатой или помечает его как не найденный, если он действительно есть.
→ Статья 6B: пять полей, которые RAG должен извлечь из любого вопроса, содержат четыре составных шаблона.
Урок 6 — Детерминированный диспетчер, а не LLM‑решает.
Агентурный рефлекс гласит: пусть LLM выбирает, какие средства поиска, схемы и фрагменты подсказок активировать для каждого вызова. Мы выделяем три подхода: явно ориентированный на пользователя (форма управляет активациями), детерминированный диспетчерский (правила в коде соотносят функции запроса с активациями) и LLM‑решающий (модель планирует сама). Первые два остаются. Мы отказываемся от третьего варианта для предприятия, потому что система, которая перестраивает каждый вызов, не может дважды проходить аудит одним и тем же способом.
Конкретное отличие. Один и тот же вопрос о соответствии проходит через систему дважды. При использовании deterministic-dispatcher в журнале аудита оба раза отображается один и тот же путь отправки: в decide.py, строка 47, маршрут — «фактический поиск», активированы методы поиска [«ключевое слово», «оглавление»], схема генерации AmountWithEvidence. При использовании LLM-decisions в журнале аудита отображаются две разные логические цепочки, и вы не можете гарантировать, что завтра маршрут будет таким же. Первая доступна для проверки, вторая — нет.
Статья 6C: один разобранный вопрос RAG, четыре решения касаются шаблона диспетчера.
В шести уроках есть один общий ход: сделайте шаг, который в обычном учебнике рассматривается как встроенная обработка строк, и превратите его в типизированный блок. Как только вопрос становится строкой со столбцами, остальная часть конвейера выполняет фильтрацию, проверку типа и отправку так, как никогда не смогла бы обычная строка. Устройства для глубоких погружений (6A, 6B, 6C, 6bis) содержат код, который может быть использован в реальных корпусах; этот раздел является каталогом, который указывает на них.
Примечание по обнаружению намерений. Объём 1 остаётся минимальным по намерениям: диспетчер распознаёт базовый набор (поиск фактов, перечисление, краткое изложение из parsing_summary.summary, подробное изложение из TOC + первые строки, разрешение перекрёстных ссылок, отказ от использования вне корпуса), достаточный для корректной отправки наиболее распространённых корпоративных вопросов в формате PDF. Полная таксономия intent представлена в томе 2 (перевод, обобщение по документам, сравнение, редактура, вычитка), где матрица формата intent × создаёт десятки путей отправки поверх корешка из четырёх кирпичей. Том 1 содержит корешок в чистоте, том 2 формирует матрицу.
В разных секторах и профессиях
В «кирпичике» все области рассматриваются одинаково: извлекаются столбцы с типизированными данными из вопроса, выводятся два кратких описания. Экспертный словарь внутри conceptkeywordsdf привязан к конкретному сектору; схема и логика отправки универсальны. Пять секторов ниже, один шаблон синтаксического анализа, те же пять столбцов.
В brick все домены обрабатываются одинаково; меняется только экспертный словарь. Изображение автора.
Что меняется от строки к строке — так это экспертный словарь. В понятии страхового брокера conceptkeywordsdf «выплачивать каждый месяц» отображается как [«премия», «ежемесячный взнос», «ежемесячный взнос»]; медицинский эквивалент отображает «разжижитель крови» как [«антикоагулянт», «варфарин», «гепарин», «DOAC»]; финансовый эквивалент отображает «верхняя строка» как [«выручка», «чистая выручка», «выручка по GAAP»]. Столбцы, отправка и контрольный журнал остаются идентичными.
В каких разделах серии представлены эти уроки
В пронумерованных статьях каждый урок развивается в виде кода с помощью записных книжек, которые можно запускать:
В статье 6A (разбор вопроса: тезис) доказывается, что строка не является запросом, и показана форма отношения.
В статье 6B (разбор вопроса: извлечение) рассматриваются пять семейств столбцов (ключевые слова, область действия, форма, декомпозиция, уточнение), которые заполняют question_df.
В статье 6C (разбор вопросов: диспетчеризация) разработан диспетчер, который преобразует проанализированный вопрос в решения о маршрутизации.
Статья 6bis (цикл уточнений) применяется в случае, когда вопрос слишком расплывчатый для маршрутизации, и система запрашивает конкретное разъяснение.
Источники и дальнейшее чтение
Литература, посвящённая пониманию запросов в книгах и статьях, ориентирована на поисковые запросы пользователей (Elastic, Google) и не подходит для небольших предприятий, где экспертный словарь является основным ресурсом. В основе серии лежит перестройка в соответствии с отношениями поверх структурированного документа.
Проанализируйте вопрос перед выполнением поиска (статья 6A). Опубликованный тезис о разборе вопроса.
Пять полей, которые RAG должен извлечь из любого вопроса (статья 6B). Извлечение данных — столбец за столбцом в коде.
Один проанализированный вопрос RAG, четыре решения (статья 6C). Шаблон диспетчера, который преобразует проанализированные столбцы в решения о маршрутизации.
Когда пользователи RAG задают неопределённые вопросы (статья 6bis). Цикл уточнений, который определяет значение по умолчанию после одного запроса.
Ранее в серии:
Статья 1: Базовый корпоративный документ RAG — от PDF до выделенного ответа. Конвейер из четырёх блоков от начала до конца, где вопрос по‑прежнему передаётся в виде дословной строки.
Статья 2: Внедрение — это не волшебство. Каталог способов устранения сбоев, в котором объясняется, почему внедрение пользовательской строки не заменяет её синтаксический анализ.
Статья 3: RAG — это не машинное обучение. Сопутствующая позиция: ответ либо существует, либо его нет, поэтому структура вопроса превосходит статистическое обобщение.
Статья 4: От регулярных выражений к визуальным моделям. Система принятия решений, которая выбирает технику по типу вопроса, является основой для каждой отправки, выполняемой этим блоком.
Автор
Анджела Ши
Смотрите все от Анджелы Ши
Llm, приложения Llm, синтаксический анализ, Rag, архитектура Rag
Поделитесь этой статьёй
Поделитесь на Facebook
Поделитесь на LinkedIn
Поделитесь на X
Towards Data Science — это публикация сообщества. Поделитесь своими идеями, чтобы привлечь нашу глобальную аудиторию и заработать с помощью программы оплаты авторских прав TDS.
Напишите для TDS