<НА ГЛАВНУЮ

Создание модульных и самокорректирующихся систем вопросов-ответов с DSPy и Google Gemini 1.5

Руководство по созданию модульной и самокорректирующейся системы QA с DSPy и Google Gemini 1.5, включая извлечение контекста и оптимизацию подсказок.

Использование DSPy и Gemini для интеллектуальных QA-систем

В этом руководстве показано, как разработать модульную и самокорректирующуюся систему вопросов-ответов (QA) с использованием фреймворка DSPy и модели Google Gemini 1.5 Flash. Основой являются структурированные Signatures, чётко задающие входные и выходные данные, что позволяет DSPy строить надёжные AI-конвейеры.

Декларативное программирование с DSPy

DSPy использует декларативный подход, позволяющий создавать составные модули, такие как AdvancedQA и SimpleRAG. AdvancedQA формирует ответы с рассуждениями и проверяет фактическую точность, реализуя самокоррекцию через повторные попытки с уточнённым контекстом. SimpleRAG имитирует генерацию с дополнением извлечением (retrieval-augmented generation), выбирая релевантные документы из базы знаний с помощью ключевых слов.

Определение Signatures для структурирования данных

Созданы два DSPy Signature: 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="True, если ответ фактологически верен")

Реализация самокоррекции в AdvancedQA

Модуль AdvancedQA использует 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\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))
       
        # Возвращаем top-k наиболее релевантных документов
        scored_docs.sort(reverse=True)
        return "\n\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)

Обучение и оптимизация

Подготовлена база знаний и тренировочные примеры для дообучения системы. С помощью оптимизатора BootstrapFewShot DSPy улучшает генерацию ответов, автоматически подстраивая подсказки на основе примеров.

Оценка и результаты

Используется метрика точности, проверяющая наличие правильного ответа в предсказании. Тестирование до и после оптимизации показывает рост точности, подтверждая эффективность DSPy.

Ключевые идеи

В ходе урока раскрыты важные возможности DSPy: определение Signatures, создание модульных систем, реализация самокоррекции, генерация с дополнением извлечением, оптимизация подсказок и оценка производительности — всё на базе Google Gemini 1.5 Flash API.

🇬🇧

Switch Language

Read this article in English

Switch to English