Пошаговые инструкции intermediate 26 мин

Как подключить ИИ-агента к базе знаний через RAG: документы, chunks, embeddings и citations

Пошаговая инструкция по подключению ИИ-агента к базе знаний через RAG: sources, documents, chunks, embeddings, vector store, hybrid retrieval, citations, access rules, evals и monitoring.

RAG embeddings Qdrant Инструкция база знаний ИИ-агент vector search chunks retrieval

Что получится в результате

Соберем RAG-контур для ИИ-агента: документы из базы знаний попадают в реестр, очищаются, режутся на chunks, превращаются в embeddings, сохраняются в vector store, ищутся по вопросу пользователя, передаются в prompt с источниками, а агент отвечает только по найденному контексту.

В первой версии RAG не должен быть "загрузили все файлы и надеемся". Нужны статусы документов, контроль версий, права доступа, фильтры, проверка качества поиска, ссылки на источники и понятное поведение, если ответа нет.

В результате будет рабочий MVP:

  1. источники описаны в `knowledge_sources`;
  2. документы лежат в `knowledge_documents`;
  3. версии документов лежат в `knowledge_document_versions`;
  4. очищенный текст лежит в `knowledge_text_blocks`;
  5. chunks лежат в `knowledge_chunks`;
  6. embeddings лежат в `knowledge_embeddings`;
  7. vector collection описана в `vector_collections`;
  8. metadata фильтры лежат в `chunk_metadata`;
  9. права доступа лежат в `knowledge_access_rules`;
  10. индексация пишется в `indexing_jobs`;
  11. поиск пишется в `retrieval_runs`;
  12. найденные chunks пишутся в `retrieval_results`;
  13. ответы агента с источниками лежат в `rag_answer_log`;
  14. вопросы без ответа лежат в `unanswered_questions`;
  15. тесты качества лежат в `rag_eval_cases`;
  16. метрики пишутся в `rag_metrics`.

Финальная проверка: вы задаете вопрос по документу, агент находит правильные chunks, отвечает с источником, не выдумывает при отсутствии ответа и не видит документы, к которым у пользователя нет доступа.

Что понадобится

Подготовьте:

  1. набор документов базы знаний;
  2. формат источников: Notion, Confluence, Google Docs, Markdown, PDF, HTML или CMS;
  3. backend для индексации;
  4. базу данных для metadata;
  5. vector store: Qdrant, Chroma, Weaviate, pgvector или другой;
  6. embedding-модель;
  7. LLM для ответа;
  8. список прав доступа;
  9. список документов, которые нельзя индексировать;
  10. 20-50 тестовых вопросов;
  11. владельца базы знаний;
  12. процесс обновления документов;
  13. лимит стоимости embeddings и LLM.

Для MVP возьмите 20-100 документов одной темы. Не начинайте с тысячи файлов, пока не проверили качество chunks и retrieval.

Шаг 1. Выберите первый RAG-сценарий

Опишите, на какие вопросы агент должен отвечать.

Хороший первый сценарий:

  1. ответы по FAQ продукта;
  2. поддержка по инструкциям;
  3. поиск по базе знаний компании;
  4. ответы по регламентам;
  5. подбор статьи из документации;
  6. помощь оператору с ответом клиенту.

Плохой первый сценарий:

  1. искать по всем файлам компании без прав;
  2. отвечать по устаревшим документам;
  3. смешивать клиентские данные и публичные статьи;
  4. делать юридические выводы без проверки;
  5. обещать точные цены без актуального источника.

Проверка: можно перечислить 10 вопросов, на которые RAG обязан отвечать.

Шаг 2. Создайте реестр источников

Создайте `knowledge_sources`.

Колонки:

id
source_key
source_type
source_name
base_url
owner
sync_mode
status
created_at
updated_at

`source_type`:

  1. `notion`;
  2. `confluence`;
  3. `google_docs`;
  4. `markdown_repo`;
  5. `pdf_folder`;
  6. `html_site`;
  7. `cms`;
  8. `manual_upload`.

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

Шаг 3. Создайте таблицу документов

Создайте `knowledge_documents`.

Колонки:

id
source_key
external_id
title
source_url
document_type
status
language
owner
last_seen_at
created_at
updated_at

Статусы:

  1. `draft`;
  2. `published`;
  3. `outdated`;
  4. `archived`;
  5. `blocked`;
  6. `deleted`.

