AGI i przyszłość AI
Budowanie agentów LLM dla RAG od podstaw i poza: Kompleksowy przewodnik
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.
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:
- Agent/Czerep: Podstawowy model językowy, który przetwarza i rozumie język.
- Planowanie: Możliwość rozumowania, rozkładania zadań i tworzenia konkretnych planów.
- Pamięć: Zachowuje rekordy poprzednich interakcji i uczy się z nich.
- 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["OPENAI_API_KEY"] = "twój_klucz_api_tutaj"</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("knowledge_base.txt") 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="stuff", retriever=vectorstore.as_retriever())</p>
Krok 3: Zapytaj system
Możemy teraz zapytać nasz system RAG:
<p>query = "Jakie są główne zastosowania machine learningu?" 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 = "Kalkulator" description = "Przydatne, gdy potrzebujesz odpowiedzi na pytania matematyczne"</p> <p>def _run(self, query: str) try: return str(eval(query)) except: return "Nie mogłem tego obliczyć. Upewnij się, że Twoje wprowadzenie jest prawidłowym wyrażeniem matematycznym."</p> <p># Utwórz instancje narzędzi search = DuckDuckGoSearchRun() calculator = CalculatorTool()</p> <p># Zdefiniuj narzędzia tools = [Tool(name="Wyszukiwarka",func=search.run,description="Przydatne, gdy potrzebujesz odpowiedzi na pytania o bieżące wydarzenia"), Tool(name="RAG-QA",func=qa.run,description="Przydatne, gdy potrzebujesz odpowiedzi na pytania o AI i machine learning"), Tool(name="Kalkulator",func=calculator._run,description="Przydatne, gdy potrzebujesz wykonać obliczenia matematyczne") ]</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("Jaka jest różnica między nadzorowanym a nienadzorowanym uczeniem? Również, jaka jest 15% z 80?") 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("facebook/dpr-question_encoder-single-nq-base") context_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")</p> <p># Funkcja do kodowania fragmentów def encode_passages(passages): return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output</p> <p># Funkcja do kodowania zapytania def encode_query(query): return question_encoder(query, max_length=512, return_tensors="pt").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("t5-small")
tokenizer = T5Tokenizer.from_pretrained("t5-small")</p>
<p>def expand_query(query):
input_text = f"rozszerz zapytanie: {query}"
input_ids = tokenizer.encode(input_text, return_tensors="pt")
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"Na podstawie tego wyniku: '{result}', jakie następne pytanie powinienem zadać, aby uzyskać bardziej szczegółowe informacje?")
if clarification.lower().strip() == "none":
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("Badania", [Tool(name="RAG-QA", func=qa.run, description="Dla pytań o AI i machine learning")])
math_agent = SpecialistAgent("Matematyka", [Tool(name="Kalkulator", func=calculator._run, description="Dla obliczeń")])
general_agent = SpecialistAgent("Ogólny", [Tool(name="Wyszukiwarka", func=search.run, description="Dla ogólnych pytań")])</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 "calculate" in query.lower() or any(op in query for op in ['+', '-', '*', '/']):
return self.agents['Matematyka'].run(query)
elif any(term in query.lower() for term in ['ai', 'machine learning', 'deep learning']):
return self.agents['Badania'].run(query)
else:
return self.agents['Ogólny'].run(query)</p>
<p>coordinator = Coordinator({'Badania': research_agent, 'Matematyka': math_agent, 'Ogólny': general_agent})</p>
<p># Przetestuj system wieloagentowy
result = coordinator.run("Jaka jest różnica między CNN a RNN? Również, jaka jest 25% z 120?")
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="en") 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ę.














