BlogAI agenti
Umělá inteligenceAI AgentiProgramování

Co je vektorová databáze a jak ji používají AI agenti

16. 6. 2026 · cca 16 minut čtení

Klasická databáze najde řádek, který přesně odpovídá dotazu. Jenže AI aplikace potřebují něco jiného: najít dokumenty, které jsou dotazu významově podobné — i když nesdílejí jediné slovo. Přesně to umí vektorová databáze. V tomto článku si vysvětlíme, co jsou embeddingy a proč se význam dá měřit vzdáleností, jak funguje HNSW index, který to celé dělá rychlým, čím se liší Qdrant, pgvector a Pinecone — a hlavně: jak vektorové databáze slouží AI agentům jako znalostní báze a dlouhodobá paměť.

Regály knihovny s teplým osvětlením

Vektorová databáze je knihovna, kde jsou knihy seřazené podle významu, ne podle abecedy. Foto: Janko Ferlic, Pexels

Nejkratší mentální model

Embedding převede text na bod v prostoru. Vektorová databáze pak neporovnává slova, ale vzdálenosti mezi body — a díky indexu typu HNSW to zvládne rychle i nad miliony dokumentů.

Proč klasické vyhledávání nestačí

Představte si firemní wiki a dotaz „jak dlouho trvá schválení dovolené“. Relevantní dokument se ale jmenuje „Směrnice o čerpání volna: lhůty pro vyjádření nadřízeného“ — nesdílí s dotazem prakticky žádné slovo. Fulltextové vyhledávání (SQL LIKE, ale i chytřejší BM25) stojí na shodě slov, takže tenhle dokument nenajde. Synonyma, parafráze, překlepy nebo dotaz v jiném jazyce jsou pro něj neviditelné.

Sémantické vyhledávání obchází slova úplně: porovnává významy. A aby se dal význam porovnávat strojově, potřebujeme ho převést na čísla. Tomu převodu se říká embedding.

Embeddingy: text jako bod v prostoru

Embedding model je neuronová síť, která vezme text (slovo, větu, odstavec, klidně i obrázek) a vrátí vektor — seznam stovek až tisíců čísel. Například text-embedding-3-small od OpenAI vrací 1536 čísel, open-source modely jako bge-m3 nebo nomic-embed-text typicky 768–1024. Ten vektor je souřadnice bodu ve vysokorozměrném prostoru a platí v něm jediné, zato zásadní pravidlo: texty s podobným významem leží blízko sebe.

Model se to naučil tréninkem na obrovském množství dvojic souvisejících textů (otázka–odpověď, titulek–článek, věta–parafráze): souvisejícím dvojicím vektory přibližoval, náhodným oddaloval. Výsledný prostor proto zachycuje sémantiku — „dovolená“ leží blízko „volna“, ačkoli jako řetězce nemají nic společného.

Embeddingový prostor: podobné významy leží blízko sebe
Embeddingový prostor: podobné významy leží blízko sebe
Klíčová myšlenka: dotaz se převede na bod v tomtéž prostoru a hledají se jeho nejbližší sousedé (k-NN).

Podobnost dvou vektorů se nejčastěji měří kosinovou podobností — kosinem úhlu, který svírají. Hodnota 1 znamená stejný směr (stejný význam), 0 kolmost (nesouvisející texty). Celé sémantické vyhledávání je pak jedna věta: převeď dotaz na vektor a najdi k nejbližších sousedů (k-nearest neighbors, k-NN).

Python
from openai import OpenAI
import numpy as np

client = OpenAI()

def embed(text: str) -> np.ndarray:
    response = client.embeddings.create(model="text-embedding-3-small", input=text)
    return np.array(response.data[0].embedding)   # 1536 cisel

def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
    return float(a.dot(b) / (np.linalg.norm(a) * np.linalg.norm(b)))

dotaz = embed("jak dlouho trva schvaleni dovolene")
dokument = embed("Smernice o cerpani volna: lhuty pro vyjadreni nadrizeneho")
nesouvisejici = embed("recept na svickovou")

print(cosine_similarity(dotaz, dokument))       # ~0.72  - vysoka podobnost
print(cosine_similarity(dotaz, nesouvisejici))  # ~0.15  - nizka podobnost

Proč na to potřebujeme speciální databázi

