Co je grafová databáze a jak ji používají AI agenti
V minulém článku jsme si ukázali, jak vektorová databáze najde významově podobný text. Jenže na otázku „kdo z našich zákazníků používá technologii, kterou spravuje tým člověka, jenž odešel minulý měsíc?“ je podobnost k ničemu — odpověď nevede přes podobná slova, ale přes řetěz vztahů. Přesně pro takové otázky existují grafové databáze. Projdeme si do hloubky, jak fungují (property graf, Cypher, index-free adjacency), kdy dávají smysl místo relační či vektorové databáze — a pak tři způsoby, jak je dnes používají AI agenti: text2Cypher, GraphRAG a temporální grafovou paměť.
V jedné větě
Grafová databáze dává smysl ve chvíli, kdy odpověď neleží v jednom záznamu ani v podobném textu, ale v cestě přes několik vztahů: kdo s kým souvisí, přes co a s jakým dopadem.
Vztahy jako data prvního řádu
Relační databáze umí vztahy odjakživa — jmenují se podle nich. Jenže vztah je v nich odvozený: existuje jen jako shoda hodnot cizích klíčů, kterou musí databáze při každém dotazu znovu vypočítat JOINem. Pro jeden či dva skoky to funguje skvěle. Problém nastává, když se ptáte do hloubky:
- Kteří kolegové mých kolegů umí Kubernetes? (2 skoky)
- Přes koho se znám s CTO firmy X? (neznámý počet skoků)
- Které komponenty v systému budou zasaženy, když selže tahle služba? (tranzitivní závislosti)
- Objednávky, zařízení a IP adresy tvoří podezřelý kruh — podvod? (cyklus v grafu)
Každý další skok znamená v SQL další JOIN, mezivýsledky rostou a plánovač dotazů se potí. U dotazu s neznámou hloubkou („najdi cestu“) SQL bez rekurzivních CTE ani nemá jak otázku položit — a s nimi se z jednoduché otázky rychle stane těžko čitelný dotaz. Grafová databáze obrací perspektivu: vztah je uložen jako plnohodnotný záznam — fyzický ukazatel mezi dvěma uzly, se svým typem, směrem a vlastnostmi. Průchod z uzlu na souseda není join, ale sledování ukazatele.
Property graf: uzly, hrany, vlastnosti
Nejrozšířenější model je property graf (labeled property graph). Skládá se ze čtyř stavebních kamenů:
- Uzly (nodes) — entity: lidé, firmy, produkty, dokumenty.
- Labely — typ uzlu (
:Osoba,:Firma); uzel jich může mít víc. - Hrany (relationships) — pojmenované, orientované vztahy mezi dvěma uzly (
:PRACUJE_V,:OVLADA). - Vlastnosti (properties) — key-value data na uzlech i hranách: u vztahu „pracuje v“ třeba od kdy a na jaké pozici.

