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

Версия 3.0 — комплексная платформа оценки гибридного поиска и сценарного тестирования.

Содержание

Обзор

Тестовая платформа предоставляет несколько инструментов оценки:

  1. Комплексный раннер бенчмарков — сценарная оценка с 20 наборами эталонных данных
  2. Бенчмарк классификации интентов — оценка точности классификатора интентов

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

1. Запуск комплексного бенчмарка

# Все сценарии, вопросы на русском
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

Отдельные hybrid/vector benchmark scripts удалены. Активная semantic-memory retrieval работает через OpenViking, а сценарные бенчмарки запускаются через tests/benchmark/.

Комплексный раннер бенчмарков

Основной инструмент (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.

Отдельные scripts/benchmark_* entrypoints удалены вместе с legacy vector-store compatibility. Для активных запусков используйте канонический harness tests/benchmark/.

Справочник метрик

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 = наихудшее ранжирование

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

Пользовательские вопросы добавляются в канонические fixtures tests/benchmark/ground_truth/.

custom_queries = [
    {
        "id": "custom_001",
        "question": "Your question here",
        "expected_scenario": "scenario_01_onboarding",
    },
]

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

Комплексный раннер бенчмарков

Результаты в 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 openviking sentence-transformers duckdb

Ошибка блокировки DuckDB

Решение: убедитесь, что gocpg.exe не запущен (проверьте ps aux | grep gocpg).

Низкие оценки бенчмарка

Решение: проверьте: 1. OpenViking содержит проиндексированные документы (директория openviking_data/) 2. DuckDB имеет данные CPG (файл *.duckdb валиден) 3. Домен задан корректно (config.yamldomain.name)

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

  1. Запустите бенчмарк гибридного поиска для оценки качества
  2. Запустите комплексный бенчмарк для полной оценки конвейера
  3. Изучите отчёты (JSON + Markdown)
  4. Настройте запросы или эталонные данные для вашего проекта
  5. Используйте --failed-from для итеративного исправления ошибок
  6. Настройте веса RRF на основе результатов

Поддержка

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