Naivní k-NN znamená spočítat podobnost dotazu s každým uloženým vektorem. Při tisících dokumentů v pohodě (a numpy vám bohatě stačí), při milionech je to na každý dotaz miliarda násobení. Vektorové databáze proto používají přibližné hledání sousedů (ANN — approximate nearest neighbors): obětují zlomek přesnosti (recall 95–99 %) výměnou za odpovědi v jednotkách milisekund.

Dominantním algoritmem je dnes HNSW (Hierarchical Navigable Small World) — používají ho Qdrant, Weaviate, pgvector, Milvus i Chroma. Funguje jako vícepatrová mapa: horní patra obsahují jen hrstku bodů s dlouhými „dálničními“ spoji, spodní patro všechny body s krátkými spoji. Hledání startuje nahoře, pár skoky se dostane do správné oblasti prostoru a dole ji dohledá detailně — podobně jako skip-list nebo jako když na mapě nejdřív najdete kraj, pak město a nakonec ulici. Složitost je zhruba logaritmická, daní je index držený v paměti (typicky 2–3× velikost samotných vektorů) a pomalejší zápisy.

Samotný ANN index (třeba knihovna FAISS) ale ještě není databáze. Vektorová databáze k němu přidává to, co v produkci potřebujete:

  • Filtrování podle metadat — „najdi podobné dokumenty, ale jen z oddělení HR a mladší než rok“. Zní triviálně, ale kombinace filtru s ANN indexem je algoritmicky zapeklitá a databáze se v ní výrazně liší.
  • Hybridní vyhledávání — kombinace sémantického a klíčoslovného (BM25) skóre, typicky přes Reciprocal Rank Fusion. Zachrání vás u přesných termínů, kódů produktů nebo jmen, kde embeddingy selhávají.
  • CRUD, perzistence, replikace, multi-tenancy — obyčejný provozní komfort: přidávat a mazat dokumenty za běhu, přežít restart, oddělit data zákazníků.
  • Kvantizace — komprese vektorů (int8, binární) ušetří 4–32× paměti za cenu mírné ztráty přesnosti, často s přepočítáním kandidátů v plné přesnosti (rescoring).

Kdo je kdo: přehled hráčů

Databáze Charakter Kdy sáhnout právě po ní
Chroma embedded, open source Prototyp na notebooku, RAG demo, jednotky milionů vektorů. Běží přímo v procesu jako SQLite.
pgvector rozšíření PostgreSQL Už máte Postgres a data do ~10–50 M vektorů. Žádná nová služba, vektory vedle relačních dat, joiny zadarmo.
Qdrant samostatná DB, Rust, open source Výkonnostně kritické nasazení, hodně filtrování podle metadat, kvantizace. Snadný self-hosting (jedna binárka/kontejner).
Weaviate samostatná DB, Go, open source Hybridní vyhledávání (BM25 + vektory) jako klíčový požadavek.
Milvus distribuovaná DB, open source Miliardy vektorů, oddělené škálování úložiště a výpočtu — za cenu provozu na Kubernetes s řadou závislostí.
Pinecone plně spravovaná služba Nulový provoz a rychlý start; platíte za dotazy, což při velkém objemu bolí.

Praktické pravidlo z produkčních srovnání (BirJob 2026, Tensoria benchmark): máte-li Postgres a méně než desítky milionů vektorů, začněte s pgvector — ušetříte si celou jednu službu v architektuře. Dedikovanou vektorovou databázi nasaďte, až když narazíte na měřitelný limit (latence, škála, filtrování). A pro pokusy na notebooku je nejrychlejší cesta Chroma.

Mléčná dráha na noční obloze

Miliony bodů ve vysokorozměrném prostoru — a úkol najít ty správné za pár milisekund. Foto: Philippe Donn, Pexels

Praktická ukázka: Qdrant za pět minut

Následující minimum ukazuje celý cyklus: spustit databázi, vytvořit kolekci, uložit dokumenty s vektory a vyhledat podobné výsledky s filtrem podle metadat.

Text only
# lokalni Qdrant v Dockeru
$ docker run -p 6333:6333 -v qdrant_data:/qdrant/storage qdrant/qdrant
Python
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct, Filter, FieldCondition, MatchValue

client = QdrantClient(url="http://localhost:6333")

