Парсинг вопросов в RAG: как из «грязной» строки собрать точный ответ ИИ

Аналитик страховой компании спрашивает: «Какая максимальная сумма покрытия? Не путай её с франшизой, их часто указывают рядом». Одна строка, а внутри четыре разных сигнала, которые обычный поиск по документам не замечает. Так и устроен парсинг вопросов в RAG-системах: без структурирования запроса такой вопрос заваливает поиск. Кежань Ши в статье для Towards Data Science (16 июля 2026) разбирает, почему это происходит и как чинится ещё до того, как система полезет в базу знаний.
Автор называет парсинг вопроса «вторым кирпичом» корпоративного RAG-конвейера. Тема кажется узкой, но она объясняет вещь, знакомую каждому, кто работал с ИИ-ассистентом по документам: почему бот иногда отвечает уверенно и мимо.
Один вопрос: четыре сигнала
Вернёмся к строке про покрытие и франшизу. Ши раскладывает её на составляющие:
- тема запроса, максимальная сумма покрытия;
- негативная подсказка, чего избегать («не франшиза»);
- ожидаемая форма ответа это число, сумма;
- структурная подсказка, где в документе это обычно лежит.
Теперь представьте, что вы отдаёте всю строку целиком обычному поиску по близости векторов (top-k косинусный поиск). Эмбеддинг слова «франшиза» притягивает именно строки про франшизу, то, чего просили избегать. Генерация хватает первое правдоподобное число. А журнал операций не объясняет, почему система выбрала этот фрагмент.
Тезис автора: это провал обработки контекста на стороне самого вопроса. Нужные типизированные части не собрали заранее.
Почему вопрос это тоже контекст
Когда инженеры говорят про «инженерию контекста» (context engineering), они обычно имеют в виду извлечение правильного куска из документа: выбор чанков, гибридный поиск, реранкинг. Ши указывает, что это половина картины. Сам вопрос пользователя тоже контекст, который увидит языковая модель, и он заслуживает такой же обработки, как найденный фрагмент.
Немного истории термина. Концепцию «инженерии контекста» в середине 2025 года ввели Тоби Лютке, глава Shopify, и Андрей Карпаты. Позже команда LangChain структурировала её в четыре канонические стратегии: запись (write), выбор (select), сжатие (compress) и изоляция (isolate). Парсер вопроса, по замечанию автора, единственный блок конвейера, который одновременно и читает контекст, и пишет его.
Четыре кирпича корпоративного RAG
Вся серия строится на четырёх блоках:
- парсинг документа;
- парсинг вопроса;
- поиск (retrieval);
- генерация ответа.
Парсер вопроса делает собственный вызов языковой модели, тут он потребитель контекста. А на выходе выдаёт типизированную строку, которая кормит три последующих шага конвейера, тут он уже писатель контекста. Задача парсинга: превратить одну «грязную» строку в набор полей, каждое из которых читается своим шагом дальше по цепочке.
Что попадает в окно парсера, а что нет
Контекстное окно самого парсера собирается с дисциплиной. Оно составлено из четырёх типизированных слотов. Первый: фиксированный системный промпт, задаётся на уровне модуля и кэшируется на всю сессию, не переписывается под каждый вопрос. Второй: компактный JSON с фактами о документе, примерно 100 токенов, тип документа, число страниц, типовые поля, чтобы парсер понимал, смотрит он на двухстраничный продуктовый лист или на двухсотстраничный полис. Третий: стабильный блок примеров, пары «вопрос → разобранный вопрос»; автор сравнивает это с кухонной заготовкой mise en place, по одной миске на каждую форму запроса. Четвёртый: сам сырой вопрос, единственная часть, которая меняется от вызова к вызову.
А теперь важное: что в окно парсера НЕ попадает. Ни текст документа, ни результат поиска, ни память о прошлых диалогах. Причина логичная: парсер стоит ДО поиска, поэтому его результата ещё физически нет. А память сломала бы воспроизводимость, один и тот же вопрос должен разбираться одинаково. Автор называет это «минимальным по замыслу» подходом к контексту.

