Тестирование RAG. Часть 1.

Тестирование RAG. Часть 1.

Любовь

Моя цель при создании RAG-модели была не в том, чтобы создать умную модель, а в том, чтобы понять, как работает RAG под капотом и научиться выявлять реальные проблемы в данных, а заодно и в коде.

Краткая врезка об архитектуре проекта еще раз. Напомню, что использовались только локальные инструменты

  • Python 3.9+
  • langchain, sentence-transformers, faiss-cpu
  • Файл syllabus.txt — мой личный силлабус по QA (8 тем, ~800 слов)
  • Нет LLM — генерация эмулируется возвратом найденных фрагментов

Структура проекта:

Наипростейшая структура проекта

Итак... наконец-то добралась до полноценного тестирования.

Мой док syllabus.txt

Начнем...

Retrieval

1.Точный запрос

Вопрос: дословная фраза из syllabus.txt (например: «Что такое жизненный цикл бага?»)

ОР: Фрагмент с перечислением стадий: New, Open, In Progress, Fixed, Verified, Closed.

Тема 3: Жизненный цикл дефекта (бага)
Когда тестировщик находит ошибку, он создаёт баг-репорт. Баг проходит следующие стадии: New (новый), Open (принят в работу), In Progress (в разработке), Fixed (исправлен), Verified (проверен тестировщиком), Closed (закрыт). Если при верификации ошибка не устранена, статус меняется на Reopened.

ФР: Возвращён заголовок Темы 3 — это хорошо. Но второй чанк — полностью нерелевантный (Тема 8 про регрессионное тестирование). При этом само описание стадий бага (New, Open, Fixed и т.д.) — не возвращено!

Фактический результат

Это указывает на две возможные причины:
1.      Чанкинг разорвал смысл: описание стадий оказалось в другом чанке, который не попал в топ-2.

2.      chunk_size слишком мал, и заголовок "Тема 3" оказался в отдельном чанке без содержимого.

Заводим Баг-репорт №1:

Тема: Retrieval / Chunking
Описание: При запросе "Что такое жизненный цикл дефекта (бага)?" система возвращает заголовок темы и нерелевантный чанк (Тема 8), но не возвращает само описание стадий бага, хотя оно присутствует в syllabus.txt. Параметры чанкинга: chunk_size=300, chunk_overlap=50.
ОР: В топ-2 чанков должен входить фрагмент с текстом: "Баг проходит следующие стадии: New, Open, In Progress..."
ФР: Возвращены только заголовки.
Важность: High
Рекомендация: Увеличить chunk_size до 500–600, или добавить "\n\n" в separators, чтобы заголовки не отрывались от содержимого.

2. Перефразированный запрос

Вопрос: «Какие стадии проходит баг?» (в файле указано: «Баг проходит стадии: New, Open…»)

ОР: найден релевантный чанк.

ФР: Первый чанк только заголовок, а второй чанк вообще из другой темы, и начинается с точки.

Фактический результат

Проблема аналогичная: содержимое темы разорвано на чанки, и описание не попадает в топ-k. Добавила в описание первого бага этот пример, чтобы показать, что проблема не в формулировке вопроса, а в структуре данных и чанкинге:

Описание: Проблема воспроизводится как при точном запросе («Что такое жизненный цикл дефекта (бага)?»), так и при перефразированном («Какие стадии проходит баг?»). В обоих случаях система находит только заголовок «Тема 3», но не само описание стадий, что указывает на проблему с целостностью чанков, а не с семантическим поиском.

Чтобы дальше мое тестирование не страдало от чанков – я увеличила их размер до 600 и 100 соответственно и пересобрала базу. 

def load_and_split_syllabus(file_path: str, chunk_size: int = 600, chunk_overlap: int = 100)

Повторное тестирование п.1 и п.2:

Повторное тестирование точного и перефразированного запроса после исправлений

Вывела отдельно результат ретеста в таблицу ниже, тк на скриншоте выше не особо видно происходящее

Результаты ретеста

Итак баг был исправлен за счёт настройки chunk_size и chunk_overlap.

