Качество источников для RAG: почему плохие документы нельзя исправить промптом
Сделайте authority, lifecycle, access и evidence проверяемыми до попадания документа в retrieval
Source receipts, precedence, permissions, structure, evaluation и correction routes
Авторская SRC-6 архитектура для approve или quarantine исходного материала RAG
качество данных для RAG, качество источников для RAG, RAG система, AI база знаний, governance источников и SRC-6

$ inspect rag-sources --contract SRC-6
> receive: receipt / identity / collection
> classify: authority / precedence / lifecycle
> gate: access / structure / freshness
> test: retrieve / denied / no-answer / correction
> route: approve / quarantine / reviewerНачинайте с контракта источника, а не с промпта
RAG помогает связать ответ с разрешёнными и актуальными документами, но не превращает неактуальную, противоречивую или бесхозную коллекцию в надёжную базу знаний. Более строгий промпт может сделать ответ осторожнее по тону. Он не назначит документу владельца, не восстановит потерянную версию, не создаст отсутствующие права доступа и не докажет, что retrieval нашёл нужное evidence.
Широкий вопрос внедрения разобран на странице RAG-систем. Здесь — более узкий production-вопрос: какими должны быть исходные документы, прежде чем их индексировать для RAG?
Архитектура качества источников SRC-6
Рассматривайте документ как операционный объект, а не просто текст для embeddings. Авторская модель SRC-6 проводит источник через шесть проверяемых шагов до того, как он сможет участвовать в evidence для ответа.
получение source → идентификация → authority → lifecycle
→ access → retrieval test → approve / quarantine
вопрос → identity + scope → разрешённые source candidates
→ passages + version → evidence packet
→ bounded answer / no-answer / reviewer routeИндекс — производный слой доставки, а не владелец истины. Когда policy меняется, owner сначала обновляет или отзывает исходный документ; ingestion фиксирует новое состояние; retrieval показывает только разрешённую актуальную версию.
Проблема и требования: что означает «достаточно качественный» источник
Источник пригоден для RAG, только если команда может дать шесть практических ответов:
- Identity: что это за материал, откуда он пришёл и какой stable ID его представляет?
- Authority: это governing policy, справочный материал, draft или устаревшая копия?
- Lifecycle: кто обновляет его, какая версия текущая и когда материал надо пересмотреть или удалить?
- Access: какой пользователь, tenant, role или workflow вправе его получать?
- Structure: может ли читатель без догадок отличить заголовок, section, исключение, дату действия и scope?
- Evaluation: подтверждают ли representative questions, что нужный passage находится, цитируется и безопасно обрабатывается при отсутствии evidence?
Это не требование идеальной документации. Это минимальный контракт, который позволяет решить, может ли система использовать материал как evidence. Маленький корпус с владельцами обычно лучше для пилота, чем большая папка с экспортами, презентациями и файлами «финальная версия».
Ключевые компоненты pipeline качества источников
1. Inventory и стабильный receipt
До ingestion внесите каждого кандидата в inventory. Сохраните stable source ID, исходное расположение, content hash, owner, collection, время получения и declared type. Receipt делает возможными повторную обработку и удаление: команда понимает, что попало в индекс, и может убрать верные derived chunks после исправления.
Не используйте имя файла как единственный identity. policy-final.pdf, policy-final-2.pdf и new-policy.pdf — признак проблемы lifecycle, а не версии, которые retriever обязан угадать по confidence score.
2. Authority и правило приоритета
Документы на одну тему могут иметь разную силу. Подписанная актуальная policy, процедура операционной команды, поясняющий FAQ и старая training-презентация не должны быть взаимозаменяемыми passages. До retrieval зафиксируйте source class и правило приоритета.
Если два разрешённых текущих source противоречат друг другу, корректный маршрут — видимый conflict или escalation к reviewer. Нельзя просить модель выбрать более убедительное предложение и считать это policy decision.
3. Lifecycle, freshness и удаление
У каждого retrievable source нужен named owner и lifecycle event: published, superseded, expired, archived или removed. Добавляйте effective date там, где это важно, и явно фиксируйте замену версии. Успешный ingestion run не доказывает актуальность корпуса.
Production-требование — обратимое изменение: owner может отозвать документ, pipeline находит его derived records, а система подтверждает, что они больше не участвуют в retrieval. Для операции оставляют audit receipt, но не хранят данные дольше объявленной policy.
4. Access до retrieval
Permissions применяются до поиска кандидатов, а не после черновика модели. Связывайте документ и chunk с минимально достаточным scope: tenant, role, team, project или named workflow. Сначала разрешите identity и purpose вызывающего, затем спрашивайте индекс.
Поздняя фильтрация широкого списка кандидатов ненадёжна: чувствительный текст может оказаться в логах, reranker, prompt или cache. Если access model не готова, источник нельзя добавлять в RAG-корпус.
5. Читаемая структура и границы chunks
Chunking не восстанавливает заголовки, таблицы, исключения и scope, которые исчезли при экспорте. Сохраняйте title, иерархию section, page или source locator, version и применимую audience рядом с каждой единицей retrieval. Сначала делите по смысловым границам, затем проверяйте, что passage удерживает условие, меняющее его значение.
Например, фраза с лимитом без абзаца «кроме случая…» — не атомарный факт. Такой chunk должен оставаться связанным с исключением или направлять вопрос к полному source.
6. Evaluation retrieval и correction loop
Соберите небольшой reviewed test set до широкого запуска. В нём нужны обычные вопросы, changed-source cases, неоднозначные термины, denied-access requests, retired documents, conflicts и вопросы, на которые система обязана ответить no-answer. Проверяйте retrieval и финальный ответ: беглый текст с неверным passage — failure, даже если звучит правдоподобно.
Сохраняйте correction route, который отличает дефект source, metadata, access rule, chunk boundary, ranking, prompt или reviewer policy. Иначе команда будет снова и снова настраивать промпт для проблемы, возникшей выше по pipeline.
Failure modes, которые промпт не исправит
| Failure mode | Почему промпт не решает проблему | Безопасный следующий шаг |
|---|---|---|
| Два файла называют себя актуальными | У модели нет legitimate authority выбрать приоритет | назначить governing source или направить conflict владельцу |
| Устаревшая policy осталась в индексе | Предупреждение в промпте не найдёт каждый stale passage | отметить superseded, удалить derived records и проверить отсутствие |
| Private и shared материалы в одной collection | Ответ может увидеть текст до позднего filter | применять identity-aware access до retrieval |
| OCR потерял headings, dates или exceptions | Потерянной связи больше нет в context | исправить source или сохранить structural metadata |
| Нет owner для corrections | Модель не создаёт процесс сопровождения | назначить owner lifecycle и correction |
| В evaluation только happy path | Хорошая формулировка не показывает нетестированные риски | добавить representative, denied и no-answer cases |
Это системные, а не стилистические failures. Инструкция «используй только надёжные источники» полезна как guardrail после source governance, но не заменяет её.
Минимальный acceptance gate SRC-6
Используйте этот авторский псевдокод как опору архитектурного ревью. Он намеренно небольшой: production-система добавит storage, audit и failure handling в нужном для неё объёме.
require(source.id && source.owner && source.version && source.authority);
require(source.lifecycle.active && source.accessRule && source.structurePreserved);
require(testSet.normal && testSet.changed && testSet.denied && testSet.noAnswer);
eligible = source.authority === "governing" || source.precedence.isDefined;
retrievable = eligible && caller.permitted(source.accessRule) && source.lifecycle.current;
release = retrievable && evaluation.beatsBaseline && corrections.haveOwner;Gate не обещает score. Он требует условий, при которых команда может расследовать miss, заменить плохой source и не отвечать, когда evidence недостаточно.
Тестирование и production-чек
До добавления collection проведите проверки на representative slice, а не на отполированном демо:
- Receipt check: можно ли связать каждый выданный passage со stable source и version?
- Freshness check: исчезает ли superseded source после ожидаемого lifecycle event?
- Access check: получает ли denied user ни passage, ни намёк на restricted content?
- Precedence check: выдаёт ли conflict governed result или reviewer route вместо тихого synthesis?
- Context check: сохраняет ли каждый test passage scope, exceptions и locator?
- No-answer check: отказывает ли система в unsupported вопросе, не выдумывая source?
- Correction check: может ли owner исправить один source и затем проверить derived state индекса?
Для каждого сигнала фиксируйте denominator. Формулировка «почти все ответы выглядели хорошо» не отличает рабочую RAG-систему от демо, где исключили stale, restricted и ambiguous cases.
Практический первый шаг
Выберите один question class и небольшой corpus одной команды. Соберите inventory, договоритесь об authority и access boundaries, затем создайте reviewed test set до embeddings. Сравните retrieval с текущим baseline: search, прямым запросом в систему, curated directory или human queue. Расширяйте corpus только когда evidence показывает, что retrieval улучшает определённый outcome и не ослабляет контроль.
Для ограниченного архитектурного ревью подготовьте примеры вопросов, inventory источников, permissions, lifecycle rules и несколько наблюдаемых failures. Это создаёт предметную стартовую точку для RAG-системы, технического аудита или evidence-led пилота. Дополнительно: RAG простыми словами, когда RAG не нужен и кейсы.
require(source.id && source.owner && source.version && source.authority);
require(source.lifecycle.active && source.accessRule && source.structurePreserved);
require(testSet.normal && testSet.changed && testSet.denied && testSet.noAnswer);
eligible = source.authority === "governing" || source.precedence.isDefined;
retrievable = eligible && caller.permitted(source.accessRule) && source.lifecycle.current;
release = retrievable && evaluation.beatsBaseline && corrections.haveOwner;