client.create_collection(
    collection_name="wiki",
    vectors_config=VectorParams(size=1536, distance=Distance.COSINE),
)

# ulozeni dokumentu: vektor + puvodni text + metadata (payload)
client.upsert(
    collection_name="wiki",
    points=[
        PointStruct(
            id=1,
            vector=embed("Smernice o cerpani volna: nadrizeny se vyjadri do 5 dnu.").tolist(),
            payload={"text": "Smernice o cerpani volna...", "oddeleni": "HR", "rok": 2026},
        ),
        # ... dalsi dokumenty
    ],
)

# semanticke hledani + filtr podle metadat
vysledky = client.query_points(
    collection_name="wiki",
    query=embed("jak dlouho trva schvaleni dovolene").tolist(),
    query_filter=Filter(must=[FieldCondition(key="oddeleni", match=MatchValue(value="HR"))]),
    limit=3,
)

for bod in vysledky.points:
    print(bod.score, bod.payload["text"])

A pro srovnání totéž v pgvector — vektor je prostě další sloupec a podobnost se počítá SQL operátorem (<=> je kosinová vzdálenost):

SQL
CREATE EXTENSION vector;

CREATE TABLE wiki (
    id        bigserial PRIMARY KEY,
    text      text,
    oddeleni  text,
    embedding vector(1536)
);

CREATE INDEX ON wiki USING hnsw (embedding vector_cosine_ops);

-- 3 nejpodobnejsi dokumenty z HR
SELECT text, 1 - (embedding <=> :dotaz) AS podobnost
FROM wiki
WHERE oddeleni = 'HR'
ORDER BY embedding <=> :dotaz
LIMIT 3;

Jak vektorovou databázi používají agenti

V článku o AI agentech jsme rozebrali agentní smyčku: model přemýšlí, volá nástroje a vyhodnocuje výsledky. Vektorová databáze v ní hraje dvě odlišné role — a vyplatí se je nezaměňovat.

Dvě role vektorové databáze v agentní smyčce
Dvě role vektorové databáze v agentní smyčce
Znalostní báze odpovídá na otázku „co víme jako firma“, paměť na otázku „co jsme spolu už zažili“.

Role 1: znalostní báze (RAG jako nástroj)

Retrieval-Augmented Generation znamená: než model odpoví, dostane do kontextu relevantní pasáže nalezené ve vektorové databázi. U agentů má RAG typicky podobu nástroje — agent se sám rozhodne, kdy a na co se zeptat, a klidně hledá opakovaně s přeformulovaným dotazem:

Python
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import OpenAIEmbeddings
from langchain_qdrant import QdrantVectorStore

vectorstore = QdrantVectorStore.from_existing_collection(
    collection_name="wiki",
    embedding=OpenAIEmbeddings(model="text-embedding-3-small"),
    url="http://localhost:6333",
)

@tool
def vyhledej_v_dokumentaci(dotaz: str) -> str:
    """Najde pasaze z firemni dokumentace relevantni k dotazu."""
    dokumenty = vectorstore.similarity_search(dotaz, k=4)
    return "\n\n".join(d.page_content for d in dokumenty)

# agent dostane nastroj a sam rozhoduje, kdy ho pouzit
agent = create_agent(model="openai:gpt-4.1", tools=[vyhledej_v_dokumentaci])

Tady se hodí připomenout U-křivku: nalezené pasáže nevkládejte do promptu v pořadí, v jakém přišly. Nejrelevantnější patří na začátek a konec kontextu, protože uprostřed je model přehlíží. A protože model odpovídá z dodaných pasáží místo z vlastní „paměti vah“, je RAG zároveň nejúčinnější prevencí halucinací.

Role 2: dlouhodobá paměť agenta

Kontextové okno je pracovní paměť: po skončení konverzace zmizí. Aby si agent pamatoval napříč sezeními („uživatel preferuje stručné odpovědi“, „deployment přes GitLab CI jsme už třikrát řešili takhle“), potřebuje vzpomínky někam ukládat — a při další konverzaci si vybavit ty relevantní. Přesné klíče předem neznáte, takže se vzpomínky hledají sémanticky: přesně úloha pro vektorovou databázi.

