Přeskočit na obsah

RAG: AI nad vlastními daty · lekce 3 z 7 · 15 min čtení

Embeddingy a vektorové databáze

Jak AI najde v tisících firemních dokumentů ten pravý odstavec, i když v něm nejsou slova z tvé otázky. Co je embedding, jak se měří podobnost významu, k čemu je vektorová databáze, proč česká otázka najde anglický dokument a co tahle technika neumí.

Představ si firmu se čtyřmi tisíci dokumenty: směrnice, smlouvy, návody k produktům, zápisy z porad, odpovědi zákazníkům. Vedení chce asistenta, který na otázku „Jak dlouho se u nás schvaluje služební cesta do zahraničí?“ odpoví správně a řekne, odkud to ví. Jazykový model to sám neumí, protože ty dokumenty nikdy neviděl. A naráz mu je všechny nedáš, protože se mu nevejdou do hlavy.

V lekci Když nestačí chat jsi poznal zkratku RAG: systém nejdřív vyhledá kousky dokumentů, které s otázkou souvisejí, a jen ty předá modelu. Tahle lekce se dívá na první, méně viditelnou polovinu: jak počítač pozná, které kousky s otázkou souvisejí. Odpověď zní embeddingy. Až jim porozumíš, pochopíš, proč firemní AI asistenti někdy fungují skvěle a jindy přinesou úplně vedlejší dokument. Celý postup RAG od začátku do konce pak rozebírá další lekce.

Dva důvody, proč model firemní dokumenty nezná

Model se na nich neučil. Z lekce Jak se model trénuje víš, že model se učil z veřejně dostupného textu do určitého data. Tvoje interní směrnice mezi tím nebyla. Když se ho na ni zeptáš, nemá z čeho čerpat, a tak buď přizná, že neví, nebo si věrohodně vymyslí, jak taková směrnice „obvykle“ vypadá.

Všechno se do okna nevejde. Kontextové okno dnešních velkých modelů pojme stovky tisíc až zhruba milion tokenů. Zní to hodně, ale čtyři tisíce dokumentů jsou řádově desítky milionů tokenů. A i kdyby se vešly, platil bys za ně při každé otázce znovu, čekal bys déle a model by mohl přehlédnout to důležité uprostřed (jev „ztraceno uprostřed“ z téže lekce).

Pro malé znalostní báze to neplatí. Anthropic ve svém návodu uvádí, že bázi menší než zhruba 200 000 tokenů (kolem 500 stran) můžeš modelu klidně vložit celou. Pro všechno větší potřebuješ umět rychle vybrat několik málo relevantních pasáží. A tady začíná hledání.

Hledání podle slov a hledání podle významu

Nejjednodušší hledání znáš z každého počítače: Ctrl+F nebo vyhledávací pole na intranetu. Najde dokumenty, ve kterých se vyskytují slova z dotazu. Lepší vyhledávače k tomu přidávají chytré bodování: slovo, které je vzácné, váží víc než slovo, které je všude, a krátký dokument s hledaným slovem má přednost před dlouhým, kde se ztratí.

Hledání podle klíčových slov(keyword search, lexical search)
Vyhledávání, které porovnává slova v dotazu se slovy v dokumentech. Nejrozšířenější metodou bodování je BM25: zohledňuje, jak často se slovo v dokumentu vyskytuje, jak vzácné je v celé sbírce a jak je dokument dlouhý.

Hledání podle slov má jednu zásadní slabinu: lidé se ptají jinými slovy, než jakými jsou psané dokumenty. Zaměstnanec napíše „Kolik mám volna?“, ale směrnice mluví o „nároku na dovolenou“. Někdo hledá „práci z domova“, dokument říká „home office“ nebo „práce na dálku“. V češtině se k tomu přidává skloňování: „dovolená“, „dovolené“, „dovolenou“. Vyhledávač podle slov je v tom bezradný, pokud ho na to někdo pracně nepřipravil slovníky synonym a tvarů.

Má ale i silnou stránku. Když hledáš přesné označení, třeba číslo smlouvy, kód produktu nebo jméno, slova jsou přesně to, co chceš. K tomu se ještě vrátíme.

Co bychom chtěli, je hledání podle významu: aby „Kolik mám volna?“ našlo odstavec o nároku na dovolenou, i když spolu nesdílejí jediné slovo. K tomu potřebujeme způsob, jak význam textu zapsat tak, aby se s ním dalo počítat.

Embedding: adresa textu na mapě významů