В результатах видно, что в ответах дублируются темы, но это не совсем баг. Это произошло по той простой причине, что я увеличила chunk_size до 600+, и теперь один чанк может содержать несколько тем, если между ними мало текста, или векторы разных тем оказались близки из-за общей лексики. Дублирование в перефразированном запросе говорит о том, что возможно в векторном хранилище есть два похожих чанка с этим заголовком (например, из-за перекрытия chunk_overlap).

Самое главное здесь правило для QA:

Релевантный чанк — первый. Остальное — фон. Главное — не сколько чанков возвращается, а попадает ли нужный в топ-1 или топ-2. Если да — retrieval работает. Если нет — баг. 

Но все же исправила ограничение с k=2 на k=1. Также пишут, что это можно исправить пост-фильтрацией или переранжированием (re-ranking). Но для моей тестовой RAG-модели пока этого достаточно.

Результат с k = 1

Этот результат меня больше порадовал - ничего лишнего. Но вернула снова на k=2. Пригодится для последующих проверок.

3. Запрос с опечаткой

Вопрос: смок тестирование (вместо smoke-тестирование)

ОР: хотя бы один релевантный чанк

Тема 2: Виды тестирования
Существует множество видов тестирования. Функциональное тестирование проверяет соответствие поведения системы спецификациям. Нефункциональное тестирование оценивает такие аспекты, как производительность, безопасность, удобство использования и надёжность. Регрессионное тестирование проводится после изменений в коде, чтобы убедиться, что старая функциональность не сломалась. Smoke-тестирование — это базовая проверка критически важных функций после сборки, чтобы понять, можно ли продолжать тестирование.
Тема 7: Smoke-тестирование — подробнее
Smoke-тестирование (или "проверка сборки") выполняется сразу после получения новой версии ПО....

ФР:

Результат на запрос с опечаткой

Ни единого упоминания о смок тестировании. Модель не распознала семантического сходства. Вернула общие термины про тестирование, тк это слово в них есть (дублирую дополнительно текстом ниже ответ)

Вопрос: смок тестирование
Ответ:
Найденный контекст:
Тема 4: Тестовая документация
Основные виды тестовой документации: тест-план (описывает стратегию, ресурсы, сроки), тест-кейсы (пошаговые инструкции с ожидаемым результатом), чек-листы (упрощённый формат без детализации шагов), отчёты о тестировании (итоги прогона).
Тема 5: Методы тест-дизайна
Тема 1: Введение в тестирование программного обеспечения
Тестирование — это процесс проверки и верификации того, что система соответствует заданным требованиям и работает корректно в различных условиях. Основная цель тестирования — выявление дефектов до попадания продукта к конечному пользователю.
Тема 2: Виды тестирования

Эмбеддинги не умеют "угадывать" опечатки. Для исправления этой проблемы лучшие RAG-модели используют предообработку запросов, гибридный поиск и re-ranker после поиска. Буду считать это как предложение по улучшению текущей модели.

4. Запрос вне темы

Вопрос: Кто хочет стать миллионером?

ОР: возвращается что-то нерелевантное (это нормально!), но не пусто (FAISS всегда возвращает что-то)

ФР: Возвращены фрагменты по регрессионному тестированию, тестовой документации, методам тест-дизайна.

Результат на запрос вне темы силлабуса

Это нерелевантные чанки, но, тк в коде используется FIASS - он всегда должен что-то возвращать ближайшее по векторам - это корректное поведение для текущей модели. Система не упала - а значит код стабильный.

Если бы была включена генерация, то естественно ответ бы получили другой, например "я не знаю ответ на этот вопрос". Но пока задумано возвращение контекста напрямую. С технической точки зрения - это не баг, с точки зрения пользователя - баг, но опять же опциональный. В данном случае это все же особенность архитектуры. Поэтому пока тоже пропускаем. Повторная проверка будет проведена после добавления в проект генерации.

5. Множественный релевантный контекст

Вопрос: Расскажи про smoke-тестирование

ОР: оба фрагмента — из Темы 2 (кратко) и Темы 7 (подробно). Отсутствие дублирования и нерелевантных чанков. Тема 7 более релевантная должна быть первой.

