AGI

Construirea de agenți LLM pentru RAG de la zero și dincolo: O ghid cuprinzător

mm
Building LLM Agents for RAG from Scratch and Beyond: A Comprehensive Guide

Modelele LLM, cum ar fi GPT-3, GPT-4 și omologul lor open-source, pot avea dificultăți cu recuperarea informațiilor actualizate și, uneori, pot genera halucinații sau informații incorecte.

Generarea augmentată cu recuperare (RAG) este o tehnică care combină puterea modelelor LLM cu recuperarea cunoștințelor externe. RAG ne permite să ancorăm răspunsurile modelelor LLM în informații factuale și actualizate, îmbunătățind semnificativ acuratețea și fiabilitatea conținutului generat de IA.

În acest articol, vom explora cum să construim agenți LLM pentru RAG de la zero, scufundându-ne adânc în arhitectură, detalii de implementare și tehnici avansate. Vom acoperi totul, de la bazele RAG până la crearea de agenți sofisticați capabili de raționament complex și execuție de sarcini.

Înainte de a ne scufunda în construirea agentului nostru LLM, să înțelegem ce este RAG și de ce este important.

RAG, sau Generarea augmentată cu recuperare, este o abordare hibridă care combină recuperarea informațiilor cu generarea de text. Într-un sistem RAG:

  • O întrebare este utilizată pentru a recupera documente relevante dintr-o bază de cunoștințe.
  • Aceste documente sunt apoi introduse într-un model de limbaj împreună cu întrebarea originală.
  • Modelul generează un răspuns bazat pe întrebare și informațiile recuperate.
RAG

RAG

Această abordare are mai multe avantaje:

  • Acuratețe îmbunătățită: Prin ancorarea răspunsurilor în informații recuperate, RAG reduce halucinațiile și îmbunătățește acuratețea factuală.
  • Informații actualizate: Baza de cunoștințe poate fi actualizată în mod regulat, permițând sistemului să aibă acces la informații curente.
  • Transparență: Sistemul poate furniza surse pentru informațiile sale, crește încrederea și permite verificarea faptelor.

Înțelegerea agenților LLM

 

Când vă confruntați cu o problemă care nu are un răspuns simplu, adesea trebuie să urmați mai multe pași, să gândiți cu atenție și să vă amintiți ce ați încercat deja. Agenții LLM sunt proiectați pentru exact aceste tipuri de situații în aplicațiile modelului de limbaj. Ei combină analiza atentă a datelor, planificarea strategică, recuperarea datelor și capacitatea de a învăța din acțiunile trecute pentru a rezolva probleme complexe.

Ce sunt agenții LLM?

Agenții LLM sunt sisteme avansate de IA proiectate pentru crearea de text complex care necesită raționament secvențial. Ei pot gândi înainte, aminti conversații trecute și utiliza diferite unelte pentru a ajusta răspunsurile în funcție de situație și stil necesar.

Luăm în considerare o întrebare din domeniul juridic, cum ar fi: “Care sunt rezultatele legale potențiale ale unei încălcări a unui anumit tip de contract în California?” Un model LLM de bază cu un sistem RAG poate recupera informațiile necesare din baze de date juridice.

Pentru un scenariu mai detaliat: “În lumina noilor legi privind protecția datelor, care sunt provocările juridice comune cu care se confruntă companiile și cum au abordat instanțele aceste probleme?” Această întrebare se scufundă mai adânc decât simpla căutare de fapte. Este vorba despre înțelegerea noilor reguli, impactului lor asupra diferitelor companii și răspunsurilor instanțelor. Un agent LLM ar divide această sarcin în sub-sarcini, cum ar fi recuperarea ultimelor legi, analiza cazurilor istorice, rezumarea documentelor juridice și previziunea tendințelor pe baza modelelor.

Componentele agenților LLM

Agenții LLM se compun, în general, din patru componente:

  1. Agenț/Creier: Modelul de limbaj de bază care procesează și înțelege limbajul.
  2. Planificare: Capacitatea de a raționa, de a diviza sarcinile și de a dezvolta planuri specifice.
  3. Memorie: Menține înregistrări ale interacțiunilor trecute și învață din ele.
  4. Utilizarea uneltelor: Integrează diverse resurse pentru a efectua sarcini.

Agenț/Creier

La baza unui agent LLM se află un model de limbaj care procesează și înțelege limbajul pe baza unor cantități uriașe de date pe care a fost antrenat. Începeți prin a-i oferi o anumită prompt, ghidând agentul despre cum să răspundă, ce unelte să utilizeze și ce obiective să urmărească. Puteți personaliza agentul cu o persoană potrivită pentru sarcini sau interacțiuni specifice, îmbunătățindu-i performanța.

