AGI og fremtidens AI

Bygning af LLM-agenter til RAG fra bunden og udover: En omfattende vejledning

mm
Føj Unite.AI til dine foretrukne kilder på Google

LLM’er som GPT-3, GPT-4 og deres open-source-modstykke kæmper ofte med at hente opdateret information og kan nogle gange generere hallucinationer eller forkert information.

Retrieval-Augmented Generation (RAG) er en teknik, der kombinerer kraften fra LLM’er med ekstern videnhenting. RAG giver os mulighed for at grundlægge LLM-svar i faktuelle, opdaterede oplysninger, hvilket betydeligt forbedrer nøjagtigheden og pålideligheden af AI-genereret indhold.

I denne blogpost vil vi udforske, hvordan vi kan bygge LLM-agenter til RAG fra bunden, dykke dybt ind i arkitekturen, implementationsdetaljer og avancerede teknikker. Vi vil dække alt fra RAG’s grundlag til at skabe sofistikerede agenter, der kan udføre komplekse opgaver og tankeprocesser.

Før vi dykker ind i at bygge vores LLM-agent, lad os forstå, hvad RAG er, og hvorfor det er vigtigt.

RAG, eller Retrieval-Augmented Generation, er en hybridtilgang, der kombinerer videnhenting med tekstgenerering. I et RAG-system:

  • En forespørgsel bruges til at hente relevante dokumenter fra en videnbase.
  • Disse dokumenter indsættes derefter i en sprogmodel sammen med den oprindelige forespørgsel.
  • Modellen genererer et svar baseret på både forespørgslen og den hentede information.
RAG

RAG

Denne tilgang har flere fordele:

  • Forbedret nøjagtighed: Ved at grundlægge svar i hentet information reducerer RAG hallucinationer og forbedrer faktuelle nøjagtighed.
  • Opdateret information: Videnbasen kan opdateres regelmæssigt, hvilket giver systemet adgang til aktuel information.
  • Gennemsigtighed: Systemet kan give kilder for sin information, hvilket øger tillid og giver mulighed for faktatjek.

Forståelse af LLM-agenter

 

Når du står over for et problem med ingen enkel løsning, har du ofte brug for at følge flere skridt, tænke omhyggeligt og huske, hvad du allerede har prøvet. LLM-agenter er designed til netop disse situationer i sprogmodelapplikationer. De kombinerer omfattende dataanalyse, strategisk planlægning, datahenting og evnen til at lære fra tidligere handlinger for at løse komplekse problemer.

Hvad er LLM-agenter?

LLM-agenter er avancerede AI-systemer designed til at skabe kompleks tekst, der kræver sekventiel tankegang. De kan tænke fremad, huske tidligere samtaler og bruge forskellige værktøjer til at tilpasse deres svar efter situationen og den nødvendige stil.

Tænk på et spørgsmål inden for det juridiske område, såsom: “Hvad er de potentielle juridiske konsekvenser af en bestemt type kontraktbrud i Californien?” En grundlæggende LLM med en RAG-system kan hente den nødvendige information fra juridiske databaser.

Til en mere detaljeret scenarie: “I lyset af nye databeskyttelseslove, hvilke er de almindelige juridiske udfordringer, som virksomheder står over for, og hvordan har domstolene behandlet disse spørgsmål?” Dette spørgsmål graver dybere end blot at se oplysninger op. Det handler om at forstå nye regler, deres indvirkning på forskellige virksomheder og domstolens svar. En LLM-agent ville bryde denne opgave ned i underopgaver, såsom at hente de seneste love, analysere historiske sager, sammenfatte juridiske dokumenter og forudsige tendenser baseret på mønstre.

Komponenter af LLM-agenter

LLM-agenter består generelt af fire komponenter:

  1. Agent/Hjerne: Den centrale sprogmodel, der behandler og forstår sprog.
  2. Planlægning: Evnen til at tænke, bryde opgaver ned og udvikle specifikke planer.
  3. Hukommelse: Bevarer optegnelser over tidligere interaktioner og lærer af dem.
  4. Værktøjsbrug: Integrerer forskellige ressourcer for at udføre opgaver.

Agent/Hjerne

