Recuperare-Augmented Generation: Configurarea unui magazin de cunoștințe în R

URMĂREȘTE-NE
16,065FaniÎmi place
1,142CititoriConectați-vă

La mulți ani din partea echipei Jumping Rivers!

Pe măsură ce trecem la mijlocul anilor 2020, este un moment bun să reflectăm asupra schimbărilor pe care le-am văzut până acum în acest deceniu. În lumea științei datelor, nimic nu a dominat titlurile ca creșterea rapidă și adoptarea inteligenței artificiale generative (GenAI).

Modelele de limbaj mari (LLM) precum ChatGPT, Claude și Gemini au un potențial incredibil de a eficientiza sarcinile de zi cu zi, fie că este vorba de procesarea unor cantități mari de informații, oferind clienților o interfață de chat asemănătoare omului sau generarea de cod. Dar ele vin și cu riscuri notabile dacă nu sunt valorificate în mod responsabil.

Oricine a interacționat cu aceste modele este probabil să fi întâlnit halucinaţieunde modelul prezintă cu încredere informații false ca și cum ar fi corecte din punct de vedere faptic. Acest lucru se poate întâmpla din mai multe motive:

  • LLM-urile nu au adesea acces la informații în timp real: cum ar ști un model care a fost instruit anul trecut data de astăzi?
  • Datele de instruire ar putea să lipsească informații specifice domeniului: putem avea încredere într-adevăr într-un model standard pentru a avea o bună înțelegere a produselor farmaceutice și a medicamentelor?
  • Modelul poate fi prea dornic să pară inteligent, așa că decide să ofere un rezultat sigur, mai degrabă decât un răspuns mai nuanțat și onest.

Adesea trebuie să oferim modelului acces la informații contextuale suplimentare înainte de a-l putea face „pregătit pentru producție”. Putem realiza acest lucru folosind un generare de recuperare augmentată (RAG) fluxul de lucru. În această postare pe blog vom explora pașii implicați și vom configura un exemplu de flux de lucru RAG folosind pachete gratuite și open source în R.

Ce este RAG?

Într-o interacțiune tipică cu un LLM avem:

  • O solicitare de utilizator: textul trimis de utilizator.

  • Un răspuns: textul care este returnat de LLM.

  • (optional) Un prompt de sistem: instrucțiuni suplimentare despre cum ar trebui să răspundă LLM (de exemplu,
    "You respond in approximately 10 words or less").

Într-un flux de lucru RAG, oferim acces la un magazin de cunoștințe extern, care poate include documente și pagini web bazate pe text. Informațiile contextuale suplimentare sunt apoi preluate din depozitul de cunoștințe (deci „recuperare”) și adăugat la promptul utilizatorului înainte de a fi trimis. Procedând astfel, ne putem aștepta să primim o producție de calitate superioară.

Cum funcționează?

Înainte de a merge mai departe, trebuie mai întâi să introducem conceptul de
vectorizare.

Spre deosebire de ceea ce ați putea crede, LLM-urile nu înțeleg textul non-numeric! Sunt modele matematice, adică pot ingera și scoate doar vectori numerici.

Deci, cum poate un utilizator să interacționeze cu un model folosind limba engleză simplă? Trucul este că există mapări care pot face conversie între vectori numerici și text. Aceste mapări se numesc „înglobare vectorială” și sunt folosite pentru a converti promptul utilizatorului într-o reprezentare vectorială înainte de a fi transmisă la LLM.

Deci, atunci când ne instalăm magazinul de cunoștințe RAG, trebuie să stocăm informațiile folosind o reprezentare vectorială compatibilă. Având în vedere acest lucru, să introducem un flux de lucru tipic RAG:

  1. Conţinut: decidem ce documente să includem în depozitul de cunoștințe.
  2. Extracţie: extragem textul din aceste documente în format Markdown.
  3. Bucățire: conținutul Markdown este împărțit în „bucăți” contextuale (de exemplu, fiecare secțiune sau subsecțiune a unui document poate deveni o bucată).
  4. Vectorizare: bucățile sunt „vectorizate” (adică le convertim într-o reprezentare numerică vectorială).
  5. Index: creăm un index pentru magazinul nostru de cunoștințe care va fi folosit pentru a prelua fragmente relevante de informații.
  6. Recuperare: înregistrăm magazinul de cunoștințe cu interfața modelului nostru. Acum, când un utilizator trimite o solicitare, aceasta va fi combinată cu fragmente relevante de informații înainte de a fi ingerată de model.