Memorie

Componenta de memorie ajută agenții LLM să gestioneze sarcini complexe, menținând o înregistrare a acțiunilor trecute. Există două tipuri principale de memorie:

  • Memorie pe termen scurt: Acționează ca o agendă, ținând evidența discuțiilor în desfășurare.
  • Memorie pe termen lung: Funcționează ca un jurnal, stocând informații din interacțiunile trecute pentru a învăța modele și a lua decizii mai bune.

Prin combinarea acestor tipuri de memorie, agentul poate oferi răspunsuri mai personalizate și poate aminti preferințele utilizatorului în timp, creând o interacțiune mai conectată și relevantă.

Planificare

Planificarea permite agenților LLM să raționeze, să divizeze sarcinile în părți gestionabile și să adapteze planurile pe măsură ce sarcinile evoluează. Planificarea implică două etape principale:

  • Formularea planului: Divizarea unei sarcini în sub-sarcini mai mici.
  • Reflecția asupra planului: Revizuirea și evaluarea eficacității planului, integrând feedback-ul pentru a rafina strategiile.

Metode precum Lanțul de gândire (CoT) și Arborele de gândire (ToT) ajută în acest proces de divizare, permițând agenților să exploreze diferite căi pentru a rezolva o problemă.

Pentru a vă scufunda mai adânc în lumea agenților IA, inclusiv capacitățile și potențialul lor actual, luați în considerare citirea articolului “Auto-GPT & GPT-Engineer: O ghidă detaliată despre agenții IA de top de astăzi”

Configurarea mediului

Pentru a construi agentul nostru RAG, trebuie să configurăm mediul nostru de dezvoltare. Vom utiliza Python și câteva biblioteci cheie:

  • LangChain: Pentru orchestrarea componentelor noastre LLM și de recuperare
  • Chroma: Ca magazin de vectori pentru încorporări de documente
  • Modelele GPT ale OpenAI: Ca model LLM de bază (puteți înlocui acesta cu un model open-source, dacă preferați)
  • FastAPI: Pentru crearea unei API simple pentru a interacționa cu agentul nostru

Să începem prin configurarea mediului nostru:


<p># Creați un mediu virtual nou
python -m venv rag_agent_env
source rag_agent_env/bin/activate # Pe Windows, utilizați `rag_agent_env\Scripts\activate`</p>

<p># Instalați pachetele necesare
pip install langchain chromadb openai fastapi uvicorn

Acum, să creăm un fișier Python nou numit rag_agent.py și să importăm bibliotecile necesare:


<p>from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.text_splitter import CharacterTextSplitter
from langchain.llms import OpenAI
from langchain.chains import RetrievalQA
from langchain.document_loaders import TextLoader
import os</p>

<p># Setează cheia dvs. API OpenAI
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;cheia_dvs_api_aici&quot;</p>

Construirea unui sistem RAG simplu

Acum că am configurat mediul nostru, să construim un sistem RAG de bază. Vom începe prin crearea unei baze de cunoștințe dintr-un set de documente, apoi vom utiliza aceasta pentru a răspunde la întrebări.

Etapa 1: Pregătirea documentelor

Mai întâi, trebuie să încărcăm și să pregătim documentele noastre. Pentru acest exemplu, să presupunem că avem un fișier text numit knowledge_base.txt cu unele informații despre IA și învățarea mașinilor.


<p># Încărcați documentul
loader = TextLoader(&quot;knowledge_base.txt&quot;)
documents = loader.load()</p>

<p># Divizați documentele în bucăți
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Creați încorporări
embeddings = OpenAIEmbeddings()</p>

<p># Creați un magazin de vectori
vectorstore = Chroma.from_documents(texts, embeddings)</p>

Etapa 2: Crearea unei lanțuri de întrebări și răspunsuri bazate pe recuperare

Acum că avem magazinul nostru de vectori, putem crea o lanț de întrebări și răspunsuri bazate pe recuperare:


<p># Creați o lanț de întrebări și răspunsuri bazate pe recuperare
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=&quot;stuff&quot;, retriever=vectorstore.as_retriever())</p>

Etapa 3: Interogarea sistemului

Acum putem interoga sistemul nostru RAG:


<p>query = &quot;Care sunt principalele aplicații ale învățării mașinilor?&quot;
result = qa.run(query)
print(result)

Etapa 4: Crearea unui agent LLM

