AGI en toekomstige AI

Het bouwen van LLM-agents voor RAG van scratch en verder: een uitgebreide gids

mm
Voeg Unite.AI toe aan je voorkeursbronnen op Google

LLM’s zoals GPT-3, GPT-4 en hun open-source tegenhanger hebben moeite met het opvragen van up-to-date informatie en kunnen soms hallucinaties of onjuiste informatie genereren.

Retrieval-Augmented Generation (RAG) is een techniek die de kracht van LLM’s combineert met externe kennisopvraging. RAG stelt ons in staat om LLM-antwoorden te baseren op feitelijke, up-to-date informatie, waardoor de nauwkeurigheid en betrouwbaarheid van door AI gegenereerde inhoud aanzienlijk verbeterd wordt.

In dit blogbericht zullen we onderzoeken hoe we LLM-agents voor RAG van scratch kunnen bouwen, waarbij we diep duiken in de architectuur, implementatiedetails en geavanceerde technieken. We zullen alles behandelen, van de basis van RAG tot het creëren van geavanceerde agents die in staat zijn om complexe redeneringen en taakuitvoeringen uit te voeren.

Voordat we onze LLM-agent gaan bouwen, laten we eerst begrijpen wat RAG is en waarom het belangrijk is.

RAG, of Retrieval-Augmented Generation, is een hybride benadering die informatieopvraging combineert met tekstgeneratie. In een RAG-systeem:

  • Een query wordt gebruikt om relevante documenten op te halen uit een kennisbasis.
  • Deze documenten worden vervolgens ingevoerd in een taalmodel samen met de oorspronkelijke query.
  • Het model genereert een antwoord op basis van zowel de query als de opgehaalde informatie.
RAG

RAG

Deze benadering heeft verschillende voordelen:

  • Verbeterde nauwkeurigheid: Door antwoorden te baseren op opgehaalde informatie, vermindert RAG hallucinaties en verbetert de feitelijke nauwkeurigheid.
  • Up-to-date informatie: De kennisbasis kan regelmatig worden bijgewerkt, waardoor het systeem toegang heeft tot actuele informatie.
  • Transparantie: Het systeem kan bronnen voor zijn informatie verstrekken, waardoor vertrouwen toeneemt en feiten kunnen worden gecontroleerd.

LLM-agents begrijpen

 

Wanneer je een probleem tegenkomt met geen eenvoudig antwoord, moet je vaak verschillende stappen volgen, zorgvuldig nadenken en onthouden wat je al hebt geprobeerd. LLM-agents zijn ontworpen voor precies dit soort situaties in taalmodeltoepassingen. Ze combineren grondige gegevensanalyse, strategische planning, gegevensopvraging en de mogelijkheid om van eerdere acties te leren om complexe problemen op te lossen.

Wat zijn LLM-agents?

LLM-agents zijn geavanceerde AI-systemen die zijn ontworpen voor het creëren van complexe tekst die sequentiële redenering vereist. Ze kunnen vooruitdenken, eerdere conversaties onthouden en verschillende tools gebruiken om hun antwoorden aan te passen op basis van de situatie en stijl die nodig is.

Overweeg een vraag in het juridische veld, zoals: “Wat zijn de potentiële juridische gevolgen van een specifiek type contractbreuk in Californië?” Een basis-LLM met een RAG-systeem kan de noodzakelijke informatie ophalen uit juridische databases.

Voor een meer gedetailleerd scenario: “In het licht van nieuwe gegevensbeschermingswetten, wat zijn de meest voorkomende juridische uitdagingen waarmee bedrijven worden geconfronteerd, en hoe hebben rechtbanken deze kwesties aangepakt?” Deze vraag gaat dieper dan alleen feiten opzoeken. Het gaat om het begrijpen van nieuwe regels, hun impact op verschillende bedrijven en de reacties van de rechtbanken. Een LLM-agent zou deze taak opsplitsen in subtaken, zoals het ophalen van de laatste wetten, het analyseren van historische gevallen, het samenvatten van juridische documenten en het voorspellen van trends op basis van patronen.

