Перейти к содержанию

Ответы 2.7

Теория

  1. Память диалога: Обеспечивает чат-боту контекст между сообщениями, что позволяет генерировать более персонализированные и связные ответы.
  2. ConversationBufferMemory: Хранит всю историю переписки, что дает возможность ссылаться на прошлые сообщения в текущем диалоге.
  3. Conversation Retrieval Chain: Объединяет механизм памяти с извлечением информации из внешних источников для повышения точности и релевантности ответов.
  4. Стратегии управления контекстом: Варьируются от использования фиксированного буфера до динамического расширения контекста через извлечение документов, выбор стратегии зависит от конкретной задачи.
  5. NER (Named Entity Recognition): Помогает отслеживать ключевые сущности в диалоге и поддерживать целостность обсуждения.
  6. Конфиденциальность данных: Требует минимизации сбора данных, анонимизации чувствительной информации и наличия прозрачных и законных политик хранения данных.
  7. Смена темы: При изменении темы диалога могут помочь механизмы резюмирования, тематическая память и выборка наиболее релевантной информации из истории беседы.
  8. Метрики оценки: Включают удовлетворенность пользователей, успешность выполнения задач, а также автоматические показатели связности и релевантности ответов.
  9. Персистентная память: Полезна для поддержания контекста между повторными сессиями, сохраняя предпочтения пользователя, а также информацию о прошлых проблемах и их решениях.
  10. Практические рекомендации: Включают обеспечение приватности, прозрачности, предоставление пользователю контроля над памятью и постоянный мониторинг качества взаимодействия.

Практические задания

1.

def embed_document(document_text):
    """
    Функция-заглушка для генерации эмбеддинга документа.
    В реальном сценарии эта функция должна преобразовывать входной текст документа в числовой векторное представление.
    """
    # Симулированный эмбеддинг для демонстрационных целей (используется простой хеш на основе длины текста).
    return [hash(document_text) % 100]

def create_vector_store(documents):
    """
    Преобразует список документов в их эмбеддинги и сохраняет их в простой структуре данных в памяти.

    Args:
        documents (list of str): Список текстовых документов для преобразования в эмбеддинги.

    Returns:
        list: Список сгенерированных эмбеддингов, представляющих входные документы.
    """
    vector_store = [embed_document(doc) for doc in documents]
    return vector_store

# Пример использования функций embed_document и create_vector_store:
documents = [
    "Document 1 text content here.",
    "Document 2 text content, possibly different.",
    "Another document, the third one."
]
vector_store = create_vector_store(documents)
print("Векторное хранилище:", vector_store)

2.

def calculate_similarity(query_embedding, document_embedding):
    """
    Функция-заглушка для вычисления сходства между двумя эмбеддингами.
    На практике для этого могут использоваться метрики, такие как косинусное сходство или евклидово расстояние.

    Args:
        query_embedding (list): Эмбеддинг поискового запроса.
        document_embedding (list): Эмбеддинг документа.

    Returns:
        float: Симулированная оценка сходства между запросом и документом.
    """
    # Упрощенный расчет сходства для демонстрационных целей.
    return -abs(query_embedding[0] - document_embedding[0])

def perform_semantic_search(query, vector_store):
    """
    Выполняет семантический поиск, чтобы найти документ, наиболее похожий на запрос, в заданном векторном хранилище.

    Args:
        query (str): Поисковый запрос пользователя.
        vector_store (list): Структура данных в памяти, содержащая эмбеддинги документов.

    Returns:
        int: Индекс наиболее похожего документа в `vector_store`.
    """
    query_embedding = embed_document(query)
    similarity_scores = [calculate_similarity(query_embedding, doc_embedding) for doc_embedding in vector_store]

    # Находим индекс документа с наивысшей оценкой сходства.
    most_similar_index = similarity_scores.index(max(similarity_scores))
    return most_similar_index

# Пример использования функций calculate_similarity и perform_semantic_search:
query = "Document content that resembles document 1 more than others."
most_similar_doc_index = perform_semantic_search(query, vector_store)
print("Индекс наиболее похожего документа:", most_similar_doc_index)

3.

