AGI i przyszłość AI

Budowanie agentów LLM dla RAG od podstaw i poza: Kompleksowy przewodnik

mm
Dodaj Unite.AI do preferowanych źródeł w Google

LLM, takie jak GPT-3, GPT-4 i ich otwarte odpowiedniki, często mają trudności z pobieraniem informacji na bieżący temat i mogą generować halucynacje lub nieprawidłowe informacje.

Retrieval-Augmented Generation (RAG) to technika, która łączy moc LLM z zewnętrznym pobieraniem wiedzy. RAG pozwala nam oprzeć odpowiedzi LLM na faktach i aktualnych informacjach, znacznie poprawiając dokładność i niezawodność generowanego przez AI treści.

W tym poście blogowym, będziemy eksplorować, jak zbudować agenty LLM dla RAG od podstaw, zagłębiając się w architekturę, szczegóły implementacji i zaawansowane techniki. Będziemy pokrywać wszystko, od podstaw RAG do tworzenia zaawansowanych agentów zdolnych do złożonego rozumowania i wykonywania zadań.

Przed rozpoczęciem budowy naszego agenta LLM, rozważmy, co to jest RAG i dlaczego jest ważne.

RAG, czyli Retrieval-Augmented Generation, to hybrydowy podejście, które łączy pobieranie informacji z generowaniem tekstu. W systemie RAG:

  • Zapytanie służy do pobrania istotnych dokumentów z bazy wiedzy.
  • Te dokumenty są następnie wprowadzane do modelu językowego wraz z oryginalnym zapytaniem.
  • Model generuje odpowiedź na podstawie zapytania i pobranych informacji.
RAG

RAG

To podejście ma kilka zalet:

  • Poprawiona dokładność: Poprzez oprzanie odpowiedzi na pobranych informacjach, RAG redukuje halucynacje i poprawia faktograficzną dokładność.
  • Informacje na bieżący temat: Baza wiedzy może być regularnie aktualizowana, umożliwiając systemowi dostęp do bieżących informacji.
  • Przejrzystość: System może dostarczyć źródła informacji, zwiększając zaufanie i umożliwiając weryfikację faktów.

Zrozumienie agentów LLM

 

Gdy napotkasz problem bez prostego rozwiązania, często musisz postępować według kilku kroków, starannie myśleć i pamiętać, co już spróbowałeś. Agenci LLM są zaprojektowani specjalnie dla tego rodzaju sytuacji w aplikacjach modeli językowych. Łączą dogłębną analizę danych, strategiczne planowanie, pobieranie danych i możliwość uczenia się z przeszłych działań, aby rozwiązać złożone problemy.

Co to są agenci LLM?

Agenci LLM to zaawansowane systemy AI zaprojektowane do tworzenia złożonego tekstu, który wymaga sekwencyjnego rozumowania. Mogą myśleć naprzód, pamiętać poprzednie rozmowy i korzystać z różnych narzędzi, aby dostosować swoje odpowiedzi do sytuacji i stylu potrzebnego.

Rozważmy pytanie w dziedzinie prawa, takie jak: “Jakie są potencjalne skutki prawne naruszenia określonego rodzaju umowy w Kalifornii?” Podstawowy LLM z systemem RAG może pobrać niezbędne informacje z baz prawnych.

Dla bardziej szczegółowego scenariusza: “W świetle nowych przepisów o ochronie danych, jakie są powszechne wyzwania prawne, z którymi spotykają się firmy, i jak sądy zajmowały się tymi sprawami?” To pytanie sięga głębiej niż tylko wyszukiwanie faktów. Chodzi o zrozumienie nowych zasad, ich wpływu na różne firmy i odpowiedzi sądów. Agent LLM podzieliłby to zadanie na podzadania, takie jak pobranie najnowszych przepisów, analiza historycznych przypadków, podsumowanie dokumentów prawnych i prognozowanie trendów na podstawie wzorców.

Składniki agentów LLM

Agenci LLM składają się zwykle z czterech składników:

  1. Agent/Czerep: Podstawowy model językowy, który przetwarza i rozumie język.
  2. Planowanie: Możliwość rozumowania, rozkładania zadań i tworzenia konkretnych planów.
  3. Pamięć: Zachowuje rekordy poprzednich interakcji i uczy się z nich.
  4. Korzystanie z narzędzi: Integruje różne zasoby, aby wykonywać zadania.