Для retrieval используйте только `published`.

Проверка: документ со статусом `draft` не попадает в ответы агента.

Шаг 4. Введите версии документов

Создайте `knowledge_document_versions`.

Колонки:

id
document_id
version_hash
source_updated_at
raw_content_hash
parsed_content_hash
status
created_at

Зачем нужны версии:

  1. понимать, что документ изменился;
  2. не переиндексировать без причины;
  3. откатывать плохую индексацию;
  4. связывать answer с конкретной версией;
  5. удалять chunks старой версии.

Проверка: если документ не изменился, новая индексация не создает дубли chunks.

Шаг 5. Подготовьте pipeline индексации

Создайте `indexing_jobs`.

Колонки:

id
job_id
source_key
document_id
job_type
status
attempts
last_error
started_at
finished_at
created_at

Типы jobs:

  1. `sync_source`;
  2. `parse_document`;
  3. `split_chunks`;
  4. `embed_chunks`;
  5. `delete_old_vectors`;
  6. `reindex_document`;
  7. `full_reindex`;

Проверка: один документ можно переиндексировать отдельно, без полной пересборки базы знаний.

Шаг 6. Извлеките чистый текст

Создайте `knowledge_text_blocks`.

Колонки:

id
document_version_id
block_index
heading
text
source_anchor
page_number
created_at

Правила:

  1. убрать навигацию;
  2. убрать футеры;
  3. убрать повторяющиеся меню;
  4. сохранить заголовки;
  5. сохранить номера страниц для PDF;
  6. сохранить anchors для HTML;
  7. не терять таблицы, если они важны;
  8. не склеивать все в одну строку.

Проверка: 10 случайных blocks читаются как нормальный текст, а не мусор из верстки.

Шаг 7. Разбейте текст на chunks

Создайте `knowledge_chunks`.

Колонки:

id
document_id
document_version_id
chunk_index
heading_path
chunk_text
source_url
source_anchor
token_count
status
created_at

Правила chunking:

  1. chunk должен отвечать на одну смысловую тему;
  2. размер для старта: 500-1200 tokens;
  3. overlap: 50-150 tokens;
  4. не разрывать таблицу посередине;
  5. сохранять heading path;
  6. source URL сохранять в каждом chunk;
  7. старые chunks выключать при новой версии;
  8. пустые chunks не сохранять.

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

Шаг 8. Добавьте metadata

Создайте `chunk_metadata`.

Колонки:

id
chunk_id
product
topic
audience
language
access_level
department
document_status
valid_from
valid_to

Metadata нужна для фильтров:

  1. продукт;
  2. язык;
  3. отдел;
  4. тип клиента;
  5. уровень доступа;
  6. актуальность;
  7. регион;
  8. версия.

Проверка: вопрос по продукту A не получает chunks продукта B, если включен фильтр `product`.

Шаг 9. Выберите embedding-модель

Создайте `embedding_models`.

Колонки:

id
model_key
provider
model_name
vector_size
cost_per_1k_tokens
is_active
created_at

Критерии выбора:

  1. качество на русском языке;
  2. размер vector;
  3. цена индексации;
  4. скорость;
  5. совместимость с vector store;
  6. стабильность версии;
  7. возможность reindex при смене модели.

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

Шаг 10. Создайте embeddings

Создайте `knowledge_embeddings`.

Колонки:

id
chunk_id
embedding_model
vector_id
content_hash
status
created_at

Правила:

  1. embedding создается из `chunk_text`;
  2. не отправлять секретные документы;
  3. content hash нужен для dedupe;
  4. vector_id хранит ссылку на vector store;
  5. при изменении chunk embedding пересоздается;
  6. при удалении chunk vector удаляется.

Проверка: количество active chunks совпадает с количеством active embeddings.

Шаг 11. Настройте vector collection

Создайте `vector_collections`.

Колонки:

id
collection_name
vector_store
embedding_model
vector_size
distance
status
created_at

Пример:

{
  "collection_name": "kb_support_ru",
  "vector_store": "qdrant",
  "embedding_model": "text-embedding-3-small",
  "vector_size": 1536,
  "distance": "cosine",
  "status": "active"
}

Проверка: vector size в collection совпадает с embedding model.

Шаг 12. Добавьте права доступа

Создайте `knowledge_access_rules`.

Колонки:

id
subject_type
subject_id
document_id
access_level
can_read
created_at

