AGI og fremtidens AI
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.














