Руководство по тестовой платформе

Руководство по тестовой платформе

Оценка гибридного поиска — Этап 1

В этом руководстве объясняется, как использовать тестовую платформу для оценки эффективности гибридного поиска.

Содержание

Обзор

Тестовый фреймворк сравнивает три режима поиска: - Только векторный: чисто семантический поиск с использованием ChromaDB - Только графовый: чисто структурный поиск с использованием DuckDB/CPG - Гибридный: комбинированный поиск с объединением результатов по методу RRF

Быстрый старт

1. Запуск синтетической демо-версии

Синтетическая демо-версия имитирует реалистичные паттерны поиска без необходимости использования реальных данных:

python demo_benchmark.py

Результат:

================================================================================
ОБЗОР ТЕСТА ПРОИЗВОДИТЕЛЬНОСТИ
================================================================================
Метрика               Вектор       Граф         Гибрид       по сравнению с вектором    по сравнению с графом
--------------------------------------------------------------------------------
Precision@10         0.2182       0.2000       0.3000       +37.5%       +50.0%
Recall@10            0.4327       0.3543       0.5528       +27.8%       +56.0%
F1@10                0.2864       0.2510       0.3825       +33.6%       +52.4%
MRR                  1.0000       0.6364       1.0000       +0.0%        +57.1%
NDCG@10              0.5304       0.4443       0.6590       +24.3%       +48.3%

Основные выводы: - Гибридный подход обеспечивает улучшение F1@10 на +33,6% по сравнению с использованием только векторов - Гибридный подход обеспечивает улучшение F1@10 на +52,4% по сравнению с использованием только графа - Гибридный подход объединяет сильные стороны: семантическое понимание и структурную навигацию

2. Запуск с реальными данными

Для тестирования с реальными данными из ChromaDB и DuckDB:

from benchmark_hybrid_retrieval import HybridRetrievalBenchmark
from src.retrieval.vector_store_real import VectorStoreReal
from src.services.cpg_query_service import CPGQueryService

# Инициализация хранилищ
vector_store = VectorStoreReal(persist_directory="chroma_db")
cpg_service = CPGQueryService(db_path="cpg.duckdb")

# Создание теста
benchmark = HybridRetrievalBenchmark(
    vector_store=vector_store,
    cpg_service=cpg_service,
    output_dir="benchmark_results"
)

# Запуск теста
import asyncio
report = asyncio.run(benchmark.run_benchmark())

# Сохранение результатов
benchmark.save_report(report)

Выбор поставщика LLM

Запуск бенчмарка поддерживает несколько поставщиков LLM для оценки RAGAS через аргумент командной строки --provider.

Поддерживаемые поставщики

Поставщик Флаг Переменные окружения Модель
GigaChat –provider gigachat GIGACHAT_API_KEYилиGIGACHAT_CREDENTIALS GigaChat-2-Pro
Yandex –provider yandex YANDEX_API_KEY,YANDEX_FOLDER_ID qwen3-235b-a22b-fp8/latest
OpenAI –provider openai OPENAI_API_KEY gpt-4
Локальный –provider local LOCAL_MODEL_PATH совместимо с llama.cpp

Примеры использования

# Запуск с поставщиком Yandex (модель Qwen3)
python -m tests.benchmark.run_benchmark --provider yandex --ragas

# Запуск с GigaChat
python -m tests.benchmark.run_benchmark --provider gigachat --ragas

# Запуск с OpenAI
python -m tests.benchmark.run_benchmark --provider openai --ragas

# Быстрый запуск без оценки RAGAS
python -m tests.benchmark.run_benchmark --provider yandex -q

Настройка поставщиков

Поставщики настраиваются в файле config.yaml:

llm:
  provider: yandex  # Поставщик по умолчанию

  yandex:
    api_key: ${YANDEX_API_KEY}
    folder_id: ${YANDEX_FOLDER_ID}
    model: "qwen3-235b-a22b-fp8/latest"
    base_url: "https://llm.api.cloud.yandex.net/v1"
    timeout: 60

  gigachat:
    auth_key: ${GIGACHAT_AUTH_KEY}
    model: "GigaChat-2-Pro"

  openai:
    api_key: ${OPENAI_API_KEY}
    model: "gpt-4"

Замечания по конкретным поставщикам

Yandex Cloud AI Studio: - Использует API, совместимое с OpenAI - Модель по умолчанию: Qwen3 235B (высокое качество) - Соответствует требованиям конфиденциальности: логирование данных отключено по умолчанию - Поддерживает запросы на русском языке

GigaChat: - Российская языковая модель от Сбера - Наилучший выбор для контента на русском языке - На некоторых системах требуется обработка сертификатов

Локальные модели: - Использует llama.cpp через llama-cpp-python - Никаких затрат на API, полностью автономная работа - Требует локальной GPU или достаточной вычислительной мощности CPU

Набор данных для тестирования