V praxi se ustálily tři druhy paměti (terminologie z kognitivní psychologie, používá ji LangChain i framework Letta, dříve MemGPT):

  • Sémantická — fakta: „zákazník používá PostgreSQL 16 a Azure“.
  • Epizodická — zkušenosti: „migrace přes pg_dump u něj minule selhala na rozšířeních“.
  • Procedurální — naučené postupy a pravidla chování, často destilované do systémového promptu.

Zápis do paměti může být nástroj, který agent volá sám („tohle si zapamatuj“), nebo proces na pozadí, který po konverzaci extrahuje, co stojí za uložení. Takhle vypadá paměť agenta v LangGraphu — store se sémantickým indexem, nad kterým agent dostane nástroje pro zápis i vybavování:

Python
from langgraph.store.postgres import PostgresStore
from langmem import create_manage_memory_tool, create_search_memory_tool

# store s vektorovym indexem - vzpominky se automaticky embeduji
store = PostgresStore.from_conn_string(
    "postgresql://localhost/agent",
    index={"dims": 1536, "embed": "openai:text-embedding-3-small"},
)

agent = create_agent(
    model="openai:gpt-4.1",
    tools=[
        vyhledej_v_dokumentaci,                                # RAG nad znalostmi
        create_manage_memory_tool(namespace=("vzpominky",)),   # zapis/uprava pameti
        create_search_memory_tool(namespace=("vzpominky",)),   # semanticke vybaveni
    ],
    store=store,
)

# pozdeji, klidne v jine konverzaci:
vzpominky = store.search(("vzpominky",), query="preference uzivatele ohledne odpovedi")

Za zmínku stojí, že tenhle příklad běží nad obyčejným Postgresem s pgvectorem — další ilustrace toho, že „vektorová databáze“ je dnes spíš schopnost než nutně samostatný produkt.

Úskalí, na která v praxi narazíte

  • Chunking rozhoduje o všem. Dokumenty se před uložením dělí na kusy (chunky) — příliš malé ztratí kontext, příliš velké rozmělní význam a zaberou kontextové okno. Začněte na 500–1000 tokenech s překryvem a dělte podle struktury dokumentu (nadpisy, odstavce), ne po znacích.
  • Embedding model nejde vyměnit za pochodu. Vektory z různých modelů žijí v nekompatibilních prostorech; změna modelu znamená přeindexovat všechno. Volbu ovlivňuje i podpora češtiny — sáhněte po vícejazyčném modelu (bge-m3, text-embedding-3) a ověřte si kvalitu na MTEB leaderboardu.
  • Zastaralá paměť je horší než žádná. Vzpomínky a dokumenty stárnou: směrnice se změní, preference uživatele taky. Ukládejte časová razítka, mažte a konsolidujte — jinak si agent sebevědomě vybaví loňskou pravdu. (Rekapitulace: sebejistá nepravda je přesně mechanismus halucinace, jen tentokrát vlastnoručně vyrobená.) Systémové řešení tohoto problému nabízejí temporální grafové paměti, kterým se věnujeme v navazujícím článku.
  • Sémantika není přesnost. Na čísla objednávek, SKU kódy a jména embeddingy nestačí — proto hybridní vyhledávání s BM25. A výsledky retrievalu pravidelně vyhodnocujte (recall na sadě testovacích otázek), ne jen „vypadá to dobře“.

Co s tím v praxi

  • Prototyp: Chroma nebo numpy, žádná infrastruktura. Produkce s Postgresem: pgvector. Škála či těžké filtrování: Qdrant. Miliardy vektorů: Milvus. Nechcete provozovat nic: Pinecone.
  • RAG dejte agentovi jako nástroj, ne jako natvrdo předřazený krok — agent se umí doptat a přeformulovat dotaz.
  • Paměť strukturujte (namespace na uživatele/projekt, typ vzpomínky, timestamp) a od začátku počítejte s mazáním a konsolidací.
  • Měřte retrieval zvlášť — většina „halucinací RAG systémů“ jsou ve skutečnosti chyby vyhledávání, ne generování.

Chcete si postavit agenta s pamětí?

Na kurzu Programátor AI agentů stavíme agenty s nástroji, RAG i dlouhodobou pamětí v praxi. Práci s daty, Pythonem a základy AI (včetně embeddings) pokrývá i Datová analýza a umělá inteligence. A pokud chcete embeddingy provozovat na vlastním železe, vyzkoušejte náš GPU Lab.

Zdroje a další čtení

← Zpět na všechny články