SYNAPSE
EN
Гайды

Self-hosted RAG на локальных моделях: с чего начать

Когда облачные API нельзя, а искать по своим документам нужно. Минимальный стек и порядок шагов.

Self-hosted RAG на локальных моделях: с чего начать

Облачные API удобны, пока не появляется требование держать данные внутри периметра. Тогда собирают self-hosted RAG: поиск по своим документам плюс локальная модель, которая отвечает по найденным фрагментам.

Из чего состоит

  1. Хранилище документов. Папка с файлами и скрипт, который их читает.
  2. Разбиение на фрагменты. 500–800 токенов с перекрытием в 100–150: мельче — теряется контекст, крупнее — поиск находит не то.
  3. Эмбеддинги. Локальная модель эмбеддингов, которая работает на процессоре или видеокарте.
  4. Векторный индекс. Любая локальная база: даже SQLite с расширением хватает на десятки тысяч фрагментов.
  5. Генерация. Локальная LLM, которой в промпт кладут найденные фрагменты и вопрос.

Порядок шагов

Сначала соберите корпус и проверьте поиск без модели: введите вопрос и посмотрите, какие фрагменты находятся. Если нужного фрагмента нет в топ-5, генерация не спасёт — чините разбиение и запросы.

Порядок шагов

Минимальный каркас поиска выглядит так:

import sqlite3, numpy as np

def top_k(question_vec, k=5):
    con = sqlite3.connect("rag.db")
    rows = con.execute("select id, text, vec from chunks").fetchall()
    scored = [(float(np.dot(question_vec, np.frombuffer(v, dtype="float32"))), i, t)
              for i, t, v in rows]
    scored.sort(reverse=True)
    return scored[:k]
Порядок шагов

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

Частые ошибки

  • Один индекс на всё. Регламенты и переписка плохо ищутся вместе: разные языки, разная длина, разные синонимы.
  • Промпт без ограничений. Без фразы «если в фрагментах нет ответа — скажи об этом» модель додумывает.
  • Замер на трёх вопросах. Нужен набор из 30–50 реальных вопросов с известными ответами, иначе улучшения нечем измерять.
↗ Первоисточник: Habr