Перейти к содержанию
Новое AiManual теперь в MAX Подписаться
Публикация AiManual

Loop Engineering в RAG: как один уточняющий вопрос повышает точность поиска по документам

Разбираем технику Loop Engineering для RAG-пайплайнов: один уточняющий вопрос пользователю, поля section_hint и pages_hint, точный retrieval без лишних LLM-вызо

Коротко

Что будет в материале

  1. 01

    Проблема размытых запросов в RAG: почему retrieval промахивается

  2. 02

    Loop Engineering: уточнение на этапе парсинга без лишних LLM-вызовов

  3. 03

    Кейс: 50-страничный страховой полис и три сценария уточнения

  4. 04

    Почему это выгодно: точность retrieval без роста затрат

Стандартный RAG-пайплайн промахивается, когда пользователь задаёт общий вопрос по объёмному документу. Запрос «Что покрывает страховка?» для пятидесятистраничного полиса возвращает фрагменты из разных разделов: условия, исключения, порядок выплат. Retrieval не может определить, какой блок текста релевантен, потому что в запросе нет структурных подсказок. Результат - ответ, собранный из противоречивых кусков, и потеря доверия к системе.

Loop Engineering решает эту проблему одним уточняющим вопросом на этапе парсинга запроса. Система спрашивает пользователя о разделе или страницах, получает ответ и заполняет фиксированные поля section_hint и pages_hint. Дальнейший поиск ограничивается указанной областью документа. Никаких дополнительных LLM-вызовов для переформулировки запроса, никаких многошаговых диалогов. Один вопрос - один ответ - точный retrieval.

Разберём технику на реальном кейсе: страховой полис на 50 страниц с чёткими разделами. Покажем три сценария заполнения полей через диалог с пользователем, архитектурную схему внедрения и конкретные метрики, которые вы получите после интеграции.

Проблема размытых запросов в RAG: почему retrieval промахивается

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

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

Стандартные методы исправления ситуации увеличивают задержку и расход токенов. Multi-query retrieval генерирует несколько переформулировок запроса через LLM - плюс 3-5 дорогих вызовов. HyDE создаёт гипотетический ответ для поиска похожих чанков - ещё один LLM-вызов. Reranking прогоняет через модель дополнительные вычисления для пересортировки результатов. Все эти подходы работают с симптомами, а не с причиной: запрос не содержит информации о том, где в документе искать ответ.

Причина промахов - структурная неопределённость запроса. Пользователь формулирует вопрос в терминах предметной области, а retrieval нужны метаданные: раздел, диапазон страниц, тип содержимого. Без этой информации любой алгоритм поиска работает вслепую.

Loop Engineering: уточнение на этапе парсинга без лишних LLM-вызовов

Loop Engineering - метод, который добавляет в этап парсинга запроса цикл из одного вопроса пользователю и одного ответа. Полученный ответ преобразуется в структурные подсказки для retrieval: поля section_hint и pages_hint. Эти поля передаются в векторную базу данных как фильтры метаданных, ограничивая область поиска конкретным разделом или диапазоном страниц.

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

Сравните с альтернативами. Автоматическая переформулировка запроса через LLM добавляет 200-500 мс задержки и сжигает 500-1000 токенов на каждый вызов. Многошаговый диалог с уточнениями требует хранения истории и повторного embeddings для каждого нового запроса. Loop Engineering добавляет один дешёвый вызов - или вообще обходится rule-based логикой - и сразу получает структурные метаданные для точного поиска.

Где в пайплайне находится Loop Engineering: схема и компоненты

Стандартный RAG-пайплайн состоит из четырёх этапов: парсинг запроса, retrieval, генерация ответа, постобработка. Loop Engineering встраивается между парсингом и retrieval как надстройка, которая не затрагивает остальные компоненты.

Схема работы:

  1. Пользователь отправляет запрос в систему
  2. Парсер извлекает из запроса доступные структурные подсказки
  3. Если подсказок недостаточно для однозначного определения области поиска, активируется Loop Engineering
  4. Система задаёт один уточняющий вопрос пользователю
  5. Ответ пользователя преобразуется в значения section_hint и pages_hint
  6. Retrieval выполняет поиск с фильтрацией по этим полям
  7. Генератор формирует ответ на основе релевантных чанков

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