I centrum af en LLM-agent er en sprogmodel, der behandler og forstår sprog baseret på store mængder data, den er blevet trænet på. Du starter med at give den en bestemt prompt, der guider agenten om, hvordan den skal svare, hvilke værktøjer den skal bruge og hvilke mål den skal sigte mod. Du kan tilpasse agenten med en persona, der er egnet til bestemte opgaver eller interaktioner, hvilket forbedrer dens præstation.

Hukommelse

Hukommelseskomponten hjælper LLM-agenter med at håndtere komplekse opgaver ved at bevarer en optegnelse over tidligere handlinger. Der er to hovedtyper af hukommelse:

  • Korttids-hukommelse: Fungerer som en notesblok, der holder styr på pågående diskussioner.
  • Langtids-hukommelse: Fungerer som en dagbog, der gemmer information fra tidligere interaktioner for at lære mønstre og træffe bedre beslutninger.

Ved at kombinere disse typer af hukommelse kan agenten give mere tilpassede svar og huske brugerpræferencer over tid, hvilket skaber en mere sammenhængende og relevant interaktion.

Planlægning

Planlægning giver LLM-agenter evnen til at tænke, bryde opgaver ned i håndterbare dele og tilpasse planer, efterhånden som opgaver udvikler sig. Planlægning indebærer to hovedfaser:

  • Planformulering: At bryde en opgave ned i mindre underopgaver.
  • Planrefleksion: At gennemgå og evaluere planens effektivitet, med tilføjelse af feedback for at finpudse strategier.

Metoder som Chain of Thought (CoT) og Tree of Thought (ToT) hjælper i denne nedbrydningsproces, hvilket giver agenterne mulighed for at udforske forskellige veje for at løse et problem.

For at dykke dybere ind i verden af AI-agenter, herunder deres nuværende evner og potentiale, kan du overveje at læse “Auto-GPT & GPT-Engineer: En dybdegående vejledning til i dag førende AI-agenter”

Opsætning af miljøet

For at bygge vores RAG-agent har vi brug for at opsætte vores udviklingsmiljø. Vi vil bruge Python og flere nøglebiblioteker:

  • LangChain: Til at koordinere vores LLM- og hentingskomponenter
  • Chroma: Som vores vektorlager til dokumentindlejring
  • OpenAI’s GPT-modeller: Som vores basis-LLM (du kan erstatte dette med en open-source-model, hvis du ønsker)
  • FastAPI: Til at oprette en simpel API til at interagere med vores agent

Lad os starte med at opsætte vores miljø:


<p># Opret et nyt virtuelt miljø
python -m venv rag_agent_env
source rag_agent_env/bin/activate # På Windows, brug `rag_agent_env\Scripts\activate`</p>

<p># Installer de nødvendige pakker
pip install langchain chromadb openai fastapi uvicorn

Nu lad os oprette en ny Python-fil kaldet rag_agent.py og importere de nødvendige biblioteker:


<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># Angiv din OpenAI-API-nøgle
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;din-api-nøgle-her&quot;</p>

Bygning af et simpelt RAG-system

Nu, hvor vi har opsat vores miljø, lad os bygge et grundlæggende RAG-system. Vi starter med at oprette en videnbase fra en samling af dokumenter, derefter bruger vi denne til at besvare forespørgsler.

Trin 1: Forbered dokumenterne

Først har vi brug for at indlæse og forberede vores dokumenter. I dette eksempel antager vi, at vi har en tekstfil kaldet knowledge_base.txt med nogen information om AI og maskinlæring.


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

<p># Split dokumenterne i stykker
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Opret indlejring
embeddings = OpenAIEmbeddings()</p>

<p># Opret et vektorlager
vectorstore = Chroma.from_documents(texts, embeddings)</p>

Trin 2: Opret en hentingsbaseret QA-kæde

Nu, hvor vi har vores vektorlager, kan vi oprette en hentingsbaseret QA-kæde:


<p># Opret en hentingsbaseret QA-kæde
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=&quot;stuff&quot;, retriever=vectorstore.as_retriever())</p>

Trin 3: Spørg systemet

Vi kan nu spørgge vores RAG-system:


<p>forespørgsel = &quot;Hvad er de vigtigste anvendelser af maskinlæring?&quot;
resultat = qa.run(forespørgsel)
print(resultat)

Trin 4: Oprettelse af en LLM-agent

