Руководство по тестовой платформе¶
Оценка гибридного поиска — Этап 1
В этом руководстве объясняется, как использовать тестовую платформу для оценки эффективности гибридного поиска.
Содержание¶
- Обзор
- Быстрый старт
- 1. Запуск синтетической демонстрации
- 2. Запуск с реальными данными
- Выбор поставщика LLM
- Поддерживаемые поставщики
- Примеры использования
- Конфигурация поставщиков
- Замечания, специфичные для поставщиков
- Набор данных для тестирования
- Семантические запросы (4 запроса)
- Структурные запросы (4 запроса)
- Запросы по безопасности (3 запроса)
- Объяснение метрик
- Precision@K
- Recall@K
- F1@K
- Средний обратный ранг (MRR)
- Нормализованная дисконтированная кумулятивная выгода (NDCG@K)
- Пользовательские тестовые запросы
- Выходные файлы
- 1. JSON-отчёт (benchmark_results/hybrid_benchmark_
.json) - 2. Отчёт в формате Markdown (benchmark_results/hybrid_benchmark_
.md) - Интерпретация результатов
- Как интерпретировать улучшения
- Пример анализа
- Соображения по производительности
- Задержка (Latency)
- Кэширование
- Модульные тесты
- Воспроизводимость
- Рекомендации
- 1. Разнообразный набор запросов
- 2. Репрезентативные эталонные данные
- 3. Использование нескольких метрик
- 4. Анализ ошибок
- Научный вклад
- Цитирование
- Устранение неполадок
- Ошибка: “No module named ‘src.retrieval’”
- Ошибка: “ModuleNotFoundError: VectorStore”
- Синтетические результаты выглядят нереалистично
- Дальнейшие шаги
- Поддержка
Обзор¶
Тестовый фреймворк сравнивает три режима поиска: - Только векторный: чисто семантический поиск с использованием 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. Анализ ошибок¶
Анализируйте результаты по каждому запросу, чтобы понять: - Какие типы запросов наиболее выигрывают от гибридного поиска? - В каких случаях каждый режим поиска даёт сбой? - Как улучшить адаптивное взвешивание?
Научные результаты¶
Данная тестовая платформа позволяет:
- Количественную оценку гибридного поиска на основе графов и векторов
- Сравнительный анализ различных режимов поиска
- Анализ исключения параметров (ablation studies) в методе RRF (веса, значение k)
- Анализ типов запросов (производительность при семантических и структурных запросах)
- Воспроизводимые эксперименты для публикаций
Цитирование¶
При использовании данного тестового набора в исследовательских целях:
@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) # Измените это значение
Дальнейшие шаги¶
- ✅ Запустите синтетическую демонстрацию, чтобы понять архитектуру фреймворка
- ✅ Изучите выходные отчёты в формате JSON/MD
- ✅ Настройте тестовые запросы под ваш конкретный случай использования
- ✅ Запустите обработку с реальными данными CPG
- ✅ Проанализируйте результаты по каждому запросу, чтобы получить полезные сведения
- ✅ Настройте веса RRF на основе полученных результатов
Поддержка¶
При возникновении проблем или вопросов: - Создайте задачу (issue) в репозитории на GitHub - Приложите конфигурацию бенчмарка и логи ошибок - Предоставьте пример запроса, который завершается сбоем