AGI

Bygga LLM-agenter för RAG frÄn scratch och bortom: En komplett guide

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

LLM:er som GPT-3, GPT-4 och deras öppen källkods motsvarighet kämpar ofta med att hämta uppdaterad information och kan ibland generera hallucinationer eller felaktig information.

Retrieval-Augmented Generation (RAG) är en teknik som kombinerar kraften i LLM:er med extern kunskapshämtning. RAG låter oss grunda LLM-svar i faktiska, uppdaterade uppgifter, vilket förbättrar betydligt noggrannheten och tillförlitligheten hos AI-genererat innehåll.

I den här bloggposten kommer vi att utforska hur man bygger LLM-agenter för RAG från scratch, med djupgående diskussioner om arkitektur, implementationsdetaljer och avancerade tekniker. Vi kommer att täcka allt från RAG-grunderna till att skapa sofistikerade agenter som kan utföra komplexa resonemang och uppgifter.

Innan vi dyker in i att bygga vår LLM-agent, låt oss förstå vad RAG är och varför det är viktigt.

RAG, eller Retrieval-Augmented Generation, är en hybridapproach som kombinerar informationshämtning med textgenerering. I ett RAG-system:

  • En fråga används för att hämta relevanta dokument från en kunskapsbas.
  • De här dokumenten matas sedan in i en språkmodell tillsammans med den ursprungliga frågan.
  • Modellen genererar ett svar baserat på både frågan och den hämtade informationen.
RAG

RAG

Den här approachen har flera fördelar:

  • Förbättrad noggrannhet: Genom att grunda svar i hämtad information minskar RAG hallucinationer och förbättrar faktisk noggrannhet.
  • Uppdaterad information: Kunskapsbasen kan uppdateras regelbundet, vilket gör att systemet kan komma åt aktuell information.
  • Transparens: Systemet kan tillhandahålla källor för sin information, vilket ökar förtroendet och möjliggör faktakontroll.

Att förstå LLM-agenter

 

När du står inför ett problem med inget enkelt svar behöver du ofta följa flera steg, tänka noga och komma ihåg vad du har provat tidigare. LLM-agenter är utformade för exakt sådana situationer i språkmodellstillämpningar. De kombinerar grundlig dataanalys, strategisk planering, datahämtning och förmågan att lära av tidigare handlingar för att lösa komplexa problem.

Vad är LLM-agenter?

LLM-agenter är avancerade AI-system utformade för att skapa komplex text som kräver sekventiellt resonemang. De kan tänka i förväg, komma ihåg tidigare samtal och använda olika verktyg för att anpassa sina svar efter situationen och den stil som behövs.

Överväg en fråga inom juridik som: “Vilka är de potentiella rättsliga resultaten av en specifik typ av kontraktbrott i Kalifornien?” En grundläggande LLM med ett RAG-system kan hämta den nödvändiga informationen från juridiska databaser.

För en mer detaljerad scenarie: “I ljuset av nya dataskyddslagar, vilka är de vanliga rättsliga utmaningarna som företag står inför, och hur har domstolarna hanterat dessa frågor?” Den här frågan gräver djupare än att bara leta upp fakta. Det handlar om att förstå nya regler, deras påverkan på olika företag och domstolarnas svar. En LLM-agent skulle bryta ner den här uppgiften i underuppgifter, som att hämta de senaste lagarna, analysera historiska fall, sammanfatta juridiska dokument och förutsäga trender baserat på mönster.

LLM-agenter består av

LLM-agenter består vanligtvis av fyra komponenter:

  1. Agent/hjärna: Den grundläggande språkmodellen som bearbetar och förstår språk.
  2. Planering: Förmågan att resonera, bryta ner uppgifter och utveckla specifika planer.
  3. Minne: Håller koll på tidigare interaktioner och lär av dem.
  4. Verktygsanvändning: Integrerar olika resurser för att utföra uppgifter.

Agent/hjärna

I hjärtat av en LLM-agent finns en språkmodell som bearbetar och förstår språk baserat på stora mängder data som den har tränats på. Du börjar med att ge den en specifik prompt, som vägleder agenten om hur den ska svara, vilka verktyg den ska använda och vilka mål den ska sträva efter. Du kan anpassa agenten med en persona som passar för specifika uppgifter eller interaktioner, vilket förbättrar dess prestanda.