Componenten van LLM-agents

LLM-agents bestaan over het algemeen uit vier componenten:

  1. Agent/Brein: Het centrale taalmodel dat taal verwerkt en begrijpt.
  2. Planning: De mogelijkheid om te redeneren, taken op te splitsen en specifieke plannen te ontwikkelen.
  3. Geheugen: Houdt een record bij van eerdere interacties en leert ervan.
  4. Toolgebruik: Integreert verschillende bronnen om taken uit te voeren.

Agent/Brein

Het centrale taalmodel van een LLM-agent is een taalmodel dat taal verwerkt en begrijpt op basis van grote hoeveelheden data waarop het is getraind. Je begint met het geven van een specifieke prompt, waarmee je de agent aanwijst hoe hij moet reageren, welke tools hij moet gebruiken en welke doelen hij moet nastreven. Je kunt de agent aanpassen met een persona die geschikt is voor specifieke taken of interacties, waardoor de prestaties worden verbeterd.

Geheugen

De geheugencomponent helpt LLM-agents om complexe taken aan te pakken door een record bij te houden van eerdere acties. Er zijn twee hoofdtypen geheugen:

  • Kortetermijngeheugen: Functie als een notitieblok, waarin de lopende discussies worden bijgehouden.
  • Langetermijngeheugen: Functie als een dagboek, waarin informatie uit eerdere interacties wordt opgeslagen om patronen te leren en betere beslissingen te nemen.

Door deze typen geheugen te combineren, kan de agent meer aangepaste antwoorden bieden en gebruikersvoorkeuren onthouden over tijd, waardoor een meer verbonden en relevantie interactie ontstaat.

Planning

Planning stelt LLM-agents in staat om te redeneren, taken op te splitsen in beheersbare delen en plannen aan te passen naarmate taken evolueren. Planning omvat twee hoofdstadia:

  • Planformulering: Het opspliten van een taak in kleinere subtaken.
  • Planreflectie: Het beoordelen en evalueren van de effectiviteit van het plan, met feedback om strategieën te verfijnen.

Methoden zoals de Chain of Thought (CoT) en Tree of Thought (ToT) helpen bij dit decompositieproces, waardoor agents verschillende paden kunnen verkennen om een probleem op te lossen.

Om dieper in de wereld van AI-agents te duiken, inclusief hun huidige mogelijkheden en potentieel, overweeg het lezen van “Auto-GPT & GPT-Engineer: Een diepgaande gids voor de toonaangevende AI-agents van vandaag”

De omgeving instellen

Om onze RAG-agent te bouwen, moeten we onze ontwikkelomgeving instellen. We zullen Python en verschillende belangrijke bibliotheken gebruiken:

  • LangChain: Voor het orkestreren van onze LLM- en opvragingscomponenten
  • Chroma: Als onze vectoropslag voor documentembeddings
  • OpenAI’s GPT-modellen: Als onze basis-LLM (u kunt dit vervangen door een open-source model als u dat verkiest)
  • FastAPI: Voor het maken van een eenvoudige API om met onze agent te communiceren

Laten we beginnen met het instellen van onze omgeving:


<p># Maak een nieuwe virtuele omgeving
python -m venv rag_agent_env
source rag_agent_env/bin/activate # Op Windows, gebruik `rag_agent_env\Scripts\activate`</p>

<p># Installeer de vereiste pakketten
pip install langchain chromadb openai fastapi uvicorn

Maak nu een nieuw Python-bestand met de naam rag_agent.py en importeer de noodzakelijke bibliotheken:


<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># Stel uw OpenAI-API-sleutel in
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;your-api-key-here&quot;</p>

Een eenvoudig RAG-systeem bouwen

Nu we onze omgeving hebben ingesteld, laten we een basis-RAG-systeem bouwen. We beginnen met het maken van een kennisbasis van een set documenten en gebruiken deze om queries te beantwoorden.

Stap 1: Documenten voorbereiden

Eerst moeten we onze documenten laden en voorbereiden. Laten we aannemen dat we een tekstbestand hebben met de naam knowledge_base.txt met enkele informatie over AI en machine learning.