Vedle property grafu existuje i starší akademický model RDF (trojice subjekt–predikát–objekt, dotazování přes SPARQL), který potkáte u sémantického webu a ontologií — např. Wikidata. V praxi AI aplikací dnes dominuje property graf, mimo jiné proto, že v roce 2024 získal vlastní ISO standard GQL — první nový standard databázového jazyka od SQL (1987).
Cypher: SQL pro grafy
Nejpoužívanějším dotazovacím jazykem je Cypher z Neo4j (a jeho otevřená varianta openCypher, ze které vychází i standard GQL). Jeho půvab je v tom, že dotaz vypadá jako ASCII-art grafu: uzly píšete do kulatých závorek, vztahy do hranatých se šipkou. Vzor z diagramu výše:
// vytvoreni dat: MERGE = vytvor, pokud neexistuje
MERGE (anna:Osoba {jmeno: "Anna"})
MERGE (beeit:Firma {nazev: "Turing Institut"})
MERGE (k8s:Technologie {nazev: "Kubernetes"})
MERGE (anna)-[:PRACUJE_V {od: 2024, pozice: "devops"}]->(beeit)
MERGE (anna)-[:OVLADA]->(k8s)
// kdo v Turing Institut ovlada Kubernetes?
MATCH (o:Osoba)-[:PRACUJE_V]->(:Firma {nazev: "Turing Institut"}),
(o)-[:OVLADA]->(:Technologie {nazev: "Kubernetes"})
RETURN o.jmeno
Skutečná síla se ukáže u dotazů, které by v SQL byly utrpením. Proměnlivá délka cesty se zapisuje hvězdičkou, nejkratší cesta má vestavěnou funkci:
// kolegove kolegu (presne 2 skoky po vztahu ZNA), bez prime znamosti
MATCH (ja:Osoba {jmeno: "Anna"})-[:ZNA*2]-(doporuceni:Osoba)
WHERE NOT (ja)-[:ZNA]-(doporuceni) AND doporuceni <> ja
RETURN DISTINCT doporuceni.jmeno
// pres koho se znam s CTO firmy X? (nejkratsi cesta, max 6 skoku)
MATCH cesta = shortestPath(
(ja:Osoba {jmeno: "Anna"})-[:ZNA*..6]-(cto:Osoba {pozice: "CTO"})
)
RETURN [osoba IN nodes(cesta) | osoba.jmeno] AS retez
// dopad vypadku: vsechno, co primo ci neprimo zavisi na sluzbe
MATCH (s:Sluzba {nazev: "auth-api"})<-[:ZAVISI_NA*1..]-(zasazene)
RETURN DISTINCT zasazene.nazev
Proč je to rychlé? Klíčová vlastnost nativních grafových databází se jmenuje index-free adjacency: každý uzel drží přímé ukazatele na své hrany, takže krok na souseda je operace s konstantní cenou — nezávislá na velikosti databáze. Relační JOIN musí sousedy vyhledat v indexu, jehož cena roste s počtem řádků (a bez indexu je to sken). Traverz milionového grafu do hloubky 4 tak projde jen navštívené okolí, zatímco čtyřnásobný self-join tabulky vztahů si sáhne na celé indexy. Daní je horší podpora hromadných analytických dotazů přes celá data — tam relační model a sloupcové databáze vedou dál.
Tři paradigmata vedle sebe
| Databáze | Na co odpovídá | Typická otázka |
|---|---|---|
| Relační | strukturovaná fakta a agregace | „Kolik objednávek jsme měli v červnu po krajích?“ |
| Vektorová | významová podobnost | „Najdi dokumenty, které mluví o tomtéž jako tenhle dotaz.“ |
| Grafová | souvislosti a cesty mezi entitami | „Jak spolu tyhle dvě věci souvisejí a přes co?“ |
Nejsou to konkurenti, ale doplňky — a moderní AI aplikace často kombinují všechny tři. Grafová databáze se vyplatí, když jsou vztahy samy o sobě nositelem hodnoty: doporučování, detekce podvodů, dependency analýza, organizační znalosti, master data. Nevyplatí se na ukládání plochých záznamů bez propojení — tam je relační model jednodušší i rychlejší.
Z konkrétních produktů je největší Neo4j (nativní graf, Cypher, vektorový index v jádru, bezplatná community edice), rychlou in-memory alternativou je Memgraph, odlehčenou volbou pro embedded použití Kùzu (grafová obdoba SQLite) a FalkorDB cílí přímo na GraphRAG scénáře. V cloudu pak Amazon Neptune či Azure Cosmos DB (Gremlin API).
Znalostní graf: most mezi textem a grafem
Aby mohl agent po grafu chodit, musí graf nejdřív existovat. U strukturovaných dat (CRM, IS) je to otázka importu. Zajímavější je extrakce z nestrukturovaného textu: LLM přečte dokumenty a vytáhne z nich trojice entita – vztah – entita, ze kterých vznikne znalostní graf (knowledge graph). Dřív šlo o náročnou NLP disciplínu, dnes je to jeden průchod modelem s vhodným promptem — LangChain na to má hotový LLMGraphTransformer:
from langchain_experimental.graph_transformers import LLMGraphTransformer
from langchain_neo4j import Neo4jGraph
from langchain_openai import ChatOpenAI
from langchain_core.documents import Document
graph = Neo4jGraph(url="bolt://localhost:7687", username="neo4j", password="heslo")
transformer = LLMGraphTransformer(
llm=ChatOpenAI(model="gpt-4.1", temperature=0),
allowed_nodes=["Osoba", "Firma", "Technologie", "Projekt"],
allowed_relationships=["PRACUJE_V", "OVLADA", "POUZIVA", "VEDE"],
)
dokumenty = [Document(page_content=
"Anna vede projekt Phoenix pro klienta AlfaCorp. "
"Projekt bezi na Kubernetes a Anna je zaroven devops inzenyrka Turing Institut.")]
grafove_dokumenty = transformer.convert_to_graph_documents(dokumenty)
graph.add_graph_documents(grafove_dokumenty)
# vysledek: (Anna)-[:VEDE]->(Phoenix), (Phoenix)-[:POUZIVA]->(Kubernetes),
# (Anna)-[:PRACUJE_V]->(Turing Institut), ...
Omezení allowed_nodes a allowed_relationships není detail: bez něj si model vymýšlí pro tutéž věc pokaždé jiné typy (ZAMESTNAN_U vs. PRACUJE_PRO) a graf se rozpadne na nespojitelné ostrůvky. O úskalích extrakce ještě bude řeč.
Jak grafy používají agenti
A teď to hlavní. V článku o agentech jsme popsali smyčku, ve které agent volá nástroje; u vektorových databází jsme viděli role znalostní báze a paměti. Grafová databáze do téhle skládačky zapadá třemi způsoby, které se v praxi často kombinují.
Způsob 1: text2Cypher — agent píše dotazy sám
Nejpřímočařejší integrace: dát agentovi nástroj, který přeloží otázku v přirozeném jazyce na Cypher, spustí ho a vrátí výsledek. LLM dostane schéma grafu (labely, typy vztahů, vlastnosti) a otázku; vygenerovaný dotaz se provede a data putují zpět do kontextu. V LangChainu je to hotová komponenta GraphCypherQAChain:
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_neo4j import GraphCypherQAChain, Neo4jGraph
from langchain_openai import ChatOpenAI
graph = Neo4jGraph(url="bolt://localhost:7687", username="neo4j", password="heslo")
cypher_chain = GraphCypherQAChain.from_llm(
ChatOpenAI(model="gpt-4.1", temperature=0),
graph=graph,
allow_dangerous_requests=True, # viz uskali nize!
)
@tool
def zeptej_se_grafu(otazka: str) -> str:
"""Odpovi na otazku o lidech, projektech a technologiich z firemniho grafu."""
return cypher_chain.invoke({"query": otazka})["result"]
agent = create_agent(model="openai:gpt-4.1", tools=[zeptej_se_grafu])
Na rozdíl od vektorového RAG dostane model přesná strukturovaná fakta, umí agregovat („kolik projektů vede každý tým?“) a odpověď je auditovatelná — vygenerovaný Cypher si můžete přečíst a ověřit. Slabina: kvalita stojí a padá se znalostí schématu a schopností modelu psát správné dotazy; na křivé schéma nebo exotické dotazy si text2Cypher naběhne. Proto se v produkci osvědčuje přidat few-shot příklady dotazů a validaci vygenerovaného Cypheru před spuštěním.
Způsob 2: GraphRAG — retrieval po vztazích
Vektorový RAG má dvě systémové slepé skvrny. Multi-hop otázky: odpověď vzniká spojením faktů z několika dokumentů, které si navzájem nejsou podobné (dokument o Anně nezmiňuje AlfaCorp, dokument o AlfaCorpu nezmiňuje Annu — spojuje je až projekt Phoenix). A globální otázky: „jaká jsou hlavní témata v těchhle dokumentech?“ nemá žádný podobný chunk, který by šlo najít — odpověď vyžaduje pohled na celek.
GraphRAG od Microsoft Research řeší obě: při indexaci extrahuje z dokumentů znalostní graf, algoritmem Leiden ho rozdělí na hierarchické komunity (tematické shluky entit) a každou komunitu nechá LLM shrnout. V době dotazu pak nabízí několik strategií:

- Local search — pro otázky na konkrétní entity: najde vstupní uzly (typicky vektorovým hledáním), rozšíří se po hranách na sousedy, vztahy a přidružené textové chunky. Přesně tohle řeší multi-hop otázky: cesta Anna → Phoenix → AlfaCorp existuje v grafu, i když ji žádný jednotlivý dokument neobsahuje celou.
- Global search — pro otázky na celek: map-reduce přes souhrny komunit, z nichž LLM poskládá odpověď o tématech a trendech celého korpusu.
- DRIFT search — kombinace obojího: startuje globálně a iterativně se zanořuje lokálně.
Cena za to všechno: indexace znamená protlačit celý korpus přes LLM (extrakce) a pak ještě jednou (souhrny), což u velkých kolekcí stojí reálné peníze a hodiny času — a při změně dat se musí příslušná část přepočítat. GraphRAG proto dává smysl pro relativně stabilní znalostní korpusy, kde se hodně ptáte; pro rychle se měnící data zvažte lehčí variantu (jen local search nad průběžně aktualizovaným grafem) nebo následující přístup.
Způsob 3: temporální graf jako paměť agenta
U vektorové paměti jsme narazili na problém stárnutí: agent si sebevědomě vybaví loňskou pravdu. Vektorové úložiště s tím moc nenadělá — dva embeddingy vět „Anna pracuje v AlfaCorp“ a „Anna pracuje v Turing Institut“ jsou si podobné a obě se vrátí. Grafová paměť má elegantnější řešení: fakt je hrana s časovou platností.
Průkopníkem je open-source framework Graphiti (jádro paměťové platformy Zep, popsané v paperu Zep: A Temporal Knowledge Graph Architecture for Agent Memory). Každá hrana nese bi-temporální údaje: kdy fakt platil v reálném světě (valid_at, invalid_at) a kdy se o něm systém dozvěděl (created_at, expired_at). Když do paměti přijde nová informace, která odporuje existující hraně, LLM konflikt rozpozná a starou hranu invaliduje — nastaví jí konec platnosti, ale nesmaže ji:

Výsledek: agent umí odpovědět, co platí teď, co platilo kdykoli v minulosti, a nikdy nesmíchá obě verze dohromady. Navíc se paměť aktualizuje inkrementálně s každou konverzací (žádné hodinové přeindexování jako u GraphRAG) a vyhledává se kombinací sémantického, fulltextového a grafového hledání. Použití je na pár řádků:
from graphiti_core import Graphiti
graphiti = Graphiti("bolt://localhost:7687", "neo4j", "heslo")
# po kazde konverzaci: uloz epizodu, extrakce a invalidace probehnou automaticky
await graphiti.add_episode(
name="schuzka-2026-07-07",
episode_body="Anna potvrdila, ze od kvetna vede devops tym v Turing Institut. "
"Projekt Phoenix pro AlfaCorp predala Petrovi.",
reference_time=datetime(2026, 7, 7),
)
# pozdeji, v jine konverzaci: hybridni vyhledani relevantnich faktu
vysledky = await graphiti.search("kdo ted vede projekt Phoenix?")
for hrana in vysledky:
print(hrana.fact) # "Petr vede projekt Phoenix (od 2026-05)"
Grafy a vektory: ne buď–anebo
Pozorný čtenář si všiml, že se obě technologie prolínají: GraphRAG hledá vstupní entity vektorově, Graphiti kombinuje sémantické a grafové vyhledávání, Neo4j má od verze 5 vektorový index přímo v jádru. Ustálený vzor moderních AI aplikací je vektorový vstup, grafová expanze: embedding najde relevantní uzly (nemusíte uhodnout přesné jméno entity) a traverz po hranách posbírá souvislosti, které podobnost nikdy nenajde. V Cypheru vypadá tenhle vzor takto:
// 1) vektorovym indexem najdi vstupni uzly
CALL db.index.vector.queryNodes('entity_embeddings', 5, $dotaz_embedding)
YIELD node AS entita, score
// 2) grafova expanze: posbirej okoli do hloubky 2
MATCH (entita)-[vztah*1..2]-(soused)
RETURN entita.nazev, score,
collect(DISTINCT soused.nazev) AS souvislosti
ORDER BY score DESC
Úskalí, na která v praxi narazíte
- Kvalita extrakce rozhoduje o všem. Znalostní graf je jen tak dobrý jako trojice, ze kterých vznikl. Omezte typy uzlů a vztahů schématem, deduplikujte entity („Turing Institut“ vs. „Turing Institut s.r.o.“ musí být jeden uzel — tzv. entity resolution) a extrakci si vyhodnocujte na vzorku ručně.
- Text2Cypher je spouštění vygenerovaného kódu. Parametr se v LangChainu nejmenuje
allow_dangerous_requestsnáhodou: LLM může vygenerovat iDETACH DELETE. Připojujte agenta pod účtem jen pro čtení a dotazy validujte, ideálně whitelistem povolených konstrukcí. - Cena a latence LLM extrakce. GraphRAG indexace velkého korpusu stojí desítky až stovky dolarů a hodiny; Graphiti zase přidává LLM volání ke každé epizodě. Počítejte s tím v rozpočtu a u objemných dat zvažte levnější model pro extrakci a dražší pro odpovědi.
- Modelování vyžaduje rozmysl. Graf svádí k tomu, udělat uzel ze všeho. Dobré pravidlo: uzly jsou věci, na které se budete ptát; vlastnosti jsou data, podle kterých budete filtrovat; hrany jsou vztahy, po kterých budete chodit. Když po hraně nikdy nepůjde dotaz, nemá v grafu co dělat.
- Vyhodnocujte retrieval, ne dojem. Stejně jako u vektorového RAG: sada testovacích otázek se známými odpověďmi a měření, jestli graf vrací správná fakta. U multi-hop otázek testujte i cesty (přes co odpověď vede), ne jen finální text.
Co s tím v praxi
- Začněte otázkami, ne technologií. Pokud vaše otázky zní „najdi podobné“, stačí vektory. Jakmile zní „jak to spolu souvisí“, „přes co“ nebo „co se stane, když“, je čas na graf.
- Na vyzkoušení: Neo4j v Dockeru (
docker run -p 7474:7474 -p 7687:7687 neo4j) a webový Neo4j Browser, kde graf vidíte a proklikáte — vizualizace je u grafů půlka pochopení. Pro embedded experimenty Kùzu. - Pro RAG nad stabilním korpusem zvažte GraphRAG (local + global search); pro živou paměť agenta temporální graf (Graphiti). Nekombinujte obojí hned na začátku — každé má vlastní provozní režii.
- Schéma grafu dejte agentovi do promptu a udržujte ho malé a pojmenované konzistentně; každý zbytečný typ vztahu zhoršuje text2Cypher i extrakci.
- Kombinujte s vektory: vektorový vstup, grafová expanze. A pořadí výsledků v kontextu stále podléhá U-křivce — nejdůležitější fakta na okraje.
Chcete agenty se skutečnou pamětí?
Na kurzu Programátor AI agentů stavíme agenty s nástroji, RAG i pamětí — od vektorových úložišť po znalostní grafy. Širší kontext LLM a datových pipeline najdete v kurzu Umělá inteligence pro programátory, vědu a datovou analytiku. A pokud vám unikl předchozí díl, přečtěte si o vektorových databázích, na který tento článek navazuje.
Zdroje a další čtení
- Edge et al.: From Local to Global: A Graph RAG Approach to Query-Focused Summarization (Microsoft Research, 2024) a dokumentace GraphRAG
- Rasmussen et al.: Zep: A Temporal Knowledge Graph Architecture for Agent Memory (2025) a Graphiti na GitHubu
- Neo4j Getting Started a Cypher Manual — oficiální dokumentace
- LangChain Neo4j Integration — GraphCypherQAChain, LLMGraphTransformer, vektorový index
- ISO/IEC 39075:2024 GQL — standard dotazovacího jazyka pro property grafy
- Robinson, Webber, Eifrem: Graph Databases (O’Reilly) — index-free adjacency a modelování do hloubky