Agentic RAG с саморефлексией

ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Agentic RAG с саморефлексией

1. Цель задачи

Построить агентный RAG-пайплайн, в котором генерация ответа дополняется встроенным модулем самооценки faithfulness. После первичной генерации агент проверяет фактологическую точность ответа относительно исходных документов и, если faithfulness ниже порога 0.95, автоматически исправляет ошибки через повторную генерацию с учётом выявленных расхождений. Это позволяет приблизить качество ответов к уровню, когда агент «перепроверяет себя».

Ключевой результат Рабочий прототип Agentic RAG с пайплайном генерация → проверка → исправление, который на тестовом наборе вопросов достигает средней Faithfulness ≥ 0.95.

2. Исходные данные

Что нужноОткуда взять
Тестовый набор вопросов с ground truth ответами (HotpotQA / Natural Questions / собственный датасет на 20–50 примеров)Hugging Face или открытые репозитории (например, hotpotqa)
Коллекция документов-источников (chunk'ов), привязанных к вопросамСгенерировать из тех же датасетов (извлечь context), или использовать небольшой справочный корпус (например, Wikipedia mini)
LLM для генерации ответов (OpenAI / Anthropic / локальная модель)API-ключ (если платная) или локальный сервер (vLLM / Ollama)
Базовый RAG-пайплайнРеализовать самостоятельно или взять готовый шаблон из LangChain / LlamaIndex

Если нет реального датасета — симулируем:

  1. Выбрать 5–7 статей из Википедии (по одной теме, например, «Трансформеры» или «Собаки породы хаски»).
  2. Разбить статьи на chunks по 256 токенов с overlap 20.
  3. Составить по каждому chunk-у 2–3 вопроса, на которые ответ однозначно содержится в этом chunk-е.
  4. Сформировать ground truth ответы из текста chunk-а (цитаты).
  5. Добавить 3–4 вопроса, ответ на которые требует объединения информации из нескольких chunks (для усложнения).
  6. Итого 20–30 пар (вопрос → ground truth).

3. Технологический стек

КомпонентИнструментыНазначение
LLM для генерацииGPT-4o / Claude 3.5 Sonnet / Llama 3 70BГенерация и исправление ответов
LLM для оценки faithfulnessТа же модель (можно другую, но дешевле)Проверка фактологической точности (через RAGAS или кастомный промпт)
Фреймворк агентаLangChain (Agents + Tools) / LlamaIndex (AgentRunner)Построение цикла генерация → проверка → исправление
Векторная БДQdrant / Chroma / FAISS (в памяти)Хранение и поиск chunks
Embedding модельtext-embedding-3-small или sentence-transformers/all-MiniLM-L6-v2Векторизация запросов и документов
Библиотека метрикRAGAS (faithfulness)Расчёт faithfulness для автоматической оценки
Среда разработкиJupyter Notebook / Python 3.10+Прототипирование
Веб-демо (опционально)Streamlit / GradioДемонстрация работы пайплайна

4. Этапы выполнения

Этап 1: Подготовка окружения и датасета (оценка времени: 30 минут)

Действия

  1. Установить зависимости:
    pip install langchain langchain-openai qdrant-client ragas datasets sentence-transformers
    
  2. Скачать/создать датасет вопросов и chunks.
    • Если используете HotpotQA: загрузить через datasets.load_dataset("hotpotqa", "distractor"), взять первые 30 примеров.
    • Если симулируете: подготовить JSON-файл с полями question, answer_true, context_chunks (список текстов).
  3. Разделить датасет на 20 тренировочных (для отладки) и 10 тестовых (для финальной оценки).
  4. Настроить подключение к LLM (API‑ключ через переменные окружения) и инициализировать embedding модель.

Ожидаемый результат этапа
Готовый датасет (list of dicts) и работающее окружение с импортированными библиотеками.

Этап 2: Сборка базового RAG-агента (оценка времени: 1 час)

Действия

  1. Создать векторную коллекцию (Qdrant in‑memory или Chroma) и загрузить chunks.
  2. Реализовать функцию retriever(tоп_k=5) по вопросу.
  3. Написать шаблон промпта для генерации ответа:
    System: Ты — помощник, отвечающий строго на основе предоставленных документов.
    User: Вопрос: {question}
    Документы: {context}
    Ответ дай на русском, кратко и по делу.
    
  4. Обернуть генерацию в LangChain chain или простую функцию generate(question) -> answer.
  5. Протестировать на 3–5 вопросах: убедиться, что ответы осмысленные, но возможны нефатфульности (если context не полностью покрывает вопрос).

Ожидаемый результат этапа
Функция generate_answer(question, retriever) возвращает текстовый ответ.

Этап 3: Модуль оценки faithfulness (оценка времени: 1 час)

Действия

  1. Реализовать функцию evaluate_faithfulness(answer, context_chunks) -> float одним из способов:
    • Использовать RAGAS Faithfulness (требует два LLM вызова: извлечение утверждений, проверка каждого).
    • Написать кастомный промпт: «Разбей ответ на факты. Для каждого факта укажи, подтверждается ли он документами (0/1). Верни долю подтверждённых фактов».
  2. Если используется RAGAS, обязательно указать llm для оценки (та же модель или дешёвая).
  3. Проверить на синтетических примерах:
    • Верный ответ (все факты в документах) → faithfulness ≥ 0.9.
    • Ответ с галлюцинацией → faithfulness ≤ 0.3.
  4. Установить порог: THRESHOLD = 0.95.

Ожидаемый результат этапа
Функция check_faithfulness(answer, context) -> (score, issues), где issues — список неверных утверждений (для обратной связи).

Этап 4: Цикл саморефлексии и исправления (оценка времени: 1.5 часа)

Действия

  1. Реализовать класс AgenticRAG:
    class AgenticRAG:
        def __init__(self, llm, retriever, faithfulness_checker, max_iterations=3):
            ...
        
        def answer_with_self_reflection(self, question):
            context = self.retriever.get_relevant_documents(question)
            initial_answer = self.generate(question, context)
            for i in range(self.max_iterations):
                score, issues = self.faithfulness_checker(initial_answer, context)
                if score >= 0.95:
                    return initial_answer, score, i
                else:
                    # Исправление: передаём issues в промпт
                    correction_prompt = f"Твой предыдущий ответ содержал фактические ошибки: {issues}. Исправь ответ, используя только данные документы."
                    initial_answer = self.generate(question, context, correction_prompt)
            return initial_answer, score, self.max_iterations
    
  2. Внести в промпт исправления инструкцию учитывать выявленные ошибки.
  3. Ограничить число итераций (2–3), чтобы избежать бесконечного цикла.
  4. Протестировать на вопросах, где первый ответ заведомо неверен (специально обрезать контекст или удалить часть документов), убедиться, что после исправления faithfulness повышается.

Ожидаемый результат этапа
Метод answer_with_self_reflection возвращает финальный ответ, протокол и число итераций.

Этап 5: Интеграционное тестирование и отчёт (оценка времени: 1 час)

Действия

  1. Прогнать все 10 тестовых вопросов через пайплайн.
  2. Для каждого вопроса сохранить:
    • Вопрос, контекст, первый ответ, финальный ответ,
    • faithfulness первого ответа, faithfulness финального ответа,
    • количество итераций.
  3. Рассчитать средний faithfulness по финальным ответам. Если < 0.95 — проанализировать проблемные кейсы и улучшить промпт исправления или порог.
  4. Построить таблицу результатов (pandas DataFrame) и сохранить в CSV.
  5. Написать краткий отчёт (3–5 предложений) с метриками и выводами.

Ожидаемый результат этапа
CSV-файл с детальными результатами и средняя faithfulness ≥ 0.95.

5. Критерии приемки (Definition of Done)

  • Создан датасет из минимум 20 пар «вопрос + ground truth» с привязанными chunks.
  • Реализован базовый RAG (retriever + LLM‑генерация) без саморефлексии.
  • Написан модуль оценки faithfulness (с использованием RAGAS или кастомного промпта), корректно возвращающий оценки от 0 до 1.
  • Реализован цикл саморефлексии: генерация → проверка → исправление (до 3 итераций).
  • На тестовой выборке (10 вопросов) средний faithfulness финальных ответов ≥ 0.95.
  • Код воспроизводим: все шаги описаны в Jupyter Notebook, включая установку зависимостей.
  • Результаты сохранены в CSV — для каждого вопроса видна динамика изменения faithfulness.
  • В репозитории (или архиве) присутствует README с кратким описанием и инструкцией по запуску.

6. Ожидаемый результат

Основной файл
agentic_rag_with_reflection.ipynb — Jupyter Notebook, содержащий весь пайплайн: подготовку данных, базовый RAG, модуль оценки, цикл саморефлексии, финальное тестирование и вывод метрик.

Содержимое Notebook (секции):

  1. Импорты и конфигурация (ключи, модели).
  2. Загрузка/создание датасета.
  3. Сборка векторной базы и retriever.
  4. Реализация базовой генерации.
  5. Реализация оценки faithfulness.
  6. Реализация цикла саморефлексии.
  7. Тестирование на 10 вопросах и экспорт CSV.
  8. Анализ результатов (среднее, медиана, гистограмма изменения faithfulness).

Опционально (дополнительные результаты):

  • Streamlit-демо, где можно ввести вопрос и увидеть пошаговый лог (первый ответ, оценка, исправленный ответ).
  • Файл metrics.csv с колонками: question, first_answer, final_answer, faithfulness_first, faithfulness_final, iterations.

7. Возможные сложности и их решение

СложностьРешение
Модель-оценщик даёт завышенные faithfulness (например, соглашается с любым утверждением)Использовать отдельный, более строгий промпт для оценки, или применить RAGAS с другой LLM (которая не участвует в генерации).
Цикл исправления зацикливается (faithfulness не растёт)Установить максимальное число итераций (3). На последней итерации вернуть лучший ответ по оценке (даже если ниже порога).
Контекст (chunks) может не содержать ответа полностью — faithfulness никогда не достигнет 0.95Добавить в ретривер больше chunks (увеличить top_k) или дать агенту возможность дополнительно поискать документы (tool).
Большое количество LLM-запросов (затраты, задержка)Оптимизировать: уменьшить число итераций до 2, использовать более дешёвую модель для оценки.
Нестабильность ответов из-за разной формулировки в LLMЗакрепить промпт с примерами few-shot в блоке исправления.

8. Бюджет времени (оценка)

ЭтапВремя
Этап 1: Подготовка окружения и датасета30 мин
Этап 2: Сборка базового RAG-агента1 час
Этап 3: Модуль оценки faithfulness1 час
Этап 4: Цикл саморефлексии и исправления1.5 часа
Этап 5: Интеграционное тестирование и отчёт1 час
Итого5 часов
Примечание для первого разаМожет потребоваться до 8 часов с учётом отладки выбора модели и настройки промптов.

9. Связанные вопросы из базы знаний

ВопросТема
150RAG pipeline: structure and components
201Faithfulness metrics in RAGAS
305LangChain agents: tools and callbacks
410Self-consistency decoding for LLMs
525Vector database selection criteria
639Prompt engineering for factuality
748Iterative refinement loops in AI systems
831Evaluation of LLM-generated answers
899Embedding models for retrieval quality

10. Чек-лист самопроверки

  • Я подготовил датасет с question/answer_true/context, проверил, что он корректен.
  • Убедился, что базовая генерация без саморефлексии иногда даёт неверные (нефатфул) ответы.
  • Модуль оценки faithfulness выдаёт разумные оценки (0–1) на заведомо правильных и неправильных примерах.
  • Цикл исправления не превышает заданного числа итераций и завершается возвратом лучшего ответа.
  • На тестовом наборе средний faithfulness ≥ 0.95, все кейсы сохранены в CSV.