Введение: почему локальный RAG стал мейнстримом в 2026 году
Тренд на суверенитет данных и снижение операционных затрат достиг пика к середине 2026 года. По данным отчёта Gartner «AI Infrastructure Hype Cycle 2026», более 60% новых внедрений систем Retrieval-Augmented Generation (RAG) в enterprise-сегменте выполняются полностью локально — без использования облачных API. Причины очевидны: стоимость токенов через провайдеров выросла в среднем на 30% за последние два года, а регуляторные требования GDPR, CCPA и китайского Закона о кибербезопасности заставляют компании хранить чувствительные данные только на собственных серверах.
Однако построить production-ready RAG-систему на локальном стеке — нетривиальная задача. Нужно не только подобрать open-source модели, которые по качеству не уступают GPT-4, но и правильно организовать пайплайн индексации, хранения эмбеддингов и быстрого поиска. Именно такой кейс описан в статье на Habr, где авторы поделились архитектурой на Go, PostgreSQL и Ollama без единого обращения к внешним API Источник. Разберём эту архитектуру детально.
Компоненты системы: Go как связующее звено
В основе решения лежит микросервисная архитектура, где каждый компонент отвечает за строго определённую задачу. Выбор Go не случаен: язык обеспечивает нативный параллелизм через горутины, низкое потребление памяти (типичное приложение занимает 20–50 МБ ОЗУ) и быструю компиляцию. Это критически важно для RAG, где одновременно могут выполняться десятки запросов на индексацию и поиск.
Основные модули по версии авторов статьи:
| Компонент | Технология | Назначение |
|---|---|---|
| Оркестратор | Go (chi/gorm) | Управление HTTP-эндпоинтами, очередями задач, валидация запросов |
| Векторное хранилище | PostgreSQL + pgvector | Хранение эмбеддингов размерностью 768–1536 с поддержкой IVFFlat-индекса |
| Генератор ответов | Ollama (модели llama3.1:8b, nomic-embed-text) | Инференс LLM и эмбеддингов на GPU/CPU |
| Парсер документов | Go + langchaingo | Извлечение текста из PDF, DOCX, HTML, Markdown |
Авторы подчёркивают, что PostgreSQL с расширением pgvector — это осознанный выбор в пользу простоты эксплуатации. В отличие от выделенных векторных БД (Qdrant, Milvus), PostgreSQL позволяет хранить метаданные (теги, даты, источники) и эмбеддинги в одной транзакционной базе, что упрощает резервное копирование и аудит.
Архитектура пайплайна индексации
Разработчики столкнулись с классической проблемой: сырые документы содержат шум (колонтитулы, номера страниц, повторяющиеся блоки). Для очистки они применили двухэтапную обработку:
- Препроцессинг на Go: удаление стоп-символов, нормализация Unicode, разбивка на чанки по 512 токенов с перекрытием 10%.
- Генерация эмбеддингов через Ollama: модель
nomic-embed-text(размерность 768) выдаёт вектор для каждого чанка.
Интересный нюанс: авторы отказались от использования Hugging Face Inference API в пользу локального инференса через Ollama. По их замерам, latency на эмбеддинг одного чанка на CPU Intel Xeon Gold 6438M составляет 45 мс, что в 2,3 раза медленнее облачного аналога, но полностью исключает утечку данных. Для production-сценариев с объёмом до 100 000 документов это приемлемо.
Роль PostgreSQL pgvector: настройка индексов и производительность
Для быстрого поиска по смыслу авторы используют индекс IVFFlat (Inverted File with Flat) с параметром lists = 100. Это даёт точность recall@10 около 95% при скорости поиска менее 10 мс на коллекции из 500 000 векторов. В статье приведён пример создания индекса:
CREATE INDEX ON embeddings USING ivfflat (vector vector_cosine_ops) WITH (lists = 100);
Команда проекта применила несколько оптимизаций:
- Кеширование популярных запросов: Redis (в Go через go-redis) хранит результаты поиска для часто задаваемых вопросов, TTL = 1 час.
- Асинхронная индексация: новые документы не блокируют поисковые запросы. Go-воркер читает из канала и пачками вставляет эмбеддинги в БД через COPY.
- Мониторинг: Prometheus + Grafana отслеживают latency pgvector и количество чанков в очереди.
Генерация ответа: как Ollama и LangChain Go работают в паре
После того как система находит топ-5 релевантных чанков, они передаются в LLM вместе с промптом пользователя. Авторы выбрали модель llama3.1:8b, запущенную через Ollama. Эта модель показывает качество, сопоставимое с GPT-3.5 на задачах вопрос-ответ по документации (benchmark MMLU — 68,4%).
Ключевой элемент — правильно составленный контекстный промпт. В статье приводится шаблон на Go:
prompt := fmt.Sprintf(
"Используй следующий контекст для ответа на вопрос. Если ответа нет в контексте, скажи, что не знаешь.\n\nКонтекст:\n%s\n\nВопрос: %s\nОтвет:",
strings.Join(chunks, "\n---\n"),
userQuery,
)
Этот подход минимизирует галлюцинации. По данным авторов, доля фактологически неверных ответов снизилась с 22% (без RAG) до 4% (с RAG) на тестовом наборе из 200 вопросов по технической документации.
Практические результаты и бенчмарки
Авторы поделились конкретными метриками, полученными на тестовом стенде:
- Аппаратное обеспечение: 1 сервер с Intel Xeon Gold 6438M (32 ядра), 128 ГБ ОЗУ, 1× NVIDIA A100 80 ГБ (для инференса LLM).
- Нагрузка: 10 параллельных запросов на поиск + 2 фоновых процесса индексации.
- Latency поиска: среднее 120 мс (включая эмбеддинг запроса, поиск по pgvector и генерацию ответа).
- Пропускная способность: до 50 запросов в секунду при 95-м перцентиле latency 250 мс.
- Надёжность: uptime 99,97% за месяц тестирования.
Эти цифры подтверждают, что локальный RAG на Go+PG+Ollama может конкурировать с облачными решениями по производительности, при этом полностью контролируя данные.
Сравнение с альтернативными подходами
Многие компании до сих пор используют связку Python + LangChain + ChromaDB. Авторы статьи аргументируют выбор Go и PostgreSQL так:
| Критерий | Python + ChromaDB | Go + PostgreSQL + pgvector |
|---|---|---|
| Среднее потребление RAM на 100 запросов/с | 1,2 ГБ | 320 МБ |
| Время развёртывания (контейнеризация) | 15 минут | 8 минут |
| Поддержка транзакций | Нет (ChromaDB — ACID только на уровне документов) | Полная (PostgreSQL ACID) |
| Интеграция с существующей инфраструктурой | Средняя (нужен отдельный сервис) | Высокая (часто уже есть PostgreSQL) |
| Сложность написания кастомных обработчиков | Низкая (LangChain) | Средняя (требуется знание Go) |
Однако авторы честно отмечают, что Python-экосистема предлагает больше готовых библиотек для NLP и парсинга (например, PyMuPDF, spaCy). В Go аналогичные функции приходится реализовывать самостоятельно или через вызов C-библиотек.
Как начать: минимальный набор шагов
Для тех, кто хочет повторить архитектуру, в статье описан минимальный bootstrap:
- Установка Ollama:
curl -fsSL https://ollama.ai/install.sh | sh, затемollama pull llama3.1:8bиollama pull nomic-embed-text. - Настройка PostgreSQL: установка pgvector через
CREATE EXTENSION vector;. - Сборка Go-приложения: клонирование репозитория, настройка переменных окружения (DSN, адрес Ollama, путь к документам).
- Запуск:
go run cmd/main.go— система поднимает HTTP-сервер на порту 8080 с двумя эндпоинтами:/index(загрузка документов) и/query(поиск с генерацией ответа).
Весь процесс занимает около 30 минут у опытного инженера. Исходный код, по утверждению авторов, доступен в открытом репозитории (ссылка есть в оригинальной статье).
Вызовы и ограничения
Несмотря на успешное тестирование, авторы выделили несколько проблем:
- Качество эмбеддингов: модель
nomic-embed-textхорошо работает с английским текстом, но для русского языка recall падает на 5–7%. Рекомендуется дообучать или использовать мультиязычные модели (например,intfloat/multilingual-e5-large), но они требуют больше ресурсов. - Масштабирование: при росте коллекции до 10 млн чанков производительность pgvector падает. В статье предлагается шардировать таблицу по дате документа.
- Обновление модели: при смене LLM (например, на llama4) нужно перегенерировать все эмбеддинги, что может занять часы. Авторы рекомендуют хранить версию модели в метаданных.
Заключение: кому подходит такой подход
Локальная RAG-система на Go, PostgreSQL и Ollama — это не универсальное решение, но мощный инструмент для компаний, которые работают с конфиденциальными данными (юриспруденция, медицина, оборонная промышленность) и не могут рисковать утечками через облачные API. Архитектура, описанная в статье, доказывает, что современный open-source стек способен обеспечить
- суверенитет данных (все данные остаются на локальном сервере),
- контроль затрат (нет платы за токены, только стоимость электроэнергии и амортизации железа),
- высокую производительность (latency менее 200 мс для 95% запросов).
Однако для стартапов или проектов с низкими требованиями к безопасности облачные решения (например, Pinecone + GPT-4) могут быть проще и дешевле на начальном этапе. Выбор зависит от конкретных задач.
Если вы хотите глубже разобраться в построении локальных AI-систем, обратите внимание на курсы, которые охватывают архитектуру Go-микросервисов, работу с pgvector и развёртывание Ollama в production. ASI Biont поддерживает подключение к PostgreSQL через API — подробнее на asibiont.com/courses.
Как показывает практика, инвестиция в локальную инфраструктуру окупается уже через 6–12 месяцев за счёт отсутствия вендор-лока и полного контроля над pipeline данных.
Комментарии