Введение в модульные и самокорректирующие 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 позволяет быстро прототипировать, тестировать и масштабировать сложные языковые приложения.