<p># Laad het document
loader = TextLoader(&quot;knowledge_base.txt&quot;)
documents = loader.load()</p>

<p># Split het document in stukken
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Maak embeddings
embeddings = OpenAIEmbeddings()</p>

<p># Maak een vectoropslag
vectorstore = Chroma.from_documents(texts, embeddings)</p>

Stap 2: Een opvragingsgebaseerde QA-keten maken

Nu we onze vectoropslag hebben, kunnen we een opvragingsgebaseerde QA-keten maken:


<p># Maak een opvragingsgebaseerde QA-keten
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=&quot;stuff&quot;, retriever=vectorstore.as_retriever())</p>

Stap 3: Het systeem opvragen

We kunnen nu onze RAG-agent opvragen:


<p>query = &quot;Wat zijn de belangrijkste toepassingen van machine learning?&quot;
result = qa.run(query)
print(result)

Stap 4: Een LLM-agent maken

Terwijl ons eenvoudige RAG-systeem nuttig is, is het nogal beperkt. Laten we het verbeteren door een LLM-agent te maken die meer complexe taken kan uitvoeren en redeneren over de informatie die hij ophaalt.

Een LLM-agent is een AI-systeem dat tools kan gebruiken en beslissingen kan nemen over welke acties hij moet uitvoeren. We zullen een agent maken die niet alleen vragen kan beantwoorden, maar ook webzoekopdrachten en basisberekeningen kan uitvoeren.

Laten we eerst enkele tools definiëren voor onze agent:


<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># Definieer een calculator-tool
class CalculatorTool(BaseTool):
name = &quot;Calculator&quot;
description = &quot;Handig voor wanneer u vragen over wiskunde moet beantwoorden&quot;</p>

<p>def _run(self, query: str)
try:
return str(eval(query))
except:
return &quot;Ik kon dat niet berekenen. Zorg ervoor dat uw invoer een geldige wiskundige expressie is.&quot;</p>

<p># Maak tool-exemplaren
search = DuckDuckGoSearchRun()
calculator = CalculatorTool()</p>

<p># Definieer de tools
tools = [Tool(name=&quot;Search&quot;, func=search.run, description=&quot;Handig voor wanneer u vragen over actuele gebeurtenissen moet beantwoorden&quot;),
Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Handig voor wanneer u vragen over AI en machine learning moet beantwoorden&quot;),
Tool(name=&quot;Calculator&quot;, func=calculator._run, description=&quot;Handig voor wanneer u wiskundige berekeningen moet uitvoeren&quot;)
]</p>

<p># Initialiseer de agent
agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)</p>

Nu hebben we een agent die onze RAG-systeem kan gebruiken, webzoekopdrachten kan uitvoeren en berekeningen kan doen. Laten we hem testen:


<p>result = agent.run(&quot;Wat is het verschil tussen supervised en unsupervised learning? Ook, wat is 15% van 80?&quot;)
print(result)</p>

Deze agent demonstreert een belangrijk voordeel van LLM-agents: ze kunnen meerdere tools en redeneringsstappen combineren om complexe queries te beantwoorden.

De agent verbeteren met geavanceerde RAG-technieken

Terwijl ons huidige RAG-systeem goed werkt, zijn er verschillende geavanceerde technieken die we kunnen gebruiken om de prestaties te verbeteren:

a) Semantische zoekopdracht met Dense Passage Retrieval (DPR)

In plaats van gebruik te maken van eenvoudige embedding-gebaseerde opvraging, kunnen we DPR implementeren voor nauwkeurigere semantische zoekopdracht:


<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># Functie om passages te encoderen
def encode_passages(passages):
return context_encoder(passages, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

<p># Functie om query te encoderen
def encode_query(query):
return question_encoder(query, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

b) Query-uitbreiding

We kunnen query-uitbreiding gebruiken om de opvragingsprestaties te verbeteren:


<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) Iteratieve verfijning