Тема 2: Виды тестирования
Smoke-тестирование — это базовая проверка критически важных функций после сборки, чтобы понять, можно ли продолжать тестирование.
Тема 7: Smoke-тестирование — подробнее
Smoke-тестирование (или "проверка сборки") выполняется сразу после получения новой версии ПО....

ФР:

Результат проверки на множественный релевантный контекст

Что вижу:

  • дублирование темы 7 в начале и в конце - т.е. один и тот же чанк попал в выдачу дважды.
  • подробный и релевантный ответ из темы 7 про Smoke-тестирование вернулся
  • регрессионное тестирование находится в тексте рядом со smoke, но не имеет информации о smoke - нерелевантно
  • Автоматизация тестирования содержит упоминание о дымовых и нагрузочных тестах - можно сказать что частично релевантно, есть семантическая связь.

Можно сделать вывод, что кейс частично пройден, но есть шум.

Завела Баг-репорт №2 с низким приоритетом, т.к. он не ломает функционал, просто снижает удобство

Тема: Дублирование чанков в результатах поиска
Описание: При запросе «Расскажи про smoke-тестирование» один и тот же фрагмент (Тема 7) возвращается дважды. Также в выдаче присутствует нерелевантный чанк (Тема 8).
ОР: Уникальные, релевантные чанки без дублей.
ФР: Один чанк дублируется; в топ-4 есть нерелевантный фрагмент.
Важность: Low
Рекомендация: Добавить фильтрацию дубликатов по содержимому или метаданным, чтобы ограничить шум.


Augmentation

Это один из самых важных, но скрытых этапов RAG. И он у нас уже протестирован в процессе Retrieval. Это этап между поиском и генерацией.

Итог проверки по обогащению, исходя из вышеописанных кейсов:

Порядок чанков

Проверка идет ли самый релевантный чанк на первом месте ✅

В кейсе 5 "Тема 7" ожидалась первой в списке ответов.

Дублирование

Проверка дублируется ли один и тот же текст дважды ⚠️

В кейсе 5 "Тема 7" дважды в ответе.

Чистота контекста

В контексте есть то, что не относится к запросу ⚠️✅

в кейсе 1 "Тема 8" при запросе про баги, было исправлено сразу.

Обрезка (k = 2)

Проверка, что в ответ попадают не все релевантные фрагменты ✅

В кейсе 5 только 2 из 3 упоминаний smoke-тестирования

Целостность

Проверка, что не разорван смысл между чанками и заголовок не попал отдельно от содержимого ⚠️✅

в кейсе 1 сначала при запросе «жизненный цикл бага» возвращался только заголовок «Тема 3: Жизненный цикл дефекта (бага)», а описание — в другом чанке.


Генерация (проверка только на релевантность)

Прозрачность контекста

Сравнила запрос - выдачу - и исходный документ
Убедилась, что нет искажений, обрывов, замен

Стабильность (повторный запуск)

Один и тот же вопрос был задан несколько раз - результат был одинаковым. Это значит FAISS работает правильно.
Система без проблем воспроизводила свою работу

Галлюцинации

отсутствие LLM. В текущей версии проверить невозможно

Отказ от ответа

Актуально при интеграции с LLM.


Вывод:

Какие проблемы я обнаружила в процессе тестирования:

1. ✅ Баг: Чанкинг разрывает смысловые блоки → был исправлен увеличением chunk_size.

2. Предложение по улучшению: Добавить нормализацию запросов для устойчивости к опечаткам.

3. Будущая доработка по генерации: Реализовать "Не знаю", если контекст не релевантен (при интеграции LLM).

4. ⚠️ Баг (низкий): Дублирование чанков → может быть исправлено deduplication.


Итог:

  • RAG-система работает стабильно.
  • Качество retrieval напрямую зависит от параметров чанкинга.
  • Для продакшн-версии рекомендованы: предобработка запросов, контроль дублей, порог релевантности.


Что планируется делать дальше:

  • Добавить LLM и проверить галлюцинации
  • Сделать логи в файл, чтобы сохранять результаты тестов
  • Добавить предообработку запросов, контроль дублей и порог релевантности.


Продолжение следует... Спасибо за внимание

Ссылка на проект https://github.com/Luba-coder/my_rag_test.git


Report Page