Глава 39. RAG и поиск по знаниям
RAG (Retrieval-Augmented Generation, генерация с дополнением найденным контекстом) часто воспринимают как задачу поиска.
Есть документы.
Из них строятся фрагменты.
Фрагменты индексируются.
По пользовательскому запросу система находит наиболее подходящие материалы и передаёт их модели генерации.
На первый взгляд задача доступа кажется простой:
User
↓
Search
↓
Documents
↓
Answer
Но в корпоративной системе этого недостаточно.
Пользователь может иметь право увидеть один документ и не иметь права увидеть другой, хотя оба документа одинаково хорошо соответствуют запросу.
Более того, модель может не должна знать даже о существовании закрытого документа.
Поэтому в поиске по знаниям появляется важное различие:
релевантность информации и допустимость её использования — разные свойства.
39.1 Поиск отвечает не на тот же вопрос, что авторизация
Поисковая система пытается ответить:
какие материалы наиболее релевантны запросу?
Модель доступа отвечает:
какие материалы этот субъект имеет право использовать?
Это разные функции.
Пусть есть три документа:
D1 — архитектура продукта
D2 — внутренний финансовый отчёт
D3 — инструкция для клиентов
Пользователь задаёт:
"Как устроен продукт?"
Поисковая система может считать D1 и D2 наиболее релевантными.
Но это ещё не означает:
User → READ → D2
Если доступ к D2 запрещён, его нельзя передавать в последующую обработку только потому, что он оказался хорошим поисковым результатом.
Получается:
Relevance
≠
Authorization
39.2 Поиск должен работать только с допустимым множеством
Для конкретного пользователя можно представить два множества.
Первое:
Relevant(Query)
— всё, что соответствует запросу.
Второе:
Allowed(User)
— всё, что пользователь имеет право использовать.
Результат должен находиться в их пересечении:
SearchResult
=
Relevant(Query)
∩
Allowed(User)
Это не обязательно означает, что система буквально выполняет две операции над множествами.
Это архитектурный принцип.
Поиск не должен рассматривать запрещённые данные как допустимый источник ответа.
39.3 Документ и его фрагменты — не одно и то же
RAG обычно работает не с целыми документами, а с фрагментами.
Например:
Document D
├── Chunk 1
├── Chunk 2
├── Chunk 3
└── Chunk 4
Возникает вопрос:
если пользователь имеет доступ к документу, получает ли он доступ ко всем его фрагментам?
Во многих системах — да.
Но это уже правило модели.
Нельзя считать это свойство самого технического разбиения.
В другой системе разные части документа могут иметь разные ограничения.
Например:
Document D
├── public section
├── internal section
└── restricted section
Тогда физический chunk становится объектом, участвующим в модели доступа.
Это показывает, почему нельзя автоматически считать:
Document = security boundary
Граница доступа определяется моделью.
39.4 Метаданные поиска становятся частью безопасности
Чтобы найти нужный фрагмент, индекс обычно хранит не только текст.
У фрагмента могут быть метаданные:
document_id
project_id
department_id
owner_id
classification
lifecycle_state
Эти данные используются для фильтрации и поиска.
Но если они участвуют в ограничении доступа, они становятся частью security path.
Например:
chunk
↓
project_id = P1
и:
User A
↓
member of
↓
P1
могут вместе стать основанием для допуска фрагмента к поиску.
Тогда поисковый индекс уже не является нейтральным техническим хранилищем.
Он содержит производное представление данных, которое должно сохранять необходимые границы безопасности.
39.5 Доступ должен ограничивать поиск, а не только готовый ответ
Самая очевидная ошибка — разрешить поиск по всему индексу, а затем проверить доступ к найденным документам перед возвратом ответа.
Проблема в том, что запрещённый объект уже участвовал в вычислении.
Например:
Query
↓
Search all documents
↓
D1
D2 — restricted
D3
↓
Filter D2
↓
Generate answer
На первый взгляд всё выглядит безопасно.
Но архитектурно здесь уже возник вопрос:
мог ли закрытый материал повлиять на вычисление до того, как был отброшен?
Если поисковый движок, reranker или генератор использовал закрытый фрагмент, простого удаления его из конечного ответа может быть недостаточно.
Поэтому граница доступа должна проходить как можно раньше.
Более надёжная схема:
Query
↓
Security context
↓
Allowed search space
↓
Retrieval
↓
Reranking
↓
Generation
↓
Answer
Авторизация становится ограничением пространства поиска.
39.6 Контекст пользователя и контекст генерации — разные вещи
В RAG слово «контекст» используется особенно часто.
Но это два разных понятия.
Первое:
Access Context
— факты и отношения, определяющие допустимость доступа.
Второе:
Generation Context
— найденные фрагменты, переданные модели для формирования ответа.
Их нельзя смешивать.
Например:
Access Context
=
User
+
Project
+
Role
+
Object relations
+
State
а:
Generation Context
=
Chunk A
+
Chunk B
+
Chunk C
Первый определяет, какие данные могут попасть во второй.
Поэтому:
Access Context
↓
determines allowed sources
↓
Generation Context
Это особенно важно потому, что оба понятия обычно называются одним словом — context.
39.7 Один запрос может затрагивать множество объектов
В обычной CRUD-операции часто можно явно определить:
Subject
Action
Object
В поиске вопрос сложнее.
Пользователь задаёт один запрос:
"Как мы реализовали механизм публикации?"
Система может найти десятки фрагментов:
Document A
Document B
Document C
...
Document N
Каждый из них может иметь собственный контекст доступа.
Поэтому запрос пользователя не означает:
один объект → одно решение
На этапе retrieval фактически выполняется множество проверок:
Can(User, READ, Chunk1)?
Can(User, READ, Chunk2)?
Can(User, READ, Chunk3)?
...
При этом сама модель поиска должна быть построена так, чтобы эти проверки выполнялись эффективно.
39.8 Один документ может быть доступен через несколько оснований
Пусть документ относится к проекту P1.
Пользователь может получить к нему доступ потому что он:
member of P1
или:
owner of Document D
или:
explicitly granted access
Поисковая система не должна обязательно знать, почему документ разрешён, если для неё достаточно итогового security fact.
Но архитектура авторизации должна уметь построить этот результат.
Получается знакомое разделение:
Source relationships
↓
Effective permissions
↓
Allowed search space
Поисковый индекс может использовать уже подготовленный результат.
Он не обязан каждый раз самостоятельно обходить весь граф отношений.
39.9 Изменение отношения должно менять поисковую видимость
Предположим, пользователь покинул проект:
User A
↓
removed from
↓
Project P1
Документы проекта не изменились.
Индекс тоже может физически не измениться.
Но поисковая доступность пользователя должна измениться.
То есть:
Relationship change
↓
Security projection change
↓
Search visibility change
Это особенно важно для больших индексов.
Необязательно перестраивать весь индекс документа только потому, что изменилось членство одного пользователя.
Можно изменить производный security layer, через который определяется допустимость поиска.
39.10 Отзыв доступа важнее простого добавления
Допустим, пользователь имел доступ к проекту:
User A → Project P1
Документы проекта уже могли попасть:
-
в поисковый индекс;
-
в кэш;
-
в промежуточные результаты;
-
в историю поисковых запросов;
-
в другие производные представления.
После отзыва доступа:
User A → Project P1
↓
revoked
недостаточно изменить только основную запись членства.
Нужно понимать, какие производные состояния используют это отношение.
Именно поэтому ранее мы различали:
Source fact
и:
Derived security fact
Для RAG это различие становится особенно важным.
39.11 Индекс сам становится частью поверхности безопасности
Поисковый индекс часто воспринимается как техническая оптимизация.
Но если он содержит исходный текст или достаточно информации для его восстановления, то он является ещё одним местом хранения данных.
Например:
Database
↓
Search index
↓
Cache
↓
LLM context
Доступ к базе может быть ограничен, но если индекс доступен шире, модель безопасности фактически обходится через другой путь.
Поэтому для каждого производного представления нужно задать вопрос:
какие исходные данные можно восстановить из него и какие ограничения должны сохраняться?
Это относится не только к RAG.
Тот же принцип действует для:
-
кэшей;
-
материализованных представлений;
-
поисковых индексов;
-
отчётов;
-
экспортов;
-
аналитических витрин.
RAG просто делает эту проблему особенно заметной.
39.12 Генерация ответа не отменяет исходные права
Допустим, пользователь имеет доступ к документу только для чтения.
Модель генерации может на основе этого документа сформировать:
summary
Это не означает автоматически, что пользователь получил новый уровень доступа.
Но возникает другой вопрос:
не создаёт ли производный ответ новый способ раскрытия данных?
Например, документ может быть доступен для чтения, но отдельные сведения могут иметь ограничения на распространение или экспорт.
Поэтому authorization исходного объекта и правила использования производного результата могут быть связаны, но не обязаны быть идентичными.
Это снова показывает границу между:
Authorization
и более широкой:
Data security
которую мы рассматривали раньше.
39.13 RAG особенно хорошо показывает разницу между релевантностью и допустимостью
Пусть система нашла:
D1 — relevance 0.94 — allowed
D2 — relevance 0.92 — forbidden
D3 — relevance 0.88 — allowed
Нельзя рассуждать:
D2 is highly relevant
→ use D2
→ hide it later
Правильная последовательность должна сохранять ограничение доступа:
Allowed
↓
Relevant
↓
Ranked
↓
Generated
То есть безопасность задаёт допустимое пространство, внутри которого работает поиск.
Это не означает, что authorization всегда должен выполняться отдельным запросом перед retrieval.
Напротив, эффективная архитектура может объединять фильтрацию и поиск.
Но семантически эти функции остаются разными.
39.14 В RAG особенно полезны производные security facts
Предположим, исходные отношения таковы:
User A → member of Project P1
User A → member of Department D1
Документы:
Document X → Project P1
Document Y → Department D1
Document Z → Project P2
Из исходных отношений можно заранее получить производное представление:
User A
├── allowed Project P1
└── allowed Department D1
А индекс может использовать эти данные для ограничения поиска.
Такой подход переносит вычисление сложных отношений с момента запроса на момент изменения модели.
Это тот же архитектурный принцип, который мы рассматривали для security projections:
Source facts
↓
Security projections
↓
Allowed search space
↓
Retrieval
При этом индекс и security projection остаются разными понятиями.
Индекс отвечает за поиск.
Security projection — за производное представление отношений доступа.
39.15 Но нельзя превратить поисковый индекс в источник истины
Если пользователь изменил принадлежность к проекту, источником истины остаётся исходная модель:
User
Project
Membership
а не:
SearchIndex.allowed = true
Индекс должен быть перестроен или обновлён так, чтобы соответствовать актуальной модели.
Иначе производное состояние начнёт определять безопасность самостоятельно.
Получится опасная конструкция:
Domain model
↓
Search index
↓
Security decision
в которой индекс фактически становится вторым источником истины.
Правильнее:
Domain facts
↓
Security model
↓
Security projection
↓
Search filtering
39.16 Один запрос может иметь разный контекст доступа для разных пользователей
Это особенно хорошо видно на одном и том же вопросе.
Пользователи:
User A
User B
задают:
"Как устроена система?"
Поисковый запрос одинаков.
Но множества разрешённых источников различаются:
Allowed(A) ≠ Allowed(B)
Поэтому:
Search(Query, A)
и:
Search(Query, B)
могут вернуть разные результаты.
Это не ошибка поисковой системы.
Это естественное следствие того, что поиск выполняется внутри контекста субъекта.
39.17 Здесь особенно важно различать объект, фрагмент и источник
В RAG могут существовать сразу несколько уровней:
Source
↓
Document
↓
Chunk
↓
Embedding
Каждый следующий уровень является производным от предыдущего.
Но security semantics не обязана полностью совпадать с этой структурой.
Например, право может определяться на уровне документа, а фильтрация выполняться на уровне chunk.
Тогда нужно явно определить соответствие:
Chunk
↓
belongs to
↓
Document
↓
has access scope
Если такого соответствия нет или оно устарело, поисковый слой может начать показывать данные, которые исходная модель доступа не разрешает.
Следовательно, техническая декомпозиция данных должна иметь понятное отношение к security boundary.
39.18 Что RAG добавляет к общей модели
В предыдущих главах мы рассматривали доступ к одному конкретному объекту.
RAG показывает ситуацию, когда один пользовательский запрос приводит к работе сразу с множеством потенциальных объектов.
При этом:
Search relevance
определяет, что полезно найти, а:
Access context
определяет, что допустимо использовать.
Поэтому общая схема приобретает ещё один уровень:
Subject
↓
Access context
↓
Allowed objects
↓
Relevant objects
↓
Retrieved context
↓
Generation
Самое важное здесь — порядок смыслов.
Поиск не должен расширять множество разрешённых объектов.
Он только выбирает наиболее релевантные объекты внутри допустимого множества.
39.19 Главный вывод
RAG показывает, что контекст доступа становится особенно важным там, где система работает не с одним явно указанным объектом, а с большим множеством потенциальных источников информации.
Поисковая релевантность не заменяет авторизацию.
Индекс не является источником истины о правах.
Фрагмент документа не автоматически наследует все свойства документа — это должно быть определено моделью.
Изменение отношения пользователя к проекту, организации или объекту может изменить множество результатов поиска, даже если сами документы не изменились.
А производные данные — индекс, кэш, найденные фрагменты и сгенерированный ответ — становятся частью общей поверхности безопасности.
Поэтому для поиска по знаниям полезно разделять:
Что соответствует запросу?
↓
Что разрешено субъекту?
↓
Что из разрешённого наиболее релевантно?
↓
Что можно передать в дальнейшую обработку?
И снова мы приходим к той же конструкции:
Relationships
↓
Context
↓
Effective access
↓
Allowed data
↓
Search / Retrieval
В PLM контекст усложняется структурой изделия.
В RAG — множеством потенциальных источников и производных представлений данных.
Но принцип остаётся тем же: доступ определяется не отдельным свойством пользователя или объекта, а отношениями между ними в конкретном контексте.
Следующая глава переносит этот принцип в SaaS, где особенно ясно проявляется другая граница: один и тот же пользователь может работать с множеством организаций и ресурсов, а изоляция клиента становится самостоятельным измерением контекста.