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 |
Если нет реального датасета — симулируем:
- Выбрать 5–7 статей из Википедии (по одной теме, например, «Трансформеры» или «Собаки породы хаски»).
- Разбить статьи на chunks по 256 токенов с overlap 20.
- Составить по каждому chunk-у 2–3 вопроса, на которые ответ однозначно содержится в этом chunk-е.
- Сформировать ground truth ответы из текста chunk-а (цитаты).
- Добавить 3–4 вопроса, ответ на которые требует объединения информации из нескольких chunks (для усложнения).
- Итого 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 минут)
Действия
- Установить зависимости:
pip install langchain langchain-openai qdrant-client ragas datasets sentence-transformers - Скачать/создать датасет вопросов и chunks.
- Разделить датасет на 20 тренировочных (для отладки) и 10 тестовых (для финальной оценки).
- Настроить подключение к LLM (API‑ключ через переменные окружения) и инициализировать embedding модель.
Ожидаемый результат этапа
Готовый датасет (list of dicts) и работающее окружение с импортированными библиотеками.
Этап 2: Сборка базового RAG-агента (оценка времени: 1 час)
Действия
- Создать векторную коллекцию (Qdrant in‑memory или Chroma) и загрузить chunks.
- Реализовать функцию retriever(tоп_k=5) по вопросу.
- Написать шаблон промпта для генерации ответа:
System: Ты — помощник, отвечающий строго на основе предоставленных документов. User: Вопрос: {question} Документы: {context} Ответ дай на русском, кратко и по делу. - Обернуть генерацию в LangChain chain или простую функцию generate(question) -> answer.
- Протестировать на 3–5 вопросах: убедиться, что ответы осмысленные, но возможны нефатфульности (если context не полностью покрывает вопрос).
Ожидаемый результат этапа
Функция generate_answer(question, retriever) возвращает текстовый ответ.
Этап 3: Модуль оценки faithfulness (оценка времени: 1 час)
Действия
- Реализовать функцию evaluate_faithfulness(answer, context_chunks) -> float одним из способов:
- Использовать RAGAS Faithfulness (требует два LLM вызова: извлечение утверждений, проверка каждого).
- Написать кастомный промпт: «Разбей ответ на факты. Для каждого факта укажи, подтверждается ли он документами (0/1). Верни долю подтверждённых фактов».
- Если используется RAGAS, обязательно указать llm для оценки (та же модель или дешёвая).
- Проверить на синтетических примерах:
- Верный ответ (все факты в документах) → faithfulness ≥ 0.9.
- Ответ с галлюцинацией → faithfulness ≤ 0.3.
- Установить порог: THRESHOLD = 0.95.
Ожидаемый результат этапа
Функция check_faithfulness(answer, context) -> (score, issues), где issues — список неверных утверждений (для обратной связи).
Этап 4: Цикл саморефлексии и исправления (оценка времени: 1.5 часа)
Действия
- Реализовать класс 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), чтобы избежать бесконечного цикла.
- Протестировать на вопросах, где первый ответ заведомо неверен (специально обрезать контекст или удалить часть документов), убедиться, что после исправления faithfulness повышается.
Ожидаемый результат этапа
Метод answer_with_self_reflection возвращает финальный ответ, протокол и число итераций.
Этап 5: Интеграционное тестирование и отчёт (оценка времени: 1 час)
Действия
- Прогнать все 10 тестовых вопросов через пайплайн.
- Для каждого вопроса сохранить:
- Вопрос, контекст, первый ответ, финальный ответ,
- faithfulness первого ответа, faithfulness финального ответа,
- количество итераций.
- Рассчитать средний faithfulness по финальным ответам. Если < 0.95 — проанализировать проблемные кейсы и улучшить промпт исправления или порог.
- Построить таблицу результатов (pandas DataFrame) и сохранить в CSV.
- Написать краткий отчёт (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 (секции):
- Импорты и конфигурация (ключи, модели).
- Загрузка/создание датасета.
- Сборка векторной базы и retriever.
- Реализация базовой генерации.
- Реализация оценки faithfulness.
- Реализация цикла саморефлексии.
- Тестирование на 10 вопросах и экспорт CSV.
- Анализ результатов (среднее, медиана, гистограмма изменения 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: Модуль оценки faithfulness | 1 час |
| Этап 4: Цикл саморефлексии и исправления | 1.5 часа |
| Этап 5: Интеграционное тестирование и отчёт | 1 час |
| Итого | 5 часов |
| Примечание для первого раза | Может потребоваться до 8 часов с учётом отладки выбора модели и настройки промптов. |
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 150 | RAG pipeline: structure and components |
| 201 | Faithfulness metrics in RAGAS |
| 305 | LangChain agents: tools and callbacks |
| 410 | Self-consistency decoding for LLMs |
| 525 | Vector database selection criteria |
| 639 | Prompt engineering for factuality |
| 748 | Iterative refinement loops in AI systems |
| 831 | Evaluation of LLM-generated answers |
| 899 | Embedding models for retrieval quality |
10. Чек-лист самопроверки
- Я подготовил датасет с question/answer_true/context, проверил, что он корректен.
- Убедился, что базовая генерация без саморефлексии иногда даёт неверные (нефатфул) ответы.
- Модуль оценки faithfulness выдаёт разумные оценки (0–1) на заведомо правильных и неправильных примерах.
- Цикл исправления не превышает заданного числа итераций и завершается возвратом лучшего ответа.
- На тестовом наборе средний faithfulness ≥ 0.95, все кейсы сохранены в CSV.