Ответы 2.7
Теория
- Память диалога: Обеспечивает чат-боту контекст между сообщениями, что позволяет генерировать более персонализированные и связные ответы.
ConversationBufferMemory
: Хранит всю историю переписки, что дает возможность ссылаться на прошлые сообщения в текущем диалоге.- Conversation Retrieval Chain: Объединяет механизм памяти с извлечением информации из внешних источников для повышения точности и релевантности ответов.
- Стратегии управления контекстом: Варьируются от использования фиксированного буфера до динамического расширения контекста через извлечение документов, выбор стратегии зависит от конкретной задачи.
- NER (Named Entity Recognition): Помогает отслеживать ключевые сущности в диалоге и поддерживать целостность обсуждения.
- Конфиденциальность данных: Требует минимизации сбора данных, анонимизации чувствительной информации и наличия прозрачных и законных политик хранения данных.
- Смена темы: При изменении темы диалога могут помочь механизмы резюмирования, тематическая память и выборка наиболее релевантной информации из истории беседы.
- Метрики оценки: Включают удовлетворенность пользователей, успешность выполнения задач, а также автоматические показатели связности и релевантности ответов.
- Персистентная память: Полезна для поддержания контекста между повторными сессиями, сохраняя предпочтения пользователя, а также информацию о прошлых проблемах и их решениях.
- Практические рекомендации: Включают обеспечение приватности, прозрачности, предоставление пользователю контроля над памятью и постоянный мониторинг качества взаимодействия.
Практические задания
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()