Paprastas RAG diegimas: vadovas žingsnis po žingsnio
Šiame pradedantiesiems skirtame vadove paaiškinama, kaip veikia paprastas RAG diegimas, aptariama geriausia praktika ir žingsnis po žingsnio parodoma, kaip sukurti veikiančią komandų eilutės RAG sistemą naudojant Python, ChromaDB bei Perplexity įterpinių ir kalbos modelius.

RAG yra esminis šiuolaikinės LLM pagrįstos infrastruktūros komponentas. Leisdamas DI modeliams pasiekti išorinius duomenis, jis padeda spręsti tokias problemas kaip haliucinacijos ir neišsamūs mokymo duomenys. Be to, įmonės gali naudoti vidines žinių bazes, kuriose yra jautrios ar konfidencialios informacijos.
RAG diegimas gali būti labai sudėtingas. Tačiau paprastą RAG sistemą sukurti stebėtinai lengva. Pradedantiesiems paprastos architektūros sukūrimas gali padėti suprasti, kaip RAG veikia realiame pasaulyje, ir tapti atspirties tašku tolesniems eksperimentams.
Šiame straipsnyje apžvelgsime paprasto RAG diegimo struktūrą, aptarsime geriausią praktiką ir sukursime veikiančią sistemą naudodami Python, ChromaDB ir du Perplexity modelius – įterpiniams kurti ir atsakymams generuoti.
Paprasto RAG diegimo procesas: bendra apžvalga
Paprastą RAG sistemą sudaro trys pagrindiniai komponentai: orkestratorius, informacijos šaltinis ir LLM. Įprastoje darbo eigoje naudotojas įveda užklausą, o orkestratorius ją pritaiko, kad galėtų ieškoti visuose prijungtuose informacijos šaltiniuose. Tada gauta informacija pridedama prie pradinio įvesties konteksto ir perduodama LLM, kad būtų sugeneruotas atsakymas.
Kurdami savo RAG diegimą turėsite atsižvelgti į šiuos etapus:
- Indeksavimas ir įterpinių kūrimas: Šiame etape jūsų dokumentai paverčiami informacijos šaltiniu, kuriame orkestratorius gali ieškoti. Vienas dažniausių būdų tai padaryti – sukurti vektorinį indeksą, kuriame galima ieškoti. Jūsų dokumentų fragmentams paversti įterpiniais naudosime specialų Perplexity modelį. Tada įterpinius saugosime populiarioje atvirojo kodo vektorinėje duomenų bazėje ChromaDB.
- Orkestravimas: Tai programa, esanti tarp išorinio informacijos šaltinio (mūsų atveju – vektorinės duomenų bazės) ir LLM. Sukursime paprastą Python scenarijų, kuris atliks orkestratoriaus vaidmenį.
- Paieška ir generavimas: Kai naudotojas užduoda klausimą per pokalbių sąsają, orkestratorius jį priima, atlieka vektorinę paiešką ir perduoda išplėstą įvestį LLM. Užuot kūrę atskirą naudotojo sąsają, su Python orkestratoriumi bendrausime per komandų eilutę.
Geriausia praktika: kas lemia veiksmingą RAG diegimą?
Yra įvairių RAG architektūros tipų, o skirtingiems naudojimo atvejams reikia skirtingų metodų. Vis dėlto daugelis geriausios praktikos principų taikomi visais atvejais ir užtikrina tikslias, ekonomiškas, keičiamo mastelio ir lengvai prižiūrimas sistemas.
Toliau pateikti geriausios praktikos principai taikomi visų tipų RAG diegimams:
- Užtikrinkite švarų duomenų įkėlimo konvejerį: Prieš indeksuojant šaltinio duomenys turėtų būti kuo švaresni. Taip pat turėtumėte naudoti jūsų turiniui tinkamą įterpinių modelį.
- Naudokite hibridinę paiešką: Geriausi paieškos metodai – ar tai būtų paieška vektorinėje duomenų bazėje, API pagrįsta žiniatinklio paieška, žinių grafo naršymas, paieška pagal raktinius žodžius, ar kiti metodai – priklauso nuo naudojimo atvejo. Norint sumažinti sąnaudas, svarbu pasirinkti tinkamą jų derinį.
- Įvertinkite savo sistemą: Įdiegę sistemą turėtumėte ją įvertinti pagal tris pagrindinius rodiklius: tikslumą, aktualumą ir delsą. Tikslumas reiškia faktinį teisingumą, aktualumas – gautos informacijos tinkamumą naudotojų užklausoms, o delsa – greitį, kuriuo informacija gaunama.
- Saugiai tvarkykite informaciją: Jei jūsų RAG sistema naudoja privačią vidinę informaciją, užtikrinkite, kad ji būtų patikimai apsaugota, o prieiga prie sistemos sąsajos – valdoma. Niekada nesidalykite API raktais.
Paprastas RAG diegimas: 7 žingsnių vadovas
Šiame vadove sukursime komandų eilutės programą, kuri atsako į klausimus apie vieną dokumentą. Naudosime Python, ChromaDB ir Perplexity API.
Tikslas – ne sukurti gamybinei aplinkai paruoštą RAG sistemą. Tai pradedantiesiems skirtas vadovas, kuriuo siekiama parodyti, kaip paprasta RAG architektūra veikia praktikoje.
1 žingsnis: įdiekite programinę įrangą
Įsitikinkite, kad kompiuteryje įdiegta toliau nurodyta programinė įranga ir kad turite Perplexity API paskyrą:
- Python: Tai programavimo kalba, kuria kursime orkestratorių, koordinuosiantį duomenų srautą tarp įterpinių modelio, ChromaDB ir Perplexity.
- Visual Studio: Kaip kodo redaktorių naudosime Visual Studio. Įdiegę atidarykite skydelį Extensions ir atsisiųskite plėtinį Python.
- Perplexity API paskyra: Perplexity pateiks ir įterpinių modelį (kuris paverčia jūsų duomenis vektoriniais įterpiniais), ir LLM, kuris apdoros išplėstą užklausą. Tam nereikia mokamos paskyros, tačiau bus sunaudota šiek tiek kreditų.
2 žingsnis: sukurkite projekto aplanką
Pirmiausia sukurkite aplanką pavadinimu rag-project ir atidarykite jį programoje VS Code pasirinkdami File > Open Folder. Tada atidarykite integruotą terminalą pasirinkdami Terminal > New Terminal.
Įveskite toliau pateiktą komandą, kad sukurtumėte virtualią Python aplinką:
py -3.12 -m venv .venvDabar reikia įdiegti keturias Python bibliotekas: perplexityai, chromadb, python-dotenv ir numpy. Perplexity SDK leis jums prisijungti prie Perplexity modelių per API. ChromaDB sukuria vektorinę duomenų bazę ir veiks jūsų kompiuteryje. Python-dotenv saugiai įkelia jūsų API raktus iš vietinio failo, o NumPy reikalinga duomenų įkėlimo proceso metu.
Įdiekite jas šia komanda:
.\.venv\Scripts\python.exe -m pip install perplexityai chromadb python-dotenv numpy3 žingsnis: paruoškite failus
Pridėkite šiuos failus į rag-project (projekto šakninį aplanką) šoninėje juostoje Explorer pasirinkdami New File…:
- index.py: Tai programa, kuri indeksuos jūsų dokumentą. Galite ją paleisti iš naujo, kad pridėtumėte daugiau teksto.
- rag.py: Tai Python programa, kuri atliks orkestratoriaus vaidmenį.
- document.txt: Šiame faile bus dokumentacija, kurią paversite vektorine duomenų baze.
- .env: Čia laikysite savo Perplexity API raktą.
Faile .env įveskite toliau pateiktą tekstą:
PERPLEXITY_API_KEY=your_api_key_herePakeiskite your_api_key_here savo tikruoju raktu. Tam reikės atidaryti Perplexity API Console pagrindinį prietaisų skydelį ir pasirinkti Create an API key. Niekam neatskleiskite šio API rakto.
Naudosime du modelius: Perplexity modelį pplx-embed-v1-0.6b, kuriuo prieš įkeldami dokumentaciją į ChromaDB paversime ją įterpiniais, ir GPT-5.6-Luna (pasiekiamą per Perplexity API), kuris apdoros gautą informaciją.
Į document.txt įrašykite tekstą, iš kurio jūsų RAG konvejeris gaus informaciją. Jei neturite po ranka tinkamo dokumento, šiam vadovui naudokite Williamo Blake'o rinkinį Songs of Innocence and of Experience iš Project Gutenberg. Tai trumpas, lengvai suprantamas viešojo naudojimo tekstas.
4 žingsnis: parašykite indeksavimo programą
Nukopijuokite toliau pateiktą kodą ir įklijuokite jį į index.py. Kiekviena paantraštė trumpai paaiškina, ką daro po jos einantis kodo segmentas. Ši programa pavers jūsų šaltinio medžiagą vektoriniais įterpiniais ir išsaugos juos ChromaDB duomenų bazėje, naudodama Perplexity įterpinių modelį pplx-embed-v1-0.6b ir NumPy biblioteką.
Štai ką daro programa:
- Atidaro document.txt.
- Padalija tekstą į persidengiančius fragmentus.
- Siunčia tuos fragmentus Perplexity įterpinių modeliui pplx-embed-v1-0.6b.
- Iškoduoja ir normalizuoja grąžintus vektorius naudodama NumPy – Python skaičiavimo funkcijų biblioteką.
- Išsaugo vektorius ir pradinius fragmentus ChromaDB duomenų bazėje (ji atsiras jūsų projekto kataloge).
Ji sukonfigūruota taip, kad iš naujo neindeksuotų jūsų dokumento kiekvieną kartą ją paleidus. Jei papildysite informaciją faile document.txt, ji pavers įterpiniais tik naują tekstą.
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())5 žingsnis. Parašykite RAG sistemos orkestratorių
Nukopijuokite toliau pateiktą kodą ir įklijuokite jį į rag.py. Tai išbaigtas, bet minimalus RAG diegimas, kuriame naudojami Perplexity SDK ir ChromaDB vietinės vektorinės duomenų bazės funkcijos.
Štai kas vyks paleidus programą:
- Prisijungia prie Perplexity ir jūsų naujos ChromaDB duomenų bazės.
- Patikrina, ar duomenų bazėje yra indeksuotų dokumentų.
- Priima naudotojo klausimą.
- Siunčia klausimą Perplexity įterpinių modeliui.
- Iškoduoja ir normalizuoja gautą įterpinį naudodama NumPy.
- ChromaDB duomenų bazėje ieško trijų panašiausių dokumento fragmentų.
- Sudaro užklausą, kurioje yra gauti fragmentai ir naudotojo klausimas.
- Siunčia užklausą modeliui GPT-5.6 Luna per Perplexity Agent API.
- Parodo atsakymą ir laukia kito klausimo.
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)6 žingsnis: paleiskite programas
VS Code PowerShell terminale įveskite toliau pateiktą komandą, kad paverstumėte failo document.txt turinį įterpiniais:
.\.venv\Scripts\python.exe index.pyJei dokumentas sėkmingai suindeksuotas, turėtumėte pamatyti panašią išvestį:
Indexing complete!
Unchanged chunks: 0
New or modified chunks: 58
Removed chunks: 0
Total stored chunks: 58Dabar metas paleisti pagrindinę orkestratoriaus programą. Įveskite šią komandą:
.\.venv\Scripts\python.exe rag.pyJei paleidimas bus sėkmingas, pamatysite štai ką:
Connected to existing ChromaDB database.
Stored chunks: 58
Ask a question (or type exit): Dabar galite užduoti klausimus, į kuriuos bus atsakoma remiantis jūsų sukurta vektorine duomenų baze, pavyzdžiui:
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.7 žingsnis: supraskite, ką sukūrėte
Jūsų sukurtoje sistemoje yra du pagrindiniai konvejeriai, būdingi kiekvienai RAG architektūrai: indeksavimo, arba „įkėlimo“, konvejeris ir paieškos bei generavimo konvejeris.
Jūsų paprastas RAG diegimas dabar atlieka visa tai:
- Vektorių saugojimas: Įterpiniai, sukurti pagal jūsų žinių failą, išsaugomi ChromaDB duomenų bazėje jūsų vietinėje aplinkoje.
- Inkrementinis indeksavimas: Nepakitę dokumento fragmentai iš naujo nepaverčiami įterpiniais, o dokumentą galite atnaujinti kada tik norite.
- Semantinė paieška: ChromaDB randa fragmentus pagal vektorių panašumą (paiešką inicijuoja orkestratorius).
- Šaltiniais pagrįstų atsakymų generavimas: LLM gauna rastas ištraukas kaip kontekstą ir panaudoja jas atsakyme.
- Atskiras indeksavimas ir užklausos: Galite užduoti klausimus iš naujo neapdorodami viso jūsų žinių faile esančio teksto.
- Prisijungimas prie modelio per API: Visi atsakymai generuojami naudojant modelį GPT-5.6 Luna per Perplexity, o ne jūsų kompiuteryje veikiantį modelį.
Tolesni žingsniai: kaip toliau plėtoti šį diegimą
Šio vadovo tikslas – sukurti nesudėtingą, paprastą diegimą. Jame aptariami kai kurie pagrindiniai RAG architektūros komponentai, naudojami šiuolaikinėse sistemose. Jei norite žengti toliau, jį galima plėtoti įvairiais būdais.
Štai keletas idėjų, kaip išplėsti savo diegimo galimybes:
- Eksperimentuokite su LangChain: LangChain yra vienas populiariausių atvirojo kodo orkestravimo karkasų. Jame yra iš anksto paruoštų komponentų, skirtų kurti programas, galinčias vykdyti sudėtingus RAG konvejerius.
- Išplėskite paieškos galimybes: Derinkite tankiųjų vektorių paiešką su leksine (raktinių žodžių) paieška, pavyzdžiui, BM25. Pridėję žiniatinklio paiešką per Perplexity Search API, taip pat galėtumėte grįsti atsakymus naujausiais duomenimis.
- Pridėkite pakartotinio reitingavimo modelį: Integruokite pakartotinio reitingavimo modelį, kuris surikiuoja rastas ištraukas pagal pradinę užklausą ir atrenka aktualiausias, kad jos būtų įtrauktos į LLM pateikiamą įvesties kontekstą.
- Sukurkite adaptyviąją RAG sistemą: Adaptyvusis RAG naudoja LLM arba klasifikatorių (orkestratoriaus komponentą), kad nustatytų, kurį paieškos metodą naudoti modulinėje RAG sistemoje. Tokios sistemos kūrimas – puikus būdas susipažinti su sudėtingesniais RAG diegimais.
Nors visa tai gali skambėti sudėtingai, nepamirškite, kad populiarios DI platformos, pavyzdžiui, Perplexity, gali suteikti pažangią pagalbą programuojant. Jos puikiai tinka asmeniniams projektams ir eksperimentams, o išlaidas galima išlaikyti gana mažas.
Pastaba: šiame vadove naudojamas GPT-5.6 Luna. Modelių prieinamumas gali keistis, todėl gali tekti atnaujinti API iškvietimą.