Vienkārša RAG ieviešana: pamācība soli pa solim
Šajā iesācējiem draudzīgajā pamācībā ir paskaidrots, kā darbojas vienkārša RAG ieviešana, apskatīta labākā prakse un soli pa solim parādīts, kā izveidot funkcionējošu komandrindas RAG sistēmu ar Python, ChromaDB un Perplexity iegulumu un valodas modeļiem.

RAG ir būtisks mūsdienu uz LLM balstītas infrastruktūras komponents. Ļaujot MI modeļiem piekļūt ārējiem datiem, tas palīdz risināt tādas problēmas kā halucinācijas un nepilnīgi apmācības dati. Tas arī nozīmē, ka uzņēmumi var izmantot iekšējās zināšanu bāzes, kurās ir sensitīva vai uzņēmumam piederoša informācija.
RAG ieviešana var būt ļoti sarežģīta. Tomēr vienkāršu RAG sistēmu izveidot ir pārsteidzoši viegli. Iesācējiem vienkāršas arhitektūras izveide var palīdzēt saprast, kā RAG darbojas reālajā pasaulē, un kalpot par atspēriena punktu turpmākiem eksperimentiem.
Šajā rakstā mēs ieskicēsim vienkāršu RAG ieviešanu, apskatīsim labāko praksi un pēc tam izveidosim funkcionējošu sistēmu, izmantojot Python, ChromaDB un divus Perplexity modeļus — iegulumu izveidei un atbilžu ģenerēšanai.
Vienkāršas RAG ieviešanas process: vispārīgs pārskats
Vienkāršai RAG sistēmai ir trīs galvenie komponenti: orķestrētājs, informācijas avots un LLM. Tipiskā darbplūsmā lietotājs ievada uzvedni, un orķestrētājs to pārveido, lai veiktu meklēšanu visos pievienotajos informācijas avotos. Pēc tam izgūtā informācija tiek pievienota sākotnējās ievades kontekstam un nosūtīta LLM, lai varētu ģenerēt atbildi.
Veidojot savu RAG ieviešanu, jums būs jāņem vērā šādi soļi:
- Indeksēšana un iegulumu izveide: Šajā posmā jūsu dokumenti tiek pārveidoti informācijas avotā, kurā orķestrētājs var veikt meklēšanu. Viens no izplatītākajiem veidiem, kā to izdarīt, ir izveidot meklējamu vektoru indeksu. Mēs izmantosim īpašu Perplexity modeli, lai pārveidotu jūsu dokumentu fragmentus iegulumos. Pēc tam iegulumus saglabāsim ChromaDB — populārā atvērtā pirmkoda vektoru datubāzē.
- Orķestrēšana: Šī ir lietojumprogramma, kas atrodas starp ārējo informācijas avotu (mūsu gadījumā — vektoru datubāzi) un LLM. Mēs izveidosim vienkāršu Python skriptu, kas darbosies kā orķestrētājs.
- Izguve un ģenerēšana: Kad lietotājs uzdod jautājumu tērzēšanas saskarnē, orķestrētājs to saņems, veiks vektoru meklēšanu un nodos paplašināto ievadi LLM. Tā vietā, lai veidotu atsevišķu lietotāja saskarni, saziņai ar mūsu Python orķestrētāju izmantosim komandrindu.
Labākā prakse: kas padara RAG ieviešanu efektīvu?
Pastāv vairāki RAG arhitektūras veidi, un dažādiem lietošanas gadījumiem nepieciešamas atšķirīgas pieejas. Tomēr vairāki labākās prakses principi ir piemērojami visos gadījumos un nodrošina precīzas, izmaksu ziņā efektīvas, mērogojamas un viegli uzturamas sistēmas.
Šie labākās prakses principi attiecas uz visiem RAG ieviešanas veidiem:
- Nodrošiniet tīru datu uzņemšanas konveijeru: Pirms indeksēšanas avota datiem jābūt pēc iespējas tīrākiem. Jāizmanto arī jūsu saturam piemērots iegulumu modelis.
- Izmantojiet hibrīdmeklēšanu: Labākās izguves metodes — vai tā būtu meklēšana vektoru datubāzē, uz API balstīta tīmekļa meklēšana, zināšanu grafa šķērsošana, atslēgvārdu meklēšana vai citas metodes — atšķiras atkarībā no lietošanas gadījuma. Pareizas kombinācijas izvēle ir svarīga izmaksu samazināšanai.
- Novērtējiet savu sistēmu: Pēc ieviešanas jānovērtē trīs pamatrādītāji: precizitāte, atbilstība un latentums. Precizitāte attiecas uz faktu pareizību, atbilstība — uz to, cik izgūtā informācija ir piemērojama lietotāju vaicājumiem, bet latentums — uz ātrumu, ar kādu informācija tiek izgūta.
- Apstrādājiet informāciju droši: Ja jūsu RAG sistēma izmanto privātu iekšējo informāciju, nodrošiniet, lai tā tiktu glabāta droši un piekļuve sistēmas saskarnei tiktu pārvaldīta. API atslēgas nekad nedrīkst kopīgot ar citiem.
Vienkārša RAG ieviešana: pamācība 7 soļos
Šajā pamācībā mēs izveidosim komandrindas lietojumprogrammu, kas atbild uz jautājumiem par vienu dokumentu. Izmantosim Python, ChromaDB un Perplexity API.
Mērķis nav izveidot ražošanai gatavu RAG sistēmu. Drīzāk tā ir iesācējiem draudzīga pamācība, kas paredzēta, lai ilustrētu, kā elementāra RAG arhitektūra darbojas praksē.
1. solis: instalējiet programmatūru
Pārliecinieties, ka datorā ir instalēts tālāk norādītais un jums ir Perplexity API konts:
- Python: Šo programmēšanas valodu izmantosim, lai izveidotu orķestrētāju, kas koordinēs datu plūsmu starp iegulumu modeli, ChromaDB un Perplexity.
- Visual Studio: Kā koda redaktoru izmantosim Visual Studio. Pēc instalēšanas atveriet paneli Extensions un lejupielādējiet paplašinājumu Python.
- Perplexity API konts: Perplexity nodrošinās gan iegulumu modeli (kas pārveido jūsu datus vektoru iegulumos), gan LLM, kas apstrādās paplašināto uzvedni. Tam nav nepieciešams maksas konts, lai gan tiks iztērēts neliels kredītu apjoms.
2. solis: izveidojiet projekta mapi
Vispirms izveidojiet mapi ar nosaukumu rag-project un atveriet to VS Code, atlasot File > Open Folder. Pēc tam atveriet integrēto termināli, izmantojot Terminal > New Terminal.
Ievadiet tālāk norādīto, lai izveidotu Python virtuālo vidi:
py -3.12 -m venv .venvTagad jāinstalē četras Python bibliotēkas: perplexityai, chromadb, python-dotenv un numpy. Perplexity SDK ļaus jums izveidot savienojumu ar Perplexity modeļiem, izmantojot API. ChromaDB izveido vektoru datubāzi un darbosies lokāli. Python-dotenv droši ielādē jūsu API atslēgas no lokāla faila, un NumPy ir nepieciešams datu uzņemšanas procesā.
Instalējiet tās ar šo komandu:
.\.venv\Scripts\python.exe -m pip install perplexityai chromadb python-dotenv numpy3. solis: sagatavojiet failus
Pievienojiet mapē rag-project (projekta saknes direktorijā) šādus failus, sānjoslā Explorer atlasot New File…:
- index.py: Šī ir lietojumprogramma, kas indeksēs jūsu dokumentu. Varat to palaist atkārtoti, lai pievienotu papildu tekstu.
- rag.py: Šī ir Python lietojumprogramma, kas darbosies kā orķestrētājs.
- document.txt: Šajā failā būs dokumentācija, ko pārveidosiet vektoru datubāzē.
- .env: Šeit glabāsiet savu Perplexity API atslēgu.
Failā .env ievadiet šo:
PERPLEXITY_API_KEY=your_api_key_hereAizstājiet your_api_key_here ar savu īsto atslēgu. Lai to iegūtu, atveriet Perplexity API Console sākuma informācijas paneli un atlasiet Create an API key. Neizpaudiet šo API atslēgu citiem.
Mēs izmantosim divus modeļus: Perplexity pplx-embed-v1-0.6b, lai izveidotu dokumentācijas iegulumus pirms to augšupielādes ChromaDB datubāzē, un GPT-5.6-Luna (pieejams, izmantojot Perplexity API), kas apstrādās izgūto informāciju.
Failā document.txt pievienojiet tekstu, ko izgūs jūsu RAG konveijers. Ja jums nav pieejama piemērota dokumenta, šajā pamācībā izmantojiet Viljama Bleika darbu Songs of Innocence and of Experience no Project Gutenberg. Tas ir īss, viegli saprotams teksts, kas ir publiskajā domēnā.
4. solis: uzrakstiet indeksēšanas programmu
Nokopējiet tālāk redzamo kodu un ielīmējiet to failā index.py. Katrā apakšvirsrakstā ir īss skaidrojums par to, ko dara nākamais koda segments. Šī ir programma, kas, izmantojot Perplexity iegulumu modeli pplx-embed-v1-0.6b un bibliotēku NumPy, pārveidos jūsu avota materiālu vektoru iegulumos un saglabās tos ChromaDB datubāzē.
Lūk, ko dara programma:
- Atver failu document.txt.
- Sadala tekstu fragmentos, kas daļēji pārklājas.
- Nosūta šos fragmentus Perplexity iegulumu modelim pplx-embed-v1-0.6b.
- Dekodē un normalizē atgrieztos vektorus, izmantojot NumPy — Python skaitļošanas funkciju bibliotēku.
- Saglabā vektorus un sākotnējos fragmentus ChromaDB datubāzē (tā parādīsies jūsu projekta direktorijā).
Programma ir iestatīta tā, lai dokuments netiktu indeksēts no jauna katru reizi, kad to palaižat. Ja papildināsiet informāciju failā document.txt, iegulumi tiks izveidoti tikai jaunajam tekstam.
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. solis. Uzrakstiet RAG sistēmas orķestrētāju
Nokopējiet tālāk redzamo kodu un ielīmējiet to failā rag.py. Tā ir pilnīga, taču minimāla RAG ieviešana, kas izmanto Perplexity SDK un ChromaDB lokālās vektoru datubāzes funkcionalitāti.
Lūk, kas notiks, kad palaidīsiet programmu:
- Izveido savienojumu ar Perplexity un jūsu jauno ChromaDB datubāzi.
- Pārbauda, vai datubāzē ir indeksēti dokumenti.
- Pieņem lietotāja jautājumu.
- Nosūta jautājumu Perplexity iegulumu modelim.
- Dekodē un normalizē iegūto iegulumu, izmantojot NumPy.
- Meklē ChromaDB datubāzē trīs līdzīgākos dokumenta fragmentus.
- Izveido uzvedni, kurā ietverti izgūtie fragmenti un lietotāja jautājums.
- Nosūta uzvedni modelim GPT-5.6 Luna, izmantojot Perplexity Agent API.
- Parāda atbildi un gaida nākamo jautājumu.
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. solis: palaidiet lietojumprogrammas
VS Code PowerShell terminālī ievadiet tālāk norādīto, lai izveidotu iegulumus faila document.txt saturam:
.\.venv\Scripts\python.exe index.pyJa dokuments ir veiksmīgi indeksēts, jums vajadzētu redzēt līdzīgu izvadi:
Indexing complete!
Unchanged chunks: 0
New or modified chunks: 58
Removed chunks: 0
Total stored chunks: 58Tagad ir laiks palaist galveno orķestrētāja lietojumprogrammu. Ievadiet šo komandu:
.\.venv\Scripts\python.exe rag.pyJa palaišana būs veiksmīga, redzēsiet šo:
Connected to existing ChromaDB database.
Stored chunks: 58
Ask a question (or type exit): Tagad varat uzdot jautājumus, uz kuriem atbildes tiks meklētas jūsu izveidotajā vektoru datubāzē, piemēram:
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. solis: izprotiet, ko esat izveidojuši
Jūsu izveidotajā sistēmā ir divi pamata konveijeri, kas ir katrā RAG arhitektūrā: indeksēšanas jeb „datu uzņemšanas” konveijers un izguves un ģenerēšanas konveijers.
Jūsu vienkāršā RAG ieviešana tagad veic visu tālāk minēto:
- Vektoru glabāšana: Iegulumi, kas izveidoti no jūsu zināšanu faila, tiek saglabāti ChromaDB datubāzē jūsu lokālajā vidē.
- Inkrementāla indeksēšana: Nemainītajiem dokumenta fragmentiem iegulumi netiek veidoti atkārtoti, un dokumentu varat atjaunināt jebkurā laikā.
- Semantiskā izguve: ChromaDB izgūst fragmentus, pamatojoties uz vektoru līdzību (pēc orķestrētāja pieprasījuma).
- Pamatotu atbilžu ģenerēšana: LLM saņem izgūtos fragmentus kā kontekstu un iekļauj tos atbildē.
- Neatkarīga indeksēšana un vaicāšana: Varat uzdot jautājumus, atkārtoti neapstrādājot visu zināšanu failā ietverto tekstu.
- Savienojums ar modeli, izmantojot API: Visas atbildes tiek ģenerētas ar GPT-5.6 Luna, izmantojot Perplexity, nevis ar modeli, kas darbojas jūsu datorā.
Nākamie soļi: kā attīstīt šo ieviešanu tālāk
Šīs pamācības mērķis ir izveidot vienkāršu, pamata līmeņa ieviešanu. Tā aptver dažus no galvenajiem RAG arhitektūras komponentiem, kas sastopami mūsdienu sistēmās. Ja vēlaties iet tālāk, ir dažādi veidi, kā to papildināt.
Šeit ir dažas idejas, kā paplašināt savas ieviešanas tvērumu:
- Eksperimentējiet ar LangChain: LangChain ir viens no populārākajiem atvērtā pirmkoda orķestrēšanas ietvariem. Tajā ir iepriekš sagatavoti komponenti tādu lietojumprogrammu izveidei, kas spēj darbināt sarežģītus RAG konveijerus.
- Paplašiniet meklēšanas funkcionalitāti: Apvienojiet blīvo vektoru meklēšanu ar leksisko (atslēgvārdu) meklēšanu, piemēram, BM25. Pievienojot tīmekļa meklēšanu, izmantojot Perplexity Search API, varētu arī pamatot atbildes ar aktuāliem datiem.
- Pievienojiet atkārtotas ranžēšanas modeli: Integrējiet atkārtotas ranžēšanas modeli, kas sarindo izgūtos fragmentus pēc to atbilstības sākotnējai uzvednei un atlasa visatbilstošākos, lai tos iekļautu LLM sniegtajā ievades kontekstā.
- Izveidojiet adaptīvu RAG sistēmu: Adaptīvā RAG izmanto vai nu LLM, vai klasifikatoru (orķestrētāja komponentu), lai noteiktu, kuru izguves metodi izmantot modulārā RAG sistēmā. Šādas sistēmas izveide ir labs veids, kā izpētīt sarežģītākas RAG ieviešanas.
Lai gan tas viss var šķist sarežģīti, ņemiet vērā, ka populāras MI platformas, piemēram, Perplexity, var sniegt progresīvu palīdzību programmēšanā. Tās lieliski noder personīgiem projektiem un eksperimentiem, un izmaksas var saglabāt samērā zemas.
Piezīme. Šajā pamācībā tiek izmantots GPT-5.6 Luna. Modeļu pieejamība var mainīties, tāpēc, iespējams, būs jāatjaunina API izsaukums.