Стандартный тестовый набор включает 11 разнообразных запросов:

Семантические запросы (4 запроса)

Ориентированы на понимание смысла и документации: - “Как PostgreSQL обрабатывает фиксацию транзакций?” - “Какова цель менеджера буферов?” - “Как PostgreSQL реализует многоверсионное управление параллелизмом?”

Ожидаемое поведение: - Только векторный поиск: Высокая эффективность (релевантность 80–90 %) - Только графовый поиск: Низкая эффективность (релевантность 20–30 %) - Гибридный подход: Наилучшая эффективность (объединяет семантическое понимание)

Структурные запросы (4 запроса)

Ориентированы на обход графа и анализ зависимостей: - “Покажите путь вызова от BeginTransactionBlock до CommitTransactionCommand” - “Найдите все функции, вызывающие malloc” - “Какие функции косвенно вызывают MemoryContextAlloc (глубина 2–3)?”

Ожидаемое поведение: - Только векторный поиск: Низкая эффективность (релевантность 20–30 %) - Только графовый поиск: Высокая эффективность (релевантность 80–90 %) - Гибридный подход: Наилучшая эффективность (использует структуру графа)

Запросы по безопасности (3 запроса)

Требуют одновременно анализа семантических шаблонов и структуры кода: - “Найдите потенциальные уязвимости к SQL-инъекциям в функциях построения запросов” - “Определите функции, выделяющие память без надлежащей проверки ошибок” - “Найдите риски переполнения буфера в функциях обработки строк”

Ожидаемое поведение: - Только векторный поиск: Средняя эффективность (релевантность 50–60 %) - Только графовый поиск: Средняя эффективность (релевантность 50–60 %) - Гибридный подход: Наилучшая эффективность (объединяет оба подхода)

Объяснение метрик

Точность@K

P@K = (количество релевантных в топ-K) / K

Измеряет, какая доля извлечённых результатов является релевантной. - 1.0 = Все результаты в топ-K релевантны - 0.0 = Ни один из результатов в топ-K не является релевантным

Полнота@K

R@K = (количество релевантных в топ-K) / (общее количество релевантных)

Измеряет, какая доля всех релевантных документов была извлечена. - 1.0 = Все релевантные документы извлечены - 0.0 = Ни один релевантный документ не извлечён

F1@K

F1 = 2 * (P * R) / (P + R)

Гармоническое среднее точности и полноты. - Сбалансированная мера качества ранжирования

Средний обратный ранг (MRR)

MRR = 1 / (ранг первого релевантного результата)

Измеряет, насколько быстро пользователь находит релевантный результат. - 1.0 = Первый результат релевантен - 0.5 = Второй результат релевантен - 0.0 = Релевантные результаты отсутствуют

Нормализованная дисконтированная кумулятивная выгода (NDCG@K)

NDCG@K = DCG@K / IDCG@K
DCG@K = Σ (2^rel_i - 1) / log2(i + 1)

Метрика с учётом градаций релевантности (высоко релевантно > релевантно > не релевантно). - 1.0 = Идеальное ранжирование - 0.0 = Наихудшее ранжирование

Пользовательские запросы для тестирования

Создайте собственные тестовые запросы с эталонными данными:

from benchmark_hybrid_retrieval import BenchmarkQuery

custom_queries = [
    BenchmarkQuery(
        id="custom_001",
        query="Ваш вопрос здесь",
        query_type="semantic",  # или "structural", "security"
        description="Описание того, что тестируется",
        relevant_node_ids={1001, 1002, 1003, 1004},  # идентификаторы узлов CPG
        highly_relevant_node_ids={1001, 1002},      # Наиболее важные узлы
        expected_difficulty="medium"  # "easy", "medium", "hard"
    ),
    # ... дополнительные запросы
]

# Запуск с пользовательскими запросами
report = asyncio.run(benchmark.run_benchmark(queries=custom_queries))

Выходные файлы

Бенчмарк генерирует два файла:

1. JSON-отчёт (benchmark_results/hybrid_benchmark_.json)

Полные результаты в формате, пригодном для машинной обработки: - Метрики по каждому запросу (P@K, R@K, F1, MRR, NDCG) - Сводные метрики по режимам - Идентификаторы извлечённых узлов для каждого запроса - Детализация оценок

2. Отчёт в формате Markdown (benchmark_results/hybrid_benchmark_.md)

Человекочитаемое резюме: - Сравнительная таблица - Основные выводы - Проценты улучшения

Понимание результатов

Интерпретация улучшений

Положительные улучшения (+) — это хорошо:

Гибридный F1@10 против векторного: +33,6%
 Гибридный поиск на 33,6% лучше, чем только по векторам

Когда гибридный метод превосходит другие: - Семантические запросы: Гибридный ≥ Векторный > Графовый - Структурные запросы: Гибридный ≥ Графовый > Векторный - Смешанные запросы: Гибридный > Векторный, Графовый

