Версия 3.0 — комплексная платформа оценки гибридного поиска и сценарного тестирования.
Содержание¶
- Обзор
- Быстрый старт
- Бенчмарк гибридного поиска
- Комплексный раннер бенчмарков
- Выбор поставщика LLM
- Набор данных для тестирования
- Модули оценки
- Сценарное тестирование
- Конфигурация
- Дополнительные бенчмарки
- Справочник метрик
- Пользовательские запросы
- Выходные файлы
- Интерпретация результатов
- Рекомендации по производительности
- Модульные тесты
- Рекомендации
- Устранение неполадок
- Дальнейшие шаги
- Поддержка
Обзор¶
Тестовая платформа предоставляет несколько инструментов оценки:
- Бенчмарк гибридного поиска — сравнение векторного, графового и гибридного режимов
- Комплексный раннер бенчмарков — сценарная оценка с 20 наборами эталонных данных
- Бенчмарк классификации интентов — оценка точности классификатора интентов
- Бенчмарк символьного выполнения — измерение влияния V2 на taint-анализ
- Бенчмарк LLM-дизамбигуации — тестирование классификатора с поддержкой LLM
Быстрый старт¶
1. Запуск бенчмарка гибридного поиска¶
python scripts/benchmark_hybrid_retrieval.py --output-dir benchmark_results
Результат:
================================================================================
BENCHMARK SUMMARY
================================================================================
Metric Vector Graph Hybrid vs Vector vs Graph
--------------------------------------------------------------------------------
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%
2. Запуск комплексного бенчмарка¶
# Все сценарии, вопросы на русском
python -m tests.benchmark.run_benchmark --language ru
# Быстрый режим (5 вопросов на сценарий)
python -m tests.benchmark.run_benchmark -q --language ru
# Конкретные сценарии
python -m tests.benchmark.run_benchmark --scenarios 01,02,03
3. Запуск с реальными данными (Python API)¶
from scripts.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()
# Создание и запуск бенчмарка
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)
Бенчмарк гибридного поиска¶
Бенчмарк гибридного поиска (scripts/benchmark_hybrid_retrieval.py) сравнивает три режима:
- Только векторный: семантический поиск через ChromaDB
- Только графовый: структурный поиск через DuckDB/CPG
- Гибридный: комбинация обоих через RRF
Ключевые классы:
- HybridRetrievalBenchmark(vector_store, cpg_service, output_dir="benchmark_results") — оркестратор
- BenchmarkQuery — запрос с эталонными данными
- RetrievalMetrics — метрики для одного запроса
- BenchmarkReport — агрегированный отчёт
Аргументы CLI:
python scripts/benchmark_hybrid_retrieval.py [OPTIONS]
| Аргумент | По умолчанию | Описание |
|---|---|---|
--db-path |
активный проект | Путь к DuckDB CPG |
--chroma-path |
chroma_db |
Путь к ChromaDB |
--output-dir |
benchmark_results |
Директория для результатов |
--modes |
vector_only graph_only hybrid |
Режимы поиска |
Комплексный раннер бенчмарков¶
Основной инструмент (tests/benchmark/run_benchmark.py) запускает сценарную оценку всего конвейера CodeGraph.
python -m tests.benchmark.run_benchmark [OPTIONS]
Аргументы CLI:
| Аргумент | Кратко | По умолчанию | Описание |
|---|---|---|---|
--project |
None |
Имя проекта (автопереключение) | |
--scenarios |
-s |
все | Сценарии через запятую (01,02,03) |
--language |
-l |
все | Фильтр по языку (en/ru) |
--difficulty |
-d |
все | Фильтр: easy/medium/hard/expert |
--max-questions |
-n |
без лимита | Макс. вопросов на сценарий |
--quick |
-q |
Быстрый режим (5 вопросов) | |
--mock |
-m |
Мок-копилот для тестирования | |
--trace |
-t |
true |
Трассировка |
--no-trace |
Отключить трассировку | ||
--ragas |
-r |
Оценка RAGAS через LLM | |
--provider |
-p |
из конфига | Поставщик LLM (gigachat/yandex/openai/local) |
--failed-from |
Перезапуск провалившихся из предыдущего запуска | ||
--question-ids |
Конкретные ID вопросов | ||
--offset |
0 |
Пропустить N вопросов | |
--randomize |
Случайный выбор вопросов |
Примеры:
# Перезапуск провалившихся вопросов
python -m tests.benchmark.run_benchmark --failed-from 20260119_073256
# Вопросы 7-12 (пропустить 6, взять 6)
python -m tests.benchmark.run_benchmark --offset 6 --max-questions 6
# Случайная выборка (3 вопроса на сценарий)
python -m tests.benchmark.run_benchmark --randomize --max-questions 3
# Конкретные ID вопросов
python -m tests.benchmark.run_benchmark --question-ids "VULN_EN_002,VULN_EN_004"
Выбор поставщика 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 запроса)¶
Ориентированы на понимание смысла и документации: - “How does PostgreSQL handle transaction commits?” - “What is the purpose of the buffer manager?” - “How does PostgreSQL implement multi-version concurrency control?” - “How does the query optimizer choose between index scan and sequential scan?” (смешанный)
Ожидаемое поведение: - Только векторный: Высокая эффективность (релевантность 80-90%) - Только графовый: Низкая эффективность (релевантность 20-30%) - Гибридный: Наилучшая эффективность
Структурные запросы (4 запроса)¶
Ориентированы на обход графа и анализ зависимостей: - “Show me the call path from BeginTransactionBlock to CommitTransactionCommand” - “Find all functions that call malloc” - “What are the indirect callers of MemoryContextAlloc (depth 2-3)?” - “Trace the execution path for a SELECT statement with WHERE clause” (смешанный)
Ожидаемое поведение: - Только векторный: Низкая эффективность (релевантность 20-30%) - Только графовый: Высокая эффективность (релевантность 80-90%) - Гибридный: Наилучшая эффективность
Запросы по безопасности (3 запроса)¶
Требуют одновременно семантического и структурного анализа: - “Find potential SQL injection vulnerabilities in query building functions” - “Identify functions that allocate memory without proper error checking” - “Find buffer overflow risks in string manipulation functions”
Ожидаемое поведение: - Только векторный: Средняя эффективность (релевантность 50-60%) - Только графовый: Средняя эффективность (релевантность 50-60%) - Гибридный: Наилучшая эффективность
Примечание: Запросы, отмеченные (смешанный), требуют как семантического понимания, так и структурного обхода. Они отнесены к семантической/структурной категории по основному значению
query_type.
Модули оценки¶
Платформа включает 4 модуля оценки в tests/benchmark/evaluation/:
IR-метрики (ir_metrics.py)¶
Стандартные метрики информационного поиска через класс IRMetrics:
| Метрика | Метод | Описание |
|---|---|---|
| Precision@K | precision_at_k(retrieved, relevant, k) |
Доля релевантных в топ-K |
| Recall@K | recall_at_k(retrieved, relevant, k) |
Доля найденных релевантных |
| F1@K | f1_at_k(retrieved, relevant, k) |
Гармоническое среднее P и R |
| MRR | mrr(retrieved, relevant) |
Обратный ранг первого релевантного |
| NDCG@K | ndcg_at_k(retrieved, relevant, highly_relevant, k) |
Градуированное ранжирование |
| Average Precision | average_precision(retrieved, relevant) |
Площадь под кривой P-R |
| Hit Rate@K | hit_rate_at_k(retrieved, relevant, k) |
Бинарный индикатор |
Значения K по умолчанию: [5, 10, 20]. Метод compute_all() вычисляет все метрики сразу.
Метрики производительности (performance_metrics.py)¶
Метрики выполнения через класс PerformanceMetrics:
- Латентность: min, max, mean, median, p50, p95, p99
- Токены: input, output, total, per-question, per-second
- Кеш: попадания, промахи, процент попаданий
- Сложность SQL: взвешенная оценка (JOIN +2, подзапрос +3, агрегация +1)
Метрики точности (accuracy_metrics.py)¶
Качество ответов через класс AccuracyMetrics:
- Семантическая схожесть: косинусная через sentence-transformers (модель: paraphrase-multilingual-MiniLM-L12-v2)
- Покрытие ключевых слов: проверка наличия с поддержкой русской морфологии
- Покрытие функций: precision/recall/F1 для найденных и ожидаемых функций
- Паттерн-матчинг: проверка регулярными выражениями
- Фактическая точность: композитная оценка
Мультисущностные метрики (multi_entity_metrics.py)¶
Оценка по 9 типам сущностей через класс MultiEntityIRMetrics:
| Тип сущности | Вес | Описание |
|---|---|---|
functions |
1.0 | Определения функций |
external_functions |
0.9 | Внешние функции |
structs |
0.9 | Структуры/классы |
macros |
0.8 | Макросы |
types |
0.7 | Типы данных |
enums |
0.7 | Перечисления |
callers |
0.85 | Вызывающие функции |
callees |
0.85 | Вызываемые функции |
files |
0.95 | Исходные файлы |
Возможности: нечёткое сопоставление имён функций (подстрока/префикс), кросс-платформенная нормализация путей, взвешенная комбинация метрик.
Сценарное тестирование¶
Комплексный бенчмарк использует эталонные вопросы, организованные по сценариям:
tests/benchmark/ground_truth/
+-- scenario_01_onboarding/
| +-- questions_en.yaml
| +-- questions_ru.yaml
| +-- questions_en_codegraph.yaml (для конкретного проекта)
+-- scenario_02_security_audit/
+-- ...
+-- scenario_20_dependencies/
20 директорий сценариев с наборами вопросов на EN + RU. Конфигурация бенчмарка (benchmark_config.yaml) определяет 16 основных сценариев; сценарии 17-20 (редактирование файлов, оптимизация кода, проверка стандартов, зависимости) имеют эталонные данные, но пока не включены в конфиг.
Формат YAML эталонных данных¶
scenario:
id: "scenario_01_onboarding"
name: "Codebase Onboarding"
mapped_workflow: "onboarding_workflow"
metadata:
version: "1.0"
language: "en"
question_count: 35
difficulty_distribution:
easy: 12
medium: 15
hard: 8
questions:
- id: "ONBOARD_EN_001"
question: "Where is heap_insert defined?"
category: "definition_search"
difficulty: "easy"
postgresql_subsystem: "storage"
target_function: "heap_insert"
ground_truth:
expected_functions: ["heap_insert"]
expected_files: ["heapam.c"]
required_keywords: ["heap", "insert", "tuple"]
keyword_coverage_only: false
evaluation:
metrics: ["ir_metrics", "accuracy"]
semantic_similarity_threshold: 0.7
Ключевые поля ground_truth:
- expected_functions, expected_callers, expected_callees — списки сущностей для IR-метрик
- expected_structs, expected_macros, expected_types, expected_enums — дополнительные типы
- expected_files — ожидаемые исходные файлы
- required_keywords — ключевые слова, которые должны быть в ответе
- key_patterns — регулярные выражения для проверки
- keyword_coverage_only: true — для концептуальных вопросов без конкретных сущностей
Конфигурация¶
Конфигурация бенчмарка (tests/benchmark/config/benchmark_config.yaml)¶
benchmark:
name: "CodeGraph Comprehensive Benchmark"
version: "2.1"
execution:
k_values: [5, 10, 20]
max_parallel_questions: 1
question_timeout: 60
enable_tracing: true
languages: ["en", "ru"]
thresholds:
easy:
precision_at_10: 0.3
recall_at_10: 0.5
mrr: 0.4
semantic_similarity: 0.5
keyword_coverage: 0.5
medium:
precision_at_10: 0.2
recall_at_10: 0.3
mrr: 0.3
hard:
precision_at_10: 0.1
recall_at_10: 0.2
mrr: 0.2
success_criteria:
min_scenario_pass_rate: 0.5
min_scenarios_passed: 8
min_overall_pass_rate: 0.5
Дополнительные бенчмарки¶
Бенчмарк классификации интентов¶
python -m tests.benchmark.intent_benchmark --language ru --show-failures
Оценка точности классификатора по 17 сценариям. Поддерживает --compare-languages для сравнения EN и RU.
Бенчмарк символьного выполнения¶
python scripts/benchmark_symbolic_execution.py --db data/projects/codegraph.duckdb
Измерение влияния V2: процент фильтрации ложных срабатываний, накладные расходы по времени/памяти, покрытие парсера.
Бенчмарк LLM-дизамбигуации¶
python scripts/benchmark_with_llm.py --llm --verbose
Тестирование классификатора с LLM-дизамбигуацией в сравнении с правилами.
Справочник метрик¶
Precision@K¶
P@K = (кол-во релевантных в топ-K) / K
- 1.0 = все результаты в топ-K релевантны
- 0.0 = ни один результат не релевантен
Recall@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)
Градуированная релевантность: высоко релевантно (rel=2) > релевантно (rel=1) > нерелевантно (rel=0). - 1.0 = идеальное ранжирование - 0.0 = наихудшее ранжирование
Пользовательские запросы¶
Создание пользовательских запросов для бенчмарка гибридного поиска:
from scripts.benchmark_hybrid_retrieval import BenchmarkQuery
custom_queries = [
BenchmarkQuery(
id="custom_001",
query="Your question here",
query_type="semantic", # или "structural", "security"
description="Описание того, что тестируется",
relevant_node_ids={1001, 1002, 1003, 1004}, # ID узлов CPG
highly_relevant_node_ids={1001, 1002}, # Наиболее важные
expected_difficulty="medium" # "easy", "medium", "hard"
),
]
# Запуск с пользовательскими запросами
import asyncio
report = asyncio.run(benchmark.run_benchmark(queries=custom_queries))
Выходные файлы¶
Бенчмарк гибридного поиска¶
Два файла в benchmark_results/:
-
JSON-отчёт (
hybrid_benchmark_<timestamp>.json) — полные машиночитаемые результаты: метрики по запросам, агрегированные метрики, ID извлечённых узлов, детализация оценок. -
Markdown-отчёт (
hybrid_benchmark_<timestamp>.md) — человекочитаемое резюме: сравнительная таблица, ключевые выводы, проценты улучшения.
Комплексный раннер бенчмарков¶
Результаты в tests/benchmark/results/{RUN_ID}/:
tests/benchmark/results/20260307_120000/
+-- summary.json # Сводка результатов
+-- scenario_01.json # Разбивка по сценарию
+-- scenario_02.json
+-- traces/
| +-- ONBOARD_EN_001.trace
| +-- VULN_EN_002.trace
+-- metadata.json # Метаданные запуска
Интерпретация результатов¶
Как интерпретировать улучшения¶
Положительные значения (+) — это хорошо:
Гибридный F1@10 против векторного: +33,6%
= Гибридный поиск на 33,6% лучше, чем только векторный
Когда гибридный превосходит: - Семантические запросы: Гибридный >= Векторный > Графовый - Структурные запросы: Гибридный >= Графовый > Векторный - Смешанные запросы: Гибридный > Векторный, Графовый
Пример анализа¶
Запрос: “How does PostgreSQL handle transaction commits?” - Тип: Семантический - Результаты: - Векторный: 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 добавляет структурный контекст)
Рекомендации по производительности¶
Латентность¶
Гибридный поиск медленнее одиночного источника из-за накладных расходов на параллельное выполнение. Конкретная латентность зависит от объёма данных, оборудования и сложности запроса.
Компромисс: гибридный подход увеличивает латентность ради 30-50% лучшей релевантности.
Кеширование¶
Для эксплуатации в рабочей среде: 1. Кешируйте часто встречающиеся запросы 2. Предварительно вычисляйте эмбеддинги 3. Используйте пул соединений для DuckDB
Модульные тесты¶
Запуск тестов метрик:
pytest tests/unit/test_benchmark_metrics.py -v
Покрытие (30 тестов в 8 классах): - TestPrecisionAtK: 5 тестов - TestRecallAtK: 4 теста - TestF1Score: 4 теста - TestMRR: 5 тестов - TestNDCG: 6 тестов - TestBenchmarkQuery: 2 теста - TestRetrievalMetrics: 2 теста - TestBenchmarkDataset: 3 теста
Дополнительные тестовые файлы:
- tests/unit/test_benchmark_ir_coverage.py — проверка покрытия IR-метриками всех эталонных вопросов
Рекомендации¶
1. Разнообразный набор запросов¶
Включайте запросы разных типов (семантические, структурные, безопасность, смешанные) и сложности (лёгкие, средние, сложные).
2. Репрезентативные эталонные данные¶
Убедитесь, что эталонные данные отражают реальные оценки: - Явно помечайте узлы с высокой релевантностью - Включайте частичные совпадения - Привлекайте экспертов для проверки
3. Несколько метрик оценки¶
Не полагайтесь на одну метрику: - F1@10: общее качество ранжирования - MRR: пользовательский опыт (время до первого релевантного) - NDCG@10: градуированная релевантность
4. Анализ ошибок¶
Анализируйте результаты по каждому запросу: - Какие типы запросов выигрывают от гибридного? - Где каждый режим даёт сбой? - Как улучшить адаптивное взвешивание?
5. Итеративная отладка¶
Используйте расширенные фильтры:
- --failed-from RUN_ID для перезапуска провалов
- --offset N --max-questions M для пакетного тестирования
- --question-ids для конкретных вопросов
Устранение неполадок¶
Ошибка: “No module named ‘src.retrieval’”¶
Решение: запускайте из корневой директории проекта.
Ошибка: “ModuleNotFoundError: VectorStore”¶
Решение: установите зависимости:
pip install chromadb sentence-transformers duckdb
Ошибка блокировки DuckDB¶
Решение: убедитесь, что gocpg.exe не запущен (проверьте ps aux | grep gocpg).
Низкие оценки бенчмарка¶
Решение: проверьте:
1. ChromaDB содержит проиндексированные документы (директория chroma_db/)
2. DuckDB имеет данные CPG (файл *.duckdb валиден)
3. Домен задан корректно (config.yaml → domain.name)
Дальнейшие шаги¶
- Запустите бенчмарк гибридного поиска для оценки качества
- Запустите комплексный бенчмарк для полной оценки конвейера
- Изучите отчёты (JSON + Markdown)
- Настройте запросы или эталонные данные для вашего проекта
- Используйте
--failed-fromдля итеративного исправления ошибок - Настройте веса RRF на основе результатов
Поддержка¶
При возникновении проблем: - Создайте задачу (issue) в репозитории на GitHub - Приложите конфигурацию и логи ошибок - Предоставьте пример запроса, который завершается сбоем