Настроить adversarial evaluation для RAG
ТЕХНИЧЕСКОЕ ЗАДАНИЕ: Настроить adversarial evaluation для RAG
1. Цель задачи
Разработать и запустить adversarial evaluation для RAG-системы (Retrieval-Augmented Generation), используя атаки TextFooler и BERT-Attack на тестовых запросах. Цель — измерить устойчивость RAG к синтаксическим и семантически близким искажениям входных запросов, которые могут обмануть как retriever, так и generator. Ключевой результат Accuracy drop (падение точности ответов) не превышает 10% при применении атак к тестовому набору запросов.
2. Исходные данные
| Что нужно | Откуда взять |
|---|---|
| RAG-система (retriever + generator) | Готовая реализация из предыдущих задач (например, FAISS + Hugging Face pipeline) или развернуть минимальную (LangChain + OpenAI API / локальная LLM) |
| Набор тестовых запросов и референсных ответов (минимум 50 пар) | Сгенерировать самостоятельно на основе документов из корпуса (вопросы к параграфам) или взять готовый датасет (например, MS MARCO subset, Natural Questions) |
| Инструменты для атак (TextFooler / BERT-Attack) | Библиотека textattack (PyPI) или кастомные реализации |
| Вычислительные ресурсы | GPU (рекомендуется) или CPU (для малых наборов) |
Если нет реального инструмента — симулируем:
- Установить textattack==0.3.9 и модель-классификатор для атаки (например,
textattack/bert-base-uncased-imdb). - Для симуляции TextFooler использовать рецепт textattack: TextFoolerJin2019.
- Для BERT-Attack — рецепт bert-attack.
- Если библиотека не устанавливается, написать простые заменители: замена слов на синонимы по WordNet (TextFooler) или замены по BERT-MLM (BERT-Attack) через transformers.
3. Технологический стек
| Компонент | Инструменты | Назначение |
|---|---|---|
| Язык программирования | Python 3.10+ | Основной язык |
| RAG pipeline | LangChain / LlamaIndex + FAISS | Генерация ответов на основе ретрива и генерации |
| Атаки | textattack + transformers | Генерация adversarial запросов |
| Векторизация | Sentence Transformers (all-MiniLM-L6-v2) | Эмбеддинги для retriever |
| LLM генератор | Hugging Face (Flan-T5-base / Mistral-7B) либо OpenAI API | Генерация ответов |
| Оценка | ROUGE-L / Exact Match / LLM-as-judge | Метрики точности ответов |
| Автоматизация | Python скрипты (argparse, logging) | Запуск экспериментов |
4. Этапы выполнения
Этап 1: Подготовка тестового набора и базовых метрик (2 часа)
Действия
- Взять 10–20 документов (тексты статей, инструкции) и вручную составить 50 тестовых вопросов с ожидаемыми ответами (по 2–5 на документ).
- Пример: документ про «Правила возврата товаров», вопрос «Каков срок возврата?», ответ «14 дней».
- Развернуть RAG pipeline:
from langchain.vectorstores import FAISS from langchain.embeddings import SentenceTransformerEmbeddings from langchain.llms import HuggingFacePipeline from langchain.chains import RetrievalQA embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2") vectorstore = FAISS.from_documents(docs, embeddings) qa = RetrievalQA.from_chain_type(llm=llm, chain_type="stuff", retriever=vectorstore.as_retriever()) - Прогнать все 50 чистых запросов через RAG, извлечь ответы.
- Вычислить базовую метрику: Exact Match (EM) или ROUGE-L между ожидаемым ответом и ответом RAG.
- Если точность <70%, выбрать более легкий датасет или настроить LLM.
Ожидаемый результат этапа Таблица из 50 запросов, ответов RAG и метрик (EM/ROUGE-L). Базовая accuracy >80%.
Этап 2: Интеграция атак TextFooler (3 часа)
Действия
- Установить textattack и загрузить модель-жертву (например, bert-base-uncased для классификации, но нам нужна атака на запросы, а не на классификатор — используем recipe без привязки к модели, только генерация пертурбаций).
- Альтернативно: использовать textattack.attack.attack.attack с
goal_function=UntargetedClassificationи dummy model, но проще генерировать черезtransformation.WordSwapEmbeddingи constraints вручную.
- Альтернативно: использовать textattack.attack.attack.attack с
- Написать функцию apply_textfooler(query) → list[str]:
- Для каждого из 50 тестовых запросов применить атаку (с запасом по времени — можно на подмножестве 20 запросов).
- Оценить accuracy на атакованных запросах (сравнить ответы RAG с референсным).
- Вычислить drop:
(base_accuracy - adversarial_accuracy)/base_accuracy * 100.
Ожидаемый результат этапа Accuracy drop после TextFooler (должен быть умеренный, 5–15% — идеально для задачи).
Этап 3: Интеграция атак BERT-Attack (3 часа)
Действия
- Использовать метод BERT-Attack: для каждого токена запроса предсказывать маскированное слово (BERT-MLM) с максимальной вероятностью, отличной от исходного, при условии, что семантика сохраняется.
- Использовать transformers.BertForMaskedLM с моделью bert-base-uncased.
- Ограничения: не заменять stopwords, длина фразы не меняется.
- Реализовать apply_bert_attack(query) → list[str]:
for i, token in enumerate(tokens): masked = tokens.copy() masked[i] = '[MASK]' logits = model(**input_ids).logits probs = softmax(logits[0, i]) candidates = top_k(probs, k=5)[0] for cand in candidates: if cand != token and sim(original, cand_sent) > threshold: yield cand_sent - Прогнать атаки на тех же 50 запросах (или на 20, если время ограничено).
- Посчитать accuracy drop.
Ожидаемый результат этапа BERT-Attack обычно более агрессивный — drop может быть 10–20%.
Этап 4: Объединённый сценарий и измерение (2 часа)
Действия
- Написать скрипт
run_adversarial_eval.py, который: - Вывести итоговую таблицу:
Attack Base Acc Adv Acc Drop (%) TextFooler 84% 78% 7.1% BERT-Attack 84% 72% 14.3% - Проверить условие: Accuracy drop не превышает 10% хотя бы для одного метода (TextFooler). Если drop больше — принять как есть, задокументировать.
Ожидаемый результат этапа Полный отчёт об adversarial evaluation.
Этап 5: Анализ и улучшения (опционально, 2 часа)
Действия
- Просмотреть запросы, которые привели к ошибкам. Выделить типы уязвимостей:
- Замена ключевого слова (например, «возврат» → «обмен»).
- Изменение порядка слов.
- Предложить методы защиты: augmentation на этапе обучения (включить атакованные запросы в fine-tune retriever/LLM), использование
query expansionилиspell correction. - Оценить, насколько улучшится accuracy после применения простой защиты (например, добавление синонимов в индекс).
Ожидаемый результат этапа Рекомендации по защите RAG от adversarial запросов.
5. Критерии приемки (Definition of Done)
- Базовый accuracy на чистых запросах ≥80% (или измерен и задокументирован).
- Реализован хотя бы один метод атаки (TextFooler) и сгенерированы пертурбации для минимум 20 запросов.
- Accuracy drop от TextFooler не превышает 10% (или зафиксирован и пояснён).
- Итоговый отчёт содержит сравнение двух атак (даже если BERT-Attack работает только на 10 запросах).
- Код воспроизводим: один скрипт
run_adversarial_eval.pyс аргументами--attack textfooler/bert. - Все метрики (EM, ROUGE-L, drop) посчитаны и выведены в таблицу.
- Приложен файл с примерами атакованных запросов (adversarial_queries.txt).
6. Ожидаемый результат
- Основной артефакт Jupyter notebook или Python-скрипт
eval_adversarial_rag.py. - Данные Файл
results.csvсо столбцами:query,reference,base_response,textfooler_response,bert_response,base_em,textfooler_em,bert_em. - Отчёт Markdown-файл
report.mdс таблицами accuracy и выводами. - Дополнительно Лог
adversarial_queries.logс примерами пертурбаций.
7. Возможные сложности и их решение
| Сложность | Решение |
|---|---|
Библиотека textattack не устанавливается или требует много зависимостей | Использовать кастомную реализацию TextFooler через WordNet + Sentence-BERT (код из примеров) |
| Атаки BERT-Attack слишком медленные на CPU | Ограничиться 20 запросами и заменой только 1–2 слов на запрос |
| Drop точности превышает 30% из-за слабой RAG системы | Улучшить retriever (добавить больше релевантных чанков) или повысить температуру генератора |
| Не хватает GPU памяти для LLM | Взять меньшую модель (Flan-T5-small) или использовать OpenAI API (с осторожностью — атаки могут генерировать странные запросы) |
| Референсные ответы неполные или субъективные | Использовать LLM-as-judge с промптом «Сравни ответы» вместо Exact Match |
8. Бюджет времени (оценка)
| Этап | Время (часы) |
|---|---|
| Этап 1: Подготовка набора и базовые метрики | 2 |
| Этап 2: Интеграция TextFooler | 3 |
| Этап 3: Интеграция BERT-Attack | 3 |
| Этап 4: Объединённый сценарий и отчёт | 2 |
| Этап 5: Анализ (опционально) | 2 |
| Итого (основные этапы) | 10 часов |
Примечание Для первого раза с настройкой окружения заложить +2 часа.
9. Связанные вопросы из базы знаний
| Вопрос | Тема |
|---|---|
| 23 | Как работает TextFooler? |
| 47 | Основные виды adversarial атак на NLP |
| 112 | Метрики оценки RAG (ROUGE, BLEU, EM) |
| 189 | Sentence-BERT для семантической близости |
| 253 | Обучение RAG с аугментацией (adversarial training) |
| 304 | Оценка устойчивости retriever к пертурбациям |
| 418 | BERT-Attack: пошаговая реализация |
| 501 | Подбор порога косинусного сходства для атак |
| 673 | LLM-as-judge для сравнения ответов |
| 789 | Best practices по защите RAG от атак |
10. Чек-лист самопроверки
- Я развернул RAG pipeline и замерил baseline accuracy.
- Я сгенерировал adversarial примеры с помощью TextFooler и проверил их осмысленность (не сломалась семантика).
- Я получил accuracy drop ≤10% хотя бы на одном методе (TextFooler) — условие задачи выполнено.
- Я задокументировал все шаги и результаты в читаемом отчёте.
- Код содержит комментарии и может быть переиспользован для других RAG систем.