Přesně tohle dělá embedding. Speciální model, kterému se říká embeddingový model, přečte text a vrátí seznam čísel: jeho adresu v „prostoru významů“. Texty s podobným významem dostanou podobná čísla.

Embedding(embedding)
Seznam čísel (vektor), který vyjadřuje význam textu. Vytváří ho embeddingový model tak, aby texty s podobným významem měly podobná čísla. Embedding sám o sobě nic neříká, smysl dává jen ve srovnání s jinými embeddingy ze stejného modelu.

Slovo vektor tu neznamená nic tajemného: je to prostě uspořádaný seznam čísel, jako dvojice souřadnic na mapě.

Proč nestačí dvě čísla

Na mapě se dvěma souřadnicemi bys rychle narazil. Věta „Výpovědní lhůta nájemní smlouvy jsou tři měsíce“ souvisí s právem, s bydlením, s časem i se smlouvami obecně. Měla by tedy ležet blízko vět o právu, blízko vět o bydlení a zároveň blízko vět o lhůtách. Na ploše to nejde: každý bod může být blízko jen omezenému počtu sousedů. Každé další číslo v adrese přidává nový směr, ve kterém se texty mohou lišit, a tím víc prostoru pro jemné rozdíly.

Proto mají skutečné embeddingy stovky až tisíce čísel. Například embeddingové modely Googlu vracejí v době psaní ve výchozím nastavení 3 072 čísel, modely Voyage AI, které doporučuje Anthropic, 1 024. Představit si prostor s tisíci rozměry neumí nikdo, ani výzkumníci. Matematika vzdáleností ale funguje stejně jako na mapě, jen s víc čísly.

Jedna důležitá výhrada: jednotlivá čísla nemají lidské názvy. Neexistuje „rozměr číslo 17 = míra formálnosti“. Model si rozměry vytvořil sám během tréninku (jak, popisuje rozbalovací část níže) a jejich význam je rozprostřený napříč všemi. Mapu s popisky „čtvrť dovolená“ si tedy ber jako pomůcku. Skutečně platí jen to, že blízké body znamenají podobný význam.

Jak se měří podobnost

Když máš dva embeddingy, potřebuješ číslo, které řekne, jak podobné jsou. Nejčastěji se používá kosinová podobnost.

Kosinová podobnost(cosine similarity)
Míra podobnosti dvou vektorů podle toho, jakým směrem míří, ne podle jejich délky. Vychází mezi −1 a 1: čím blíž k 1, tím podobnější směr, a tedy podobnější význam.

Zkus si to představit takhle: každý embedding je šipka, která vychází ze středu prostoru a míří někam ven. Kosinová podobnost se ptá jen na jedno: míří ty dvě šipky stejným směrem? Pokud ano, vyjde číslo blízko 1. Pokud jsou na sebe kolmé, vyjde 0, texty spolu nesouvisejí. Opačný směr dá −1. Na délce šipky nezáleží, takže krátká věta a dlouhý odstavec o stejném tématu mohou vyjít jako velmi podobné.

V praxi to vypadá třeba takhle (čísla jsou ilustrační, skutečné hodnoty se mezi modely liší):

Dotaz: „Kolik mám dní volna za rok?“Podobnost
„Zaměstnanci mají nárok na 25 dní dovolené v kalendářním roce.“vysoká
„Žádost o dovolenou podává zaměstnanec přes docházkový systém.“střední
„Faktury jsou splatné do 14 dnů od vystavení.“nízká

Dvě věci stojí za zapamatování. Zaprvé, záleží jen na pořadí. Systém nehledá „podobnost nad 0,8“, ale vezme několik nejbližších textů. Absolutní čísla se mezi modely liší natolik, že univerzální práh „dost podobné“ neexistuje. Zadruhé, „podobný“ neznamená „obsahuje odpověď“. Druhá věta v tabulce je tématicky blízko, ale na otázku neodpovídá. Vyhledávání proto obvykle vrací víc kandidátů a výběr dokončuje až další krok.

Vektorová databáze

Embedding jednoho dotazu spočítáš za zlomek sekundy. Ale porovnat ho s miliony uložených embeddingů tak, aby odpověď přišla okamžitě, je samostatný problém. Na to jsou vektorové databáze.

Vektorová databáze(vector database)
Databáze, která ukládá embeddingy spolu s původním textem a dalšími údaji a umí rychle najít ty, které jsou nejbližší zadanému vektoru. Obvykle hledá přibližně: obětuje nepatrnou část přesnosti za obrovské zrychlení.