Minne

Minneskomponenten hjälper LLM-agenter att hantera komplexa uppgifter genom att hålla koll på tidigare handlingar. Det finns två huvudtyper av minne:

  • Korttidsminne: Fungerar som en anteckningsbok, som håller koll på pågående diskussioner.
  • Långtidsminne: Fungerar som en dagbok, som lagrar information från tidigare interaktioner för att lära av mönster och fatta bättre beslut.

Genom att kombinera dessa typer av minne kan agenten erbjuda mer anpassade svar och komma ihåg användarpreferenser över tid, vilket skapar en mer sammanhängande och relevant interaktion.

Planering

Planering möjliggör för LLM-agenter att resonera, bryta ner uppgifter i hanterbara delar och anpassa planer när uppgifter utvecklas. Planering omfattar två huvudstadier:

  • Planformulering: Att bryta ner en uppgift i mindre underuppgifter.
  • Planreflektion: Att granska och bedöma planens effektivitet, med feedback för att förbättra strategier.

Metoder som Chain of Thought (CoT) och Tree of Thought (ToT) hjälper till i den här nedbrytningsprocessen, vilket möjliggör för agenter att utforska olika vägar för att lösa ett problem.

För att dyka djupare in i världen av AI-agenter, inklusive deras nuvarande förmågor och potential, kan du läsa “Auto-GPT & GPT-Engineer: En djupgående guide till dagens ledande AI-agenter”

Att ställa in miljön

För att bygga vår RAG-agent behöver vi ställa in vår utvecklingsmiljö. Vi kommer att använda Python och flera nyckellibrarier:

  • LangChain: För att orkestrera vår LLM och hämtningskomponenter
  • Chroma: Som vår vektorlagring för dokumentinbäddningar
  • OpenAI:s GPT-modeller: Som vår grundläggande LLM (du kan ersätta detta med en öppen källkodsmodell om du föredrar)
  • FastAPI: För att skapa en enkel API för att interagera med vår agent

Låt oss börja med att ställa in vår miljö:


<p># Skapa en ny virtuell miljö
python -m venv rag_agent_env
source rag_agent_env/bin/activate # På Windows, använd `rag_agent_env\Scripts\activate`</p>

<p># Installera nödvändiga paket
pip install langchain chromadb openai fastapi uvicorn

Nu, låt oss skapa en ny Python-fil som heter rag_agent.py och importera de nödvändiga biblioteken:


<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># Ställ in din OpenAI API-nyckel
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;din-api-nyckel-här&quot;</p>

Att bygga ett enkelt RAG-system

Nu när vi har vår miljö inställd, låt oss bygga ett grundläggande RAG-system. Vi kommer att börja med att skapa en kunskapsbas från en uppsättning dokument, sedan använda den för att svara på frågor.

Steg 1: Förbered dokumenten

Först behöver vi ladda och förbereda våra dokument. För det här exemplet, låt oss anta att vi har en textfil som heter knowledge_base.txt med några uppgifter om AI och maskinlärning.


<p># Ladda dokumentet
loader = TextLoader(&quot;knowledge_base.txt&quot;)
documents = loader.load()</p>

<p># Dela dokumenten i bitar
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Skapa inbäddningar
embeddings = OpenAIEmbeddings()</p>

<p># Skapa en vektorlagring
vectorstore = Chroma.from_documents(texts, embeddings)</p>

Steg 2: Skapa en hämtningsbaserad QA-kedja

Nu när vi har vår vektorlagring, kan vi skapa en hämtningsbaserad QA-kedja:


<p># Skapa en hämtningsbaserad QA-kedja
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=&quot;stuff&quot;, retriever=vectorstore.as_retriever())</p>

Steg 3: Fråga systemet

Vi kan nu fråga vårt RAG-system:


<p>fråga = &quot;Vilka är de viktigaste tillämpningarna av maskinlärning?&quot;
resultat = qa.run(fråga)
print(resultat)

Steg 4: Skapa en LLM-agent

Medan vårt enkla RAG-system är användbart, är det ganska begränsat. Låt oss förbättra det genom att skapa en LLM-agent som kan utföra mer komplexa uppgifter och resonera om den information den hämtar.

