Введение в модульные и самокорректирующие QA-системы с DSPy
В современном мире автоматизации бизнеса, создание эффективных систем вопросов и ответов (QA) становится все более актуальным. Используя фреймворк DSPy и модель Gemini 1.5 от Google, мы можем построить интеллектуальную QA-систему, способную самостоятельно исправлять ошибки. В этой статье мы рассмотрим, как создать такую систему, акцентируя внимание на практическом применении и возможных затратах.
Установка необходимых библиотек
Для начала работы нам понадобятся библиотеки DSPy и google-generativeai. Устанавливаем их с помощью следующей команды:
!pip install dspy-ai google-generativeai
После установки мы импортируем необходимые модули и настраиваем модель Gemini с использованием нашего API-ключа.
Определение подписей для системы
Следующим этапом является создание структурированных подписей, которые определяют входные и выходные параметры нашей системы. Мы создадим две основные подписи: QuestionAnswering для обработки вопросов и FactualityCheck для проверки фактической корректности ответов. Это позволит нашей системе быть более надежной и предсказуемой.
class QuestionAnswering(dspy.Signature): context: str = dspy.InputField(desc="Информация о контексте") question: str = dspy.InputField(desc="Вопрос для ответа") reasoning: str = dspy.OutputField(desc="Логика ответа") answer: str = dspy.OutputField(desc="Финальный ответ") class FactualityCheck(dspy.Signature): context: str = dspy.InputField() question: str = dspy.InputField() answer: str = dspy.InputField() is_correct: bool = dspy.OutputField(desc="Правда, если ответ корректен")
Создание модуля AdvancedQA
Модуль AdvancedQA добавляет возможность самокоррекции нашей QA-системе. Он использует предсказатель Chain-of-Thought для генерации ответа с логикой. Если ответ оказывается неверным, модуль уточняет контекст и пытается снова. Это позволяет системе повышать точность ответов.
class AdvancedQA(dspy.Module): def __init__(self, max_retries: int = 2): super().__init__() self.max_retries = max_retries self.qa_predictor = dspy.ChainOfThought(QuestionAnswering) self.fact_checker = dspy.Predict(FactualityCheck) def forward(self, context: str, question: str) -> dspy.Prediction: prediction = self.qa_predictor(context=context, question=question) for attempt in range(self.max_retries): fact_check = self.fact_checker(context=context, question=question, answer=prediction.answer) if fact_check.is_correct: break refined_context = f"{context}\nПредыдущий неверный ответ: {prediction.answer}\nПожалуйста, предоставьте более точный ответ." prediction = self.qa_predictor(context=refined_context, question=question) return prediction
Реализация модуля SimpleRAG
Модуль SimpleRAG позволяет нам использовать генерацию ответов на основе извлечения информации. Мы создаем базу знаний и реализуем простой механизм поиска, чтобы находить наиболее релевантные документы для заданного вопроса. Эти документы служат контекстом для нашего модуля AdvancedQA.
class SimpleRAG(dspy.Module): def __init__(self, knowledge_base: List[str]): super().__init__() self.knowledge_base = knowledge_base self.qa_system = AdvancedQA() def retrieve(self, question: str, top_k: int = 2) -> str: scored_docs = [] question_words = set(question.lower().split()) for doc in self.knowledge_base: doc_words = set(doc.lower().split()) score = len(question_words.intersection(doc_words)) scored_docs.append((score, doc)) scored_docs.sort(reverse=True) return "\n".join([doc for _, doc in scored_docs[:top_k]]) def forward(self, question: str) -> dspy.Prediction: context = self.retrieve(question) return self.qa_system(context=context, question=question)
База знаний и примеры обучения
Мы создаем небольшую базу знаний, содержащую разнообразные факты по различным темам, и подготавливаем набор примеров для обучения системы. Эти примеры помогут DSPy лучше понимать, как давать точные ответы.
knowledge_base = [ "Используйте ваш контекст и базу знаний здесь" ] training_examples = [ dspy.Example( question="Какова высота Эйфелевой башни?", context="Эйфелева башня расположена в Париже, Франция. Она была построена с 1887 по 1889 год и имеет высоту 330 метров, включая антенны.", answer="330 метров" ).with_inputs("question", "context"), dspy.Example( question="Кто создал язык программирования Python?", context="Python — это высокоуровневый язык программирования, созданный Гвидо ван Россумом. Он был впервые выпущен в 1991 году и акцентирует внимание на читаемости кода.", answer="Гвидо ван Россум" ).with_inputs("question", "context"), dspy.Example( question="Что такое машинное обучение?", context="Машинное обучение сосредоточено на алгоритмах, которые могут учиться на данных без явного программирования.", answer="Машинное обучение сосредоточено на алгоритмах, которые учатся на данных без явного программирования." ).with_inputs("question", "context") ]
Оценка системы
Для оценки точности нашей системы мы определяем простую метрику, которая проверяет, содержит ли предсказанный ответ правильный ответ. Затем мы тестируем систему на примере вопроса до и после оптимизации.
def accuracy_metric(example, prediction, trace=None): return example.answer.lower() in prediction.answer.lower() rag_system = SimpleRAG(knowledge_base) basic_qa = dspy.ChainOfThought(QuestionAnswering) test_question = "Какова высота Эйфелевой башни?" test_context = knowledge_base[0] initial_prediction = basic_qa(context=test_context, question=test_question) optimizer = dspy.BootstrapFewShot(metric=accuracy_metric, max_bootstrapped_demos=2) optimized_qa = optimizer.compile(basic_qa, trainset=training_examples)
Финальная оценка
Мы проводим демонстрацию Advanced RAG, задавая несколько вопросов по различным темам. Для каждого вопроса система извлекает наиболее релевантный контекст и использует модуль AdvancedQA для генерации обоснованного ответа. Мы показываем, как DSPy сочетает извлечение и продуманную генерацию, чтобы предоставить надежные ответы.
def evaluate_system(qa_module, test_cases): correct = 0 total = len(test_cases) for example in test_cases: prediction = qa_module(context=example.context, question=example.question) if accuracy_metric(example, prediction): correct += 1 return correct / total
Заключение
В заключение, мы успешно продемонстрировали потенциал DSPy для создания продвинутых QA-пайплайнов. DSPy упрощает проектирование интеллектуальных модулей с четкими интерфейсами, поддерживает циклы самокоррекции и позволяет оптимизировать подсказки с минимальным количеством кода. С помощью нескольких строк кода мы можем настраивать и оценивать наши модели, используя реальные примеры и измеряя прирост производительности. Это практическое руководство показывает, как DSPy в сочетании с API Google Gemini позволяет быстро прототипировать, тестировать и масштабировать сложные языковые приложения.