Как вы документируете RAG-систему для команды?

Краткий тезис

Документация RAG-системы — это не статичный PDF, а живой артефакт, который снижает time-to-productivity для новых членов команды и предотвращает ошибки эксплуатации. Ключевые компоненты: архитектурная схема, спецификация API, конфигурация моделей (chunk size, embedding model, LLM), метрики и SLO, инструкция по деплою, примеры запросов-ответов и раздел known issues. Документировать нужно в формате, который легко обновляется (Markdown, OpenAPI) и хранится рядом с кодом.


1. Зачем документировать RAG-систему?

RAG-система включает множество движущихся частей: векторную БД, эмбеддер, LLM, пайплайн chunking'а и retrieval'а, реранкер, prompt template. Без документации:

  • Ошибки при деплое: неправильные переменные окружения, неверный chunk size, пропущенный этап эмбеддинга.
  • Долгий онбординг: новый разработчик тратит недели на выяснение, как вызывать сервис и почему ответы неполные.
  • Трудности с отладкой: невозможно быстро понять, что изменилось в конфигурации.

Документация — это скорость ввода новых членов команды и снижение рисков при передаче системы в поддержку.


2. Архитектурная схема (первое, что видит разработчик)

Схема должна отображать поток данных от запроса пользователя до генерации ответа. Используйте C4 model или PlantUML для версионирования схемы вместе с кодом.

Пример упрощённой схемы (текстовое описание):

[Client] → [API Gateway] → [RAG Service]
   ├── POST /query              ├── Embedding Service (bge-m3)
   │                            ├── Vector DB (Qdrant)
   │                            ├── Reranker (cross-encoder)
   │                            └── LLM (Llama 3-70B via vLLM)
   └── Get /health              └── Monitoring (Prometheus + Grafana)

На схеме обязательно указать:

  • какие эмбеддинги используются (модель, размерность, нормализация)
  • тип векторной БД и её параметры (расстояние — cosine, dot product)
  • какие LLM поддерживаются и как переключаются (A/B тесты)
  • сервисы-зависимости (кэш Redis, реранкер, мониторинг)

3. Спецификация API (как вызывать систему)

Опишите интерфейсы в формате OpenAPI (Swagger) или gRPC proto. Для REST-эндпоинтов обязательно:

ПолеОписание
POST /queryОсновной эндпоинт. Тело: {"query": str, "top_k": int, "stream": bool}. Ответ: {"response": str, "sources": [{"chunk_id": str, "score": float, "text": str}]}
GET /healthПроверка живучести сервиса (статус эмбеддера, LLM, БД).
POST /feedbackОбратная связь от пользователя (лайк/дизлайк) для мониторинга.

Пример кода вызова (Python-клиент):

import requests

response = requests.post(
    "https://rag.example.com/query",
    json={
        "query": "Как настроить chunk size?",
        "top_k": 5,
        "stream": False
    },
    headers={"Authorization": "Bearer <token>"}
)
print(response.json()["response"])

Примечания: опишите лимиты (max query length, max context length), формат ошибок (коды 400, 429, 500), поддерживаемые источники авторизации.


4. Параметры моделей и конфигурация

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

ПараметрЗначениеПояснение
Embedding modelBAAI/bge-m31024-мерные вектора, нормализованные; query_instruction_for_retrieval = ""
Chunk size512 токеновКомпромисс между полнотой и шумом. Измерять через recall@10.
Chunk overlap128 токеновПредотвращает разрыв предложений.
Top-K retrieval10Количество чанков, передаваемых в LLM (без реранкера).
RerankerBAAI/bge-reranker-v2-m3Включён. После reranker берётся top-3.
LLMmeta-llama/Meta-Llama-3-70B-InstructПровайдер: vLLM. Temperature=0.1, max_tokens=1024.
Prompt template./prompts/rag_v4.txtСодержит инструкцию «Отвечай только на основе контекста. Если нет ответа, скажи "Не знаю".»
Vector DBQdrant (standalone), metric=cosineКластер из 3 нод, шардирование по tenant_id.

Почему эти значения — ссылайтесь на эксперименты, графики recall@k или faithfulness из дашборда.


5. Метрики и SLO (Service Level Objectives)

Документируйте целевые значения метрик для production:

МетрикаSLOКак измеряем
P95 latency< 2 секOpenTelemetry + Jaeger
Recall@5> 0.85Оффлайн-оценка на тестовом датасете (RAGAS)
Faithfulness (RAGAS)> 0.9Ежедневный скрипт с промптами из логов
Availability99.9%Uptime Kuma, проверка/health
Context relevance> 0.85Автоматическая оценка каждого запроса

Пример кода для вычисления faithfulness (используем RAGAS):

from ragas import evaluate
from datasets import Dataset

dataset = Dataset.from_dict({
    "question": ["Как настроить chunk size?"],
    "answer": ["Рекомендуемый chunk size 512 токенов..."],
    "contexts": [["Chunk size влияет на recall и latency..."]]
})
result = evaluate(dataset, metrics=["faithfulness"])
print(result["faithfulness"])

6. Инструкция по деплою (Docker + Helm)

Опишите шаги для развёртывания в Kubernetes:

  1. Prerequisites: кластер K8s (>=1.25), установленный Helm 3, доступ к Docker registry.

  2. Сборка образов:

    docker build -t registry.example.com/rag-service:v1.0 .
    docker push registry.example.com/rag-service:v1.0
    
  3. Установка через Helm:

    helm upgrade --install rag-service ./charts/rag-service \
      --set image.tag=v1.0 \
      --set qdrant.host=qdrant-cluster \
      --set llm.endpoint=http://vllm-svc:8000
    
  4. Конфигурация (через values.yaml):

    env:
      EMBEDDING_MODEL: "BAAI/bge-m3"
      CHUNK_SIZE: 512
      TOP_K: 10
    
  5. Healthcheck: пропишите liveness probe и readiness probe (например, /health).

Дополнительно: схема сети (NodePort / Ingress), требования к GPU (для реранкера), настройка TLS.


7. Примеры запросов и ответов (Golden Test Cases)

Добавьте 3–5 примеров, которые покрывают разные сценарии:

ЗапросОжидаемый ответКомментарий
«Что такое chunk size?»«Chunk size — это количество токенов в одном фрагменте текста. По умолчанию — 512.»Нормальный казус
«Какой курс доллара завтра?»«Извините, у меня нет информации о курсе доллара. Задайте вопрос по документации RAG-системы.»Запрос вне RAG
«В ответе ошибка: chunk size 123»«Проверьте, что chunk size в конфиге не превышает 1024 токенов. Рекомендуется 512.»Граничный случай

Эти тесты автоматизируются в CI/CD (pytest) и гарантируют, что изменения не сломают базовое поведение.


8. Known Issues and Workarounds (известные проблемы и их обходы)

Ведите таблицу, которая обновляется с каждым инцидентом:

ПроблемаПричинаWorkaroundСтатус
Ответ LLM содержит галлюцинации, даже если контекст пустLLM игнорирует инструкцию «отвечай только на основе контекста»Заменить prompt template на жёсткий: «Если контекст пуст, отвечай "Не знаю".»Fixed v2.1
Latency > 5 сек при высоких нагрузкахReranker загружает модель на одном GPU, очередь растётМасштабировать реранкер до 2 подов, добавить rate-limiterIn progress
Векторная БД не отвечаетСбой в Qdrant кластереДобавить circuit breaker и кэш Redis для топ K результатовPlanned

9. Пет-проект для закрепления

Задача: Создать документацию для микро-RAG-системы, которая отвечает на вопросы по API популярного сервиса (например, OpenWeather).
Инструменты: MkDocs (хостинг на GitHub Pages), PlantUML (диаграмма), OpenAPI (спецификация эндпоинта /query).
Шаги:

  1. Развернуть простой RAG: FastAPI + Chroma + OpenAI embeddings.
  2. Написать MkDocs-проект: архитектура, API, конфигурация (chunk_size, model).
  3. Добавить автотесты (pytest) с проверкой recall@5.
  4. Включить раздел «Known issues» (например, проблема с актуальностью погоды).
  5. Опубликовать на GitHub Pages.
    Ожидаемый результат: Документация, по которой коллега сможет за 30 минут локально запустить и протестировать систему.

10. Связь с другими вопросами

ВопросТема
1Как спроектировать RAG под 10 000 документов?
5Оценка качества retrieval
7Уменьшение latency
10Self-RAG и когда его использовать
20Обновление документов в существующей RAG-системе

Навигация