Co se v ní typicky ukládá ke každému kousku textu:

  • embedding (těch 1 024 nebo 3 072 čísel),
  • původní text, protože model pak potřebuje číst slova, ne čísla,
  • metadata: název dokumentu, kapitola, datum, platnost, autor, kdo má k dokumentu přístup.

Metadata jsou nenápadná, ale pro firmu zásadní. Díky nim jde hledat jen v dokumentech, které daný člověk smí vidět, nebo jen v platných verzích směrnic. Podrobněji v další lekci.

Vektorové databáze existují jako samostatné produkty (například Pinecone, Qdrant, Weaviate nebo Milvus) i jako doplněk běžných databází, třeba rozšíření pgvector pro PostgreSQL nebo vektorové hledání v Elasticsearch. Pro firmu to znamená, že často nemusí zavádět nic nového: vektory umí uložit i databáze, kterou už provozuje.

Do hloubkyPro ty, kdo programují: embedding a hledání v pár řádcích

Tahle ukázka je zjednodušená verze příkladu z dokumentace Anthropicu (embeddingy tam dodává Voyage AI). Vektorová databáze tu chybí: pro šest vět stačí porovnat vektory přímo.

import numpy as np
import voyageai

vo = voyageai.Client()  # klíč se načte z proměnné prostředí VOYAGE_API_KEY

dokumenty = [
    "Zaměstnanci mají nárok na 25 dní dovolené v kalendářním roce.",
    "Žádost o dovolenou se podává přes docházkový systém.",
    "Faktury jsou splatné do 14 dnů od vystavení.",
]
# Dokumenty a dotaz se kódují s jiným input_type, ale stejným modelem
doc_vektory = vo.embed(dokumenty, model="voyage-4", input_type="document").embeddings
dotaz = vo.embed(["Kolik mám dní volna za rok?"], model="voyage-4", input_type="query").embeddings[0]

# Vektory Voyage mají délku 1, takže skalární součin = kosinová podobnost
podobnosti = np.dot(doc_vektory, dotaz)
for i in np.argsort(-podobnosti):
    print(round(float(podobnosti[i]), 3), dokumenty[i])

Názvy modelů se mění, aktuální najdeš v dokumentaci. Ve skutečné aplikaci by místo np.dot přes všechny dokumenty přišel dotaz do vektorové databáze, která vrátí nejbližších pár desítek záznamů.

Česká otázka, anglický dokument

Jedna vlastnost embeddingů firmy často příjemně překvapí. Vícejazyčné embeddingové modely umisťují texty se stejným významem blízko sebe bez ohledu na jazyk. Česká otázka „Jak dlouho platí záruka na čerpadlo?“ tak může najít odstavec z anglického manuálu „The pump is covered by a 24-month warranty“.

Funguje to proto, že se tyto modely učily i na dvojicích vět, které jsou navzájem překladem, a naučily se je klást na stejné místo mapy. Například model LaBSE od Googlu z roku 2020 pokrývá přes 109 jazyků, současné komerční modely uvádějí podporu desítek až více než sta jazyků.

Pro české firmy to má dva důsledky. Dobrá zpráva: nemusíš překládat anglickou dokumentaci od dodavatelů, aby v ní asistent hledal. Opatrnější zpráva: kvalita se mezi jazyky liší a čeština bývá v trénovacích datech zastoupená méně než angličtina. Než se pro model rozhodneš, otestuj ho na vlastních českých dotazech a dokumentech. Jak takový test postavit, probírá kurz o kvalitě, lekce Testovací sady.

Co embeddingy neumí