La etapa de recuperare, se folosește de obicei un algoritm de potrivire, astfel încât din depozitul de cunoștințe să fie preluate numai fragmente extrem de relevante. În acest fel, suntem capabili să menținem dimensiunea solicitărilor utilizatorului (și orice costuri suportate) la minimum.

Configurarea unui flux de lucru RAG în R

Vom folosi două pachete care sunt disponibile pentru a fi instalate prin Comprehensive R Archive Network (CRAN). Ambele sunt întreținute în mod activ de Posit (fostă RStudio) și sunt libere de instalat și utilizat.

{ragnar}

Pachetul {ragnar} oferă funcții pentru extragerea de informații atât din documente bazate pe text, cât și din pagini web și oferă încorporari vectoriale care sunt compatibile cu furnizorii LLM populari, inclusiv OpenAI și Google.

Vom folosi {ragnar} pentru a ne construi magazinul de cunoștințe.

{ellmer}

Pachetul {ellmer} ne permite să interacționăm cu o varietate de API-uri LLM de la R. O listă completă a furnizorilor de modele acceptați poate fi găsită în documentația pachetului.

Rețineți că, deși {ellmer} poate fi instalat și utilizat gratuit, va trebui totuși să configurați un token API cu furnizorul dvs. de model preferat înainte de a putea interacționa cu orice model. Vom folosi nivelul gratuit Google Gemini pentru exemplul nostru de flux de lucru. Consultați documentația Gemini API pentru crearea unei chei API și documentația {ellmer} pentru autentificarea cu cheia dvs. API de la R.

Exemplu de flux de lucru RAG

Începem prin a încărca pachetul {ragnar}.

library("ragnar")

URL-ul furnizat mai jos face legătura cu pagina de titlu a manualului „Programare eficientă R”, scris de Robin Lovelace și propriul nostru Colin Gillespie. Vom folosi câteva capitole din carte pentru a construi un magazin de cunoștințe RAG.

url = "https://csgillespie.github.io/efficientR/"

Să folosim {ragnar} pentru a citi conținutul acestei pagini într-un format Markdown.

md = read_as_markdown(url)

Am putea vectoriza aceste informații așa cum sunt, dar mai întâi ar trebui să le împărțim în bucăți contextuale.

chunks = markdown_chunk(md)
chunks
#> # @document@origin: https://csgillespie.github.io/efficientR/
#> # A tibble: 2 × 4
#> start end context text 
#> *     
#> 1 1 1572 "" "# Efficient R programmin…
#> 2 597 2223 "# Welcome to Efficient R Programming" "## Authorsnn(Colin Gil…

Bucățile sunt stocate într-un format tibble, cu un rând pe bucată. The
text coloana stochează textul fragmentului (pentru a economisi spațiu, am inclus doar începutul fiecărei părți în rezultatul tipărit de mai sus).

Pagina de titlu a fost împărțită în două bucăți și putem vedea că există o suprapunere semnificativă (porțiunea 1 se întinde pe caracterele de la 1 la 1572 și porțiunea 2 se întinde pe caracterele de la 597 la 2223). Bucățile suprapuse sunt perfect normale și oferă context suplimentar cu privire la locul în care se află fiecare bucată în raport cu celelalte bucăți.

Rețineți că puteți inspecta vizual bucățile rulând
ragnar_chunks_view(chunks).

Este timpul să ne construim magazinul de cunoștințe cu o încorporare vectorială adecvată pentru modelele Google Gemini.

# Initialise a knowledge store with the Google Gemini embedding
store = ragnar_store_create(
 embed = embed_google_gemini()
)