Пример анализа

Запрос: “Как PostgreSQL обрабатывает фиксацию транзакций?” - Тип: Семантический - Результаты: - Векторный: P@10=0,60, R@10=0,80, F1@10=0,69 - Графовый: P@10=0,20, R@10=0,30, F1@10=0,24 - Гибридный: P@10=0,70, R@10=0,90, F1@10=0,79

Анализ: - Векторный метод показывает хорошие результаты (семантический запрос) - Графовый метод справляется хуже (запрос не структурный) - Гибридный — лучший: +14,5% по сравнению с векторным (RRF добавляет структурный контекст)

Рекомендации по производительности

Задержка

Гибридный поиск медленнее, чем поиск из одного источника: - Только векторный: ~50-80 мс - Только графовый: ~50-80 мс - Гибридный: ~100-150 мс (накладные расходы на параллельное выполнение)

Компромисс: гибридный подход увеличивает задержку в 2 раза, но обеспечивает на 30–50 % лучшую релевантность.

Кэширование

Для эксплуатации в продакшене: 1. Кэшируйте часто встречающиеся запросы 2. Предварительно вычисляйте эмбеддинги 3. Используйте пул соединений для DuckDB

Модульные тесты

Запуск тестов метрик оценки:

pytest tests/unit/test_benchmark_metrics.py -v

Охват: - ✅ Вычисление Precision@K (5 тестов) - ✅ Вычисление Recall@K (4 теста) - ✅ Вычисление F1-меры (4 теста) - ✅ Вычисление MRR (5 тестов) - ✅ Вычисление NDCG (5 тестов) - ✅ Проверка корректности набора данных (3 теста)

Всего: 30 тестов, 100% прохождение

Воспроизводимость

Синтетический тест использует seed=42 для обеспечения воспроизводимости:

simulator = SyntheticRetrievalSimulator(seed=42)

Многократный запуск даёт идентичные результаты.

Рекомендации

1. Разнообразный набор запросов

Включайте запросы различных типов (семантические, структурные, по безопасности) и уровней сложности (лёгкие, средние, сложные).

2. Репрезентативные эталонные данные

Убедитесь, что эталонные данные отражают реальные оценки релевантности: - Явно помечайте узлы с высокой релевантностью - Включайте частичные совпадения в набор релевантных результатов - Привлекайте экспертов предметной области для проверки

3. Несколько метрик оценки

Не полагайтесь на одну метрику: - F1@10: Общее качество ранжирования - MRR: Пользовательский опыт (время до первого релевантного результата) - NDCG@10: Градуированная релевантность (высокая релевантность против обычной)

4. Анализ ошибок

Анализируйте результаты по каждому запросу, чтобы понять: - Какие типы запросов наиболее выигрывают от гибридного поиска? - В каких случаях каждый режим поиска даёт сбой? - Как улучшить адаптивное взвешивание?

Научные результаты

Данная тестовая платформа позволяет:

  1. Количественную оценку гибридного поиска на основе графов и векторов
  2. Сравнительный анализ различных режимов поиска
  3. Анализ исключения параметров (ablation studies) в методе RRF (веса, значение k)
  4. Анализ типов запросов (производительность при семантических и структурных запросах)
  5. Воспроизводимые эксперименты для публикаций

Цитирование

При использовании данного тестового набора в исследовательских целях:

@software{hybrid_cpg_benchmark_2025,
  title = {Hybrid Code Property Graph Retrieval Benchmark},
  author = {Phase 1 Implementation},
  year = {2025},
  month = {11},
  note = {CodeGraph: Hybrid Graph-Vector Code Analysis}
}

Устранение неполадок

Ошибка: “No module named ‘src.retrieval’”

Решение: Запускайте из корневой директории проекта.

Ошибка: “ModuleNotFoundError: VectorStore”

Решение: Убедитесь, что установлены все зависимости:

pip install chromadb sentence-transformers duckdb

Синтетические результаты выглядят нереалистично

Решение: Откорректируйте параметры симуляции в файле demo_benchmark.py:

# Для семантических запросов векторный поиск возвращает X% релевантных результатов
num_highly = int(len(highly_relevant) * 0.85)  # Измените это значение

Дальнейшие шаги

  1. ✅ Запустите синтетическую демонстрацию, чтобы понять архитектуру фреймворка
  2. ✅ Изучите выходные отчёты в формате JSON/MD
  3. ✅ Настройте тестовые запросы под ваш конкретный случай использования
  4. ✅ Запустите обработку с реальными данными CPG
  5. ✅ Проанализируйте результаты по каждому запросу, чтобы получить полезные сведения
  6. ✅ Настройте веса RRF на основе полученных результатов

Поддержка

При возникновении проблем или вопросов: - Создайте задачу (issue) в репозитории на GitHub - Приложите конфигурацию бенчмарка и логи ошибок - Предоставьте пример запроса, который завершается сбоем