Моя RAG-система: как я за 8 дней собрал RAG для своего сайта визитки. ai.. ai. llm.. ai. llm. NestJS.. ai. llm. NestJS. Node.JS.. ai. llm. NestJS. Node.JS. pgvector.. ai. llm. NestJS. Node.JS. pgvector. PostgreSQL.. ai. llm. NestJS. Node.JS. pgvector. PostgreSQL. rag.. ai. llm. NestJS. Node.JS. pgvector. PostgreSQL. rag. react.. ai. llm. NestJS. Node.JS. pgvector. PostgreSQL. rag. react. ReactJS.. ai. llm. NestJS. Node.JS. pgvector. PostgreSQL. rag. react. ReactJS. site15.

За 8 дней частичной занятости я собрал RAG-систему на NestJS + PostgreSQL (pgvector), которая обрабатывает ~11 000 чанков документов.
Первая версия отвечала около 4 минут, после оптимизации – 40–60 секунд.
Главный вывод: RAG – это не «векторный поиск + LLM», а в первую очередь подготовка данных, фильтрация контекста и аккуратная работа с промптами.


Зачем я это делал

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

RAG-система была интегрирована с моим сайтом-визиткой site15.ru. Там я показываю и описываю часть проектов за последние 10 лет: скачивания, звёзды, просмотры, npm-библиотеки, счётчики групп, посты и карму на Habr и dev.to.

Технически это реализовано так: фронтенд site15.ru → backend site15.ru → сервер rag-system. Backend передаёт специальный API-ключ, что хотя бы частично защищает сайт от лишних запросов.

Форма ввода API-ключа на фронтенде админки, демонстрирующая защиту доступа

Форма ввода API-ключа на фронтенде админки, демонстрирующая защиту доступа

Таким образом, site15.ru выступает как демо и интерфейс для взаимодействия с RAG.

Фронтенд чата на site15.ru, пример запроса к RAG и ответа

Фронтенд чата на site15.ru, пример запроса к RAG и ответа

Почему RAG оказался сложнее, чем казалось

На старте проект выглядел просто:

RAG = векторный поиск + LLM

На практике оказалось, что большая часть времени уходит на:

  • подготовку и сегментацию данных,

  • фильтрацию контекста,

  • формирование и согласование промптов.

Первая версия системы делала всё последовательно – и отвечала около 4 минут даже на простой вопрос.


Архитектура системы

Источники данных (Telegram переписки, статьи, портфолио, резюме)
            ↓
Backend (NestJS)
 ├─ LLM-модуль
 ├─ PostgreSQL + pgvector
 ├─ RxJS асинхронный pipeline
 ├─ Dialog Manager
 └─ API контроллер для site15.ru
            ↓
RAG-компоненты
 ├─ Question Transformer
 ├─ Фильтрация документов и секций
 ├─ Векторный поиск
 └─ Формирование промпта
            ↓
LLM-провайдеры
(OpenAI / Groq / Ollama)
Swagger документация от backend, демонстрирующая API для RAG
Swagger документация от backend, демонстрирующая API для RAG

Выбор стека

Backend – NestJS
Я постоянно пишу бэкенды на NestJS, поэтому выбор очевиден.

Main файл nestjs

Main файл nestjs

Frontend – React Admin
Нужна была админка, чтобы управлять данными и промптами.

Cписок embedding документов

Cписок embedding документов
Embedding документ

Embedding документ

PostgreSQL + pgvector
Одна система для обычных данных и векторов – проще и надежнее, чем раздельные хранилища.

Таблицы в базе данных

Таблицы в базе данных

Несколько LLM-провайдеров
Поддержка разных провайдеров позволяет использовать бесплатные лимиты и легко переключаться при необходимости.

Список нейронных сетей

Список нейронных сетей

Ключевое архитектурное решение: иерархическая фильтрация

Главная идея – не отправлять в LLM всё подряд.
Pipeline обработки запроса:

Запрос пользователя (frontend site15.ru)
  ↓
Backend site15.ru
  ↓
RAG-сервер: нормализация вопроса
  ↓
Фильтрация по метаданным      (11 000 → ~500)
  ↓
Фильтрация по секциям/заголовкам (500 → ~200)
  ↓
Векторный поиск                (200 → 5–10)
  ↓
Один оптимизированный запрос в LLM
Визуализация pipeline запросов/ответов в админке или диаграмма архитектуры

Визуализация pipeline запросов/ответов в админке или диаграмма архитектуры

Так удалось значительно сократить объём данных, отправляемых в LLM, и ускорить ответы.


Самая большая техническая проблема

Создание метаданных для 11 005 чанков документов.
Так как я хотел, чтобы всё работало, используя только бесплатные лимиты LLM, я не мог создавать метаданные в облачных LLM — там я быстро упирался в ограничения, поэтому пришлось запускать локально через LM Studio с моделью qwen2.5-7b-instruct и обработка заняла 2 дня на RTX 2060 SUPER.

LM Studio

LM Studio

Почему первая версия была медленной

Первая версия: 8 промежуточных промптов, последовательные вызовы LLM → ~4 минуты на ответ.

После оптимизации: 4 согласованных промпта, часть этапов параллельна, асинхронная очередь на RxJS → 40–60 секунд.


Промпты и ошибки

Промпты оказались самым сложным моментом. Примеры:

Утечка контекста

Пользователь: "Расскажи про NestJS"
LLM: "NestJS - отличный фреймворк. Кстати, у меня есть телеграм-бот для кофе..."

Конфликт инструкций

Промпт 1: отвечай кратко
Промпт 2: приводи подробные примеры

Вывод: меньше, но согласованных промптов – лучше.


Использование ИИ при разработке

Около 70% кода писалось с помощью ИИ-ассистентов, но без моей архитектурной правки и отладки он не работал бы.

Код сгенерированный AI

Код сгенерированный AI

Безопасность

  • проверка разрешённого IP,

  • проверка API-ключа для запросов с backend site15.ru.

Проект не production-ready, но это позволяет хоть как-то защитить основной сайт от лишних запросов.

AuthGuard - проверка IP / API-ключа в админке

AuthGuard – проверка IP / API-ключа в админке

Развёртывание

  • RAG-сервер на отдельном VPS,

  • docker-compose для PostgreSQL и Ollama,

  • backend через pm2,

  • интеграция с site15.ru.

Docker-compose

Docker-compose

Текущий статус

Экспериментальный проект, не MVP, не production-ready.
Site15.ru выступает как интерфейс для демонстрации работы RAG и статистики проектов.


Планы на будущее

  • Написание тестов пользовательских сценариев (проверка корректности ответов и pipeline).

  • Рефакторинг LLM-модуля в стиле NestJS.

  • Добавление аналитики: время обработки, количество вызовов LLM, расход токенов.

  • Автоматизация деплоя через Docker / Kubernetes.

  • Улучшение точности и скорости через оптимизацию фильтрации контекста.


Выводы

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

За 8 дней частичной занятости удалось собрать рабочую систему, интегрировать её с site15.ru и получить реальный опыт работы с RAG.


Ссылки

https://github.com/site15/rag-system – Репозиторий проекта
https://site15.ru – Мой сайт визитка с чатом поддержки

Автор: kaufmanendy

Источник

Rambler's Top100