# Insert the Markdown chunks
ragnar_store_insert(store, chunks)

Bucățile Markdown sunt convertite automat într-o reprezentare vectorială la pasul de inserare. Este important să folosim încorporarea vectorială adecvată atunci când creăm magazinul. Un magazin de cunoștințe creat folosind o încorporare OpenAI nu va fi compatibil cu modelele Google Gemini!

Înainte de a putea prelua informații din magazinul nostru, trebuie să creăm un index de magazin.

ragnar_store_build_index(store)

Acum putem testa capacitățile de recuperare ale magazinului nostru de cunoștințe folosind ragnar_retreive() funcţie. De exemplu, pentru a prelua orice fragmente relevante pentru text Cine sunt autorii cărții „Programare eficientă R”? putem rula:

relevant_knowledge = ragnar_retrieve(
 store,
 text = "Who are the authors of "Efficient R Programming"?"
)
relevant_knowledge
#> # A tibble: 1 × 9
#> origin doc_id chunk_id start end cosine_distance bm25 context text 
#>         
#> 1 https://csgi… 1  1 2223   "" "# E…

Rețineți că operatori în "Efficient R Programming" au fost folosite pentru a tipări ghilimele duble brute în șirul de caractere.

Fără a intra în prea multe detalii, cosine_distance şi bm25
coloanele din tibble returnat oferă informații referitoare la algoritmul de potrivire utilizat pentru a identifica bucățile. Celelalte coloane se referă la locația și conținutul bucăților.

Din tibble de ieșire vedem că întregul conținut al paginii de titlu (caracterele de la 1 la 2223) a fost returnat. Acest lucru se datorează faptului că cele două bucăți originale conțineau ambele informații despre autori.

Să adăugăm un capitol mai tehnic din manual în magazinul de cunoștințe. URL-ul furnizat mai jos face legătura cu Capitolul 7 („Optimizare eficientă”). Să adăugăm acest lucru în magazinul de cunoștințe și să reconstruim indexul.

url = "https://csgillespie.github.io/efficientR/performance.html"

# Extract Markdown content and split into chunks
chunks = url |>
 read_as_markdown() |>
 markdown_chunk()

# Add the chunks to the knowledge store
ragnar_store_insert(store, chunks)

# Rebuild the store index
ragnar_store_build_index(store)

Acum că magazinul nostru de cunoștințe include conținut atât din pagina de titlu, cât și din capitolul 7, să întrebăm ceva mai tehnic, cum ar fi Care sunt câteva bune practici pentru calculul paralel în R?.

relevant_knowledge = ragnar_retrieve(
 store,
 text = "What are some good practices for parallel computing in R?"
)
relevant_knowledge
#> # A tibble: 4 × 9
#> origin doc_id chunk_id start end cosine_distance bm25 context text 
#>         
#> 1 https://csgi… 1  1 2223   "" "# E…
#> 2 https://csgi… 2  1 1536   "" "# 7…
#> 3 https://csgi… 2  22541 23995   "# 7 E… "## …
#> 4 https://csgi… 2  23996 26449   "# 7 E… "The…

Au fost returnate patru bucăți:

Este logic că avem fragmente din Secțiunea 7.5, care pare a fi foarte relevantă pentru întrebare. Prin includerea paginii de titlu și începutul capitolului 7, LLM va avea acces și la metadate utile în cazul în care utilizatorul dorește să afle de unde își obține modelul informațiile.

Acum că am construit și testat instrumentul nostru de recuperare, este timpul să îl conectăm la o interfață Gemini folosind {ellmer}. Codul de mai jos va crea un chat obiect care ne permite să trimitem solicitări de utilizator către Gemeni.

chat = ellmer::chat_google_gemini(
 system_prompt = "You answer in approximately 10 words or less."
)

Un prompt de sistem a fost inclus aici pentru a asigura un răspuns succint din partea modelului API.

Putem înregistra această interfață de chat cu instrumentul nostru de recuperare.

ragnar_register_tool_retrieve(chat, store)

Pentru a verifica dacă fluxul nostru de lucru RAG a fost configurat corect, să discutăm cu modelul.