În timp ce sistemul nostru RAG simplu funcționează bine, este destul de limitat. Să îl îmbunătățim prin crearea unui agent LLM care să poată efectua sarcini mai complexe și să raționeze despre informațiile pe care le recuperează.

Un agent LLM este un sistem de IA care poate utiliza unelte și lua decizii despre acțiunile pe care le va întreprinde. Vom crea un agent care să poată nu numai să răspundă la întrebări, dar și să efectueze căutări pe web și calcule de bază.

Mai întâi, să definim câteva unelte pentru agentul nostru:


<p>from langchain.agents import Tool
from langchain.tools import DuckDuckGoSearchRun
from langchain.tools import BaseTool
from langchain.agents import initialize_agent
from langchain.agents import AgentType</p>

<p># Definiți o unealtă de calculator
class CalculatorTool(BaseTool):
name = &quot;Calculator&quot;
description = &quot;Util pentru când aveți nevoie de răspunsuri la întrebări matematice&quot;</p>

<p>def _run(self, query: str)
try:
return str(eval(query))
except:
return &quot;Nu am putut calcula asta. Vă rugăm să vă asigurați că inputul dvs. este o expresie matematică validă.&quot;</p>

<p># Creați instanțe de unelte
search = DuckDuckGoSearchRun()
calculator = CalculatorTool()</p>

<p># Definiți uneltele
tools = [Tool(name=&quot;Search&quot;, func=search.run, description=&quot;Util pentru când aveți nevoie de răspunsuri la întrebări curente&quot;),
Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Util pentru când aveți nevoie de răspunsuri la întrebări despre IA și învățarea mașinilor&quot;),
Tool(name=&quot;Calculator&quot;, func=calculator._run, description=&quot;Util pentru când aveți nevoie de calcule matematice&quot;)
]</p>

<p># Inițializați agentul
agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)</p>

Acum avem un agent care poate utiliza sistemul nostru RAG, efectua căutări pe web și calcule de bază. Să îl testăm:


<p>result = agent.run(&quot;Care este diferența dintre învățarea supervizată și cea nesupervizată? De asemenea, ce este 15% din 80?&quot;)
print(result)</p>

Acest agent demonstrează un avantaj cheie al agenților LLM: ei pot combina multiple unelte și pași de raționament pentru a răspunde la întrebări complexe.

Îmbunătățirea agentului cu tehnici RAG avansate

În timp ce sistemul nostru RAG actual funcționează bine, există câteva tehnici avansate pe care le putem utiliza pentru a-și îmbunătăți performanța:

a) Căutare semantică cu recuperare de pasaje dense (DPR)

În loc de a utiliza o recuperare bazată pe încorporări simple, putem implementa DPR pentru o căutare semantică mai precisă:


<p>from transformers import DPRQuestionEncoder, DPRContextEncoder</p>

<p>question_encoder = DPRQuestionEncoder.from_pretrained(&quot;facebook/dpr-question_encoder-single-nq-base&quot;)
context_encoder = DPRContextEncoder.from_pretrained(&quot;facebook/dpr-ctx_encoder-single-nq-base&quot;)</p>

<p># Funcție pentru a încorpora pasaje
def encode_passages(passages):
return context_encoder(passages, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

<p># Funcție pentru a încorpora întrebarea
def encode_query(query):
return question_encoder(query, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

b) Extinderea întrebării

Putem utiliza extinderea întrebării pentru a îmbunătăți performanța de recuperare:


<p>from transformers import T5ForConditionalGeneration, T5Tokenizer</p>

<p>model = T5ForConditionalGeneration.from_pretrained(&quot;t5-small&quot;)
tokenizer = T5Tokenizer.from_pretrained(&quot;t5-small&quot;)</p>

<p>def expand_query(query):
input_text = f&quot;expand query: {query}&quot;
input_ids = tokenizer.encode(input_text, return_tensors=&quot;pt&quot;)
outputs = model.generate(input_ids, max_length=50, num_return_sequences=3)
expanded_queries = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return expanded_queries</p>

c) Rafinare iterativă

Putem implementa un proces de rafinare iterativă în care agentul poate pune întrebări de urmărire pentru a clarifica sau extinde răspunsul său inițial:


<p>def iterative_retrieval(initial_query, max_iterations=3):
query = initial_query
for _ in range(max_iterations):
result = qa.run(query)
clarification = agent.run(f&quot;Pe baza acestui răspuns: &#039;{result}&#039;, ce întrebare de urmărire ar trebui să pun pentru a obține informații mai specifice?&quot;)
if clarification.lower().strip() == &quot;none&quot;:
break
query = clarification
return result</p>

# Utilizați această funcție în procesul dvs. de agent

Implementarea unui sistem multi-agent

Pentru a gestiona sarcini mai complexe, putem implementa un sistem multi-agent în care diferiți agenți se specializează în domenii diferite. Iată un exemplu simplu:


<p>class SpecialistAgent:
def __init__(self, name, tools):
self.name = name
self.agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)</p>

