Перейти к содержимому

Что индексировать в продуктовой компании

Судьбу RAG-проекта определяет решение, которое принимается до всякой архитектуры: что вообще класть в индекс.

Соблазн понятен: подключить всё, до чего дотянулись коннекторы: вики целиком, весь трекер, всю переписку. Так делают часто, и результат предсказуем: система отвечает уверенно и мимо, потому что тонет в черновиках, отменённых решениях и чужих обсуждениях. Индекс устроен как витрина: в него попадает только то, чему вы готовы доверить ответ.

По убыванию отдачи для компании вроде «Маркета».

  • Архитектурные решения (ADR, RFC). Лучший источник из существующих: короткие, датированные, с явным «что решили и почему». На них и отвечаются самые дорогие вопросы вроде «почему возвраты считаются так». Если в компании их нет, RAG-проект даёт хороший повод завести.
  • README и runbook в репозиториях. Живут рядом с кодом, обновляются вместе с ним, содержат самое операционно ценное: как запустить, как выкатить, что делать при отказе.
  • Контракты API: OpenAPI, protobuf, схемы событий. Формально точны и почти никогда не устаревают, потому что генерируются из кода. Закрывают весь класс межкомандных вопросов «какие поля приходят в событии о выплате».
  • Постмортемы инцидентов. Плотное знание о том, как система ломается на самом деле. Немедленно окупаются на дежурстве: похожий алерт → похожий инцидент → готовый разбор.
  • Задачи в трекере: описания и решения. Ценность средняя, шума много. Полезнее брать не все, а закрытые и с содержательным описанием; комментарии берите выборочно.
  • Обсуждения в PR-ревью. Здесь живут неписаные соглашения команды. Шумно, но иногда это единственное место, где объяснено, почему сделали именно так.
  • Страницы вики. Самый большой и самый неровный источник: рядом лежат актуальный регламент и черновик двухлетней давности. Без фильтрации по свежести и владельцу приносит больше вреда, чем пользы.
  • Описания метрик и дашбордов. Узкая, но частая польза для аналитиков: что именно считает эта цифра.
  • Переписка в чатах. Максимум шума при минимуме структуры: обрывки, шутки, устаревшие договорённости, сказанные как факт. Брать в последнюю очередь и лучше не брать вовсе; вместо этого использовать чаты как источник вопросов для золотого набора (см. Качество и оценка).
  • Сам код. Индексировать можно, но обычно эффективнее отдать агенту с поиском по репозиторию, это уровень 0 из вариантов архитектуры. Индекс кода устаревает с каждым коммитом.

Индексируйте только то, что кто-то поддерживает.

Устаревший документ не нейтрален. Для поиска он выглядит так же авторитетно, как актуальный ADR: тот же формат, те же слова, та же уверенность. Разницы система не видит, а человек, получив ответ со ссылкой, склонен ему верить. Один живой регламент и один заброшенный черновик про то же самое дают на выходе не «наполовину верно», а уверенно неверно.

Отсюда три практики:

  • Не индексировать документы без владельца и даты изменения.
  • Помечать архивное как архивное и исключать из поиска, а не удалять.
  • Отслеживать документы, которые часто попадают в ответы и давно не менялись: это очередь на пересмотр.

Права доступа: фильтровать при поиске, а не после

Заголовок раздела «Права доступа: фильтровать при поиске, а не после»

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

Инструкция модели «не рассказывай про финансовые условия» защитой не является. Если текст оказался в контексте, он уже утёк: его достанут переформулировкой вопроса, а иногда модель перескажет его сама, не заметив запрета. Это тот же класс проблем, что и prompt injection: вопрос доступа не решается просьбой к модели.

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

Устаревший индекс остаётся самой частой причиной неверных ответов. Что с этим делать:

  • Переиндексация по событию, а не только по расписанию. Изменился документ, обновился его фрагмент. Ночная переиндексация всего подряд работает, пока объёмы малы.
  • Дата в ответе. Ответ должен нести дату источника: «по регламенту от 12 марта». Пользователь сам оценит, доверять ли.
  • Заметная просрочка сигнализирует о проблеме. Документ старше года, на который часто ссылаются, стоит показывать с оговоркой.

Норма, которую полезно принять сразу: ответ без даты и ссылки на источник считается половиной ответа.

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

Ломается это там же, где RAG нужнее всего: на межкомандных вопросах. Аналитик Рекламы, у которого вопрос про возвраты, не знает, что искать надо в индексе Платежей; он вообще не знает, что возвраты живут в Платежах. Это и был исходный вопрос.

Для компании такого размера работает общий индекс с обязательной меткой домена у каждого фрагмента и маршрутизацией запросов (уровень 4 из вариантов архитектуры). Единый вход для пользователя, разделение ответственности за контент внутри: команды отвечают за свою часть индекса, а не за свою отдельную систему.

Чтобы RAG отвечал хорошо, документация должна лежать рядом с кодом и меняться тем же pull request’ом. Это давняя рекомендация, которую обычно игнорируют, потому что цена игнорирования размазана: устаревший README никого не будит ночью.

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

Автор учебника: Шахматов Алексей