Agent/Czerep

W centrum agenta LLM znajduje się model językowy, który przetwarza i rozumie język na podstawie ogromnych ilości danych, na których został wyszkolony. Zaczynasz od podania mu konkretnego promtu, który kieruje agentem, jak odpowiedzieć, jakie narzędzia użyć i jakie cele osiągnąć. Możesz dostosować agenta do określonej osobowości, odpowiedniej dla konkretnych zadań lub interakcji, co poprawia jego wydajność.

Pamięć

Składnik pamięci pomaga agentom LLM radzić sobie z złożonymi zadaniami, zachowując rekord poprzednich działań. Istnieją dwa główne typy pamięci:

  • Pamięć krótkotrwała: Działa jak notatnik, śledząc bieżące dyskusje.
  • Pamięć długotrwała: Funkcjonuje jak dziennik, przechowując informacje z poprzednich interakcji, aby uczyć się wzorców i podejmować lepsze decyzje.

Łącząc te typy pamięci, agent może oferować bardziej dopasowane odpowiedzi i pamiętać preferencje użytkownika w czasie, tworząc bardziej powiązaną i istotną interakcję.

Planowanie

Planowanie umożliwia agentom LLM rozumowanie, rozkładanie zadań na mniejsze części i dostosowywanie planów, gdy zadania ewoluują. Planowanie obejmuje dwa główne etapy:

  • Formułowanie planu: Rozkładanie zadania na mniejsze podzadania.
  • Ocena planu: Przegląd i ocena skuteczności planu, włączając informacje zwrotne, aby udoskonalić strategie.

Metody takie jak Chain of Thought (CoT) i Tree of Thought (ToT) pomagają w tym procesie dekompozycji, pozwalając agentom na eksplorację różnych ścieżek, aby rozwiązać problem.

Aby zagłębić się w świat agentów AI, w tym ich bieżące możliwości i potencjał, rozważ przeczytanie “Auto-GPT & GPT-Engineer: Dogłębny przewodnik po wiodących agentach AI”

Konfigurowanie środowiska

Aby zbudować naszego agenta RAG, musimy skonfigurować nasze środowisko programistyczne. Będziemy używać Pythona i kilku kluczowych bibliotek:

  • LangChain: Do orchestracji naszych składników LLM i pobierania.
  • Chroma: Jako nasz magazyn wektorowy dla osadzania dokumentów.
  • Modele GPT OpenAI: Jako nasz podstawowy model LLM (można go zastąpić modelem open-source, jeśli wolisz).
  • FastAPI: Do tworzenia prostego API do interakcji z naszym agentem.

Zacznijmy od konfigurowania naszego środowiska:


<p># Utwórz nowe środowisko wirtualne
python -m venv rag_agent_env
source rag_agent_env/bin/activate # Na Windowsie, użyj `rag_agent_env\Scripts\activate`</p>

<p># Zainstaluj wymagane pakiety
pip install langchain chromadb openai fastapi uvicorn

Teraz, utwórz nowy plik Pythona o nazwie rag_agent.py i zaimportuj niezbędne biblioteki:


<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># Ustaw swój klucz API OpenAI
os.environ[&quot;OPENAI_API_KEY&quot;] = &quot;twój_klucz_api_tutaj&quot;</p>

Budowanie prostego systemu RAG

Teraz, gdy mamy skonfigurowane środowisko, zbudujmy podstawowy system RAG. Zacznijmy od utworzenia bazy wiedzy z zestawu dokumentów, a następnie użyjemy jej do odpowiedzi na zapytania.

Krok 1: Przygotuj dokumenty

Najpierw musimy załadować i przygotować nasze dokumenty. Załóżmy, że mamy plik tekstowy o nazwie knowledge_base.txt z pewnymi informacjami o AI i machine learning.


<p># Załaduj dokument
loader = TextLoader(&quot;knowledge_base.txt&quot;)
documents = loader.load()</p>

<p># Podziel dokumenty na fragmenty
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)</p>

