Ответы 2.6
Теория
- Три стадии RAG-QA: Прием запроса, извлечение релевантных документов и генерация ответа.
- Ограничение окна контекста: Из-за ограничения размера контекстного окна LLM невозможно передать все фрагменты документов. Стратегии MapReduce и Refine помогают агрегировать или уточнять информацию из нескольких документов.
- Векторная база данных: Хранит эмбеддинги документов и обеспечивает быстрый поиск наиболее релевантных документов на основе их смыслового сходства.
- Цепочка RetrievalQA: Объединяет этапы поиска (Retrieval) и генерации ответа (QA), что повышает уместность и точность конечного результата.
- MapReduce и Refine: MapReduce позволяет быстро получить сводный ответ из большого количества документов, тогда как Refine обеспечивает последовательное уточнение информации, что критично для задач, где важна высокая точность. Выбор между ними зависит от конкретной задачи.
- Распределенные системы: При работе в распределенных системах необходимо учитывать сетевые задержки и механизмы сериализации данных.
- Экспериментирование: Рекомендуется экспериментировать с техниками MapReduce и Refine, поскольку их эффективность сильно зависит от типа данных и характера задаваемых вопросов.
- Ограничение RetrievalQA: Основным ограничением RetrievalQA является отсутствие встроенной истории диалога, что затрудняет поддержание контекста в последующих запросах.
- Память диалога: Необходима для учета предыдущих сообщений и обеспечения контекстных ответов в ходе продолжительной беседы.
- Направления для дальнейшего изучения: Новые подходы LLM, их влияние на RAG-системы и развитие стратегий управления памятью в RAG-цепочках.
Практические задания
1.
from langchain.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
def initialize_vector_database(directory_path):
# Инициализируем генератор эмбеддингов, используя модель OpenAI для создания векторных представлений текста.
embeddings_generator = OpenAIEmbeddings()
# Инициализируем векторную базу данных Chroma, указывая директорию для сохранения данных
# и функцию для генерации эмбеддингов.
vector_database = Chroma(persist_directory=directory_path, embedding_function=embeddings_generator)
# Отображаем текущее количество документов в векторной базе данных для проверки корректности инициализации.
# Предполагается, что объект `_collection` в Chroma предоставляет метод `count()`.
document_count = vector_database._collection.count()
print(f"Количество документов в VectorDB: {document_count}")
# Пример использования функции initialize_vector_database:
documents_storage_directory = 'path/to/your/directory'
initialize_vector_database(documents_storage_directory)
2.
from langchain.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate
def setup_retrieval_qa_chain(model_name, documents_storage_directory):
# Инициализируем генератор эмбеддингов и векторную базу данных Chroma.
embeddings_generator = OpenAIEmbeddings()
vector_database = Chroma(persist_directory=documents_storage_directory, embedding_function=embeddings_generator)
# Инициализируем языковую модель (LLM) для использования в цепочке RetrievalQA.
language_model = ChatOpenAI(model=model_name, temperature=0)
# Определяем пользовательский шаблон промпта для форматирования запросов к LLM.
custom_prompt_template = """To better assist with the inquiry, consider the details provided below as your reference...
{context}
Inquiry: {question}
Insightful Response:"""
# Инициализируем цепочку RetrievalQA, передавая языковую модель,
# ретривер из векторной базы данных, и настраивая возвращение исходных документов,
# а также используя пользовательский шаблон промпта.
question_answering_chain = RetrievalQA.from_chain_type(
language_model,
retriever=vector_database.as_retriever(),
return_source_documents=True,
chain_type_kwargs={"prompt": PromptTemplate.from_template(custom_prompt_template)}
)
return question_answering_chain
# Пример использования функции setup_retrieval_qa_chain:
model_name = "gpt-4o-mini"
documents_storage_directory = 'path/to/your/documents'
qa_chain = setup_retrieval_qa_chain(model_name, documents_storage_directory)
3.
# Предполагаем, что функция `setup_retrieval_qa_chain` определена в том же скрипте или импортирована.
# Настройка для демонстрации обеих техник (MapReduce и Refine),
# используя ту же языковую модель и директорию хранения документов.
model_name = "gpt-3.5-turbo"
documents_storage_directory = 'path/to/your/documents'
qa_chain = setup_retrieval_qa_chain(model_name, documents_storage_directory)
# Настраиваем цепочки ответов на вопросы: одну для MapReduce, другую для Refine.
question_answering_chain_map_reduce = RetrievalQA.from_chain_type(
qa_chain.language_model,
retriever=qa_chain.retriever,
chain_type="map_reduce" # Указываем тип цепочки как MapReduce
)
question_answering_chain_refine = RetrievalQA.from_chain_type(
qa_chain.language_model,
retriever=qa_chain.retriever,
chain_type="refine" # Указываем тип цепочки как Refine
)
# Определяем пример запроса для тестирования обеих техник.
query = "What is the importance of probability in machine learning?"
# Выполняем технику MapReduce и выводим полученный ответ.
response_map_reduce = question_answering_chain_map_reduce({"query": query})
print("Ответ MapReduce:", response_map_reduce["result"])
# Выполняем технику Refine и выводим полученный ответ.
response_refine = question_answering_chain_refine({"query": query})
print("Ответ Refine:", response_refine["result"])
4.
def handle_conversational_context(initial_query, follow_up_query, qa_chain):
"""
Симулирует обработку уточняющего вопроса в контексте продолжительной беседы.
Параметры:
- initial_query (str): Первый пользовательский запрос.
- follow_up_query (str): Уточняющий пользовательский запрос, относящийся к предыдущему контексту.
- qa_chain (RetrievalQA): Инициализированная цепочка ответов на вопросы, способная обрабатывать запросы.
Возвращает:
- None: Функция выводит ответы на оба запроса непосредственно в консоль.
"""
# Генерируем ответ на первоначальный запрос пользователя.
initial_response = qa_chain({"query": initial_query})
print("Ответ на первоначальный запрос:", initial_response["result"])
# Генерируем ответ на уточняющий запрос, который должен использовать контекст предыдущего диалога.
follow_up_response = qa_chain({"query": follow_up_query})
print("Ответ на уточняющий запрос:", follow_up_response["result"])
# Пример использования функции handle_conversational_context:
# Предполагается, что `question_answering_chain` уже настроена, как показано ранее.
initial_query = "What is the significance of probability in statistics?"
follow_up_query = "How does it apply to real-world problems?"
# handle_conversational_context(initial_query, follow_up_query, question_answering_chain)