File size: 3,391 Bytes
0341212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from typing import Annotated, Any

from fastapi import APIRouter, Depends, File, HTTPException, UploadFile

import common.dependencies as DI
from common import auth
from components.services.search_metrics import SearchMetricsService
from schemas.evaluation import EvaluationParams, EvaluationResponse

# Создание роутера
router = APIRouter(prefix="/evaluate", tags=["Evaluation"])

# Важно: добавить импорт logger, если его нет
import logging

logger = logging.getLogger(__name__)

# Определение эндпоинта
@router.post(
    "/from_file/{dataset_id}",
    response_model=EvaluationResponse,
    summary="Оценка RAG по файлу",
    description="Загружает XLSX файл с вопросами/ответами и рассчитывает метрики RAG (Precision, Recall, F1) для указанного dataset_id и различных значений top_n. Опционально применяет Query Expansion."
)
async def evaluate_rag_from_file(
    dataset_id: int,
    params: Annotated[EvaluationParams, Depends()],
    file: Annotated[UploadFile, File(description="XLSX файл с колонками 'id', 'question', 'text' (эталонные ответы через \\n)")],
    metrics_service: Annotated[SearchMetricsService, Depends(DI.get_search_metrics_service)],
    current_user: Annotated[any, Depends(auth.get_current_user)], # Защита эндпоинта
) -> Any: # Возвращаем Any, т.к. сервис возвращает dict, а FastAPI валидирует по response_model
    """Эндпоинт для оценки RAG.

    - Принимает ID датасета в пути.
    - Принимает параметры оценки (порог, top_n, use_query_expansion) и файл как multipart/form-data.
    - Вызывает SearchMetricsService для выполнения расчетов.
    - Возвращает рассчитанные метрики.
    """
    try:
        # --- Вызываем сервис, он теперь возвращает полный словарь ---
        evaluation_full_results = await metrics_service.evaluate_from_file(
            file=file,
            dataset_id=dataset_id,
            similarity_threshold=params.similarity_threshold,
            top_n_values=params.top_n_values,
            use_query_expansion=params.use_query_expansion,
            top_worst_k=params.top_worst_k # Передаем новый параметр
        )

        # --- Просто возвращаем результат сервиса ---
        # FastAPI сам проверит его по схеме EvaluationResponse
        return evaluation_full_results

    except HTTPException as e:
        # Просто пробрасываем HTTP ошибки дальше
        raise e
    except Exception as e:
        # Логирование ошибки может быть полезно здесь
        logger.exception("Internal server error during evaluation endpoint execution.") # Пример логирования
        # Ловим другие возможные ошибки во время оценки
        # Логгер уже есть в SearchMetricsService
        raise HTTPException(status_code=500, detail=f"Internal server error during evaluation: {e}")