`subject_type`:

  1. `public`;
  2. `user`;
  3. `team`;
  4. `department`;
  5. `organization`;
  6. `tenant`;

Правила:

  1. public docs доступны всем;
  2. internal docs доступны только сотрудникам;
  3. tenant docs доступны только своему tenant;
  4. retrieval применяет фильтры до ответа модели;
  5. prompt не должен получать запрещенные chunks.

Проверка: пользователь без доступа не получает закрытый документ даже через похожий вопрос.

Шаг 13. Настройте hybrid retrieval

Один vector search часто недостаточен. Используйте гибрид:

  1. keyword search;
  2. vector search;
  3. metadata filters;
  4. rerank;
  5. threshold;
  6. dedupe chunks;
  7. citations.

Создайте `retrieval_runs`.

Колонки:

id
run_id
user_id
query_text
filters_json
retrieval_strategy
top_k
created_at

Проверка: retrieval strategy записана, чтобы сравнивать качество разных подходов.

Шаг 14. Сохраняйте результаты поиска

Создайте `retrieval_results`.

Колонки:

id
retrieval_run_id
chunk_id
rank
vector_score
keyword_score
rerank_score
used_in_prompt
created_at

Правила:

  1. сохранять top 10-20 candidates;
  2. в prompt отправлять top 3-5;
  3. не отправлять chunks ниже threshold;
  4. не отправлять дубликаты соседних chunks без причины;
  5. логировать, какие chunks реально использованы.

Проверка: можно открыть retrieval run и увидеть, почему агент ответил именно так.

Шаг 15. Добавьте rerank

Rerank помогает выбрать лучшие chunks из кандидатов.

Создайте `rerank_config`.

Колонки:

id
config_key
provider
model_name
input_top_k
output_top_k
min_score
is_active

Старт:

  1. vector top 20;
  2. keyword top 20;
  3. merge и dedupe;
  4. rerank top 20;
  5. prompt top 5;
  6. min_score 0.55-0.75 после тестов.

Проверка: похожие, но неверные chunks не попадают выше точного ответа.

Шаг 16. Сформируйте context для prompt

Context должен быть коротким и с источниками.

Формат:

Контекст базы знаний:
[1] Заголовок: Возврат оплаты
Источник: https://example.com/refund#rules
Текст: ...

[2] Заголовок: Сроки обработки
Источник: https://example.com/refund#time
Текст: ...

Правила:

  1. каждый chunk имеет номер;
  2. каждый chunk имеет source URL;
  3. context не превышает лимит tokens;
  4. устаревшие chunks не попадают;
  5. приватные chunks фильтруются;
  6. context не смешивается с памятью пользователя без маркировки.

Проверка: модель может сослаться на `[1]` и `[2]`, а пользователь видит источник.

Шаг 17. Напишите system prompt RAG-агента

Каркас:

Ты отвечаешь только на основе контекста базы знаний.
Если в контексте нет ответа, скажи, что не нашел подтвержденный ответ.
Не выдумывай факты, цены, сроки, правила и ссылки.
В конце ответа укажи источники по номерам.
Если источники противоречат друг другу, скажи, что нужна проверка человека.
Если вопрос связан с деньгами, юридическими условиями или персональными данными, отвечай осторожно и предлагай handoff.
Верни JSON.

Формат:

{
  "answer": "Возврат можно оформить через личный кабинет. Обычно заявка рассматривается до 10 рабочих дней.",
  "used_sources": [1, 2],
  "confidence_score": 0.86,
  "needs_human": false,
  "no_answer": false
}

Проверка: если context пустой, `no_answer = true`.

Шаг 18. Сохраняйте ответы с источниками

Создайте `rag_answer_log`.

Колонки:

id
answer_id
run_id
retrieval_run_id
question_text
answer_text
used_chunk_ids_json
confidence_score
no_answer
needs_human
created_at

Правила:

  1. каждый ответ связан с retrieval;
  2. used chunks сохраняются;
  3. no_answer сохраняется отдельно;
  4. confidence не равен retrieval score автоматически;
  5. human review нужен для рискованных тем.

Проверка: можно проверить любой ответ и увидеть использованные chunks.

Шаг 19. Обрабатывайте отсутствие ответа

Создайте `unanswered_questions`.

Колонки:

id
question_text
user_id
filters_json
reason
suggested_owner
status
created_at

