Конечно-конечная система RAG с Chroma, FastAPI и Llama 3.2
Полностью работающий ассистент на основе RAG от начала до конца: разбиение PDF на части, повторная ранжировка с использованием кросс-кодера, Chroma, Llama 3.2 в Ollama, FastAPI, Docker, pytest и GitHub Actions в рамках процесса CI.
Источники: 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 и инструменты для отслеживания задержек при получении данных.
Подход в стиле производственных систем означает, что процессы оценки и упаковки выполняются вместе с идеями, заложенными в ноутбуки — это не значит, что один ноутбук может заменить команду по разработке платформы.
Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.
Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.
Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.
Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.
Отслеживайте размер и степень перекрытия фрагментов в настройках, чтобы эксперименты оставались сопоставимыми между разными ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.
Отслеживайте размер и степень перекрытия блоков в конфигурации, чтобы эксперименты оставались сопоставимыми между ветками.