chat$chat("What are some good practices for parallel computing in R?")
#> Use the `parallel` package, ensure you stop clusters with `stopCluster()` (or 
#> `on.exit()`), and utilize `parLapply()`, `parApply()`, or `parSapply()`.

Ieșirea pare plauzibilă. Doar pentru a ne asigura, haideți să verificăm de unde modelul a aflat aceste informații.

chat$chat("Where did you get that answer from?")
#> I retrieved the information from "Efficient R programming" by Colin Gillespie 
#> and Robin Lovelace.

Succes! LLM a identificat numele manualului și dacă am dori, am putea chiar să întrebăm despre capitolul specific. Un utilizator care interacționează cu interfața modelului nostru ar putea acum să caute online acest manual pentru a verifica răspunsurile.

În exemplul de flux de lucru de mai sus, am selectat manual câteva capitole din manual pentru a le include în magazinul nostru de cunoștințe. Este demn de remarcat faptul că puteți utiliza și ragnar_find_links(url) funcția de a prelua o listă de link-uri de la o anumită pagină web.

Dacă faceți acest lucru pentru pagina de titlu, veți furniza link-uri către toate capitolele.

ragnar_find_links("https://csgillespie.github.io/efficientR/")
#> (1) "https://csgillespie.github.io/efficientR/" 
#> (2) "https://csgillespie.github.io/efficientR/building-the-book-from-source.html"
#> (3) "https://csgillespie.github.io/efficientR/collaboration.html" 
#> (4) "https://csgillespie.github.io/efficientR/data-carpentry.html" 
#> (5) "https://csgillespie.github.io/efficientR/hardware.html" 
#> (6) "https://csgillespie.github.io/efficientR/index.html" 
#> (7) "https://csgillespie.github.io/efficientR/input-output.html" 
#> (8) "https://csgillespie.github.io/efficientR/introduction.html" 
#> (9) "https://csgillespie.github.io/efficientR/learning.html" 
#> (10) "https://csgillespie.github.io/efficientR/performance.html" 
#> (11) "https://csgillespie.github.io/efficientR/preface.html" 
#> (12) "https://csgillespie.github.io/efficientR/programming.html" 
#> (13) "https://csgillespie.github.io/efficientR/references.html" 
#> (14) "https://csgillespie.github.io/efficientR/set-up.html" 
#> (15) "https://csgillespie.github.io/efficientR/workflow.html"

Puteți apoi să repetați aceste link-uri, extragând conținutul din fiecare pagină web și inserându-le în magazinul dvs. de cunoștințe RAG. Rețineți, totuși, că includerea de informații suplimentare în magazinul dvs. va crește probabil cantitatea de text trimisă către model, ceea ce ar putea crește costurile. Prin urmare, ar trebui să vă gândiți la ce informații sunt de fapt relevante pentru aplicația dvs. LLM.

Rezumat

În rezumat, am introdus conceptul de generare îmbunătățită prin recuperare pentru fluxurile de lucru bazate pe LLM și am construit un exemplu de flux de lucru în R folosind pachete open source.

Înainte de a termina, suntem încântați să anunțăm că noul nostru curs „LLM-Driven Applications with R & Python” tocmai a fost adăugat la portofoliul nostru de formare. Îl poți căuta aici.

Dacă sunteți interesat de fluxuri de lucru practice bazate pe AI, ne-ar plăcea să vă vedem la viitoarea noastră conferință AI In Production 2026, care se desfășoară în perioada 4-5 iunie la Newcastle-Upon-Tyne. Dacă doriți să prezentați o discuție sau un workshop, vă rugăm să trimiteți rezumatele înainte de termenul limită de pe 23 ianuarie.

Pentru actualizări și revizuiri ale acestui articol, consultați postarea inițială

Dominic Botezariu
Dominic Botezariuhttps://www.noobz.ro/
Creator de site și redactor-șef.

Cele mai noi știri

Pe același subiect

LĂSAȚI UN MESAJ

Vă rugăm să introduceți comentariul dvs.!
Introduceți aici numele dvs.