Základná implementácia RAG: návod krok za krokom
Tento návod pre začiatočníkov vysvetľuje, ako funguje základná implementácia RAG, predstavuje osvedčené postupy a krok za krokom vás prevedie vytvorením funkčného systému RAG pre príkazový riadok pomocou jazyka Python, ChromaDB a embeddingových a jazykových modelov Perplexity.

RAG je nevyhnutnou súčasťou modernej infraštruktúry založenej na LLM. Tým, že modelom AI umožňuje pristupovať k externým dátam, pomáha riešiť problémy, ako sú halucinácie a neúplné trénovacie dáta. Firmy vďaka nemu môžu využívať aj interné databázy znalostí, ktoré obsahujú citlivé alebo proprietárne informácie.
Implementácia RAG môže byť veľmi zložitá. Základný systém RAG sa však dá zostaviť prekvapivo ľahko. Začiatočníkom môže jednoduchá architektúra objasniť, ako RAG funguje v praxi, a poslúžiť ako odrazový mostík na ďalšie experimentovanie.
V tomto článku načrtneme základnú implementáciu RAG, prejdeme si osvedčené postupy a potom zostavíme funkčný systém pomocou jazyka Python, ChromaDB a dvoch modelov Perplexity – jedného na tvorbu embeddingov a druhého na generovanie odpovedí.
Proces základnej implementácie RAG: celkový prehľad
Základný systém RAG má tri hlavné komponenty: orchestrátor, zdroj informácií a LLM. V typickom pracovnom postupe používateľ zadá prompt a orchestrátor ho upraví tak, aby mohol prehľadať všetky pripojené zdroje informácií. Získané informácie sa potom pridajú k pôvodnému vstupnému kontextu a odošlú do LLM, ktorý vygeneruje odpoveď.
Pri zostavovaní vlastnej implementácie RAG budete musieť zohľadniť tieto kroky:
- Indexovanie a tvorba embeddingov: V tejto fáze sa vaše dokumenty premenia na zdroj informácií, ktorý môže orchestrátor prehľadávať. Jedným z najbežnejších spôsobov je vytvorenie prehľadávateľného vektorového indexu. Na prevod úsekov dokumentov na embeddingy použijeme špecializovaný model od Perplexity. Embeddingy potom uložíme do ChromaDB, populárnej open-source vektorovej databázy.
- Orchestrácia: Ide o aplikáciu, ktorá stojí medzi externým zdrojom informácií (v našom prípade vektorovou databázou) a LLM. Ako orchestrátor nám poslúži jednoduchý skript v jazyku Python.
- Získavanie a generovanie: Keď používateľ položí otázku cez chatové rozhranie, orchestrátor ju prevezme, spustí vektorové vyhľadávanie a rozšírený vstup odovzdá LLM. Namiesto vytvárania samostatného frontendu budeme s naším orchestrátorom v jazyku Python komunikovať prostredníctvom príkazového riadka.
Osvedčené postupy: čo robí implementáciu RAG efektívnou?
Existuje viacero typov architektúry RAG a jednotlivé prípady použitia si vyžadujú odlišné prístupy. Niektoré osvedčené postupy však platia vo všetkých prípadoch a zaručujú, že systémy budú presné, nákladovo efektívne, škálovateľné a ľahko udržiavateľné.
Pre všetky typy implementácie RAG platia tieto osvedčené postupy:
- Zabezpečte čistý proces načítavania dát: Zdrojové dáta by mali byť pred indexovaním čo najčistejšie. Mali by ste tiež použiť embeddingový model vhodný pre váš obsah.
- Používajte hybridné vyhľadávanie: Najlepšie metódy získavania informácií – či už ide o vyhľadávanie vo vektorovej databáze, webové vyhľadávanie cez API, prechádzanie znalostného grafu, vyhľadávanie podľa kľúčových slov alebo iné metódy – sa líšia v závislosti od prípadu použitia. Výber správnej kombinácie je dôležitý na minimalizáciu nákladov.
- Vyhodnoťte svoj systém: Po implementácii by ste mali systém vyhodnotiť podľa troch základných ukazovateľov: presnosti, relevantnosti a latencie. Presnosť označuje faktickú správnosť, relevantnosť vhodnosť získaných informácií pre dopyty používateľov a latencia rýchlosť, akou sa informácie získavajú.
- Zaobchádzajte s informáciami bezpečne: Ak váš systém RAG čerpá zo súkromných interných informácií, zabezpečte ich bezpečné uloženie a spravujte prístup k rozhraniu systému. Kľúče API nikdy nezdieľajte.
Základná implementácia RAG: návod v 7 krokoch
V tomto návode vytvoríme aplikáciu pre príkazový riadok, ktorá odpovedá na otázky o jednom dokumente. Použijeme jazyk Python, ChromaDB a Perplexity API.
Cieľom nie je vytvoriť systém RAG pripravený na produkčné nasadenie. Ide skôr o návod pre začiatočníkov, ktorý má ukázať, ako jednoduchá architektúra RAG funguje v praxi.
Krok 1: Nainštalujte softvér
Uistite sa, že máte v počítači nainštalované nasledujúce nástroje a že máte účet Perplexity API:
- Python: Ide o programovací jazyk, v ktorom vytvoríme orchestrátor koordinujúci tok dát medzi embeddingovým modelom, ChromaDB a Perplexity.
- Visual Studio: Ako editor kódu použijeme Visual Studio. Po nainštalovaní otvorte panel Extensions a stiahnite si rozšírenie Python.
- Účet Perplexity API: Perplexity poskytne embeddingový model (ktorý premení vaše dáta na vektorové embeddingy) aj LLM, ktorý spracuje rozšírený prompt. Nepotrebujete na to platený účet, spotrebujete však malé množstvo kreditov.
Krok 2: Vytvorte priečinok projektu
Najprv vytvorte priečinok s názvom rag-project a otvorte ho vo VS Code výberom položky File > Open Folder. Potom otvorte integrovaný terminál cez Terminal > New Terminal.
Zadaním nasledujúceho príkazu vytvorte virtuálne prostredie pre Python:
py -3.12 -m venv .venvTeraz musíte nainštalovať štyri knižnice jazyka Python: perplexityai, chromadb, python-dotenv a numpy. Perplexity SDK vám umožní pripojiť sa k modelom Perplexity cez API. ChromaDB vytvorí vektorovú databázu a bude bežať lokálne. Python-dotenv bezpečne načíta vaše kľúče API z lokálneho súboru a NumPy je potrebný pri načítavaní dát.
Nainštalujte ich týmto príkazom:
.\.venv\Scripts\python.exe -m pip install perplexityai chromadb python-dotenv numpyKrok 3: Pripravte si súbory
Do priečinka rag-project (koreňový adresár projektu) pridajte nasledujúce súbory výberom možnosti New File… na bočnom paneli Explorer:
- index.py: Toto je aplikácia, ktorá zaindexuje váš dokument. Ak chcete pridať ďalší text, môžete ju spustiť znova.
- rag.py: Toto je aplikácia v jazyku Python, ktorá bude fungovať ako orchestrátor.
- document.txt: Tento súbor bude obsahovať dokumentáciu, ktorú prevediete do vektorovej databázy.
- .env: Sem uložíte svoj kľúč Perplexity API.
Do súboru .env zadajte tento obsah:
PERPLEXITY_API_KEY=your_api_key_hereNahraďte your_api_key_here svojím skutočným kľúčom. Získate ho tak, že prejdete na domovský panel v Perplexity API Console a vyberiete možnosť Create an API key. Tento kľúč API uchovávajte v tajnosti.
Použijeme dva modely: pplx-embed-v1-0.6b od Perplexity na vytvorenie embeddingov našej dokumentácie pred jej nahraním do ChromaDB a GPT-5.6-Luna (dostupný cez API Perplexity), ktorý spracuje získané informácie.
Do súboru document.txt pridajte text, ktorý bude váš systém RAG vyhľadávať. Ak nemáte po ruke vhodný dokument, použite v tomto návode dielo Williama Blakea Songs of Innocence and of Experience z knižnice Project Gutenberg. Ide o krátky, ľahko zrozumiteľný text, ktorý je voľným dielom.
Krok 4: Napíšte indexovací program
Skopírujte nižšie uvedený kód a vložte ho do súboru index.py. Každý podnadpis stručne vysvetľuje, čo robí nasledujúca časť kódu. Tento program prevedie váš zdrojový materiál na vektorové embeddingy a uloží ich do databázy ChromaDB pomocou embeddingového modelu Perplexity pplx-embed-v1-0.6b a knižnice NumPy.
Program robí toto:
- Otvorí súbor document.txt.
- Rozdelí text na prekrývajúce sa úseky.
- Odošle tieto úseky do embeddingového modelu pplx-embed-v1-0.6b od Perplexity.
- Dekóduje a normalizuje vrátené vektory pomocou NumPy, knižnice výpočtových funkcií pre Python.
- Uloží vektory a pôvodné úseky do databázy ChromaDB (zobrazí sa v adresári vášho projektu).
Program je nastavený tak, aby dokument pri každom spustení znova neindexoval. Ak do súboru document.txt pridáte ďalšie informácie, vytvorí embeddingy iba pre nový text.
from pathlib import Path
from collections import defaultdict, deque
from hashlib import sha256
import base64
import numpy as np
import chromadb
from dotenv import load_dotenv
from perplexity import Perplexity
# 1. Connect to Perplexity and ChromaDB
load_dotenv()
ai = Perplexity()
db = chromadb.PersistentClient(path="./rag_database_perplexity")
collection = db.get_or_create_collection(
name="documents",
metadata={"hnsw:space": "cosine"}
)
# Convert Perplexity's encoded embeddings into numerical vectors
def decode_embedding(encoded):
vector = np.frombuffer(base64.b64decode(encoded), dtype=np.int8).astype(np.float32)
norm = np.linalg.norm(vector)
if norm == 0:
raise ValueError("Received a zero-length embedding vector.")
return (vector / norm).tolist()
# 2. Read the document and split it into chunks
text = Path("document.txt").read_text(encoding="utf-8")
words = text.split()
chunk_size = 180
overlap = 30
step = chunk_size - overlap
chunks = [" ".join(words[i:i + chunk_size]) for i in range(0, len(words), step)]
if not chunks:
raise ValueError("document.txt is empty.")
# 3. Retrieve the chunks already stored in ChromaDB
existing = collection.get(include=["documents"])
stored_chunks = defaultdict(deque)
existing_ids = set(existing["ids"])
for chunk_id, document in zip(existing["ids"], existing["documents"]):
stored_chunks[document].append(chunk_id)
# 4. Identify unchanged and new chunks
new_chunks = []
new_ids = []
kept_ids = set()
unchanged = 0
for chunk in chunks:
if stored_chunks[chunk]:
chunk_id = stored_chunks[chunk].popleft()
kept_ids.add(chunk_id)
unchanged += 1
else:
chunk_hash = sha256(chunk.encode("utf-8")).hexdigest()
chunk_id = f"chunk-{chunk_hash}"
suffix = 1
while chunk_id in existing_ids or chunk_id in kept_ids or chunk_id in new_ids:
chunk_id = f"chunk-{chunk_hash}-{suffix}"
suffix += 1
new_chunks.append(chunk)
new_ids.append(chunk_id)
kept_ids.add(chunk_id)
# 5. Generate embeddings in batches of up to 100 chunks
batch_size = 100
for i in range(0, len(new_chunks), batch_size):
batch_chunks = new_chunks[i:i + batch_size]
batch_ids = new_ids[i:i + batch_size]
embeddings = ai.embeddings.create(
model="pplx-embed-v1-0.6b",
input=batch_chunks,
encoding_format="base64_int8"
)
vectors = [decode_embedding(item.embedding) for item in embeddings.data]
# 6. Store each batch in ChromaDB
collection.upsert(
ids=batch_ids,
documents=batch_chunks,
embeddings=vectors
)
print(f"Indexed batch {(i // batch_size) + 1}")
# 7. Remove outdated chunks
old_ids = [chunk_id for chunk_id in existing["ids"] if chunk_id not in kept_ids]
if old_ids:
collection.delete(ids=old_ids)
# 8. Display indexing results
print("Indexing complete!")
print("Unchanged chunks:", unchanged)
print("New or modified chunks:", len(new_chunks))
print("Removed chunks:", len(old_ids))
print("Total stored chunks:", collection.count())Krok 5. Napíšte orchestrátor pre systém RAG
Skopírujte nižšie uvedený kód a vložte ho do súboru rag.py. Ide o úplnú, no minimalistickú implementáciu RAG, ktorá využíva Perplexity SDK a funkcie lokálnej vektorovej databázy ChromaDB.
Toto sa stane, keď program spustíte:
- Pripojí sa k Perplexity a k vašej novej databáze ChromaDB.
- Overí, či databáza obsahuje zaindexované dokumenty.
- Prijme otázku od používateľa.
- Odošle otázku do embeddingového modelu Perplexity.
- Dekóduje a normalizuje výsledný embedding pomocou NumPy.
- Vyhľadá v ChromaDB tri najpodobnejšie úseky dokumentu.
- Zostaví prompt obsahujúci získané úseky a otázku používateľa.
- Odošle prompt do modelu GPT-5.6 Luna cez Agent API od Perplexity.
- Zobrazí odpoveď a čaká na ďalšiu otázku.
import base64
import numpy as np
import chromadb
from dotenv import load_dotenv
from perplexity import Perplexity
# 1. Connect to Perplexity and the existing ChromaDB database
load_dotenv()
ai = Perplexity()
db = chromadb.PersistentClient(path="./rag_database_perplexity")
collection = db.get_collection("documents")
# Convert Perplexity's encoded embeddings into numerical vectors
def decode_embedding(encoded):
vector = np.frombuffer(base64.b64decode(encoded), dtype=np.int8).astype(np.float32)
norm = np.linalg.norm(vector)
if norm == 0:
raise ValueError("Received a zero-length embedding vector.")
return (vector / norm).tolist()
# 2. Check that the database contains indexed documents
count = collection.count()
if count == 0:
raise ValueError("The database is empty. Run index.py first.")
print("Connected to existing ChromaDB database.")
print("Stored chunks:", count)
# 3. Accept questions from the user
while True:
question = input("\nAsk a question (or type exit): ")
if question.lower().strip() == "exit":
break
if not question.strip():
continue
# 4. Convert the question into a Perplexity embedding
question_response = ai.embeddings.create(
model="pplx-embed-v1-0.6b",
input=[question],
encoding_format="base64_int8"
)
question_vector = decode_embedding(question_response.data[0].embedding)
# 5. Retrieve the most similar document chunks from ChromaDB
results = collection.query(
query_embeddings=[question_vector],
n_results=min(3, count)
)
context = "\n\n".join(results["documents"][0])
# 6. Construct a prompt and send it to the fixed LLM
response = ai.responses.create(
model="openai/gpt-5.6-luna",
instructions=(
"Answer using only the supplied document excerpts. "
"Do not use external information. "
"If the answer is not present, say you don't know."
),
input=f"Document excerpts:\n{context}\n\nQuestion: {question}"
)
# 7. Display the answer
print("\nAnswer:\n", response.output_text)Krok 6: Spustite aplikácie
V termináli PowerShell vo VS Code zadajte nasledujúci príkaz, ktorým vytvoríte embeddingy obsahu súboru document.txt:
.\.venv\Scripts\python.exe index.pyAk sa dokument úspešne zaindexoval, mali by ste vidieť výstup podobný tomuto:
Indexing complete!
Unchanged chunks: 0
New or modified chunks: 58
Removed chunks: 0
Total stored chunks: 58Teraz je čas spustiť hlavnú aplikáciu orchestrátora. Zadajte tento príkaz:
.\.venv\Scripts\python.exe rag.pyAk sa aplikácia úspešne spustí, zobrazí sa toto:
Connected to existing ChromaDB database.
Stored chunks: 58
Ask a question (or type exit): Teraz môžete klásť otázky, pri ktorých bude systém čerpať z vytvorenej vektorovej databázy, napríklad:
Ask a question (or type exit): What animals does William Blake talk about?
Answer: The excerpts mention sheep, lambs, birds, beasts, wolves, tigers, and a lion.Krok 7: Pochopte, čo ste vytvorili
Systém, ktorý ste vytvorili, obsahuje dva základné pipeliny prítomné v každej architektúre RAG: indexovací pipeline, nazývaný aj pipeline na „načítavanie“ dát, a pipeline na získavanie a generovanie.
Vaša základná implementácia RAG teraz zvláda všetko toto:
- Vektorové úložisko: Embeddingy vytvorené z vášho znalostného súboru sa ukladajú do databázy ChromaDB vo vašom lokálnom prostredí.
- Inkrementálne indexovanie: Pre nezmenené úseky dokumentu sa embeddingy znova nevytvárajú a dokument môžete aktualizovať, kedykoľvek budete chcieť.
- Sémantické vyhľadávanie: ChromaDB vyhľadáva úseky na základe vektorovej podobnosti (na podnet orchestrátora).
- Generovanie podložených odpovedí: LLM dostane získané pasáže ako kontext a začlení ich do odpovede.
- Nezávislé indexovanie a dopytovanie: Môžete klásť otázky bez toho, aby bolo potrebné znova spracovať celý text vo vašom znalostnom súbore.
- Pripojenie modelu cez API: Všetky odpovede generuje model GPT-5.6 Luna cez Perplexity, nie model bežiaci na vašom počítači.
Ďalšie kroky: ako túto implementáciu rozšíriť
Cieľom tohto návodu je vytvoriť jednoduchú, základnú implementáciu. Pokrýva niektoré zo základných komponentov architektúry RAG, ktoré nájdete v moderných systémoch. Ak chcete ísť ďalej, môžete na nej stavať viacerými spôsobmi.
Tu je niekoľko nápadov, ako rozšíriť rozsah vašej implementácie:
- Experimentujte s LangChain: LangChain je jeden z najpopulárnejších open-source orchestračných frameworkov. Obsahuje predpripravené komponenty na tvorbu aplikácií, ktoré dokážu spúšťať zložité pipeliny RAG.
- Rozšírte funkcie vyhľadávania: Skombinujte husté vektorové vyhľadávanie s lexikálnym vyhľadávaním (podľa kľúčových slov), napríklad BM25. Pridanie webového vyhľadávania cez Perplexity Search API by vám tiež umožnilo podložiť odpovede aktuálnymi dátami.
- Pridajte model na opätovné zoradenie: Integrujte model na opätovné zoradenie (reranking), ktorý ohodnotí získané pasáže vzhľadom na pôvodný prompt a vyberie tie najrelevantnejšie na zaradenie do vstupného kontextu, ktorý dostane LLM.
- Vytvorte adaptívny systém RAG: Adaptívny RAG používa buď LLM, alebo klasifikátor (komponent v rámci orchestrátora) na určenie, ktorú metódu získavania v modulárnom systéme RAG použiť. Vytvorenie takého systému je dobrý spôsob, ako preskúmať sofistikovanejšie implementácie RAG.
Hoci to všetko môže znieť zložito, majte na pamäti, že bežné platformy AI, ako je Perplexity, dokážu poskytnúť pokročilú pomoc s programovaním. Sú výborné na osobné projekty a experimentovanie a náklady sa dajú udržať pomerne nízke.
Poznámka: V tomto návode sa používa model GPT-5.6 Luna. Dostupnosť modelov sa môže zmeniť, takže možno budete musieť aktualizovať volanie API.