База данных для RAG: где хранить знания — векторная БД, поиск или контекст
Для RAG не обязательно ставить векторную базу. Разбираем четыре способа хранить знания, считаем стоимость запроса и показываем рабочий пример на SQLite.
6 мин · · разработка · модели
Когда разработчик впервые слышит про RAG, следом идёт вопрос «а какую базу данных для RAG ставить». В большинстве руководств ответ один: векторную. Но хранилище знаний для модели можно собрать четырьмя способами, и для небольших и средних объёмов самый дорогой в обслуживании вариант часто не нужен. Ниже сравниваем варианты, считаем стоимость одного запроса и даём код, который запускается без отдельного сервера.
Что вообще хранит RAG-хранилище
Архитектура RAG в двух словах: в системе есть два этапа. Сначала вы режете документы на фрагменты и кладёте их в хранилище. Потом на каждый вопрос находите несколько подходящих фрагментов и вставляете их в запрос к модели вместе с вопросом. Хранилище нужно ради второго шага: быстро ответить на вопрос «какие 3–5 кусков текста относятся к этому вопросу».
От способа поиска зависит, что именно вы храните: сам текст, текст и его числовое представление (вектор, эмбеддинг) или просто весь корпус целиком.
Четыре варианта хранения
Векторная база
Каждый фрагмент превращается в вектор моделью эмбеддингов, вопрос превращается в вектор той же моделью, а база возвращает ближайшие по смыслу фрагменты. Готовых решений много: расширение pgvector для PostgreSQL, Qdrant, Chroma, FAISS как библиотека. Главное достоинство: находит по смыслу, даже когда слова в вопросе и в тексте не совпадают.
Что нужно учитывать. Нужна отдельная модель эмбеддингов, и её придётся запускать локально или брать у другого сервиса: в таблице моделей Zukko, с которой мы работаем на 18 октября 2026, эмбеддинг-моделей нет (актуальный список проверяйте через GET https://api.zukko.pro/v1/models). При смене модели эмбеддингов все векторы пересчитываются. Плюс ещё одно звено, которое надо хранить, бэкапить и обновлять.
Полнотекстовый поиск
Классический поиск по словам с ранжированием BM25: такой есть в PostgreSQL (tsvector), в SQLite (модуль FTS5), в Elasticsearch и OpenSearch. Эмбеддинги не нужны. Находит то, что совпало по словам, поэтому хорош для документации, регламентов, кода, артикулов и названий, где пользователь использует те же термины. Слабое место: синонимы и перефразирование («расторжение договора» против «прекращение соглашения»), а для русского языка ещё и склонения, потому что стандартный токенизатор не приводит слова к начальной форме.
Гибридный поиск
Результаты полнотекстового и векторного поиска объединяются в один список. Так обычно находится больше нужных фрагментов, но вариант и самый сложный: две системы, два индекса и правило слияния рейтингов. Оправдан, когда база большая и вопросы разные по характеру.
Длинный контекст вместо поиска
Все документы кладутся прямо в запрос. Все модели из таблицы Zukko имеют окно 1M токенов, кроме Grok (256K) и GLM (128K), так что база на сотни тысяч токенов физически помещается. Хранилища нет вообще: достаточно файлов.
Сравнение
| Способ | Что нужно поднять | Находит по смыслу | Стоимость запроса | Когда подходит |
|---|---|---|---|---|
| Векторная БД | база + модель эмбеддингов | да | мала: в запрос идут 3–5 кусков | много документов, вопросы перефразированы |
| Полнотекстовый поиск | SQLite, PostgreSQL или поисковый движок | нет, только по словам | мала | термины и названия совпадают |
| Гибрид | оба хранилища | да | мала | большая база, разные вопросы |
| Длинный контекст | ничего | да, модель читает всё | растёт с размером базы | база небольшая, запросов немного |
Сколько это стоит: считаем один запрос
Допустим, база знаний занимает 300 000 токенов, ответ модели 1 000 токенов. Цены Zukko на 18 октября 2026 за 1M токенов: gpt-6.1-sol — вход 0.27, выход 1.32; deepseek-v4.1-flash — вход 0.013, выход 0.038. Это условный расчёт, реальную длину вашей базы покажет count_tokens (см. документацию).
Длинный контекст, gpt-6.1-sol, без кэша. Вход: 0,3 × 0,27 = $0.081. Выход: 0,001 × 1,32 = $0.00132. Итого $0.08232 за вопрос. При 10 000 вопросов в месяц: 0,08232 × 10 000 = $823.2.
Тот же вариант, deepseek-v4.1-flash. Вход: 0,3 × 0,013 = $0.0039. Выход: 0,001 × 0,038 = $0.000038. Итого около $0.00394, на 10 000 вопросов $39.4.
RAG с пятью фрагментами по 500 токенов и вопросом в 500 токенов. Вход 3 000 токенов. gpt-6.1-sol: 0,003 × 0,27 = $0.00081, плюс выход $0.00132, итого $0.00213; на 10 000 вопросов $21.3.
Вывод: при большом потоке запросов поиск заметно экономит на токенах, а при нескольких десятках запросов в день длинный контекст проще и стоит терпимо. Кэш меняет картину: у GPT чтение кэша для gpt-6.1-sol стоит $0.013 за 1M, то есть 0,3 × 0,013 = $0.0039 за повторяющийся префикс, но первый запрос идёт по полной цене входа, и сработает кэш только при неизменном начале запроса. Как это считается, разобрано в статье про чтение и запись кэша.
Рабочий пример: полнотекстовый RAG на SQLite
Без отдельного сервера и без эмбеддингов. SQLite с модулем FTS5 идёт в составе большинства сборок Python; если у вас FTS5 недоступен, потребуется другая сборка SQLite.
import re
import sqlite3
from openai import OpenAI
db = sqlite3.connect("kb.db")
db.execute("CREATE VIRTUAL TABLE IF NOT EXISTS chunks USING fts5(title, body)")
client = OpenAI(base_url="https://api.zukko.pro/v1", api_key="fetch_ваш_ключ")
def add(title: str, body: str) -> None:
db.execute("INSERT INTO chunks(title, body) VALUES (?, ?)", (title, body))
db.commit()
Слова в запросе берутся в кавычки, чтобы спецсимволы из вопроса не ломали синтаксис поиска. Для русского языка встроенный токенизатор не знает склонений, поэтому вопрос «договоры» не найдёт слово «договор»: лечится либо приведением слов к начальной форме перед индексацией и поиском (например, морфологическим анализатором pymorphy3), либо поиском по префиксу. Точные возможности токенизаторов смотрите в документации SQLite.
Как выбрать
- База до нескольких сотен тысяч токенов и немного вопросов: начните с длинного контекста, хранилище не нужно.
- Вопросы задаются теми же словами, что и в документах: полнотекстовый поиск, SQLite или PostgreSQL, которые у вас, скорее всего, уже есть.
- Нужен поиск по смыслу или база в миллионы токенов: векторная база либо гибрид, и тогда придётся решить, откуда брать эмбеддинги.
- Не уверены: соберите 30–50 реальных вопросов с известными ответами и проверьте, какой вариант находит нужные фрагменты.
Дальше по теме: RAG на дешёвой модели без векторной БД и минимальный RAG-пайплайн.
Частые вопросы
Нужна ли векторная база для RAG?
Нет. Векторная база нужна, когда поиск должен работать по смыслу, а не по словам, или когда документов очень много. Для небольшой базы с однотипной терминологией хватает полнотекстового поиска, а для совсем небольшой можно положить всё в контекст.
Где хранить знания для ИИ-агента на моих данных?
Храните тексты там, где они уже лежат: в файлах, SQLite или PostgreSQL. Агенту нужна функция поиска, которая возвращает фрагменты, а не конкретный тип хранилища. Фрагменты обычно режут на куски по несколько сотен токенов с названием документа.
Чем отличается RAG от длинного контекста по цене?
Длинный контекст платит за всю базу на каждый вопрос, RAG только за найденные фрагменты. Расчёт выше показывает порядок: $0.082 против $0.002 за вопрос на gpt-6.1-sol при базе 300K токенов. Кэш для повторяющегося начала запроса сокращает эту разницу, но не убирает.
Можно ли использовать модели Zukko для эмбеддингов?
В списке моделей, с которым мы работаем на 18 октября 2026, эмбеддинг-моделей нет. Проверьте актуальный список через GET /v1/models; если их нет, используйте локальную модель эмбеддингов или полнотекстовый поиск.
Чтобы собрать свой вариант, создайте ключ в кабинете Zukko и подключите его по примеру выше: адрес https://api.zukko.pro/v1.
zukko
Платите в 25×
меньше
за Claude Code & ChatGPT
Один ключ fetch_* и base URL api.zukko.pro — в Cursor, Claude Code, Codex и любом SDK.
Похожие статьи
- Промпт-инжиниринг: примеры и 12 готовых шаблонов для работыДвенадцать шаблонов промптов для рабочих задач: что в них написано, почему именно так и сколько стоит один вызов по API.
- Лучшая нейросеть для программирования на C#: выбор и настройкаРейтингов «лучшей модели для C#» мы не даём, зато показываем, как сравнить варианты по цене и индексу, настроить агента для .NET и проверить результат сборкой и тестами.
- Claude Opus 4.6: что это и как перейти на Opus 5.5 без сюрпризовOpus 4.6, 4.7 и 4.8 — прошлое поколение, а в каталоге уже Opus 5 и 5.5. Даём план миграции из четырёх шагов: id модели, прогон своих промптов, сравнение стоимости, откат.
- LangChain with_structured_output: типизированный ответ моделиКак получить из модели не текст, а объект Pydantic: with_structured_output, три метода, include_raw, повторы при ошибках и проверка нескольких моделей на своих данных.