Hledání podle významu je silný nástroj, ale má slepá místa. Když je znáš, pochopíš většinu podivných chyb firemních asistentů.

  • Přesné kódy a čísla. Embedding zachycuje význam, ne přesný zápis. Dotaz na „smlouvu 2024/117“ může najít smlouvu 2024/171, protože obě „vypadají stejně“. Anthropic to ve svém návodu ilustruje na chybovém kódu „TS-999“: embeddingy najdou obecné texty o chybových kódech, ale ne nutně tu jedinou správnou stránku. Proto se hledání podle významu kombinuje s hledáním podle slov.
  • Zápor a jemné logické rozdíly. „Zaměstnanec smí pracovat z domova“ a „Zaměstnanec nesmí pracovat z domova“ jsou si tématicky skoro totožné, a embeddingy je proto často řadí těsně vedle sebe. Vyhledání obě najde, rozlišit je musí až jazykový model, který text čte.
  • Pravdivost a aktuálnost. Embedding neví, že směrnice z roku 2019 už neplatí. Stará i nová verze leží na mapě vedle sebe. O platnosti musí rozhodnout metadata nebo úklid dokumentů.
  • Dlouhé texty. Jeden embedding pro celou padesátistránkovou smlouvu je jako jedna adresa pro celé město: zprůměruje všechno a nevystihne nic. Dokumenty se proto dělí na menší kousky, o tom v další lekci.
  • Podobné není totéž co odpovídající. Otázka a odpověď na ni nemusí znít podobně. Proto mají moderní embeddingové modely zvláštní režim pro dotazy a pro dokumenty a proto se výsledky často ještě přeřazují dalším modelem.
  • Odborný žargon. Obecný model nemusí vědět, že u vás „zelená karta“ znamená interní formulář, a ne povolení k pobytu. Pomáhají oborově zaměřené modely nebo kombinace s hledáním podle slov.
Do hloubkyJak se embeddingový model učí (kontrastivní učení)

Embeddingový model je neuronová síť podobná jazykovým modelům, jen místo dalšího tokenu vrací jeden vektor pro celý text. Zajímavé je, jak se naučí dávat podobným textům podobná čísla, když mu nikdo neřekne, co je „podobné“. Nejrozšířenější postup se jmenuje kontrastivní učení (contrastive learning).

Dvojice, které k sobě patří. Trénink začíná obrovským množstvím dvojic textů, o kterých víme, že spolu souvisejí. Výzkumníci z OpenAI v článku Text and Code Embeddings by Contrastive Pre-Training (2022) použili jako dvojice sousední kousky textu z internetu: dva po sobě jdoucí odstavce obvykle mluví o stejné věci. U kódu brali popis funkce a její kód. Tým z Microsoftu u modelů E5 sestavil sbírku dvojic typu nadpis a text, otázka a odpověď nebo příspěvek a komentář. Vícejazyčná verze E5 se trénovala zhruba na miliardě vícejazyčných dvojic.

Kontrast s ostatními. Model dostane najednou tisíce dvojic (tzv. dávku). Pro každý text má mezi všemi ostatními texty v dávce najít jeho pravý protějšek. Ostatní texty slouží jako záporné příklady: „tohle k sobě nepatří“. Model se tedy učí dvě věci současně: přitáhnout k sobě vektory, které patří k sobě, a odtlačit od sebe ty, které ne. Odtud název kontrastivní. Ve zmíněném článku OpenAI měly dávky kolem pěti až dvanácti tisíc dvojic a větší dávky dávaly lepší výsledky, protože model musí rozlišit víc „podobně vypadajících“ nesprávných kandidátů.

Dolaďování. Po tomto hrubém tréninku na levných dvojicích se model obvykle doladí na menší sadě kvalitních, ručně označených dat, například skutečných otázek a pasáží, které na ně odpovídají. Teprve tím se dobře naučí, že otázka a odpověď mají ležet blízko sebe, i když nezní stejně.

Odkud se bere vícejazyčnost. Když trénovací dvojice obsahují věty a jejich překlady, model se naučí klást je na stejné místo. Takhle byl trénován například model LaBSE (Google, 2020). Výsledkem je jedna společná mapa pro všechny jazyky.

Jak přesně komerční výrobci trénují své současné modely, většinou nezveřejňují. Výše popsaný princip ale odpovídá veřejným výzkumným článkům a nástrojům, které se pro trénink embeddingů běžně používají.

Co si odnést

  • Model firemní dokumenty nezná a všechny se mu do kontextového okna nevejdou. Proto se k otázce nejdřív vyhledá několik relevantních pasáží.
  • Embedding je seznam stovek až tisíců čísel, který vyjadřuje význam textu. Texty s podobným významem mají podobná čísla, i když používají jiná slova nebo jiný jazyk.
  • Podobnost se nejčastěji měří kosinovou podobností: míří dvě „šipky“ stejným směrem? Rozhoduje pořadí výsledků, ne absolutní číslo.
  • Vektorová databáze ukládá embeddingy spolu s textem a metadaty a rychle najde nejbližší. Dotaz i dokumenty musí projít stejným embeddingovým modelem.
  • Embeddingy neumí přesné kódy, zápor, aktuálnost ani dlouhé texty. Proto se kombinují s hledáním podle slov, metadaty a dělením dokumentů na kousky.

Zdroje a další čtení