<p># Utwórz osadzania
embeddings = OpenAIEmbeddings()</p>

<p># Utwórz magazyn wektorowy
vectorstore = Chroma.from_documents(texts, embeddings)</p>

Krok 2: Utwórz łańcuch RAG

Teraz, gdy mamy magazyn wektorowy, możemy utworzyć łańcuch RAG:


<p># Utwórz łańcuch RAG
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type=&quot;stuff&quot;, retriever=vectorstore.as_retriever())</p>

Krok 3: Zapytaj system

Możemy teraz zapytać nasz system RAG:


<p>query = &quot;Jakie są główne zastosowania machine learningu?&quot;
result = qa.run(query)
print(result)

Krok 4: Tworzenie agenta LLM

Podczas gdy nasz prosty system RAG jest użyteczny, jest dość ograniczony. Zwiększmy go, tworząc agenta LLM, który może wykonywać bardziej złożone zadania i rozumować o informacjach, które pobiera.

Agent LLM to system AI, który może używać narzędzi i podejmować decyzje o działaniach. Utworzymy agenta, który może nie tylko odpowiadać na pytania, ale także wykonywać wyszukiwania w sieci i podstawowe obliczenia.

Najpierw, zdefiniujmy kilka narzędzi dla naszego agenta:


<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># Zdefiniuj narzędzie do obliczeń
class CalculatorTool(BaseTool):
name = &quot;Kalkulator&quot;
description = &quot;Przydatne, gdy potrzebujesz odpowiedzi na pytania matematyczne&quot;</p>

<p>def _run(self, query: str)
try:
return str(eval(query))
except:
return &quot;Nie mogłem tego obliczyć. Upewnij się, że Twoje wprowadzenie jest prawidłowym wyrażeniem matematycznym.&quot;</p>

<p># Utwórz instancje narzędzi
search = DuckDuckGoSearchRun()
calculator = CalculatorTool()</p>

<p># Zdefiniuj narzędzia
tools = [Tool(name=&quot;Wyszukiwarka&quot;,func=search.run,description=&quot;Przydatne, gdy potrzebujesz odpowiedzi na pytania o bieżące wydarzenia&quot;),
Tool(name=&quot;RAG-QA&quot;,func=qa.run,description=&quot;Przydatne, gdy potrzebujesz odpowiedzi na pytania o AI i machine learning&quot;),
Tool(name=&quot;Kalkulator&quot;,func=calculator._run,description=&quot;Przydatne, gdy potrzebujesz wykonać obliczenia matematyczne&quot;)
]</p>

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

Teraz mamy agenta, który może używać naszego systemu RAG, wykonywać wyszukiwania w sieci i obliczenia. Zobaczmy, jak to działa:


<p>result = agent.run(&quot;Jaka jest różnica między nadzorowanym a nienadzorowanym uczeniem? Również, jaka jest 15% z 80?&quot;)
print(result)</p>

Ten agent demonstruje kluczową zaletę agentów LLM: mogą one łączyć wiele narzędzi i kroków rozumowania, aby odpowiedzieć na złożone zapytania.

Poprawianie agenta zaawansowanymi technikami RAG

Chociaż nasz bieżący system RAG działa dobrze, istnieją kilka zaawansowanych technik, których możemy użyć, aby poprawić jego wydajność:

a) Wyszukiwanie semantyczne z gęstym pobieraniem fragmentów (DPR)

Zamiast używać prostego pobierania opartego na osadzaniu, możemy zaimplementować DPR, aby uzyskać bardziej dokładne wyszukiwanie semantyczne:


<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># Funkcja do kodowania fragmentów
def encode_passages(passages):
return context_encoder(passages, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

<p># Funkcja do kodowania zapytania
def encode_query(query):
return question_encoder(query, max_length=512, return_tensors=&quot;pt&quot;).pooler_output</p>

b) Rozszerzanie zapytania

Możemy użyć rozszerzania zapytania, aby poprawić wydajność pobierania:


<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;rozszerz zapytanie: {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) Wielokrotne udoskonalanie

Możemy zaimplementować proces wielokrotnego udoskonalania, w którym agent może zadawać następne pytania, aby wyjaśnić lub rozszerzyć swoje pierwotne pobieranie:


<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;Na podstawie tego wyniku: &#039;{result}&#039;, jakie następne pytanie powinienem zadać, aby uzyskać bardziej szczegółowe informacje?&quot;)
if clarification.lower().strip() == &quot;none&quot;:
break
query = clarification
return result</p>

# Użyj tego w procesie agenta

Implementowanie systemu wieloagentowego

Aby obsłużyć bardziej złożone zadania, możemy zaimplementować system wieloagentowy, w którym różni agenci specjalizują się w różnych dziedzinach. Oto prosty przykład:


<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># Utwórz agenty specjalistyczne
research_agent = SpecialistAgent(&quot;Badania&quot;, [Tool(name=&quot;RAG-QA&quot;, func=qa.run, description=&quot;Dla pytań o AI i machine learning&quot;)])
math_agent = SpecialistAgent(&quot;Matematyka&quot;, [Tool(name=&quot;Kalkulator&quot;, func=calculator._run, description=&quot;Dla obliczeń&quot;)])
general_agent = SpecialistAgent(&quot;Ogólny&quot;, [Tool(name=&quot;Wyszukiwarka&quot;, func=search.run, description=&quot;Dla ogólnych pytań&quot;)])</p>

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

<p>def run(self, query):
# Określ, który agent użyć
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;Matematyka&#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;Badania&#039;].run(query)
else:
return self.agents[&#039;Ogólny&#039;].run(query)</p>

<p>coordinator = Coordinator({&#039;Badania&#039;: research_agent, &#039;Matematyka&#039;: math_agent, &#039;Ogólny&#039;: general_agent})</p>

<p># Przetestuj system wieloagentowy
result = coordinator.run(&quot;Jaka jest różnica między CNN a RNN? Również, jaka jest 25% z 120?&quot;)
print(result)</p>

Ten system wieloagentowy pozwala na specjalizację i może obsłużyć szerszy zakres zapytań w bardziej efektywny sposób.

Ocena i optymalizacja agentów RAG

Aby upewnić się, że nasz agent RAG działa dobrze, musimy zaimplementować metryki oceny i techniki optymalizacji:

a) Ocena istotności

Możemy użyć metryk takich jak BLEU, ROUGE lub BERTScore, aby ocenić istotność pobranych dokumentów:


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) Ocena jakości odpowiedzi

Możemy użyć oceny ludzkiej lub automatycznych metryk, aby ocenić jakość odpowiedzi:


<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># Użyj tego, aby ocenić odpowiedzi agenta

Przyszłe kierunki i wyzwania

Gdy patrzymy w przyszłość agentów RAG, pojawiają się kilka interesujących kierunków i wyzwań:

a) Wielomodalny RAG: Rozszerzenie RAG, aby uwzględnić dane obrazu, audio i wideo.

b) Federowany RAG: Zaimplementowanie RAG w rozproszonych, chronionych bazach wiedzy.

c) Ciągłe uczenie: Rozwój metod, które pozwalają agentom RAG na aktualizację swojej wiedzy i modeli w czasie.

d) Zagadnienia etyczne: Rozwiązanie problemów związanych z uprzedzeniami, uczciwością i przejrzystością w systemach RAG.

e) Skalowalność: Optymalizacja RAG dla dużych, rzeczywistych aplikacji.

Podsumowanie

Budowanie agentów LLM dla RAG od podstaw jest złożonym, ale satysfakcjonującym procesem. Przedstawiliśmy podstawy RAG, zaimplementowaliśmy prosty system, utworzyliśmy agenta LLM, poprawiliśmy go zaawansowanymi technikami, zbadaliśmy systemy wieloagentowe i omówiliśmy ocenę i optymalizację.

Przez ostatnie pięć lat zanurzałem się w fascynującym świecie Machine Learning i Deep Learning. Moja pasja i ekspertyza doprowadziły mnie do udziału w ponad 50 różnorodnych projektach inżynierii oprogramowania, ze szczególnym uwzględnieniem AI/ML. Moja nieustanna ciekawość również skierowała mnie w stronę Natural Language Processing, dziedziny, którą chcę dalej eksplorować.