En LLM-agent är ett AI-system som kan använda verktyg och fatta beslut om vilka åtgärder som ska vidtas. Vi kommer att skapa en agent som inte bara kan svara på frågor, utan också utföra webbsökningar och grundläggande beräkningar.

Först, låt oss definiera några verktyg för vår 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># Definiera ett kalkylverktyg
class CalculatorTool(BaseTool):
name = &quot;Kalkylator&quot;
description = &quot;Användbart när du behöver svara på matematiska frågor&quot;</p>

<p>def _run(self, fråga: str)
try:
return str(eval(fråga))
except:
return &quot;Jag kunde inte beräkna det. Se till att din inmatning är ett giltigt matematiskt uttryck.&quot;</p>

<p># Skapa verktygsinstanser
sök = DuckDuckGoSearchRun()
kalkylator = CalculatorTool()</p>

<p># Definiera verktygen
verktyg = [Tool(name=&quot;Sök&quot;, func=sök.run, description=&quot;Användbart när du behöver svara på frågor om aktuella händelser&quot;),
Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Användbart när du behöver svara på frågor om AI och maskinlärning&quot;),
Tool(name=&quot;Kalkylator&quot;, func=kalkylator._run, description=&quot;Användbart när du behöver utföra matematiska beräkningar&quot;)
]</p>

<p># Initiera agenten
agent = initialize_agent(verktyg, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)</p>

Nu har vi en agent som kan använda vårt RAG-system, utföra webbsökningar och göra beräkningar. Låt oss testa den:


<p>resultat = agent.run(&quot;Vad är skillnaden mellan övervakad och oövervakad inlärning? Och vad är 15% av 80?&quot;)
print(resultat)</p>

Den här agenten demonstrerar en viktig fördel med LLM-agenter: de kan kombinera flera verktyg och resonemangssteg för att svara på komplexa frågor.

Att förbättra agenten med avancerade RAG-tekniker

Medan vårt nuvarande RAG-system fungerar bra, finns det flera avancerade tekniker som vi kan använda för att förbättra dess prestanda:

a) Semantisk sökning med Dense Passage Retrieval (DPR)

I stället för att använda enkel inbäddningsbaserad hämtning, kan vi implementera DPR för mer exakt semantisk sökning:


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

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

<p># Funktion för att koda passager
def koda_passager(passager):
return sammanhangskodare(passager, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

<p># Funktion för att koda fråga
def koda_fråga(fråga):
return frågekodare(fråga, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

b) Frågeexpansion

Vi kan använda frågeexpansion för att förbättra hämtningsprestanda:


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

<p>modell = T5ForConditionalGeneration.from_pretrained(&quot;t5-small&quot;)
tokenisatör = T5Tokenizer.from_pretrained(&quot;t5-small&quot;)</p>

<p>def expandera_fråga(fråga):
inmatningstext = f&quot;expandera fråga: {fråga}&quot;
inmatningsid = tokenisatör.encode(inmatningstext, return_tensors=&quot;pt&quot;)
utgångar = modell.generate(inmatningsid, max_length=50, num_return_sequences=3)
expanderade_frågor = [tokenisatör.decode(utgång, skip_special_tokens=True) for utgång in utgångar]
return expanderade_frågor</p>

c) Iterativ förfining

Vi kan implementera en iterativ förfiningsprocess där agenten kan ställa följdfrågor för att förtydliga eller expandera sin initiala hämtning:


<p>def iterativ_hämtning(inledande_fråga, max_iterationer=3):
fråga = inledande_fråga
for _ in range(max_iterationer):
resultat = qa.run(fråga)
förtydligande = agent.run(f&quot;Baseras på det här resultatet: &#039;{resultat}&#039;, vilken följdfråga bör jag ställa för att få mer specifik information?&quot;)
if förtydligande.lower().strip() == &quot;ingen&quot;:
break
fråga = förtydligande
return resultat</p>

# Använd det här i din agents process

Att implementera ett multiagent-system

För att hantera mer komplexa uppgifter kan vi implementera ett multiagent-system där olika agenter specialiserar sig på olika områden. Här är ett enkelt exempel:


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

<p>def run(self, fråga):
return self.agent.run(fråga)</p>

<p># Skapa specialistagenter
forskningsagent = SpecialistAgent(&quot;Forskning&quot;, [Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;För AI- och ML-frågor&quot;)])
matematikagent = SpecialistAgent(&quot;Matematik&quot;, [Tool(name=&quot;Kalkylator&quot;, func=kalkylator._run, description=&quot;För beräkningar&quot;)])
allmänagent = SpecialistAgent(&quot;Allmänt&quot;, [Tool(name=&quot;Sök&quot;, func=sök.run, description=&quot;För allmänna frågor&quot;)])</p>