class Chatbot:
    def __init__(self):
        # Инициализируем пустой список для хранения истории чата. Каждый элемент этого списка
        # будет представлять собой кортеж, содержащий запрос пользователя и соответствующий ответ бота.
        self.history = []

    def generate_response(self, query, context):
        """
        Функция-заглушка для симуляции генерации ответа на основе текущего запроса пользователя
        и предоставленного контекста (истории чата).

        Args:
            query (str): Текущий запрос пользователя.
            context (list of tuples): Список кортежей, где каждый кортеж содержит пару (запрос, ответ),
                                      представляющую историю чата.

        Returns:
            str: Симулированный ответ чат-бота.
        """
        # Для простоты демонстрации ответ является перевернутым запросом
        # с добавлением информации о количестве предыдущих взаимодействий в истории.
        return f"Response to '{query}' (with {len(context)} past interactions)."

    def respond_to_query(self, query):
        """
        Принимает запрос пользователя, генерирует ответ с учетом текущей истории чата и
        обновляет историю новым взаимодействием (запрос-ответ).

        Args:
            query (str): Запрос пользователя.

        Returns:
            str: Сгенерированный ответ чат-бота.
        """
        # Используем текущее состояние истории чата как контекст для генерации ответа.
        response = self.generate_response(query, self.history)

        # Обновляем историю чата, добавляя текущий запрос и сгенерированный ответ.
        self.history.append((query, response))

        return response

# Пример использования класса Chatbot:
chatbot = Chatbot()
print(chatbot.respond_to_query("Hello, how are you?"))
print(chatbot.respond_to_query("What is the weather like today?"))
print(chatbot.respond_to_query("Thank you!"))

4

class LanguageModel:
    def predict(self, input_text):
        # Заглушка метода `predict` языковой модели. В реальной реализации здесь будет
        # выполняться вызов к настоящей языковой модели для генерации ответа.
        return f"Mock response for: {input_text}"

class DocumentRetriever:
    def retrieve(self, query):
        # Заглушка метода `retrieve` для извлечения документов. В реальной системе
        # этот метод будет искать и возвращать релевантные документы на основе запроса.
        return f"Mock document related to: {query}"

class ConversationMemory:
    def __init__(self):
        # Инициализируем пустой список для хранения истории беседы.
        self.memory = []

    def add_to_memory(self, query, response):
        # Добавляет новую запись (запрос и ответ) в историю памяти.
        self.memory.append((query, response))

    def reset_memory(self):
        # Очищает всю историю памяти, сбрасывая беседу.
        self.memory = []

    def get_memory(self):
        # Возвращает текущую историю памяти.
        return self.memory

def setup_conversational_retrieval_chain():
    # Инициализируем отдельные компоненты для цепочки извлечения:
    # языковую модель, извлекатель документов и память беседы.
    language_model = LanguageModel()
    document_retriever = DocumentRetriever()
    conversation_memory = ConversationMemory()

    # Для демонстрационных целей эта функция возвращает словарь, представляющий
    # инициализированные компоненты. В реальной реализации эти компоненты были бы
    # интегрированы в более сложную и функциональную систему извлечения.
    retrieval_chain = {
        "language_model": language_model,
        "document_retriever": document_retriever,
        "conversation_memory": conversation_memory
    }

    return retrieval_chain

# Пример использования функции setup_conversational_retrieval_chain:
retrieval_chain = setup_conversational_retrieval_chain()
print(retrieval_chain)

5.

class EnhancedChatbot(Chatbot):
    def __init__(self):
        super().__init__()
        # Инициализируем `ConversationMemory` из предыдущей задачи для управления историей чата.
        self.conversation_memory = ConversationMemory()

    def add_to_history(self, query, response):
        """
        Добавляет новую запись (запрос пользователя и ответ чат-бота) в историю беседы,
        используя `ConversationMemory`.

        Args:
            query (str): Запрос пользователя.
            response (str): Ответ чат-бота.
        """
        self.conversation_memory.add_to_memory(query, response)

    def reset_history(self):
        """
        Сбрасывает всю историю беседы, очищая все прошлые взаимодействия.
        """
        self.conversation_memory.reset_memory()

    def respond_to_query(self, query):
        """
        Переопределяет метод `respond_to_query` базового класса `Chatbot` для включения
        расширенного управления памятью беседы.
        """
        # Генерируем ответ, используя метод базового класса и текущую историю памяти.
        response = super().generate_response(query, self.conversation_memory.get_memory())

        # Обновляем историю беседы с новым запросом и сгенерированным ответом.
        self.add_to_history(query, response)

        return response

# Пример использования класса EnhancedChatbot:
enhanced_chatbot = EnhancedChatbot()
print(enhanced_chatbot.respond_to_query("Hello, how are you?"))
enhanced_chatbot.reset_history()
print(enhanced_chatbot.respond_to_query("Starting a new conversation."))

6.

def embed_document(document_text):
    # Функция-заглушка для симуляции эмбеддинга текста документа. В реальной системе
    # здесь использовалась бы настоящая модель эмбеддингов, например, OpenAI Embeddings.
    return sum(ord(char) for char in document_text) % 100  # Простой хеш для демонстрации

