Зачем RAG нужно уметь работать со структурой документа
Поисковая дополненная генерация (retrieval-augmented generation, RAG) уже стала стандартным приёмом для корпоративных баз знаний, юридического и финансового анализа и научных поисковиков. В основе большинства систем лежит одна и та же схема: разбить документ на фрагменты, проиндексировать эмбеддингами, достать топ-K при запросе, передать модели. Проблема в том, что корпоративные документы — это не набор независимых абзацев: у них есть главы, секции, подраздела, приложения. Игнорировать эту иерархию значит терять важные подсказки о том, где именно искать факт.
Недавние системы — MoDora, BookRAG, KohakuRAG, DeepRead — начали явно использовать структуру документа для навигации. DeepRead, в частности, позволяет агенту итеративно листать оглавление и добирать доказательства по ходу рассуждения. Но за это приходится платить: DeepRead сериализует полное оглавление каждого документа-кандидата в промпт. Чем больше документов и чем глубже иерархия, тем толще контекст в каждом раунде — и тем дороже вызов модели. При многодокументном корпусе такой подход быстро становится финансово неподъёмным.
Авторы статьи ставят задачу: добиться точности, сопоставимой с лучшими структурно-осведомлёнными методами, но при этом тратить существенно меньше токенов. Результирующая система называется VikingRAG.
Ключевая идея: иерархия как внешнее адресуемое состояние
Главное архитектурное решение VikingRAG — вынести структуру документа за пределы промпта и представить её как внешнее хранилище с URI-адресацией. Вместо того чтобы передавать агенту полный текст оглавления, система даёт ему четыре инструмента (tools): Search, List, Grep, Read. Агент сам решает, какую часть иерархии открыть и прочитать. В промпт попадают только результаты тех вызовов, которые агент явно запросил.
На этой основе строятся два дополнения. VikingRAG-E материализует успешные многоходовые трассировки поиска как «рёбра опыта» (experience edges) — ярлыки, связывающие начально найденные фрагменты с фрагментами-ответами. Для похожих будущих запросов агент может сразу перейти по таком ребру, минуя промежуточные раунды. VikingRAG-E+ добавляет адаптивный порог: сначала пробует однораундовый поиск с рёбрами опыта, и только если проверка достаточности доказательств провалилась — запускает полный агентный режим.
Как устроено хранилище и поиск
Хранение документа
При загрузке документа (Markdown, PDF, DOCX, TXT) VikingRAG:
-
Извлекает дерево оглавления — напрямую из заголовков Markdown или после конвертации PDF/DOCX через pdfplumber и python-docx.
-
Нарезает документ на чанки с учётом границ структурных разделов. Каждый чанк сохраняет ссылку на свой структурный узел.
-
Строит многоуровневые аннотации (abstracts) снизу вверх: листовая аннотация описывает чанки своего раздела, внутренний узел суммирует аннотации дочерних узлов.
-
Присваивает каждому объекту — директорному узлу, чанку, аннотации — URI так, что путь URI кодирует иерархию включения. Если узел
Aявляется предком узлаB, то URIAявляется компонентным префиксом URIB. -
Строит векторный индекс по чанкам и аннотациям; каждая запись хранит эмбеддинг, URI, тип, уровень иерархии и превью.
Благодаря общим URI семантический поиск сразу даёт точку входа в иерархию, а любой директорный URI ограничивает область последующего поиска нужным поддеревом.
Четыре инструмента агента
-
Search(q, scope?)— векторный поиск по чанкам и аннотациям, с опциональным ограничением по URI-области. Возвращает топ-K совпадений с URI. -
List(uri)— показывает непосредственных потомков директории. Агент видит структуру ровно настолько глубоко, насколько нужно. -
Grep(pattern, scope)— лексический поиск по ключевым словам внутри выбранного поддерева. -
Read(uri)— загружает содержимое объекта: чанка или аннотации.
Многораундовый поиск
Алгоритм поиска прост: агент на каждом шаге видит историю предыдущих вызовов и их результатов, решает — достаточно доказательств или нет, и либо формирует ответ, либо вызывает очередной инструмент. Количество раундов ограничено бюджетом R (по умолчанию 10). Если бюджет исчерпан, агент выдаёт лучший ответ на основе накопленного.
В отличие от DeepRead, токенная стоимость структурного контекста пропорциональна только тем фрагментам оглавления, которые агент явно запросил, — а не полному набору оглавлений всех документов-кандидатов.
Пример трассировки
В статье разобран пример: вопрос «нужно ли по силлабусу cs466 покупать учебник?». Правильный ответ — нет. Агент: (1) вызывает Search и находит чанк заголовка силлабуса cs466, получая URI; (2) вызывает Read — видит метаданные курса без политики учебника; (3) вызывает List для просмотра соседних чанков; (4) вызывает Grep со словами textbook, book, required, purchase в области cs466; (5) вызывает Read на найденный фрагмент и видит «optional accompanying textbook». Каждый вызов ограничен уже найденным URI — корпус в целом не сканируется.
Рёбра опыта
После успешного многораундового поиска VikingRAG-E строит направленные рёбра: источник — URI, найденный первым семантическим поиском; цель — URI, прочитанные как финальное доказательство. К каждому ребру прикрепляется эмбеддинг исходного вопроса и компактное описание трассировки. При новом запросе ребро активируется только если косинусное сходство текущего вопроса с историческим превышает порог τ (по умолчанию 0,8). Это предотвращает слепое следование рёбрам при изменении темы.
Адаптивный порог эскалации
VikingRAG-E+ сначала выполняет однораундовый поиск (с рёбрами опыта), строит кандидатный ответ и запускает специально разработанную проверку достаточности. Проверка просит модель сначала выделить ключевые ограничения вопроса (сущности, временны́е рамки, область), затем найти в контексте прямые доказательства по каждому ограничению и только потом вынести вердикт. Если вердикт — «достаточно», ответ возвращается без агентного раунда; иначе запускается полный VikingRAG-E.
Результаты
Эксперименты проведены на шести датасетах: VersionQA, SyllabusQA, QASPER, HotpotQA, LegalBench-cuad, FinanceBench. Корпуса содержат до 8,78 млн токенов. В качестве основной LLM использован DeepSeek-V4-Pro Preview; дополнительно проверены GPT-5.5, Seed-2.0, GLM-4.7. Точность оценивается протоколом LLM-as-a-judge с экспертной проверкой.
Ключевой результат: VikingRAG при сопоставимой точности с лучшими базовыми методами потребляет только 11,6%–51,9% их токенов. VikingRAG-E+ снижает стоимость до 5,1%–32,5%.
| Датасет | VikingRAG / 1-й | VikingRAG / 2-й | VikingRAG-E / 1-й | VikingRAG-E / 2-й | VikingRAG-E+ / 1-й | VikingRAG-E+ / 2-й |
|---|---|---|---|---|---|---|
VersionQA |
36,9% |
12,9% |
31% |
10,8% |
23,1% |
8% |
SyllabusQA |
40,3% |
51,9% |
31,2% |
40,2% |
25,2% |
32,5% |
QASPER |
48,7% |
34,4% |
39,3% |
27,8% |
31,4% |
22,1% |
HotpotQA |
28,1% |
11,6% |
24,8% |
10,2% |
12,3% |
5,1% |
LegalBench |
49,8% |
40,1% |
38,6% |
31,1% |
30,7% |
24,8% |
FinanceBench |
14,4% |
18,4% |
9,7% |
12,4% |
7,9% |
10% |
По задержке VikingRAG(-E+) значительно быстрее DeepRead — самого точного базового метода.
Рёбра опыта добавляют небольшой накладной расход. Среднее время построения одного ребра — от 1,5 до 3,7 секунд в зависимости от датасета. Количество построенных рёбер: от 12 764 (HotpotQA) до 38 540 (FinanceBench). VikingRAG-E в среднем потребляет 67,3%–88,1% токенов и 72,3%–91,5% задержки по сравнению с базовым VikingRAG при сохранении точности.
Адаптивная эскалация VikingRAG-E+ дополнительно снижает до 49,8%–81,1% токенов и 73,1%–89,8% задержки VikingRAG-E. Разработанный constraint-aware checker для оценки достаточности доказательств на всех датасетах значительно превосходит наивный промпт: доля правильных решений выше, а доля «ложной не-эскалации» (false-NoEscalation) ниже — от 3% до 14,4% против 8%–29,7% у наивного подхода.
При масштабировании числа документов (эксперимент на HotpotQA с 991 документом) у DeepRead точность падает и растут токены с ростом корпуса, тогда как VikingRAG(-E+) сохраняет стабильную производительность.
По скорости загрузки документов VikingRAG сопоставим с DeepRead и MoDora и значительно быстрее графовых методов (LightRAG, HippoRAG-2), которые не укладываются в 24-часовой бюджет на ряде датасетов. При этом VikingRAG тратит больше токенов при загрузке (из-за генерации превью для каждого объекта) — авторы считают это приемлемым, так как загрузка происходит редко, а поиск — постоянно.
Ограничения и открытые вопросы
Авторы явно обозначают следующее:
-
Холодный старт. Рёбра опыта требуют исторических запросов. В эксперименте они генерировались моделью на основе корпуса (по умолчанию 500 запросов на датасет). В реальном деплое рёбра появятся только после накопления пользовательских запросов; до этого VikingRAG-E+(+) работает как базовый VikingRAG.
-
Токены при загрузке документов. VikingRAG тратит больше токенов на этапе загрузки, чем DeepRead и MoDora. Для сценариев с частой ротацией документов это может быть значимо.
-
Доля ложной не-эскалации. Даже у лучшего чекера этот показатель превышает 5% на нескольких датасетах, хотя авторы отмечают, что это не всегда транслируется в ошибку ответа.
-
Оценка охватывает только текстовый контент. Датасеты содержат вопросы только по текстовой части документов; таблицы, формулы и изображения не рассматриваются.
-
Только английский язык — все эксперименты проведены на английских датасетах; применимость к другим языкам не проверялась.
-
Только шесть датасетов — несмотря на разнообразие доменов, вопрос о генерализации на иные типы структур (например, XML-документы стандартов или кодовые репозитории) открыт.
Кому это важно и что с этим делать
Статья непосредственно полезна инженерам, которые строят или эксплуатируют корпоративные базы знаний, юридические и финансовые поисковики, или любые RAG-системы поверх документов с иерархической структурой (технические руководства, регуляторная документация, научные книги). Ключевые наблюдения:
-
Если вы уже используете DeepRead-подобный подход (агент листает полное оглавление) — попробуйте заменить его на инструментальный интерфейс с URI-адресацией. Авторы показывают, что это даёт сопоставимую точность при кратно меньших токенах.
-
Паттерн «experience edges» — фактически кэш успешных путей поиска. Если ваш рабочий датасет имеет повторяющиеся типы запросов (что типично для корпоративного support-бота), этот приём работает хорошо: порог сходства τ = 0,8 оказался хорошим компромиссом.
-
Адаптивная эскалация имеет смысл только после набора истории. Не включайте её сразу при деплое — только после того как накопятся реальные пользовательские сессии.
-
Исходный код открыт: github.com/rucdatascience/VikingRAG, а ядро механизма интегрировано в базу контекстов OpenViking для AI-агентов.
-
Для оценки своей системы полезно разделить метрики на токены при поиске (повторяющийся расход) и токены при загрузке (разовый расход) — авторы показывают, что эти компоненты вносят очень разный вклад в общую стоимость.
Оригинал статьи: arXiv:2609.11390