<p>class Koordinator:
def __init__(self, agenter):
self.agenter = agenter</p>

<p>def run(self, fråga):
# Bestäm vilken agent som ska användas
if &quot;beräkna&quot; in fråga.lower() or any(op in fråga for op in [&#039;+&#039;, &#039;-&#039;, &#039;*&#039;, &#039;/&#039;]):
return self.agenter[&#039;Matematik&#039;].run(fråga)
elif any(term in fråga.lower() for term in [&#039;ai&#039;, &#039;maskinlärning&#039;, &#039;djupinlärning&#039;]):
return self.agenter[&#039;Forskning&#039;].run(fråga)
else:
return self.agenter[&#039;Allmänt&#039;].run(fråga)</p>

<p>koordinator = Koordinator({&#039;Forskning&#039;: forskningsagent, &#039;Matematik&#039;: matematikagent, &#039;Allmänt&#039;: allmänagent})</p>

<p># Testa multiagent-systemet
resultat = koordinator.run(&quot;Vad är skillnaden mellan CNN och RNN? Och beräkna 25% av 120.&quot;)
print(resultat)</p>

Det här multiagent-systemet möjliggör specialisering och kan hantera en bredare variation av frågor mer effektivt.

Att utvärdera och optimera RAG-agenter

För att säkerställa att vår RAG-agent fungerar bra, behöver vi implementera utvärderingsmetoder och optimeringstekniker:

a) Relevansutvärdering

Vi kan använda metoder som BLEU, ROUGE eller BERTScore för att utvärdera relevansen hos hämtade dokument:


<p>from bert_score import score</p>

<p>def utvärdera_relevans(fråga, hämtat_dokument, genererat_svar):
P, R, F1 = score([genererat_svar], [hämtat_dokument], lang=&quot;sv&quot;)
return F1.mean().item()</p>

b) Svarskvalitetsutvärdering

Vi kan använda mänsklig utvärdering eller automatiserade metoder för att bedöma svarskvalitet:


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

<p>def utvärdera_svarskvalitet(referenssvar, genererat_svar):
return sentence_bleu([referenssvar.split()], genererat_svar.split())</p>

<p># Använd det här för att utvärdera din agents svar

Framtida riktningar och utmaningar

När vi ser framåt mot framtiden för RAG-agenter, finns det flera spännande riktningar och utmaningar:

a) Multi-modal RAG: Att utöka RAG till att omfatta bild-, ljud- och videodata.

b) Federerad RAG: Att implementera RAG över distribuerade, sekretessbevarande kunskapsbaser.

c) Kontinuerligt lärande: Att utveckla metoder för RAG-agenter att uppdatera sina kunskapsbaser och modeller över tid.

d) Etiska överväganden: Att hantera fördomar, rättvishet och transparens i RAG-system.

e) Skalbarhet: Att optimera RAG för stora, realtidsapplikationer.

Slutsats

Att bygga LLM-agenter för RAG från scratch är en komplex men givande process. Vi har täckt grunderna i RAG, implementerat ett enkelt system, skapat en LLM-agent, förbättrat den med avancerade tekniker, utforskat multiagent-system och diskuterat utvärderings- och optimeringstekniker.

Jag har tillbringat de senaste fem Ären med att dyka djupt in i den fascinerande vÀrlden av MaskinlÀrning och DjupinlÀrning. Min passion och expertis har lett mig till att bidra till över 50 olika mjukvaruprojekt, med sÀrskild fokus pÄ AI/ML. Min pÄgÄende nyfikenhet har ocksÄ lett mig mot Naturlig SprÄkbehandling, ett omrÄde som jag Àr angelÀgen om att utforska vidare.