def split_document_into_chunks(document, chunk_size=100):
    # Разбивает входной текст документа на управляемые фрагменты (чанки) заданного размера.
    return [document[i:i+chunk_size] for i in range(0, len(document), chunk_size)]

def perform_semantic_search(query_embedding, vector_store):
    # Находит наиболее релевантный фрагмент документа в векторном хранилище
    # на основе сходства эмбеддингов. Логика поиска здесь является заглушкой.
    similarities = [abs(query_embedding - chunk_embedding) for chunk_embedding in vector_store]
    return similarities.index(min(similarities))

def generate_answer_from_chunk(chunk):
    # Функция-заглушка для симуляции генерации ответа из выбранного фрагмента документа.
    # В реальной системе использовалась бы LLM для формулирования ответа.
    return f"Based on your question, a relevant piece of information is: \"{chunk[:50]}...\""

# Основная логика простой системы вопросов и ответов (Q&A).
document = "This is a long document. " * 100  # Симулированный длинный документ
chunks = split_document_into_chunks(document, 100)
vector_store = [embed_document(chunk) for chunk in chunks]

# Симулируем вопрос пользователя и его эмбеддинг.
user_question = "What is this document about?"
question_embedding = embed_document(user_question)

# Находим наиболее релевантный фрагмент документа для ответа.
relevant_chunk_index = perform_semantic_search(question_embedding, vector_store)
relevant_chunk = chunks[relevant_chunk_index]

# Генерируем ответ на основе найденного релевантного фрагмента.
answer = generate_answer_from_chunk(relevant_chunk)
print(answer)

7.

def integrate_memory_with_retrieval_chain(retrieval_chain, user_query):
    """
    Интегрирует конверсационную цепочку извлечения с системой памяти для поддержания контекста
    в ходе диалога.

    Args:
        retrieval_chain (dict): Мок-цепочка извлечения, которая содержит языковую модель,
                                 извлекатель документов и память беседы.
        user_query (str): Текущий запрос пользователя для обработки.
    """
    # Получаем необходимые компоненты из переданной цепочки извлечения.
    conversation_memory = retrieval_chain["conversation_memory"]
    language_model = retrieval_chain["language_model"]
    document_retriever = retrieval_chain["document_retriever"]

    # Симулируем использование извлекателя документов для поиска релевантной информации
    # на основе запроса пользователя.
    relevant_info = document_retriever.retrieve(user_query)

    # Получаем текущую историю беседы для использования в качестве контекста.
    context = conversation_memory.get_memory()

    # Симулируем генерацию ответа с помощью языковой модели, используя запрос,
    # контекст и извлеченную информацию.
    response = language_model.predict(f"Query: {user_query}, Context: {context}, Relevant Info: {relevant_info}")

    # Обновляем память беседы, добавляя текущий запрос пользователя и сгенерированный ответ.
    conversation_memory.add_to_memory(user_query, response)

    return response

# Используем цепочку извлечения из задачи 4 с фиктивным запросом для демонстрации работы.
dummy_query = "Tell me more about this document."
response = integrate_memory_with_retrieval_chain(retrieval_chain, dummy_query)
print("Сгенерированный ответ:", response)

8.

def chatbot_cli():
    # Инициализируем EnhancedChatbot, предполагая, что это расширенная версия
    # чат-бота из предыдущих задач с поддержкой памяти.
    enhanced_chatbot = EnhancedChatbot()

    while True:
        print("\nДоступные опции: ask [вопрос], view history, reset history, exit")
        user_input = input("Что бы вы хотели сделать? ").strip().lower()

        if user_input.startswith("ask "):
            question = user_input[4:]
            response = enhanced_chatbot.respond_to_query(question)
            print("Чат-бот:", response)
        elif user_input == "view history":
            for i, (q, a) in enumerate(enhanced_chatbot.conversation_memory.get_memory(), 1):
                print(f"{i}. Вопрос: {q} Ответ: {a}")
        elif user_input == "reset history":
            enhanced_chatbot.reset_history()
            print("История беседы была успешно сброшена.")
        elif user_input == "exit":
            print("Завершение работы чат-бота. До свидания!")
            break
        else:
            print("Неверная опция. Пожалуйста, попробуйте еще раз.")

# Чтобы запустить интерфейс командной строки (CLI) чат-бота, раскомментируйте следующую строку.
# (Закомментировано, чтобы предотвратить автоматическое выполнение в неинтерактивных средах.)
# chatbot_cli()