Причины:

  1. `no_chunks_found`;
  2. `low_score`;
  3. `conflicting_sources`;
  4. `access_denied`;
  5. `outdated_document`;
  6. `needs_human_policy`;

Поведение агента:

  1. не выдумывать;
  2. сказать, что ответа нет в базе;
  3. предложить передать вопрос человеку;
  4. записать вопрос в backlog базы знаний.

Проверка: вопрос без ответа попадает в `unanswered_questions`, а не превращается в уверенную фантазию.

Шаг 20. Настройте обновление документов

Создайте `source_sync_state`.

Колонки:

id
source_key
last_sync_at
last_cursor
documents_seen
documents_changed
documents_deleted
status

Режимы:

  1. manual reindex;
  2. scheduled sync;
  3. webhook on change;
  4. full reindex;
  5. document-level reindex.

Правила:

  1. changed document получает новую version;
  2. old chunks выключаются;
  3. old vectors удаляются;
  4. new chunks индексируются;
  5. eval запускается после важных изменений.

Проверка: изменение одного документа не ломает всю коллекцию.

Шаг 21. Добавьте удаление документов

Создайте `knowledge_delete_jobs`.

Колонки:

id
document_id
delete_reason
status
chunks_deleted
vectors_deleted
created_at
finished_at

При удалении:

  1. document status = `deleted` или `archived`;
  2. chunks status = `deleted`;
  3. vectors удаляются из vector store;
  4. retrieval больше не возвращает документ;
  5. audit log получает событие.

Проверка: удаленный документ нельзя найти вопросом по старому содержанию.

Шаг 22. Настройте контроль качества chunks

Создайте `chunk_quality_checks`.

Колонки:

id
chunk_id
check_key
result
reason
created_at

Проверяйте:

  1. chunk не пустой;
  2. chunk не слишком короткий;
  3. chunk не слишком длинный;
  4. есть source URL;
  5. есть heading;
  6. нет навигационного мусора;
  7. язык определен;
  8. metadata заполнена;
  9. нет секретов.

Проверка: chunks с мусором не индексируются.

Шаг 23. Создайте тесты RAG

Создайте `rag_eval_cases`.

Колонки:

id
case_key
question_text
expected_chunk_ids_json
expected_answer_contains_json
expected_no_answer
filters_json
is_critical

Минимальные тесты:

  1. точный вопрос по FAQ;
  2. вопрос с синонимами;
  3. вопрос с ошибкой в слове;
  4. вопрос на другой язык;
  5. вопрос без ответа;
  6. вопрос по устаревшему документу;
  7. вопрос с ограниченным доступом;
  8. вопрос с конфликтом источников;
  9. вопрос, где нужны два chunks;
  10. вопрос с похожим, но неверным документом.

Проверка: critical eval cases проходят перед включением RAG в production.

Шаг 24. Запустите eval

Создайте `rag_eval_runs`.

Колонки:

id
eval_run_id
retrieval_strategy
embedding_model
rerank_model
started_at
finished_at
status

Создайте `rag_eval_results`.

id
eval_run_id
case_key
retrieved_chunk_ids_json
answer_text
passed
fail_reason
latency_ms
created_at

Критерии:

  1. expected chunk в top 5;
  2. no_answer срабатывает, когда ответа нет;
  3. forbidden source не используется;
  4. ответ содержит нужные факты;
  5. ответ не содержит запрещенных обещаний;
  6. sources указаны.

Проверка: eval можно повторить после изменения chunking или embedding model.

Шаг 25. Настройте monitoring

Создайте `rag_metrics`.

Колонки:

id
date
total_questions
answered_questions
no_answer_count
avg_top_score
avg_latency_ms
retrieval_errors
human_handoff_count
created_at

Смотрите:

  1. долю no_answer;
  2. top score;
  3. latency retrieval;
  4. latency answer;
  5. частые unanswered;
  6. документы без использования;
  7. chunks с низким качеством;
  8. стоимость embeddings;
  9. стоимость LLM.

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

Шаг 26. Добавьте feedback

Создайте `rag_feedback`.

Колонки:

id
answer_id
user_id
rating
feedback_text
wrong_source
missing_answer
created_at

Используйте feedback для:

  1. обновления документов;
  2. добавления eval cases;
  3. настройки chunking;
  4. настройки threshold;
  5. улучшения prompt;
  6. handoff сложных тем.

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

Шаг 27. Проверьте безопасность

