Si deux juges aux réglages différents partagent une identité, le cache ne peut pas les distinguer. Les résultats calculés pour l'un sont servis à l'autre, et rien n'échoue.

Le défaut

Dans Microsoft PyRIT, deux instances de DecodingScorer aux réglages de matcher différents pouvaient rendre des verdicts opposés sur la même entrée tout en partageant leur hash et leur eval_hash. Des métriques d'évaluation en cache pouvaient alors être réutilisées entre des scorers qui ne se comportent pas pareil.

Le même défaut avait déjà été décrit et corrigé pour SubStringScorer. Les deux classes tiennent un matcher de texte au même endroit de la même méthode. Seule la classe sœur transmettait les paramètres du matcher à son identifiant.

Le correctif

get_matcher_params = getattr(self._text_matcher, "get_identifier_params", None)
"text_matcher_params": get_matcher_params() if callable(get_matcher_params) else None,

Deux lignes, copiées de la classe sœur à dessein. La sensibilité à la casse, le traitement des espaces, le seuil et la taille des n-grammes atteignent désormais l'identité. Les matchers personnalisés qui n'implémentent que is_match continuent de fonctionner grâce à la garde callable.

Les preuves

Les catégories de scorer sont absentes des identifiants des deux classes. Élargir l'une sans l'autre aurait cassé la symétrie sur laquelle reposait le correctif, j'ai donc gardé le changement symétrique et proposé de couvrir les catégories des deux dans une suite.

Ce que j'en retiens

Quand un bug est corrigé dans une classe, lisez ses sœurs. La deuxième occurrence d'un défaut se trouve souvent à un fichier de là, en attendant que personne ne regarde.

Ayoub Hammoudi, Ingénieur logiciel, full-stack et plateformes IA. github.com/Ayoubhm07