Előzőleg írtam arról, hogy mikor indokolt, mikor válasszunk lokális AI munkállomást, illetve milyen hardver szükséges egy lokális LLM futtatásához.
Most jöjjön egy könnyed kisérlet: tanítani szeretnénk egy lokálisan futtatott LLM modellt, hogy az általunk betáplált adatok (egyszerű dataset) alapján válaszoljon specifikus kérdésekre, csakis a betáplált adatokból, hogy kizárjuk a tárgyi tévedéseket, hallucinációt.
A mesterséges intelligencia és a természetes nyelvfeldolgozás (NLP) területén egyre világosabbá válik, hogy önmagában egy nagy nyelvi modell (LLM) használata legtöbbször nem elégséges a specifikus és releváns válaszok generálásához. Még a llama3.2-hez hasonló erős modellek sem tudnak mindig naprakész vagy speciális információkat nyújtani. Erre kínál megoldást a Retrieval Augmented Generation (RAG), amely ötvözi a lekérdezési rendszerek és az LLM-ek képességeit.
Ebben a bejegyzésben megmutatom, mi is az a RAG, és hogyan működik az Ollama llama3.2 modell és a ChromaDB kombinációjával. Ez a párosítás lehetővé teszi, hogy az AI válaszai pontosabbak, kontextusban gazdagabbak és tényszerűek legyenek.
Mi az a Retrieval Augmented Generation (RAG)?
A RAG lényege, hogy egy külső forrásból (például adatbázisból) származó releváns információkkal bővíti ki az LLM-ek generálási képességeit. Ahelyett, hogy egy modell kizárólag az előzetesen betanított tudására támaszkodna, a RAG egy külső adatbázisba küld lekérdezéseket, majd a kapott információkat felhasználja a válasz generálásához.
Példa: Ha egy kérdést teszel fel az AI-nak, ahelyett, hogy az LLM a meglévő tudására alapozva próbálna válaszolni, először releváns adatokat keres a ChromaDB-ben. Ezeket az adatokat kontextusként használva hozza létre a végső választ, amely így nemcsak pontosabb, de alátámasztható is lesz.
Miért érdemes kombinálni az Ollama llama3.2-t a ChromaDB-vel?
Az Ollama llama3.2 egy erőteljes és sokoldalú nyelvi modell, amely kiváló szöveggenerálási képességekkel rendelkezik. Ugyanakkor, mint minden LLM, ez is csak azokkal az adatokkal tud dolgozni, amelyeket a betanítás során látott. A ChromaDB ezzel szemben egy hatékony szöveges adatbázis, amely képes gyorsan visszakeresni a releváns információkat.
A kettő kombinációja lehetővé teszi, hogy a llama3.2 olyan információkra is alapozzon, amelyek frissek, specifikusak és közvetlenül elérhetők az adatbázisban. Ez különösen hasznos lehet olyan helyzetekben, ahol pontosság és tényszerűség kiemelten fontos – például kutatási eszközöknél vagy kérdés-válasz rendszerekben.
Hogyan működik a RAG az Ollama és a ChromaDB segítségével?
- Adatok tárolása: A dokumentumokat metaadatokkal (pl. oldalszám, forrásazonosító) együtt tárolod a ChromaDB-ben.
- Lekérdezés: Amikor a felhasználó kérdést tesz fel, a ChromaDB-t lekérdezed, hogy megtaláld a legrelevánsabb információkat.
- Kontextus összeállítása: A ChromaDB által visszaküldött szövegdarabokat és metaadatokat előkészíted, hogy kontextust adj az LLM-nek.
- Válasz generálása: Az Ollama llama3.2 modell a kapott információk alapján generál választ.
- Metaadatok visszacsatolása: A válasz tartalmazza a releváns forrásokat és a metaadatokat (pl. oldalszámot vagy dokumentumazonosítót).
A RAG előnyei és felhasználási területei
A RAG megközelítés jelentősen javítja az AI által generált válaszok minőségét. A válaszok nemcsak relevánsabbak, hanem ellenőrizhetőek is, mivel konkrét forrásokra támaszkodnak. Ez különösen fontos az alábbi esetekben:
- Kérdés-válasz rendszerek: Pontos és bizonyítékokkal alátámasztott válaszokat nyújt.
- Kutatási eszközök: Gyors hozzáférést biztosít a releváns információkhoz.
- Oktatási platformok: Valós idejű, naprakész válaszokat kínál diákoknak és tanároknak.
RAG implementálása Pythonban
1. A szükséges csomagok telepítése
pip install chromadb
pip install ollama
Először telepítsük a ChromaDB-t és az Ollama Python-csomagokat. Ezek felelnek a dokumentumok tárolásáért és a nyelvi modellel való kommunikációért. A pip
parancs a Python csomagkezelője, amely segít az ilyen csomagok egyszerű telepítésében. Telepítés után ellenőrizzük a verziókat:
2. ChromaDB beállítása
A telepítések után lássuk a Python szkriptet. Elsőként inicializáljuk a ChromaDB-t, ami egy adatbázisként fog működni a dokumentumok számára. Az inicializáció során megadjuk, hogy hol és milyen formában tárolja az adatokat, például memóriában vagy fájlrendszerben. Ezután elmentjük a feldolgozandó dokumentumokat az adatbázisba, hogy később könnyen elérhetők legyenek.
3. ChromaDB lekérdezése
A ChromaDB-t használjuk a releváns dokumentumok kinyerésére. Ez azt jelenti, hogy egy lekérdezés alapján megkeressük azokat a dokumentumokat, amelyek a legjobban illeszkednek a kérdéshez. Ez a folyamat a ChromaDB beépített vektorkeresési algoritmusát használja, amely nagyon gyors és pontos eredményeket ad.
4. Adatok simítása
Mivel a ChromaDB eredményei listákban térnek vissza, ezeket laposabb struktúrába rendezzük, kisimítjuk. Ez segít abban, hogy a nyers adatokat könnyebben feldolgozhassuk a következő lépésben, például egy nyelvi modellnek való átadás során. Ez a folyamat általában a kapott adatok újraformázását és tisztítását jelenti.
5. A RAG folyamat összeállítása
A RAG (Retrieval-Augmented Generation) folyamatot az alábbi módon valósítjuk meg: először lekérdezzük a ChromaDB-ből a releváns dokumentumokat, majd ezeket a nyelvi modellhez továbbítjuk, hogy a dokumentumok alapján választ generáljunk. Ez a megközelítés biztosítja, hogy a modell pontos, kontextushoz illeszkedő válaszokat adjon, miközben a háttérben elérhető információkat is kihasználja.
6. A rendszer prompt meghatározása
A rendszer prompt biztosítja, hogy a válasz generálása kontextusban maradjon, és hivatkozzon a releváns forrásokra:
SYSTEM_PROMPT = """
Egy segítőkész AI asszisztens vagy, aki kizárólag a megadott kontextus alapján válaszol.
Minden válaszban az alábbiakat add meg:
1. Idézd közvetlenül a releváns szöveget bizonyítékként.
2. Tüntesd fel az idézett szöveg forrását, beleértve az oldalszámot vagy más elérhető metaadatot.
3. Légy a lehető legrövidebb és lényegre törő.
Ha nem tudod, vagy a kontextus nem tartalmaz elegendő információt, azt írd: "Nem tudom."
Kontextus:
"""
A teljes, működő Python kód
# rag_chroma.py
import chromadb
import ollama
# ChromaDB kliens inicializálása
chroma_client = chromadb.PersistentClient(path="./")
# Gyűjtemény létrehozása vagy lekérése
collection = chroma_client.get_or_create_collection(name="gyujtemeny_0")
# Funkció a szöveges adatok és metaadatok feltöltésére a ChromaDB-be
def upsert_into_chromadb(chunks, metadata):
# Dokumentumok feltöltése metaadatokkal és egyedi azonosítókkal
collection.add(
documents=chunks,
metadatas=metadata,
ids=[f"chunk_{i+1}" for i in range(len(chunks))] # Egyedi azonosítók, pl. "chunk_1", "chunk_2", stb.
)
# ChromaDB lekérdezése
def query_chromadb(prompt, n_results=3):
# A ChromaDB beágyazást készít a lekérdezéshez, és visszakeresi a legjobban illeszkedő részeket
results = collection.query(
query_texts=[prompt], # A ChromaDB elkészíti az embed beágyazást
n_results=n_results,
include=["documents", "metadatas"] # A találatok között legyenek a dokumentumok és metaadatok is
)
return results
# Dokumentumok listájának kisimítása
def flatten_documents(documents):
return [mondat for dokumentum in documents for mondat in dokumentum]
# Metaadatok listájának kisimítása
def flatten_metadatas(metadatas):
return [meta for meta_lista in metadatas for meta in meta_lista]
# A RAG folyamat: Visszakeresés + Generálás
def rag_process(prompt, SYSTEM_PROMPT, filename):
# Szöveges adatok és metaadatok definiálása
chunks = [
"Pán Péter egy kitalált karakter, akit J. M. Barrie skót író, drámaíró hozott létre...",
"Pán Péter a Sohaországban élő fiú, aki nem akar felnőni...",
"Pán Péter bátor és kalandvágyó, gyakran küzd meg Hook kapitánnyal...",
"Wendy Darling a londoni lány, aki testvéreivel együtt Sohaországba utazik. Végül visszatér a való világba...",
"Pán Péter elviszi Wendy Darlingot és testvéreit Sohaországba, ahol izgalmas kalandokat élnek át...",
"Pán Péter történetében fontos szereplő még Tiger Lily, egy indián hercegnő...",
"Pán Péter történetét számos filmben, színdarabban és könyvben feldolgozták...",
"Pán Péter egy jóképű fiatalember."
]
metadata = [
{"oldal": "1. oldal"}, {"oldal": "2. oldal"}, {"oldal": "3. oldal"},
{"oldal": "4. oldal"}, {"oldal": "5. oldal"}, {"oldal": "6. oldal"},
{"oldal": "7. oldal"}, {"oldal": "8. oldal"}
]
# 1. Szövegdarabok feltöltése a ChromaDB-be metaadatokkal (oldalszámokkal)
upsert_into_chromadb(chunks, metadata)
# 2. A ChromaDB lekérdezése a prompt alapján releváns szövegekért
chromadb_results = query_chromadb(prompt, n_results=3)
# Dokumentumok és metaadatok laposítása
flat_chunks = flatten_documents(chromadb_results["documents"])
flat_metadata = flatten_metadatas(chromadb_results["metadatas"])
# A releváns szövegrészek összeállítása forrásokkal együtt
retrieved_chunks = []
for i, chunk in enumerate(flat_chunks):
if i < len(flat_metadata):
metadata_entry = flat_metadata[i]
# A szöveg és forrásának hozzáadása, ha van metaadat
if metadata_entry and isinstance(metadata_entry, dict):
retrieved_chunks.append(f"{chunk} (Forrás: {metadata_entry.get('oldal', 'Nincs elérhető oldal')})")
else:
retrieved_chunks.append(f"{chunk} (Forrás: Metaadat hiányzik)")
else:
retrieved_chunks.append(f"{chunk} (Forrás: Nincs elérhető metaadat)")
# A visszakeresett szövegrészek összefűzése
full_retrieved_chunks = " ".join(retrieved_chunks)
# 3. Az LLM használata válasz generálására (generálási folyamat)
response = ollama.chat(
model="llama3.2",
messages=[
{
"role": "system",
"content": f"{SYSTEM_PROMPT}\nKontekxtus:\n{full_retrieved_chunks}"
},
{
"role": "user",
"content": f"Válaszolj erre a kérdésre: {prompt}. Kérlek, tüntesd fel a forrásokat is a válaszodban."
}
]
)["message"]["content"]
return response
def main():
SYSTEM_PROMPT = """
Egy segítőkész AI asszisztens vagy, aki kizárólag a megadott kontextus alapján válaszol.
Minden válaszban az alábbiakat add meg:
1. Idézd közvetlenül a releváns szöveget bizonyítékként.
2. Tüntesd fel az idézett szöveg forrását, beleértve az oldalszámot vagy más elérhető metaadatot.
3. Légy a lehető legrövidebb és lényegre törő.
Ha nem tudod, vagy a kontextus nem tartalmaz elegendő információt, írd: "Nem tudom."
Kontextus:
"""
prompt = "Kik a történet szereplői?"
# A RAG folyamat végrehajtása: releváns szövegrészek keresése és válasz generálása
response = rag_process(prompt, SYSTEM_PROMPT, 'pan_peter')
print("Kérdés:")
print(prompt)
print("Generált válasz:")
print(response)
if __name__ == '__main__':
main()
# A Python kód futtatásakor kapott kimenet:
# Kérdés:
# Kik a történet szereplői?
# Generált válasz:
# A Pán Péter történet fontos szereplői között megtalálható "Pán Péter" (Forrás: 7. oldal), "Tiger Lily, egy indián hercegnő" (Forrás: 6. oldal), és "Wendy Darling, a londoni lány" (Forrás: 4. oldal).
Következtetés
A Retrieval Augmented Generation (RAG) egy hatékony módszer az AI által generált tartalmak pontosabbá és relevánsabbá tételére. Az Ollama llama3.2 és a ChromaDB kombinációjával az AI nemcsak a kiadásáig betanított tudásra támaszkodik, hanem képes valós idejű, általunk validált, specifikus adatokból meríteni.
Ez a megközelítés különösen hasznos olyan helyzetekben, ahol fontos a tényszerű pontosság és az alátámasztott válaszok biztosítása. A RAG segítségével az AI-generált tartalmak jövője intelligensebb, relevánsabb és megbízhatóbb.