Как да създам vector database?
Най-практичният начин да „създадеш vector database“ е да избереш платформа (най-често Postgres + pgvector за старт или управлявана услуга като Pinecone/Weaviate/Qdrant), да дефинираш схема за (текст + embedding + метаданни), да индексираш за бързо търсене по сходство и да изградиш надежден процес за ingest (chunking, embeddings, обновявания и мониторинг).
Vector database е полезна само ако имаш ясна дефиниция какво означава „сходство“ за твоите данни.
Въведение
Vector database (vector DB) е база, оптимизирана за съхранение и бързо търсене на вектори (embedding-и) с метрики като cosine similarity или dot product. Това е основен компонент в RAG (Retrieval-Augmented Generation), семантично търсене, препоръчващи системи и детекция на дубликати.
В тази статия ще минем през процес, който работи в реални проекти: започваш с минимална, ясна архитектура (за да стигнеш до работещ прототип), после добавяш индекси, филтри, обновявания и оценка на качеството.
Стъпка 1: Изясни use case и метриката за сходство
Преди да инсталираш каквото и да е, отговори на тези въпроси:
- Какво търсиш: „най-близки по смисъл параграфи“, „подобни продукти“, „сходни тикети“, „подобни изображения“?
- Какъв е входът: текст, таблици, PDF, изображения, аудио?
- Какво е unit of retrieval: документ, страница, параграф, изречение?
- Нужни ли са филтри: по език, дата, клиент, тагове, права за достъп?
Метриката има значение:
- Cosine similarity: често работи добре за нормализирани embedding-и.
- Dot product: удобна и бърза; често еквивалентна при нормализация.
- Euclidean distance: по-рядко в практиката за текст.
Най-честата причина vector DB да „не работи“ е лош chunking и неподходящ embedding модел, не самата база.
Стъпка 2: Избери платформа: Postgres + pgvector или управлявана услуга
Има два разумни пътя.
Вариант A: Postgres + pgvector (често най-добрият старт)
Подходящо, ако:
- правиш MVP или пилот;
- искаш и класически SQL заявки + векторно търсене в една база;
- имаш нужда от транзакции, RLS/права, joins и отчетност.
Можеш да го пуснеш локално (Docker) или като управляван Postgres (например Supabase). В Supabase цената зависи от compute и disk; страницата им за Compute and Disk описва примерни планове и как се формират разходите за compute, storage и I/O (проверено към 10 февруари 2026).
Вариант B: Управлявана vector DB услуга (Pinecone / Weaviate / Qdrant)
Подходящо, ако:
- очакваш бърз растеж и искаш „готово за продукция“ с минимален DevOps;
- търсиш специфични възможности (многорегионност, HA, специализирани оптимизации).
Към началото на 2026 (провери страниците за ценообразуване преди решение):
- Pinecone: има Starter и Standard планове, като Standard започва от минимум месечна такса и после се таксува според ползването.
- Weaviate Cloud: публикува облачни планове/минимуми и различни режими (включително serverless).
- Qdrant Cloud: има free tier и платени планове според ресурси.
Ако не си сигурен за натоварването и данните, започни с Postgres + pgvector и мигрирай към специализирана услуга, когато имаш метрики и болки.
Стъпка 3: Създай схема и индекси (пример с PostgreSQL + pgvector)
1) Инсталирай разширението
CREATE EXTENSION IF NOT EXISTS vector;
2) Създай таблица за chunk-ове
Измеренията (vector(1536) например) трябва да съвпадат с embedding модела, който използваш.
CREATE TABLE IF NOT EXISTS doc_chunks (
id bigserial primary key,
doc_id text not null,
source text,
chunk_index int not null,
content text not null,
metadata jsonb default '{}'::jsonb,
embedding vector(1536) not null,
created_at timestamptz default now()
);
CREATE INDEX IF NOT EXISTS doc_chunks_doc_id_idx ON doc_chunks (doc_id);
CREATE INDEX IF NOT EXISTS doc_chunks_metadata_gin ON doc_chunks USING gin (metadata);
3) Добави векторен индекс
Подходът зависи от pgvector версията и размера на данните. За старт (и малки обеми) може да минеш и без индекс, но за реално търсене ще ти трябва.
Пример (HNSW, ако е налично):
CREATE INDEX IF NOT EXISTS doc_chunks_embedding_hnsw
ON doc_chunks USING hnsw (embedding vector_cosine_ops);
Важно: индексът ускорява, но изисква настройка и периодично VACUUM/ANALYZE.
Стъпка 4: Подготви данните: чистене, chunking, метаданни
Добър ingest започва с дисциплина:
- Нормализирай текста (премахни шум, странни символи, повторения).
- Chunking:
- за общ текст: 300–800 думи е добър старт;
- добави overlap (например 10–20%), за да не режеш смисъл по средата;
- пази
chunk_index, за да можеш да възстановиш контекст.
- Метаданни:
language,created_date,customer_id,permissions,tags;- ако ще филтрираш, сложи ги в
metadataи индексирай (GIN).
Стъпка 5: Генерирай embeddings (API или локален модел)
Имаш два варианта:
- API услуга (по-бързо за старт, плаща се на токени/заявки).
- Локален/само-хостван embedding модел (по-ниска маргинална цена при голям обем, но изисква GPU/ops).
Как да избереш:
- Ако данните са чувствителни: прецени дали имаш право да ги изпращаш към външен доставчик.
- Ако обемът е малък: API често е най-евтиният път към резултат.
- Ако обемът е голям и постоянен: локалният модел може да намали разходите, но увеличава инженерната сложност.
Стъпка 6: Ingest: запиши embeddings и метаданни
Минималният pipeline изглежда така:
- Зареждаш документ.
- Разделяш на chunk-ове.
- За всеки chunk генерираш embedding.
- INSERT в таблицата.
Псевдо-Python (идеята, не библиотеките):
chunks = chunk_text(text)
rows = []
for i, chunk in enumerate(chunks):
emb = embed(chunk) # връща list[float] с фиксирана дължина
rows.append((doc_id, source, i, chunk, metadata, emb))
# после batch insert
Практически съвети:
- Прави batch insert-и (примерно 100–1000 реда), вместо по един.
- Записвай
doc_idи версия на документа, за да можеш да обновяваш. - Ако документ се промени, изтрий старите chunk-ове за
doc_idи вкарай новите (или поддържайversion).
Стъпка 7: Търси, филтрирай и измервай качество
1) Семантично търсене
В Postgres с pgvector често ще правиш заявки тип:
SELECT id, doc_id, chunk_index, content, metadata,
1 - (embedding <=> $1) AS score
FROM doc_chunks
WHERE metadata @> '{"language":"bg"}'
ORDER BY embedding <=> $1
LIMIT 10;
Тук $1 е query embedding.
2) Добави филтри
С филтри можеш да намалиш „шум“ и да подобриш precision. Пример: по клиент, дата, тип документ.
3) Въведи втори етап: reranking (по желание)
Vector търсенето е първи етап (retrieval). Ако искаш по-точни резултати, добави втори етап:
- взимаш top 20–50 chunk-а;
- прилагаш по-„умен“ модел/правила за да подредиш отново (rerank);
- подаваш на LLM само най-добрите 3–8.
Това често подобрява качеството повече от „още индекси“.
Настройки за скалиране и производителност (когато натоварването расте)
Когато започнеш да имаш хиляди заявки на ден или милиони chunk-ове, дребните решения стават важни:
- Измервай latency по етапи: embedding на заявката, vector search, rerank, LLM отговор.
- Използвай кеширане за популярни заявки (дори само кеш на query embedding-ите може да свали разход и време).
- Пази размерите под контрол: embedding-ите са „широки“ данни; метаданните също могат да надуят storage.
- Не увеличавай
top_kбез причина: честоk=5..20е достатъчно, ако chunking-ът и метаданните са добри. - Планирай re-embed: смяна на embedding модел почти винаги означава преизчисляване на всички вектори; това е проект сам по себе си.
Сигурност, права и съответствие (лесно се пропуска)
Vector DB често държи „извадка“ от фирмено знание. Ако работиш с клиентски или вътрешни данни:
- прилагай филтри по
customer_id/права на ниво заявка, не само в приложението; - внимавай с PII: понякога е по-добре да mask-неш или да не индексираш чувствителни полета;
- дефинирай retention: кога триеш данни и как доказваш, че са изтрити;
- логовете са данни: ако логваш заявки и пасажи, третирай ги като чувствителни.
Семантичното търсене без контрол на достъп е риск за изтичане на информация, дори когато „нямаш директни линкове“.
Архитектура за продукция: минимален чеклист
Когато MVP тръгне, добави тези 6 елемента:
- Версиониране на данните (документ/източник/дата).
- Контрол на достъп: филтри по клиент/права, за да няма data leak.
- Наблюдение: latency, грешки, rate limiting, размер на индекса.
- Оценка:
recall@k, human spot-check, „лоши“ заявки. - Backup и възстановяване: особено ако embedding-ите са скъпи за пресмятане.
- План за миграция: ако смениш embedding модел, ще преизчисляваш (re-embed) и ще имаш период на „двойно“ поддържане.
Съвети за по-добри резултати
- Започни с ясна цел: „намирам най-добрите 5 пасажа за отговор“, не „правя AI“.
- Дръж метаданните чисти и консистентни; филтрите са половината качество.
- Ако резултатите са близки, добави reranking (втори етап) преди да покажеш на потребителя.
- Логвай заявки и кликове (implicit feedback) и обновявай evaluation set-а.
- Помисли за hybrid search (BM25 + vector), ако имаш много термини/номера/кодове.
Чести грешки, които да избягваш
- Да индексираш всичко, без да знаеш какво ще търсиш.
- Да правиш огромни chunk-ове (целият документ) или микроскопични (по 1 изречение) без причина.
- Да смесваш езици и домейни в един индекс без метаданни и филтри.
- Да пускаш в продукция без метрики (поне
recall@kи latency). - Да пренебрегнеш правата за достъп и да „смесиш“ клиентски данни в еднакъв retrieval.
Често задавани въпроси
1) Трябва ли ми отделна vector DB или стига Postgres?
Ако правиш MVP, имаш умерен обем и искаш SQL + права + транзакции, Postgres + pgvector често е достатъчен. При много големи обеми или специфични SLA изисквания, управляваните vector услуги могат да са по-подходящи.
2) Колко „скъпо“ е да съхранявам embeddings?
Цената идва от три места: генериране на embeddings (ако е платен API), съхранение (disk) и заявки/compute. Управляваните услуги често имат минимум или pay-as-you-go модели, а при Postgres плащаш compute/disk според хостинга.
3) Какъв размер chunk да избера?
Започни с 300–800 думи и 10–20% overlap, после измери recall@k на реални въпроси. Няма универсално число, но има универсален тест: работи ли за твоите случаи.
4) Как да обновявам данните без хаос?
Въведи doc_id + version (или checksum). При промяна: изтрий старите chunk-ове за документа и вкарай новите, или маркирай версията и филтрирай по „активна“.
5) Как да разбера дали ми трябва специализирана услуга като Pinecone/Weaviate/Qdrant?
Когато имаш ясни метрики и виждаш ограничения: latency при голям k, сложни SLA изисквания, HA/многорегионност, или оперативна тежест. Тогава сравни актуалните планове и модели за таксуване на страниците им (проверено към 10 февруари 2026).
Източници (проверено към 10 февруари 2026)
- Pinecone Pricing: https://www.pinecone.io/pricing/
- Weaviate Pricing и Weaviate Cloud pricing update (Oct 27, 2025): https://weaviate.io/pricing/ и https://weaviate.io/blog/weaviate-cloud-pricing-update
- Qdrant Pricing: https://qdrant.tech/pricing/
- Supabase Compute and Disk: https://supabase.com/docs/guides/platform/compute-and-disk