<p>def run(self, query):
return self.agent.run(query)</p>

<p># Creați agenți specializați
research_agent = SpecialistAgent(&quot;Cercetare&quot;, [Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Pentru întrebări despre IA și învățarea mașinilor&quot;)])
math_agent = SpecialistAgent(&quot;Matematică&quot;, [Tool(name=&quot;Calculator&quot;, func=calculator._run, description=&quot;Pentru calcule&quot;)])
general_agent = SpecialistAgent(&quot;General&quot;, [Tool(name=&quot;Search&quot;, func=search.run, description=&quot;Pentru întrebări generale&quot;)])</p>

<p>class Coordinator:
def __init__(self, agents):
self.agents = agents</p>

<p>def run(self, query):
# Determinați care agent să utilizați
if &quot;calculate&quot; in query.lower() or any(op in query for op in [&#039;+&#039;, &#039;-&#039;, &#039;*&#039;, &#039;/&#039;]):
return self.agents[&#039;Matematică&#039;].run(query)
elif any(term in query.lower() for term in [&#039;ai&#039;, &#039;învățare mașinilor&#039;, &#039;învățare profundă&#039;]):
return self.agents[&#039;Cercetare&#039;].run(query)
else:
return self.agents[&#039;General&#039;].run(query)</p>

<p>coordinator = Coordinator({&#039;Cercetare&#039;: research_agent, &#039;Matematică&#039;: math_agent, &#039;General&#039;: general_agent})</p>

<p># Testați sistemul multi-agent
result = coordinator.run(&quot;Care este diferența dintre rețelele neuronale convolutive și rețelele neuronale recurente? De asemenea, calculați 25% din 120.&quot;)
print(result)</p>

Acest sistem multi-agent permite specializarea și poate gestiona o gamă mai largă de întrebări în mod mai eficient.

Evaluarea și optimizarea agenților RAG

Pentru a ne asigura că agentul nostru RAG funcționează bine, trebuie să implementăm metrice de evaluare și tehnici de optimizare:

a) Evaluarea relevanței

Putem utiliza metrice precum BLEU, ROUGE sau BERTScore pentru a evalua relevanța documentelor recuperate:


<p>from bert_score import score</p>

<p>def evaluate_relevance(query, retrieved_doc, generated_answer):
P, R, F1 = score([generated_answer], [retrieved_doc], lang=&quot;en&quot;)
return F1.mean().item()</p>

b) Evaluarea calității răspunsului

Putem utiliza evaluarea umană sau metrice automate pentru a evalua calitatea răspunsului:


<p>from nltk.translate.bleu_score import sentence_bleu</p>

<p>def evaluate_answer_quality(reference_answer, generated_answer):
return sentence_bleu([reference_answer.split()], generated_answer.split())</p>

<p># Utilizați această funcție pentru a evalua răspunsurile agentului dvs.

Viitoare direcții și provocări

Pe măsură ce ne uităm spre viitorul agenților RAG, apar mai multe direcții și provocări interesante:

a) RAG multi-modal: Extinderea RAG pentru a include date de imagine, audio și video.

b) RAG federat: Implementarea RAG pe baze de cunoștințe distribuite și cu protecție a confidențialității.

c) Învățare continuă: Dezvoltarea metodelor pentru agenții RAG să-și actualizeze bazele de cunoștințe și modelele în timp.

d) Considerații etice: Abordarea problemelor de polarizare, echitate și transparență în sistemele RAG.

e) Scalabilitate: Optimizarea RAG pentru aplicații la scară largă și în timp real.

Concluzii

Construirea de agenți LLM pentru RAG de la zero este un proces complex, dar răsplătitor. Am acoperit bazele RAG, am implementat un sistem simplu, am creat un agent LLM, l-am îmbunătățit cu tehnici avansate, am explorat sisteme multi-agente și am discutat evaluarea și optimizarea.

Am petrecut ultimii cinci ani scufundându-mă în lumea fascinantă a Machine Learning și Deep Learning. Pasinea și expertiza mea m-au condus să contribui la peste 50 de proiecte diverse de inginerie software, cu un focus deosebit pe AI/ML. Curiozitatea mea în continuare m-a atras și spre Natural Language Processing, un domeniu pe care sunt dornic să îl explorez mai departe.