BUG: Overlapping scorer-evaluation globs duplicate CSVs and change accuracy

Fermée Adaptée aux débutants
#3,430 2 commentaires 0 réactions 1 personne assignée Voir sur GitHub

Les mainteneurs répondent en général sous 2 jours

@its-amann y travaille déjà.

Depuis le 24/10/2026.

  • #3514 par @its-amann — fusionnée

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
78/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
pandas, python
Domaine
backend, data

Piste de recherche

Commencez dans pyrit/score/scorer_evaluation/scorer_evaluator.py, à run_evaluation_async(), et suivez la manière dont les motifs human_labeled_datasets_files sélectionnent les fichiers CSV. Ajoutez une couverture de régression pour les motifs qui se chevauchent et ceux qui sont répétés, tout en préservant les fichiers distincts ayant des chaînes de version identiques ; vérifiez que les deux configurations évaluent deux réponses avec une précision de 0.5.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

Describe the bug

Overlapping human_labeled_datasets_files patterns load the same CSV more than once in run_evaluation_async(), changing sample weights and reported accuracy. For the same two files and deterministic scorer, adding an already-matched filename changes accuracy from 0.5 to 0.6667.

Steps/Code to Reproduce

No model API or external dataset needed. Only the dataset root is redirected; loading, scoring, and metrics use the real implementations.

import asyncio
from pathlib import Path
from tempfile import TemporaryDirectory
from unittest.mock import patch

from pyrit.memory import CentralMemory, SQLiteMemory
from pyrit.score import RegistryUpdateBehavior, SubStringScorer
from pyrit.score.scorer_evaluation import scorer_evaluator as se


async def run_async(root: Path) -> None:
    try:
        with patch.object(se, "SCORER_EVALS_PATH", root):
            for patterns in (["*.csv"], ["*.csv", "a.csv"]):
                evaluator = se.ObjectiveScorerEvaluator(SubStringScorer(substring="marker"))
                result = await evaluator.run_evaluation_async(
                    dataset_files=se.ScorerEvalDatasetFiles(
                        human_labeled_datasets_files=patterns, result_file="unused.jsonl"
                    ),
                    num_scorer_trials=1,
                    update_registry_behavior=RegistryUpdateBehavior.NEVER_UPDATE,
                )
                print(patterns, result.num_responses, round(float(result.accuracy), 4))
    finally:
        await CentralMemory.get_memory_instance().dispose_engine_async()


with TemporaryDirectory() as directory:
    root = Path(directory)
    for name, label in [("a.csv", 1), ("b.csv", 0)]:
        (root / name).write_text(
            "# dataset_version=1.0\nassistant_response,objective,human_score\n"
            f"marker,Synthetic objective,{label}\n",
            encoding="utf-8",
        )
    CentralMemory.set_memory_instance(SQLiteMemory(db_path=":memory:", silent=True))
    asyncio.run(run_async(root))
Expected Results

Both configurations evaluate the same two responses, with accuracy 0.5.

Actual Results
['*.csv'] 2 0.5
['*.csv', 'a.csv'] 3 0.6667

Would deduplicating matched paths before loading be appropriate? I'd keep distinct files with equal version strings intact and add regression tests for overlapping and repeated patterns. I'd like to take this if you mark it ready for contribution; I'll wait for triage before preparing a PR.

Versions

macOS ARM64, Python 3.12.13, PyRIT 1.2.0.dev0 (ac196e57, main), numpy 2.4.6, pandas 3.0.6, scipy 1.17.1. Dependencies installed with uv sync --locked --no-dev.

AI-assisted investigation; the reproduction above was executed locally against unmodified source.

Langage dominant
Python
Étoiles
4.7k
Forks
1k
Merge moyen
2 j 6 h
PR mergées (30 j)
513

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

  • Aucun Dockerfile ni fichier Docker Compose
  • Propose un modèle de pull request
  • Aucun guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de microsoft/PyRIT

Toutes les issues de microsoft/PyRIT

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.