AGI та майбутній ШІ
Будування агентів LLM для RAG з нуля та далі: Комплексний посібник
Моделі LLM, такі як GPT-3, GPT-4 та їх відкритий аналог, часто мають труднощі з пошуком актуальної інформації та іноді генерують хибну інформацію.
Пошук з підтримкою генерації (RAG) – це техніка, яка поєднує потужність моделей LLM з зовнішнім пошуком інформації. RAG дозволяє нам ґрунтувати відповіді моделей LLM на фактичній, актуальній інформації, суттєво покращуючи точність та надійність згенерованого вмісту.
У цьому блог-пості ми дослідимо, як будувати агенти LLM для RAG з нуля, заглиблючись у архітектуру, деталі реалізації та просунуті техніки. Ми покриємо все, від основ RAG до створення складних агентів, здатних до складного мислення та виконання завдань.
Перш ніж ми почнемо будувати наш агент LLM, давайте зрозуміємо, що таке RAG і чому воно важливе.
RAG, або пошук з підтримкою генерації, – це гібридний підхід, який поєднує пошук інформації з генерацією тексту. У системі RAG:
- Запит використовується для пошуку відповідних документів у базі знань.
- Ці документи потім передаються у модель мови разом з початковим запитом.
- Модель генерує відповідь на основі як запиту, так і отриманої інформації.
Цей підхід має кілька переваг:
- Покращена точність: Ґрунтуючи відповіді на отриманій інформації, RAG зменшує хибну інформацію та покращує фактичну точність.
- Актуальна інформація: База знань може бути регулярно оновлена, що дозволяє системі отримувати доступ до актуальної інформації.
- Прозорість: Система може надавати джерела інформації, збільшуючи довіру та дозволяючи проводити фактологічну перевірку.
Розуміння агентів LLM
Коли ви стикаєтеся з проблемою, яка не має простого答案у, вам часто потрібно виконати кілька кроків, ретельно подумати та пам’ятати, що ви вже спробували. Агенти LLM призначені саме для таких ситуацій у застосуваннях моделей мови. Вони поєднують ретельний аналіз даних, стратегічне планування, пошук інформації та здатність навчатися на минулих діях, щоб вирішувати складні питання.
Що таке агенти LLM?
Агенти LLM – це просунуті системи штучного інтелекту, призначені для створення складного тексту, який вимагає послідовного мислення. Вони можуть думати наперед, пам’ятати минулі розмови та використовувати різні інструменти для коригування своїх відповідей залежно від ситуації та стилю, який потрібен.
Розглянемо питання у сфері права, наприклад: “Які потенційні юридичні наслідки порушення певного типу договору у Каліфорнії?” Базова модель LLM з системою RAG може отримати необхідну інформацію з юридичних баз даних.
Для більш детального сценарію: “У світлі нових законів про захист даних, які спільні юридичні виклики стоять перед компаніями, та як суди розглядали ці питання?” Це питання копає глибше, ніж просто пошук фактів. Воно стосується розуміння нових правил, їх впливу на різні компанії та реакції суду. Агент LLM розбив би це завдання на підзадачі, такі як отримання останніх законів, аналіз історичних випадків, підсумовування юридичних документів та прогнозування тенденцій на основі закономірностей.
Компоненти агентів LLM
Агенти LLM загалом складаються з чотирьох компонентів:
- Агент/Мозок: Центральна модель мови, яка обробляє та розуміє мову.
- Планування: Спроможність мислити, розбивати завдання та розробляти конкретні плани.
- Пам’ять: Зберігає записи минулих взаємодій та вчиться з них.
- Використання інструментів: Інтегрує різні ресурси для виконання завдань.
Агент/Мозок
У центрі агента LLM знаходиться модель мови, яка обробляє та розуміє мову на основі великих обсягів даних, на яких вона була навчена. Ви починаєте з надання йому конкретного запиту, керуючи агентом щодо того, як відповісти, які інструменти використовувати та які цілі досягти. Ви можете налаштувати агента з персоною, придатною для конкретних завдань або взаємодій, покращуючи його продуктивність.
Пам’ять
Компонент пам’яті допомагає агентам LLM виконувати складні завдання, зберігаючи записи минулих дій. Існують два основних типу пам’яті:
- Короткочасна пам’ять: Діє як блокнот, слідкуючи за тривалими розмовами.
- Довгочасна пам’ять: Функціонує як щоденник, зберігаючи інформацію з минулих взаємодій, щоб вивчити закономірності та приймати кращі рішення.
Поєднуючи ці типи пам’яті, агент може надавати більш підходящі відповіді та пам’ятати вподобання користувача з часом, створюючи більш з’єднану та актуальну взаємодію.
Планування
Планування дозволяє агентам LLM мислити, розбивати завдання на керованих частини та адаптувати плани, коли завдання еволюціонують. Планування включає два основних етапи:
- Формулювання плану: Розбивка завдання на менші підзадачі.
- Відображення плану: Перегляд та оцінка ефективності плану, включаючи зворотний зв’язок для уточнення стратегій.
Методи, такі як ланцюг мислення (CoT) та дерево мислення (ToT), допомагають у цьому процесі розбивки, дозволяючи агентам досліджувати різні шляхи для вирішення проблеми.
Для глибшого погруження у світ агентів штучного інтелекту, включаючи їх поточні можливості та потенціал, розгляньте читання “Auto-GPT & GPT-Engineer: Глибокий огляд сучасних лідерів агентів штучного інтелекту”
Налаштування середовища
Щоб побудувати наш агент RAG, нам потрібно налаштувати середовище розробки. Ми будемо використовувати Python та кілька ключових бібліотек:
- LangChain: Для оркестрування наших компонентів LLM та пошuku
- Chroma: Як наш векторний магазин для вкладень документів
- Моделі GPT від OpenAI: Як наш базовий LLM (ви можете замінити це на відкриту модель, якщо бажаєте)
- FastAPI: Для створення простого API для взаємодії з нашим агентом
Давайте почнемо з налаштування нашого середовища:
<p># Створіть нове віртуальне середовище python -m venv rag_agent_env source rag_agent_env/bin/activate # На Windows, використовуйте `rag_agent_env\Scripts\activate`</p> <p># Встановіть необхідні пакети pip install langchain chromadb openai fastapi uvicorn
Тепер давайте створимо новий файл Python під назвою rag_agent.py та імпортуємо необхідні бібліотеки:
<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># Встановіть свій ключ API OpenAI os.environ["OPENAI_API_KEY"] = "ваш_ключ_апі_тут"</p>
Побудова простої системи RAG
Тепер, коли у нас налаштоване середовище, давайте побудуємо базову систему RAG. Ми почнемо з створення бази знань з набору документів, а потім використаємо її для відповідей на запити.
Крок 1: Підготуйте документи
Спочатку нам потрібно завантажити та підготувати наші документи. Для цього прикладу давайте припустимо, що у нас є текстовий файл під назвою knowledge_base.txt з деякою інформацією про штучний інтелект та машинне навчання.
<p># Завантажте документ loader = TextLoader("knowledge_base.txt") documents = loader.load()</p> <p># Розбийте документи на частини text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents)</p> <p># Створіть вкладення embeddings = OpenAIEmbeddings()</p> <p># Створіть векторний магазин vectorstore = Chroma.from_documents(texts, embeddings)</p>
Крок 2: Створіть ланцюг запитів RAG
Тепер, коли у нас є векторний магазин, ми можемо створити ланцюг запитів RAG:
<p># Створіть ланцюг запитів RAG qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vectorstore.as_retriever())</p>
Крок 3: Запитайте систему
Ми можемо тепер запитати нашу систему RAG:
<p>query = "Які основні застосування машинного навчання?" result = qa.run(query) print(result)
Крок 4: Створення агента LLM
Хоча наша проста система RAG корисна, вона досить обмежена. Давайте покращимо її, створивши агент LLM, який може виконувати складніші завдання та мислити про інформацію, яку він отримує.
Агент LLM – це система штучного інтелекту, яка може використовувати інструменти та приймати рішення про дії. Ми створимо агента, який може не тільки відповісти на питання, але також виконувати пошук у мережі та базові розрахунки.
Спочатку давайте визначимо деякі інструменти для нашого агента:
<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># Визначте інструмент калькулятора class CalculatorTool(BaseTool): name = "Калькулятор" description = "Корисний для математичних розрахунків"</p> <p>def _run(self, query: str) try: return str(eval(query)) except: return "Не можу виконати розрахунок. Будь ласка, переконайтесь, що ваш вхід є дійсним математичним виразом."</p> <p># Створіть інструменти search = DuckDuckGoSearchRun() calculator = CalculatorTool()</p> <p># Визначте інструменти tools = [Tool(name="Пошук", func=search.run, description="Корисний для запитів про поточні події"), Tool(name="RAG-Запит", func=qa.run, description="Корисний для запитів про штучний інтелект та машинне навчання"), Tool(name="Калькулятор", func=calculator._run, description="Корисний для математичних розрахунків") ]</p> <p># Ініціалізуйте агента agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True )</p>
Тепер у нас є агент, який може використовувати нашу систему RAG, виконувати пошук у мережі та розрахунки. Давайте протестуємо його:
<p>result = agent.run("Яка різниця між наглядним та ненаглядним навчанням? Також, яке 15% від 80?") print(result)</p>
Цей агент демонструє ключову перевагу агентів LLM: вони можуть поєднувати кілька інструментів та кроків мислення, щоб відповісти на складні запити.
Покращення агента просунутими техніками RAG
Хоча наша поточна система RAG працює добре, існують кілька просунутих технік, які ми можемо використовувати для покращення її продуктивності:
a) Семантичний пошук з густим пошуком проходів (DPR)
Замість використання простого вкладення на основі пошuku, ми можемо реалізувати DPR для більш точного семантичного пошуку:
<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># Функція для кодування проходів def encode_passages(passages): return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output</p> <p># Функція для кодування запиту def encode_query(query): return question_encoder(query, max_length=512, return_tensors="pt").pooler_output</p>
b) Розширення запиту
Ми можемо використовувати розширення запиту для покращення продуктивності пошuku:
<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"expand query: {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) Ітеративне уточнення
Ми можемо реалізувати ітеративний процес уточнення, у якому агент може задавати додаткові запитання для уточнення або розширення своєї початкової інформації:
<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"Based on this result: '{result}', what follow-up question should I ask to get more specific information?")
if clarification.lower().strip() == "none":
break
query = clarification
return result</p>
# Використайте це в процесі вашого агента
Реалізація системи багатокористувацького агента
Щоб обробляти складніші завдання, ми можемо реалізувати систему багатокористувацького агента, у якій різні агенти спеціалізуються на різних областях. Ось простий приклад:
<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># Створіть агентів-спеціалістів
research_agent = SpecialistAgent("Дослідження", [Tool(name="RAG-Запит", func=qa.run, description="Для запитів про штучний інтелект та машинне навчання")])
math_agent = SpecialistAgent("Математика", [Tool(name="Калькулятор", func=calculator._run, description="Для математичних розрахунків")])
general_agent = SpecialistAgent("Загальний", [Tool(name="Пошук", func=search.run, description="Для загальних запитів")])</p>
<p>class Coordinator:
def __init__(self, agents):
self.agents = agents</p>
<p>def run(self, query):
# Визначте, який агент використовувати
if "calculate" in query.lower() or any(op in query for op in ['+', '-', '*', '/']):
return self.agents['Математика'].run(query)
elif any(term in query.lower() for term in ['ai', 'machine learning', 'deep learning']):
return self.agents['Дослідження'].run(query)
else:
return self.agents['Загальний'].run(query)</p>
<p>coordinator = Coordinator({'Дослідження': research_agent, 'Математика': math_agent, 'Загальний': general_agent})</p>
<p># Протестуйте систему багатокористувацького агента
result = coordinator.run("Яка різниця між CNN та RNN? Також, розрахуйте 25% від 120.")
print(result)</p>
Ця система багатокористувацького агента дозволяє спеціалізуватися та обробляти ширший спектр запитів більш ефективно.
Оцінка та оптимізація агентів RAG
Щоб забезпечити, що наш агент RAG працює добре, нам потрібно реалізувати метрики оцінки та техніки оптимізації:
a) Оцінка актуальності
Ми можемо використовувати метрики, такі як BLEU, ROUGE або BERTScore, для оцінки актуальності отриманих документів:
<p>from bert_score import score</p> <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) Оцінка якості відповідей
Ми можемо використовувати оцінку людини або автоматичні метрики для оцінки якості відповідей:
<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># Використайте це для оцінки відповідей вашого агента
Майбутні напрямки та виклики
Як ми дивимося у майбутнє агентів RAG, кілька цікавих напрямків та викликів з’являються:
a) Багатомодальний RAG: Розширення RAG для включення даних зображень, аудіо та відео.
b) Федеративний RAG: Реалізація RAG у розподілених, захищених базах знань.
c) Постійне навчання: Розробка методів для оновлення знань та моделей агентів RAG з часом.
d) Етичні питання: Розгляд питань упередженості, справедливості та прозорості у системах RAG.
e) Масштабованість: Оптимізація RAG для великомасштабних, реальних застосунків.
Висновок
Будування агентів LLM для RAG з нуля – це складний, але винагороджувальний процес. Ми розглянули основи RAG, реалізували просту систему, створили агент LLM, покращили його просунутими техніками, дослідили систему багатокористувацького агента та обговорили стратегії оцінки та оптимізації.