We kunnen een iteratief verfijningsproces implementeren waarin de agent follow-up vragen kan stellen om zijn initiële opvraging te verduidelijken of uit te breiden:


<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;Op basis van dit resultaat: &#039;{result}&#039;, wat volgende vraag moet ik stellen om meer specifieke informatie te krijgen?&quot;)
if clarification.lower().strip() == &quot;none&quot;:
break
query = clarification
return result</p>

# Gebruik dit in uw agent-proces

Implementatie van een multi-agent systeem

Om complexere taken aan te pakken, kunnen we een multi-agent systeem implementeren waarin verschillende agents zich specialiseren in verschillende gebieden. Hier is een eenvoudig voorbeeld:


<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># Maak specialist-agents
research_agent = SpecialistAgent(&quot;Research&quot;, [Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Voor AI- en ML-vragen&quot;)])
math_agent = SpecialistAgent(&quot;Math&quot;, [Tool(name=&quot;Calculator&quot;, func=calculator._run, description=&quot;Voor berekeningen&quot;)])
general_agent = SpecialistAgent(&quot;General&quot;, [Tool(name=&quot;Search&quot;, func=search.run, description=&quot;Voor algemene vragen&quot;)])</p>

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

<p>def run(self, query):
# Bepaal welke agent te gebruiken
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;Math&#039;].run(query)
elif any(term in query.lower() for term in [&#039;ai&#039;, &#039;machine learning&#039;, &#039;deep learning&#039;]):
return self.agents[&#039;Research&#039;].run(query)
else:
return self.agents[&#039;General&#039;].run(query)</p>

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

<p># Test het multi-agent systeem
result = coordinator.run(&quot;Wat is het verschil tussen CNN en RNN? Ook, bereken 25% van 120.&quot;)
print(result)</p>

Dit multi-agent systeem stelt specialisten in staat om complexere vragen te beantwoorden.

Evaluatie en optimalisatie van RAG-agents

Om ervoor te zorgen dat onze RAG-agent goed presteert, moeten we evaluatiemetrics en optimalisatietechnieken implementeren:

a) Relevantiebeoordeling

We kunnen metrics zoals BLEU, ROUGE of BERTScore gebruiken om de relevantie van opgehaalde documenten te beoordelen:


from bert_score import score

<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) Antwoordkwaliteitsbeoordeling

We kunnen menselijke evaluatie of geautomatiseerde metrics gebruiken om de kwaliteit van antwoorden te beoordelen:


<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># Gebruik dit om de antwoorden van uw agent te evalueren

Toekomstige richtingen en uitdagingen

Terwijl we naar de toekomst van RAG-agents kijken, komen verschillende spannende richtingen en uitdagingen naar voren:

a) Multimodale RAG: Het uitbreiden van RAG om beeld-, audio- en videodata te incorporeren.

b) Federated RAG: Het implementeren van RAG over gedistribueerde, privacy-beschermde kennisbases.

c) Continu leren: Het ontwikkelen van methoden voor RAG-agents om hun kennisbases en modellen over tijd bij te werken.

d) Ethische overwegingen: Het aanpakken van bias, eerlijkheid en transparantie in RAG-systemen.

e) Schaalbaarheid: Het optimaliseren van RAG voor grote, real-time toepassingen.

Conclusie

Het bouwen van LLM-agents voor RAG van scratch is een complex maar lonend proces. We hebben de basis van RAG behandeld, een eenvoudig systeem geïmplementeerd, een LLM-agent gemaakt, deze verbeterd met geavanceerde technieken, een multi-agent systeem onderzocht en evaluatie- en optimalisatietechnieken besproken.

Ik heb de afgelopen vijf jaar doorgebracht met het onderdompelen van mezelf in de fascinerende wereld van Machine Learning en Deep Learning. Mijn passie en expertise hebben me geleid om bij te dragen aan meer dan 50 diverse software-engineeringprojecten, met een bijzondere focus op AI/ML. Mijn voortdurende nieuwsgierigheid heeft me ook aangetrokken tot Natural Language Processing, een vakgebied dat ik graag verder wil verkennen.