Selvom vores simple RAG-system er nyttigt, er det ret begrænset. Lad os forbedre det ved at oprette en LLM-agent, der kan udføre mere komplekse opgaver og tænke over den information, den henter.

En LLM-agent er et AI-system, der kan bruge værktøjer og træffe beslutninger om, hvilke handlinger den skal udføre. Vi vil oprette en agent, der ikke kun kan besvare spørgsmål, men også udføre web-søgninger og grundlæggende beregninger.

Først lad os definere nogle værktøjer til vores 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># Definer en beregningsværktøj
class CalculatorTool(BaseTool):
navn = &quot;Beregningsværktøj&quot;
beskrivelse = &quot;Nyttig til, når du har brug for at besvare spørgsmål om matematik&quot;</p>

<p>def _run(self, forespørgsel: str)
try:
return str(eval(forespørgsel))
except:
return &quot;Jeg kunne ikke beregne det. Sørg for, at din indtastning er en gyldig matematisk udtryk.&quot;</p>

<p># Opret værktøjsinstanser
søgning = DuckDuckGoSearchRun()
beregner = CalculatorTool()</p>

<p># Definer værktøjerne
værktøjer = [Tool(navn=&quot;Søgning&quot;,func=søgning.run,beskrivelse=&quot;Nyttig til, når du har brug for at besvare spørgsmål om aktuelle begivenheder&quot;),
Tool(navn=&quot;RAG-QA&quot;,func=qa.run,beskrivelse=&quot;Nyttig til, når du har brug for at besvare spørgsmål om AI og maskinlæring&quot;),
Tool(navn=&quot;Beregner&quot;,func=beregner._run,beskrivelse=&quot;Nyttig til, når du har brug for at udføre matematiske beregninger&quot;)
]</p>

<p># Initialiser agenten
agent = initialize_agent(værktøjer, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)</p>

Nu har vi en agent, der kan bruge vores RAG-system, udføre web-søgninger og udføre beregninger. Lad os teste den:


<p>resultat = agent.run(&quot;Hvad er forskellen på overvåget og uovervåget læring? Og hvad er 15% af 80?&quot;)
print(resultat)</p>

Denne agent demonstrerer en vigtig fordel ved LLM-agenter: de kan kombinere flere værktøjer og tankeprocesser for at besvare komplekse spørgsmål.

Forbedring af agenten med avancerede RAG-teknikker

Selvom vores nuværende RAG-system fungerer godt, er der flere avancerede teknikker, vi kan bruge til at forbedre dets præstation:

a) Semantisk søgning med Dense Passage Retrieval (DPR)

I stedet for at bruge enkel indlejringssøgning kan vi implementere DPR for mere præcis semantisk søgning:


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

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

<p># Funktion til at indlejre passager
def encode_passager(passager):
return kontekst_encoder(passager, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

<p># Funktion til at indlejre forespørgsel
def encode_forespørgsel(forespørgsel):
return spørgsel_encoder(forespørgsel, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

b) Forespørgselsudvidelse

Vi kan bruge forespørgselsudvidelse til at forbedre hentingspræstationen:


<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_forespørgsel(forespørgsel):
input_text = f&quot;expand forespørgsel: {forespørgsel}&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_forespørgsler = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return expanded_forespørgsler</p>

c) Iterativ forbedring

Vi kan implementere en iterativ forbedringsproces, hvor agenten kan stille følgespørgsmål for at klargøre eller udvide sin oprindelige henting:


<p>def iterative_retrieval(initial_forespørgsel, max_iterations=3):
forespørgsel = initial_forespørgsel
for _ in range(max_iterations):
resultat = qa.run(forespørgsel)
klarification = agent.run(f&quot;Basert på dette resultat: &#039;{resultat}&#039;, hvilket følgespørgsmål skal jeg stille for at få mere specifik information?&quot;)
if klarification.lower().strip() == &quot;none&quot;:
break
forespørgsel = klarification
return resultat</p>

# Brug dette i din agents proces

Implementering af et multi-agent-system

For at håndtere mere komplekse opgaver kan vi implementere et multi-agent-system, hvor forskellige agenter specialiserer sig i forskellige områder. Her er et simpelt eksempel:


<p>class SpecialistAgent:
def __init__(self, navn, værktøjer):
self.navn = navn
self.agent = initialize_agent(værktøjer, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True
)</p>

<p>def run(self, forespørgsel):
return self.agent.run(forespørgsel)</p>

<p># Opret specialagenter
forskningsagent = SpecialistAgent(&quot;Forskning&quot;, [Tool(navn=&quot;RAG-QA&quot;, func=qa.run, beskrivelse=&quot;Til AI- og ML-spørgsmål&quot;)])
matematikagent = SpecialistAgent(&quot;Matematik&quot;, [Tool(navn=&quot;Beregner&quot;, func=beregner._run, beskrivelse=&quot;Til beregninger&quot;)])
generelagent = SpecialistAgent(&quot;Generel&quot;, [Tool(navn=&quot;Søgning&quot;, func=søgning.run, beskrivelse=&quot;Til generelle forespørgsler&quot;)])</p>

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

<p>def run(self, forespørgsel):
# Bestem, hvilken agent der skal bruges
if &quot;beregne&quot; i forespørgsel.lower() eller nogen(op i forespørgsel for op i [&#039;+&#039;, &#039;-&#039;, &#039;*&#039;, &#039;/&#039;]):
return self.agenter[&#039;Matematik&#039;].run(forespørgsel)
elif nogen(term i forespørgsel.lower() for term in [&#039;ai&#039;, &#039;maskinlæring&#039;, &#039;dyb læring&#039;]):
return self.agenter[&#039;Forskning&#039;].run(forespørgsel)
else:
return self.agenter[&#039;Generel&#039;].run(forespørgsel)</p>

<p>koordinator = Koordinator({&#039;Forskning&#039;: forskningsagent, &#039;Matematik&#039;: matematikagent, &#039;Generel&#039;: generelagent})</p>

<p># Test multi-agent-systemet
resultat = koordinator.run(&quot;Hvad er forskellen på CNN og RNN? Og beregn 25% af 120.&quot;)
print(resultat)</p>

Dette multi-agent-system giver mulighed for specialisering og kan håndtere en bredere vifte af forespørgsler mere effektivt.

Evaluering og optimering af RAG-agenter

For at sikre, at vores RAG-agent fungerer godt, har vi brug for at implementere evaluering af metrikker og optimeringsteknikker:

a) Relevans-evaluering

Vi kan bruge metrikker som BLEU, ROUGE eller BERTScore til at evaluere relevansen af hentede dokumenter:


<p>from bert_score import score</p>

<p>def evaluate_relevans(forespørgsel, hentet_dokument, genereret_svar):
P, R, F1 = score([genereret_svar], [hentet_dokument], lang=&quot;en&quot;)
return F1.mean().item()</p>

b) Svar-kvalitets-evaluering

Vi kan bruge menneskelig evaluering eller automatiserede metrikker til at bedømme svar-kvalitet:


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

<p>def evaluate_svar_kvalitet(reference_svar, genereret_svar):
return sentence_bleu([reference_svar.split()], genereret_svar.split())</p>

<p># Brug dette til at evaluere din agents svar

Fremtidige retninger og udfordringer

Da vi ser frem til fremtiden for RAG-agenter, dukker flere spændende retninger og udfordringer op:

a) Multi-modal RAG: At udvide RAG til at omfatte billed-, lyd- og video-data.

b) Federeret RAG: At implementere RAG på tværs af distribuerede, privatlivsbeskyttende videnbaser.

c) Kontinuerlig læring: At udvikle metoder til, at RAG-agenter kan opdatere deres videnbaser og modeller over tid.

d) Etiske overvejelser: At tackle bias, lighed og gennemsigtighed i RAG-systemer.

e) Skalbarhed: At optimere RAG til store, realtidsapplikationer.

Konklusion

At bygge LLM-agenter til RAG fra bunden er en kompleks, men belønning proces. Vi har dækket grundlaget for RAG, implementeret et simpelt system, skabt en LLM-agent, forbedret den med avancerede teknikker, udforsket multi-agent-systemer og diskuteret evaluering og optimeringsteknikker.

Jeg har brugt de sidste fem år på at dykke ned i den fascinerende verden af Machine Learning og Deep Learning. Min passion og ekspertise har ført mig til at bidrage til over 50 forskellige software-ingeniørprojekter, med en særlig fokus på AI/ML. Min fortsatte nysgerrighed har også ført mig mod Natural Language Processing, et felt jeg er ivrig efter at udforske yderligere.