Главная / Статьи

Конечно-конечная система RAG с Chroma, FastAPI и Llama 3.2

Полностью работающий ассистент на основе RAG от начала до конца: разбиение PDF на части, повторная ранжировка с использованием кросс-кодера, Chroma, Llama 3.2 в Ollama, FastAPI, Docker, pytest и GitHub Actions в рамках процесса CI.

Издатель: REACTAPP.TOP8 мин чтения1747 слов

Источники: I Built a Production-Style RAG Knowledge Assistant with Python, ChromaDB, FastAPI, and Llama 3.2

RAG с учётом особенностей производства: входные данные в CI

Практический помощник с указанием источников — обработка PDF, семантический поиск, переранжирование результатов, локальная генерация с использованием Llama, FastAPI, Docker и GitHub Actions — реализованный как система обучения, а не просто игровой инструмент.

После первого эксперимента с MCP следующей проблемой стала генерация с усилением на основе извлечённых данных с оценкой качества и пакетированием результатов, а не ещё один вариант «загрузки PDF в Colab».

Цели

Индексация документов в постоянный векторный хранилище; извлечение информации, переранжирование результатов и подтверждение ответов с указанием цитат; предоставление данных через HTTP; оценка качества с помощью простых тестов и pytest; контейнеризация и интеграция с CI для своевременного выявления сбоев.

Архитектура

Схема индексации:

Documents
   ↓
Chunking
   ↓
Embeddings
   ↓
Vector Database
   ↓
Semantic Retrieval
   ↓
Reranking
   ↓
LLM
   ↓
Grounded Answer + Sources

Путь загрузки документов:

PDF Documents
      ↓
Document Loading
      ↓
Text Chunking
      ↓
Embeddings
      ↓
ChromaDB

Путь обработки вопросов и ответов:

User Question
      ↓
Semantic Retrieval
      ↓
Cross-Encoder Reranking
      ↓
Prompt Construction
      ↓
Llama 3.2
      ↓
Grounded Answer
      ↓
Source Citations

1. Ввод данных

Загружайте PDF-файлы в документы в стиле LangChain, сохраняя метаданные страниц для последующих цитат. Плохие загрузчики приводят к скрытым ошибкам при цитировании позже.

2. Разбиение на фрагменты

Chunk size: 1000 characters
Chunk overlap: 200 characters

Наличие перекрытия предотвращает исчезновение предложений, находящихся на границах фрагментов, во время извлечения информации. Рассматривайте размеры фрагментов как параметры конфигурации, а не как магические числа, спрятанные в ячейке блокнота.

3. Эмбеддинги

sentence-transformers/all-MiniLM-L6-v2

Простой инструмент типа sentence-transformer позволяет запускать демо-версию на ноутбуке, при этом он достаточно эффективен для английских технических документов.

4. Сохранение состояния Chroma

Document
   ↓
Chunks
   ↓
Embedding Vectors
   ↓
ChromaDB

Фрагменты преобразуются в векторы на диске, поэтому перезапуск не требует полной повторной обработки. Обновляйте имя коллекции при изменении стратегии разбиения на фрагменты.

5. Семантическое извлечение

documents = vector_store.similarity_search(
    query=query,
    k=top_k
)

Используйте k лучших соседних векторов в качестве первого этапа обработки, прежде чем тратить ресурсы кросс-энкодера.

6. Переупорядочивание с помощью кросс-энкодера

cross-encoder/ms-marco-MiniLM-L-6-v2
User Question
      ↓
Vector Search
      ↓
Candidate Documents
      ↓
CrossEncoder
      ↓
Reranked Documents

Показатель воспроизведения би-энкодера плюс точность кросс-энкодера представляют собой стандартную двухэтапную схему для систем RAG, чувствительных к качеству.

7. Основание для работы LLM

При формировании промпта ранжированные фрагменты вводятся как источники с номерами:

[Source 1]
Retrieved document content...
[Source 2]
Retrieved document content...[Source 3]
Retrieved document content...

Укажите модели, что она должна отвечать только на основе этих блоков и цитировать их. Откажите в запросе, если контекст пуст.

8. Локальная версия Llama через Ollama

Генерация текста происходит непосредственно на устройстве для обеспечения конфиденциальности и снижения затрат. Задайте значение тега в конфигурации и проверьте работу процесса Ollama перед принятием запросов.

9. Интерфейс FastAPI

GET /health
POST /query

Проверка работоспособности через пробы; запрос к пути RAG. Сохраняйте легкость сервиса — используйте тот же пайплайн, что и в CLI.

Напоминание о полном процессе обработки запроса:

Question
   ↓
Semantic Retrieval
   ↓
Retrieved Chunks
   ↓
CrossEncoder Reranking
   ↓
Grounded Prompt
   ↓
Llama 3.2
   ↓
Answer + Citations

10. Оценка

Questions evaluated: 5
Questions passed: 5
Keyword Match Rate: 100.00%
Hit Rate@K
Recall@K
MRR
Answer Relevance
Faithfulness
Citation Correctness

Проверка ключевых слов в сочетании с показателями поиска (коэффициент точности, воспроизводимости, MRR, релевантность ответа) позволяет выявить скрытые ухудшения при изменении эмбеддингов или промптов.

11. pytest

API health endpoint
Document chunking
Document retrieval
3 passed

Тесты на состояние покрытия кода, разбиение на чанки и базовые тесты поиска обеспечивают быстрое выявление сбоев в CI.

12. Урок Docker

Часто возникают неожиданности с размером изображений, когда модели попадают в слои:

1.36 GB
1.36 GB
2.56 KB

Необходимо правильно игнорировать кэши и виртуальные среды:

.venv/
__pycache__/
*.pyc
.pytest_cache/
.git/
.github/
.env
chroma_db/
data/sample/*.pdf
*.log

Рекомендуется монтировать кэши моделей во время выполнения, чтобы размер файлов оставался небольшим.

13. GitHub Actions

Push / Pull Request
        ↓
GitHub Actions
        ↓
Checkout Repository
        ↓
Set Up Python
        ↓
Install Dependencies
        ↓
Run pytest

Запуск запросов push и pull должен включать проверку формата кода, тесты на единицы и, по желанию, легкий тест оценки с фикстурами.

Стек технологий, уровень сложности, следующие шаги

Document Processing
        ↓
Chunking
        ↓
Embeddings
        ↓
Vector Storage
        ↓
Retrieval
        ↓
Reranking
        ↓
Prompt Construction
        ↓
LLM Generation
        ↓
Citation Handling
        ↓
Evaluation
        ↓
API
        ↓
Testing
        ↓
Deployment

Проблемы связаны скорее не с необходимостью вызова больших языковых моделей, а с границами фрагментов данных, задержкой переранжирования, форматированием цитат и чрезмерным размером слоев Docker. Следующие обновления: гибридный поиск, более крупный набор меткированных данных для оценки, аутентификация перед использованием FastAPI и инструменты для отслеживания задержек при получении данных.

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

Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.

Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.

Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.

Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.

Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.

Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.