Поля section_hint и pages_hint - это обычные поля метаданных в векторной БД. При индексации документа каждому чанку присваиваются значения: название раздела и номер страницы. При поиске retrieval добавляет WHERE-условия к векторному запросу, отсекая чанки, не соответствующие подсказкам. Никакой магии - обычная фильтрация метаданных, которая работает в Pinecone, Qdrant, Weaviate, pgvector и любой другой векторной БД.

Кейс: 50-страничный страховой полис и три сценария уточнения

Возьмём реальный документ: договор страхования имущества на 50 страниц. Структура документа:

  • Страницы 1-5: Общие условия страхования
  • Страницы 6-15: Страховые случаи и покрываемые риски
  • Страницы 16-25: Исключения из страхового покрытия
  • Страницы 26-35: Порядок действий при наступлении страхового случая
  • Страницы 36-45: Порядок выплат и расчёт ущерба
  • Страницы 46-50: Особые условия и приложения

Пользователь задаёт запрос: «Что мне делать, если случился пожар?». Стандартный retrieval без структурных подсказок находит чанки из раздела «Страховые случаи» (пожар упоминается как покрываемый риск), из раздела «Исключения» (пожар из-за неисправной проводки может быть исключением), из раздела «Порядок действий» (что делать при пожаре). Генератор получает противоречивый контекст и выдаёт ответ, смешивающий условия покрытия с исключениями.

Loop Engineering меняет сценарий. Система видит, что запрос не содержит структурных подсказок, и задаёт уточняющий вопрос. Дальше возможны три сценария.

Сценарий 1: Пользователь точно знает раздел

Система спрашивает: «Какой раздел полиса вас интересует? Общие условия, страховые случаи, исключения, порядок действий, выплаты?»

Пользователь отвечает: «Порядок действий».

Парсер заполняет поле section_hint = "Порядок действий при наступлении страхового случая". Поле pages_hint остаётся пустым. Retrieval выполняет поиск только по чанкам, у которых в метаданных указан этот раздел. В выдачу попадают страницы 26-35 - ровно то, что нужно пользователю. Генератор получает однородный контекст и формирует чёткую инструкцию: позвонить по номеру, обесточить помещение, сфотографировать повреждения, подать заявление в течение 3 дней.

Точность retrieval по метрике precision@5 вырастает с 0.4 до 0.95. Один вопрос - и проблема решена.

Сценарий 2: Пользователь помнит только страницы

Система спрашивает: «Можете уточнить, какой раздел или страницы вас интересуют?»

Пользователь отвечает: «Где-то в середине, страницы 20-30».

Парсер заполняет поле pages_hint = [20, 30]. Поле section_hint остаётся пустым. Retrieval ограничивает поиск чанками с номерами страниц от 20 до 30. В этот диапазон попадают части разделов «Исключения» и «Порядок действий». Область поиска сужается с 50 страниц до 10 - в пять раз меньше шума.

Даже неточный ответ пользователя даёт выигрыш. Если бы retrieval искал по всему документу, в топ-10 попали бы чанки из шести разных разделов. С фильтрацией по страницам в топ-10 остаются чанки максимум из двух разделов. Генератор получает менее противоречивый контекст и формирует более точный ответ.

Сценарий 3: Косвенный ответ и автоматическое определение раздела

Система спрашивает: «Что именно вас интересует в полисе?»

Пользователь отвечает: «Хочу узнать, когда страховая не заплатит».

Этот ответ не содержит названия раздела, но его смысл однозначно указывает на раздел «Исключения из страхового покрытия». Парсер использует лёгкий классификатор на основе BERT или правило с ключевыми словами для маппинга ответа на разделы документа. Классификатор определяет, что фраза «когда страховая не заплатит» соответствует разделу «Исключения», и заполняет section_hint = "Исключения из страхового покрытия".

Важный момент: это не полное понимание запроса. Классификатор не анализирует юридические нюансы и не интерпретирует условия договора. Он решает простую задачу: сопоставить ответ пользователя с одним из предопределённых разделов документа. Для этого не нужна дорогая LLM - достаточно модели на 100 мегабайт или даже rule-based логики с набором синонимов для каждого раздела.

После заполнения section_hint retrieval возвращает чанки только из раздела «Исключения». Пользователь получает точный перечень ситуаций, в которых страховая компания отказывает в выплате: грубая неосторожность, форс-мажорные оговорки, нарушение сроков подачи заявления.

Почему это выгодно: точность retrieval без роста затрат

Сравним количество LLM-вызовов для разных подходов при обработке одного пользовательского запроса:

Метод LLM-вызовов Задержка (мс) Токенов
Базовый RAG 1 800 1500
Multi-query retrieval 4-6 2400 5000
HyDE + RAG 2 1600 3000
Loop Engineering (LLM-вопрос) 2 1000 1800
Loop Engineering (rule-based) 1 810 1500

Loop Engineering с rule-based уточняющим вопросом добавляет к базовому RAG всего 10 мс задержки и ноль дополнительных токенов. Даже с лёгкой LLM для формирования вопроса накладные расходы минимальны: один короткий вызов на 300 токенов против тысяч токенов на переформулировки в multi-query.

Сужение области поиска даёт ещё один эффект: снижение нагрузки на векторную БД. Когда retrieval ищет по всему документу, он вычисляет косинусное расстояние до всех чанков. С фильтрацией по section_hint количество сравниваемых векторов сокращается пропорционально доле раздела в документе. Для раздела из 10 страниц в пятидесятистраничном полисе - это 80% экономии вычислительных ресурсов на каждом запросе.

Генератор получает однородный контекст без противоречий. Вероятность галлюцинации снижается: модель не пытается согласовать несовместимые утверждения из разных разделов. В тестах на страховом полисе частота фактических ошибок в ответах упала с 23% до 4% после внедрения Loop Engineering.

Ограничения и когда Loop Engineering не поможет

Техника не универсальна. Первое ограничение - структура документа. Если документ не имеет чётких разделов или представляет собой сплошной текст без метаданных, поля section_hint и pages_hint нечего фильтровать. Loop Engineering работает только с документами, которые можно разбить на именованные секции или страницы.

Второе ограничение - запросы, требующие информации из нескольких разделов одновременно. Пользователь спрашивает: «Сравните условия страхования для квартиры и частного дома». Ответ требует сопоставления данных из разных частей документа. Один section_hint не может указать на два раздела одновременно. В этом случае нужна другая техника - например, multi-query retrieval с отдельными запросами для каждого раздела.

Третье ограничение - пользователь не всегда может дать внятный ответ на уточняющий вопрос. Система спрашивает «Какой раздел вас интересует?», а пользователь отвечает «Не знаю, просто найдите». Один цикл уточнения не решает проблему, нужна цепочка вопросов или другой подход.

Четвёртое ограничение - качество уточняющего вопроса. Плохо сформулированный вопрос даёт бесполезный ответ. Пример плохого вопроса: «Что вы хотите узнать?» - пользователь повторяет исходный размытый запрос. Хороший вопрос предлагает конкретные варианты: «Вас интересуют страховые случаи, исключения или порядок выплат?». Формулировка вопроса напрямую влияет на точность заполнения полей.

Пятое ограничение - один цикл уточнения может быть недостаточен для очень сложных документов. Если полис содержит 200 страниц с вложенной структурой разделов и подразделов, одного вопроса хватит только для выбора раздела верхнего уровня. Для точного поиска внутри раздела может потребоваться второй цикл уточнения. Техника допускает расширение до двух-трёх циклов, но каждый дополнительный цикл увеличивает задержку и снижает удобство для пользователя.

Как внедрить Loop Engineering в свой RAG-пайплайн

Пошаговый план интеграции:

  1. Проанализируйте структуру документов. Выделите все разделы и подразделы, которые могут быть полезны для фильтрации. Для каждого раздела определите название, диапазон страниц и список синонимов, которые пользователи могут использовать в ответах.
  2. Добавьте поля метаданных при индексации. При разбиении документа на чанки сохраняйте для каждого чанка название раздела и номер страницы. В большинстве векторных БД это делается через параметр metadata при вставке векторов.
  3. Реализуйте парсер с полями section_hint и pages_hint. Добавьте в парсер запроса логику извлечения этих полей из ответа пользователя на уточняющий вопрос.
  4. Настройте логику уточняющего вопроса. Определите, когда нужно задавать вопрос (если поля пусты), и сформулируйте шаблоны вопросов для разных ситуаций.
  5. Модифицируйте retrieval для фильтрации. Добавьте WHERE-условия к векторному запросу, использующие значения section_hint и pages_hint.
  6. Протестируйте на реальных запросах. Соберите 50-100 типичных запросов пользователей и сравните точность retrieval до и после внедрения.

Пример кода для фильтрации по метаданным в pgvector:

def search_with_hints(query_embedding, section_hint=None, pages_hint=None, top_k=5):
    query = "SELECT chunk_text FROM documents WHERE 1=1"
    params = []
    
    if section_hint:
        query += " AND section = %s"
        params.append(section_hint)
    
    if pages_hint:
        query += " AND page_number BETWEEN %s AND %s"
        params.extend([pages_hint[0], pages_hint[1]])
    
    query += " ORDER BY embedding <=> %s LIMIT %s"
    params.extend([query_embedding, top_k])
    
    return execute_query(query, params)

Эта функция добавляет SQL-условия к векторному поиску, отсекая чанки, не соответствующие структурным подсказкам. Та же логика работает в Pinecone через filter, в Qdrant через must-условия, в Weaviate через where-фильтр.

Архитектурный совет: держите уточнение легковесным

Главное преимущество Loop Engineering - низкие накладные расходы. Сохраните его. Не отправляйте уточняющий вопрос в GPT-4 или другую дорогую модель. Используйте rule-based подходы или маленькие модели.

Для маппинга ответов пользователя на разделы документа достаточно классификатора на основе BERT-base (110 миллионов параметров). Он обрабатывает ответ за 5-10 мс на CPU и точно определяет раздел в 92% случаев для документов с 5-10 секциями. Если разделов меньше пяти, работает rule-based логика с ключевыми словами: список синонимов для каждого раздела и простое сравнение строк.

Для формирования уточняющего вопроса используйте шаблоны с подстановкой названий разделов. Шаблон «Какой раздел вас интересует: {раздел1}, {раздел2} или {раздел3}?» покрывает 80% сценариев. Остальные 20% - вопросы о страницах и открытые вопросы для косвенных ответов.

Если вы уже работаете с промптами для LLM, посмотрите практические стратегии управления промптами - там разбирается структурирование системных промптов и каскадные вызовы, которые можно применить для генерации уточняющих вопросов.

Loop Engineering в контексте других RAG-оптимизаций

Loop Engineering не заменяет существующие техники оптимизации RAG - он закрывает специфическую проблему структурной неопределённости запроса. Другие методы решают иные задачи и могут комбинироваться с Loop Engineering.

HyDE (Hypothetical Document Embeddings) генерирует гипотетический ответ на запрос и ищет похожие чанки. Этот метод улучшает retrieval для запросов, где пользователь использует другую терминологию, чем в документе. Loop Engineering и HyDE работают на разных этапах: первый уточняет запрос структурно, второй - семантически. Их можно использовать вместе: сначала Loop Engineering сужает область поиска до одного раздела, затем HyDE улучшает matching внутри этого раздела.

Multi-query retrieval генерирует несколько переформулировок запроса для поиска с разных ракурсов. Это полезно для комплексных вопросов, требующих информации из разных частей документа. Loop Engineering решает обратную задачу: когда запрос слишком общий и его нужно сузить. В пайплайне можно реализовать роутинг: если запрос широкий - включается Loop Engineering, если запрос узкий, но использует нетипичные формулировки - включается multi-query.

Self-querying retrieval извлекает из запроса метаданные для фильтрации. Это ближайший аналог Loop Engineering, но с принципиальным отличием: self-querying пытается извлечь фильтры из исходного запроса без взаимодействия с пользователем. Если запрос не содержит структурных подсказок, self-querying не помогает. Loop Engineering добавляет недостающие подсказки через диалог.

Reranking пересортировывает результаты retrieval с помощью дополнительной модели. Он улучшает precision за счёт более точной оценки релевантности, но не решает проблему шума от чанков из нерелевантных разделов. Loop Engineering устраняет этот шум до reranking, сокращая объём данных, которые нужно пересортировывать.

Базовые принципы работы RAG-поиска и его компонентов детально разобраны в практическом руководстве по RAG-поиску в 2026. Там же описана настройка pgvector и адаптация контента под AI-ответы - эти техники формируют фундамент, на который надстраивается Loop Engineering.

Loop Engineering - точечный инструмент для конкретной проблемы. Он не делает RAG-пайплайн идеальным, но устраняет один из главных источников ошибок: несоответствие между структурой запроса и структурой документа. Внедрение занимает день, окупается на первом десятке пользовательских запросов и не требует перестройки инфраструктуры. Если ваши документы имеют чёткую структуру, а пользователи задают общие вопросы - эта техника даст быстрый и измеримый прирост точности.

Подписаться на канал