Каждое поле написано для конкретного получателя
Выход парсера: типизированная строка (в коде она называется ParsedQuestion). Ши формулирует принцип адресности: в строку не пишется ничего, что никто ниже по конвейеру не запросит.
| Поле | Получатель | Зачем |
|---|---|---|
| keywords | детектор ключевого совпадения в поиске | усиливают лексический (BM25) компонент рядом с векторным |
| intent | диспетчер модели и стратегии чанкинга | определяет уровень модели, который потом использует блок генерации |
| pages_hint | детектор «якорей» | привязывает поиск к диапазону страниц, если пользователь его назвал |
Вот почему структурирование запроса поднимает точность. Поле keywords питает лексический поиск, точное совпадение слов. В связке с эмбеддингами это гибридный поиск, который устойчивее к ситуации «похоже по смыслу, но не то».
Проблема близких терминов
Негативные подсказки («не путай с франшизой») бьют по типичной болезни RAG, паре терминов, которые звучат рядом, но означают противоположное. Покрытие против франшизы. Брутто против нетто. Лимит против порога. Векторный поиск такие пары стягивает вместе, потому что они семантически соседи. Явная пометка «чего избегать», вынесенная в отдельное поле, помогает системе не хватать первое похожее число.
Два брифа из одной строки
В статью встроен рабочий блокнот: пять примеров вопросов можно разобрать самому, распечатать JSON разобранного вопроса и увидеть, как от него отслаиваются два брифа, бриф для поиска (retrieval brief) и бриф для генерации (generation brief). Публичный репозиторий проекта: doc-intel/notebooks-vol1.
Побочный, но ценный эффект типизированных полей, трассируемость. Видно, ПОЧЕМУ система искала именно так: какие ключевые слова сработали, какой intent выбрал уровень модели, к какому диапазону страниц привязался поиск. Для корпоративного и регуляторного контекста, где ответ ИИ нужно защитить и объяснить аудитору, это не мелочь.
Если вам важна приватность и стабильный доступ к зарубежным ИИ-сервисам вроде ChatGPT, Sigma помогает открыть их без блокировок.
Что из этого забрать читателю
Качество ответа ИИ зависит и от базы знаний, и от того, как система «поняла» и структурировала ваш вопрос. Когда чат-бот отвечает уверенно и мимо, часто нужный факт в документах есть, но вопрос никто не разложил на сигналы перед поиском.
Отсюда совет тем, кто пользуется ИИ-ассистентами каждый день: формулируйте явно. Указывайте, какой формат ответа вам нужен (число, дата, список), называйте, чего именно вы НЕ хотите, и если знаете, где искать, говорите об этом прямо. Вы делаете руками ровно ту работу, которую хороший парсер вопроса делает автоматически.
Частые вопросы
Чем парсинг вопроса отличается от парсинга документа?
Парсинг документа готовит содержимое базы знаний к поиску, режет текст на чанки, размечает поля. Парсинг вопроса работает с обратной стороной: превращает запрос пользователя в типизированную структуру ещё до того, как система полезет в документы.
Зачем парсеру отдельный вызов модели?
Чтобы разложить сырую строку на смысловые части: тему, ключевые слова, намерение, подсказку по страницам. Этот вызов дешёвый по контексту, в окно попадает только промпт, факты о документе, примеры и сам вопрос.
Почему в контекст парсера не кладут результаты поиска?
Парсер стоит ДО поиска, результата ещё не существует. А память о прошлых запросах сломала бы воспроизводимость: один и тот же вопрос должен разбираться одинаково каждый раз.
Источники
Towards Data Science, Кежань Ши о парсинге вопросов в RAG и типизированных полях




Пока нет комментариев. Будьте первым!