AGI
Bygging av LLM-agenter for RAG fra scratch og utover: En omfattende guide
LLM-er som GPT-3, GPT-4 og deres åpne kilde-konterparter kan noen ganger slite med oppdatert informasjonsøkning og generere hallucinasjoner eller feilaktig informasjon.
Retrieval-Augmented Generation (RAG) er en teknikk som kombinerer kraften til LLM-er med eksterne kunnskapsøkning. RAG lar oss grunnlegge LLM-svar i faktiske, oppdaterte opplysninger, og forbedrer nøyaktigheten og påliteligheten til AI-generert innhold.
I denne bloggposten vil vi utforske hvordan vi kan bygge LLM-agenter for RAG fra scratch, og dykke dypt inn i arkitekturen, implementeringsdetaljer og avanserte tekniker. Vi vil dekke alt fra grunnleggende RAG til å lage sofistikerte agenter som kan utføre komplekse oppgaver og tankeprosesser.
Før vi dykker inn i å bygge vår LLM-agent, la oss forstå hva RAG er og hvorfor det er viktig.
RAG, eller Retrieval-Augmented Generation, er en hybridtilnærming som kombinerer informasjonsøkning med tekstgenerering. I et RAG-system:
- En spørring brukes til å hente relevante dokumenter fra en kunnskapsbase.
- Disse dokumentene føres deretter inn i en språkmodell sammen med den opprinnelige spørringen.
- Modellen genererer et svar basert på både spørringen og den hentede informasjonen.
Denne tilnærmingen har flere fordeler:
- Forbedret nøyaktighet: Ved å grunnlegge svar i hentet informasjon, reduserer RAG hallucinasjoner og forbedrer faktisk nøyaktighet.
- Oppdatert informasjon: Kunnskapsbasen kan oppdateres regelmessig, og lar systemet få tilgang til aktuell informasjon.
- Gjennomsiktighet: Systemet kan angi kilder for sin informasjon, og øke tillit og mulighet for faktasjekking.
Forståelse av LLM-agenter
Når du møter et problem uten en enkel løsning, må du ofte følge flere trinn, tenke nøye og huske hva du allerede har prøvd. LLM-agenter er designet for nettopp slike situasjoner i språkmodell-applikasjoner. De kombinerer grundig dataanalyse, strategisk planlegging, datahenting og evnen til å lære fra tidligere handlinger for å løse komplekse problemer.
Hva er LLM-agenter?
LLM-agenter er avanserte AI-systemer designet for å lage kompleks tekst som krever sekvensiell resonnering. De kan tenke foran, huske tidligere samtaler og bruke ulike verktøy til å tilpasse svarene sine basert på situasjonen og stilen som trengs.
Overvei et spørsmål i det juridiske feltet som: “Hva er de potensielle juridiske utfallene av en bestemt type kontraktbrudd i California?” En grundig LLM med en RAG-system kan hente nødvendig informasjon fra juridiske databaser.
For en mer detaljert scenario: “I lys av nye datavernlovene, hva er de vanlige juridiske utfordringene selskaper møter, og hvordan har domstolene behandlet disse problemene?” Dette spørsmålet graver dypere enn bare å se opp fakta. Det handler om å forstå nye regler, deres innvirkning på ulike selskaper og domstolenes svar. En LLM-agent ville bryte denne oppgaven ned i underoppgaver, som å hente de nyeste lovene, analysere historiske saker, summerer juridiske dokumenter og forutsi trender basert på mønster.
Komponenter av LLM-agenter
LLM-agenter består vanligvis av fire komponenter:
- Agent/Hjerne: Den grunnleggende språkmodellen som behandler og forstår språk.
- Planlegging: Evnen til å resonere, bryte ned oppgaver og utvikle spesifikke planer.
- Hukommelse: Vedlikeholder poster over tidligere interaksjoner og lærer fra dem.
- Verktøybruk: Integrerer ulike ressurser for å utføre oppgaver.
Agent/Hjerne
I kjernen av en LLM-agent ligger en språkmodell som behandler og forstår språk basert på store mengder data den er trent på. Du starter med å gi den en bestemt prompt, og guiden agenten på hvordan den skal svare, hvilke verktøy den skal bruke og hvilke mål den skal nå. Du kan tilpasse agenten med en personlighet som er egnet for bestemte oppgaver eller interaksjoner, og forbedre dens ytelse.
Hukommelse
Hukommelseskomponenten hjelper LLM-agenter med å håndtere komplekse oppgaver ved å vedlikeholde en post over tidligere handlinger. Det finnes to hovedtyper hukommelse:
- Korttidsminne: Fungerer som en notisblokk, og holder styr på pågående samtaler.
- Langtidsminne: Fungerer som en dagbok, og lagrer informasjon fra tidligere interaksjoner for å lære mønster og ta bedre beslutninger.
Ved å blande disse typene hukommelse, kan agenten tilby mer tilpassede svar og huske brukerpreferanser over tid, og skape en mer sammenhengende og relevant interaksjon.
Planlegging
Planlegging aktiverer LLM-agenter til å resonere, bryte ned oppgaver i håndterbare deler og tilpasse planer etterhvert som oppgavene utvikler seg. Planlegging involverer to hovedfaser:
- Planformulering: Bryter ned en oppgave i mindre underoppgaver.
- Planrefleksjon: Gjennomgår og vurderer planens effektivitet, og inkorporerer tilbakemeldinger for å finjustere strategier.
Metoder som Chain of Thought (CoT) og Tree of Thought (ToT) hjelper i denne nedbrytningsprosessen, og lar agenter utforske ulike stier for å løse et problem.
For å dykke dyptere inn i verden av AI-agenter, inkludert deres nåværende evner og potensiale, kan du lese “Auto-GPT & GPT-Engineer: En dybdeguide til dagens ledende AI-agenter”
Oppsett av miljøet
For å bygge vår RAG-agent, må vi oppsette vår utviklingsmiljø. Vi vil bruke Python og flere nøkkelbiblioteker:
- LangChain: For å orkestrere vår LLM- og hentingkomponenter
- Chroma: Som vår vektorlagring for dokument-embeddings
- OpenAI’s GPT-modeller: Som vår grunnleggende LLM (du kan erstatte dette med en åpen kilde-modell hvis du ønsker)
- FastAPI: For å lage en enkel API for å interagere med vår agent
La oss starte med å oppsette vår miljø:
<p># Opprett en ny virtuell miljø python -m venv rag_agent_env source rag_agent_env/bin/activate # På Windows, bruk `rag_agent_env\Scripts\activate`</p> <p># Installer nødvendige pakker pip install langchain chromadb openai fastapi uvicorn
Na kan vi opprette en ny Python-fil kalt rag_agent.py og importere de nødvendige bibliotekene:
<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># Sett din OpenAI-API-nøkkel os.environ["OPENAI_API_KEY"] = "din-api-nøkkel-her"</p>
Bygging av et enkelt RAG-system
Na som vi har oppsatt vår miljø, la oss bygge et enkelt RAG-system. Vi vil starte med å opprette en kunnskapsbase fra en samling dokumenter, og deretter bruke denne til å svare på spørsmål.
Trinn 1: Forbered dokumentene
Først må vi laste og forberede våre dokumenter. For dette eksemplet, la oss anta at vi har en tekstfil kalt knowledge_base.txt med noen informasjon om AI og maskinlæring.
<p># Last dokumentet loader = TextLoader("knowledge_base.txt") documents = loader.load()</p> <p># Del dokumentene inn i blokker text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents)</p> <p># Opprett embeddings embeddings = OpenAIEmbeddings()</p> <p># Opprett en vektorlagring vectorstore = Chroma.from_documents(texts, embeddings)</p>
Trinn 2: Opprett en henting-basert QA-kjede
Na som vi har vår vektorlagring, kan vi opprette en henting-basert QA-kjede:
<p># Opprett en henting-basert QA-kjede qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vectorstore.as_retriever())</p>
Trinn 3: Spør systemet
Vi kan nå spørre vår RAG-system:
<p>spørsmål = "Hva er de viktigste anvendelsene av maskinlæring?" resultat = qa.run(spørsmål) print(resultat)
Trinn 4: Opprett en LLM-agent
Mens vårt enkle RAG-system er nyttig, er det ganske begrenset. La oss forbedre det ved å opprette en LLM-agent som kan utføre mer komplekse oppgaver og resonere om informasjonen den henter.
En LLM-agent er et AI-system som kan bruke verktøy og ta beslutninger om hvilke handlinger den skal utføre. Vi vil opprette en agent som ikke bare kan svare på spørsmål, men også utføre nett-søk og grunnleggende beregninger.
Først la oss definere noen verktøy for 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># Definer en regneark-verktøy class CalculatorTool(BaseTool): navn = "Regneark" beskrivelse = "Nyttig for når du må svare på spørsmål om matematikk"</p> <p>def _run(self, spørsmål: str) try: return str(eval(spørsmål)) except: return "Jeg kunne ikke beregne det. Vennligst sikre at din input er en gyldig matematisk uttrykk."</p> <p># Opprett verktøy-eksempler søk = DuckDuckGoSearchRun() regneark = CalculatorTool()</p> <p># Definer verktøyene verktøy = [Tool(navn="Søk", func=søk.run, beskrivelse="Nyttig for når du må svare på spørsmål om nåværende hendelser"), Tool(navn="RAG-QA", func=qa.run, beskrivelse="Nyttig for når du må svare på spørsmål om AI og maskinlæring"), Tool(navn="Regneark", func=regneark._run, beskrivelse="Nyttig for når du må utføre matematiske beregninger") ]</p> <p># Initialiser agenten agent = initialize_agent(verktøy, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True )</p>
Na har vi en agent som kan bruke vårt RAG-system, utføre nett-søk og utføre beregninger. La oss teste den:
<p>resultat = agent.run("Hva er forskjellen på overvåket og uovervåket læring? Og hva er 15% av 80?") print(resultat)</p>
Denne agenten demonstrerer en viktig fordel med LLM-agenter: de kan kombinere flere verktøy og resonnerings-trinn for å svare på komplekse spørsmål.
Forbedring av agenten med avanserte RAG-teknikker
Mens vårt nåværende RAG-system fungerer bra, er det flere avanserte tekniker vi kan bruke til å forbedre dens ytelse:
a) Semantisk søk med Dense Passage Retrieval (DPR)
I stedet for å bruke enkle embedding-basert søkning, kan vi implementere DPR for mer nøyaktig semantisk søk:
<p>from transformers import DPRQuestionEncoder, DPRContextEncoder</p> <p>spørsmål_encoder = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base") kontekst_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")</p> <p># Funksjon for å kode passasjer def kode_passasjer(passasjer): return kontekst_encoder(passasjer, max_length=512, return_tensors="pt").pooler_output</p> <p># Funksjon for å kode spørsmål def kode_spørsmål(spørsmål): return spørsmål_encoder(spørsmål, max_length=512, return_tensors="pt").pooler_output</p>
b) Spørsmål-utvidelse
Vi kan bruke spørsmål-utvidelse til å forbedre søkningsytelsen:
<p>from transformers import T5ForConditionalGeneration, T5Tokenizer</p>
<p>modell = T5ForConditionalGeneration.from_pretrained("t5-small")
tokenizer = T5Tokenizer.from_pretrained("t5-small")</p>
<p>def utvide_spørsmål(spørsmål):
input_tekst = f"utvide spørsmål: {spørsmål}"
input_ids = tokenizer.encode(input_tekst, return_tensors="pt")
outputs = modell.generate(input_ids, max_length=50, num_return_sequences=3)
utvidede_spørsmål = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs]
return utvidede_spørsmål</p>
c) Iterativ forfining
Vi kan implementere en iterativ forfiningsprosess hvor agenten kan stille følgespørsmål for å klargjøre eller utvide på sitt opprinnelige søk:
<p>def iterativ_søkning(innledende_spørsmål, maks_iterasjoner=3):
spørsmål = innledende_spørsmål
for _ in range(maks_iterasjoner):
resultat = qa.run(spørsmål)
klargjøring = agent.run(f"Basert på dette resultatet: '{resultat}', hva følgespørsmål bør jeg stille for å få mer spesifikk informasjon?")
if klargjøring.lower().strip() == "none":
break
spørsmål = klargjøring
return resultat</p>
# Bruk denne i din agent-prosess
Implementering av et multi-agent-system
For å håndtere mer komplekse oppgaver, kan vi implementere et multi-agent-system hvor ulike agenter spesialiserer seg i ulike områder. Her er et enkelt eksempel:
<p>class SpesialistAgent:
def __init__(self, navn, verktøy):
self.navn = navn
self.agent = initialize_agent(verktøy, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)</p>
<p>def run(self, spørsmål):
return self.agent.run(spørsmål)</p>
<p># Opprett spesialist-agenter
forsknings_agent = SpesialistAgent("Forskning", [Tool(navn="RAG-QA", func=qa.run, beskrivelse="For AI- og ML-spørsmål")])
matematikk_agent = SpesialistAgent("Matematikk", [Tool(navn="Regneark", func=regneark._run, beskrivelse="For beregninger")])
generell_agent = SpesialistAgent("Generell", [Tool(navn="Søk", func=søk.run, beskrivelse="For generelle spørsmål")])</p>
<p>class Koordinator:
def __init__(self, agenter):
self.agenter = agenter</p>
<p>def run(self, spørsmål):
# Bestemm hvilken agent som skal brukes
if "beregne" in spørsmål.lower() or any(op in spørsmål for op in ['+', '-', '*', '/']):
return self.agenter['Matematikk'].run(spørsmål)
elif any(termer in spørsmål.lower() for termer in ['ai', 'maskinlæring', 'dyplæring']):
return self.agenter['Forskning'].run(spørsmål)
else:
return self.agenter['Generell'].run(spørsmål)</p>
<p>koordinator = Koordinator({'Forskning': forskins_agent, 'Matematikk': matematikk_agent, 'Generell': generell_agent})</p>
<p># Test multi-agent-systemet
resultat = koordinator.run("Hva er forskjellen på CNN og RNN? Og beregn 25% av 120.")
print(resultat)</p>
Dette multi-agent-systemet lar oss spesialisere og håndtere en bredere rekke av spørsmål mer effektivt.
Evaluering og optimalisering av RAG-agenter
For å sikre at vår RAG-agent fungerer bra, må vi implementere evaluering-metrikker og optimaliseringsteknikker:
a) Relevans-evaluering
Vi kan bruke metrikker som BLEU, ROUGE eller BERTScore til å evaluere relevansen av hentede dokumenter:
<p>from bert_score import score</p> <p>def evaluere_relevans(spørsmål, hentet_dokument, generert_svar): P, R, F1 = score([generert_svar], [hentet_dokument], lang="en") return F1.mean().item()</p>
b) Svar-kvalitets-evaluering
Vi kan bruke menneskelig evaluering eller automatiske metrikker til å vurdere svar-kvaliteten:
<p>from nltk.translate.bleu_score import sentence_bleu</p> <p>def evaluere_svar_kvalitet(referanse_svar, generert_svar): return sentence_bleu([referanse_svar.split()], generert_svar.split())</p> <p># Bruk denne til å evaluere din agent-svar
Fremtidige retninger og utfordringer
Mens vi ser fremover mot fremtiden for RAG-agenter, finnes det flere spennende retninger og utfordringer:
a) Multi-modal RAG: Utvide RAG til å inkludere bilde-, lyd- og video-data.
b) Federeret RAG: Implementere RAG på tvers av distribuerte, privat-preserverende kunnskapsbaserte systemer.
c) Kontinuerlig læring: Utvikle metoder for RAG-agenter til å oppdatere sine kunnskapsbaserte systemer og modeller over tid.
d) Etiske overveielser: Behandle bias, rettferdighet og gjennomsiktighet i RAG-systemer.
e) Skalbarhet: Optimalisere RAG for store, sanntids-applikasjoner.
Konklusjon
Bygging av LLM-agenter for RAG fra scratch er en kompleks, men belønning prosess. Vi har dekket grunnleggende RAG, implementert et enkelt system, opprettet en LLM-agent, forbedret den med avanserte tekniker, utforsket multi-agent-systemer og diskutert evaluering og optimaliseringsteknikker.