RAG может раскрыть лишние документы, если фильтры работают плохо.

Проверьте:

  1. access filters до prompt;
  2. tenant isolation;
  3. public/internal разделение;
  4. отсутствие секретов в chunks;
  5. prompt injection в документах;
  6. HTML/script в документах;
  7. устаревшие документы;
  8. deleted vectors;
  9. audit retrieval;
  10. no-answer policy.

Создайте `rag_security_events`.

id
run_id
event_type
severity
details_json
created_at

Проверка: закрытый документ не появляется в retrieval даже при точной цитате в вопросе.

Шаг 28. Сделайте smoke test

Порядок:

  1. добавьте один документ;
  2. создайте document version;
  3. извлеките text blocks;
  4. создайте chunks;
  5. создайте embeddings;
  6. проверьте vector collection;
  7. задайте точный вопрос;
  8. проверьте retrieval results;
  9. получите ответ с источником;
  10. задайте вопрос без ответа;
  11. проверьте `unanswered_questions`;
  12. удалите документ;
  13. проверьте, что он больше не находится.

Проверка: весь путь document -> answer -> source -> delete работает.

Шаг 29. Включите ограниченный production

Первый запуск:

  1. одна база знаний;
  2. один язык;
  3. только published документы;
  4. top 5 chunks;
  5. no-answer включен;
  6. citations обязательны;
  7. handoff включен;
  8. feedback включен;
  9. eval перед релизом;
  10. monitoring каждый день.

Проверка: RAG можно выключить feature flag, если качество retrieval просело.

Шаг 30. Минимальный результат для запуска

MVP готов, если выполнены условия:

  1. источники заведены;
  2. документы синхронизируются;
  3. версии документов работают;
  4. чистый текст извлекается;
  5. chunks читаемые;
  6. metadata заполнена;
  7. embeddings созданы;
  8. vector collection активна;
  9. access rules работают;
  10. hybrid retrieval работает;
  11. retrieval results логируются;
  12. prompt получает context с источниками;
  13. агент отвечает JSON;
  14. citations выводятся;
  15. no-answer работает;
  16. reindex одного документа работает;
  17. удаление удаляет vectors;
  18. eval cases проходят;
  19. security checks проходят;
  20. monitoring и feedback включены.

Финальная проверка: задайте 20 тестовых вопросов. Если правильный chunk попадает в top 5, ответы имеют источники, закрытые документы не раскрываются, а вопросы без ответа не выдумываются, RAG можно включать ограниченно.

Что нельзя автоматизировать в первой версии

В первой версии не автоматизируйте:

  1. индексацию всех документов компании без разбора;
  2. доступ к закрытым документам без access rules;
  3. ответы без sources;
  4. ответы по устаревшим документам;
  5. юридические и финансовые выводы без handoff;
  6. удаление документов без удаления vectors;
  7. смешивание tenants;
  8. использование draft документов;
  9. сохранение секретов в chunks;
  10. full reindex без backup;
  11. смену embedding model без eval;
  12. показ низкокачественных chunks в prompt;
  13. ответ при пустом retrieval;
  14. игнорирование feedback;
  15. отключение no-answer ради красивой конверсии.

Сначала RAG должен честно находить правильные источники и отказываться, когда источника нет. Уже потом можно добавлять сложные rerank, multi-hop reasoning и автоматическое обновление больших баз знаний.

Частые вопросы

Чем RAG отличается от обучения модели на документах?

RAG не переобучает модель. Он находит релевантные фрагменты документов и передает их в prompt, чтобы модель ответила на основе актуального контекста.

Какой размер chunk выбрать?

Для старта берите 500-1200 tokens с overlap 50-150 tokens. Потом подбирайте размер по eval results: слишком маленькие chunks теряют контекст, слишком большие мешают retrieval.

Нужно ли использовать только vector search?

Лучше использовать hybrid retrieval: keyword search, vector search, metadata filters и rerank. Так меньше риск найти похожий, но неверный документ.

Что делать, если RAG не нашел ответ?

Агент должен честно сказать, что подтвержденного ответа нет, записать вопрос в `unanswered_questions` и предложить handoff человеку или владельцу базы знаний.

Как не раскрыть закрытые документы?

Фильтруйте доступ до передачи chunks в prompt: tenant, user, team, access level, status и document visibility. Prompt сам по себе не является защитой доступа.

Дальше по теме

Похожие материалы