uqlm : donner un score de confiance aux réponses d'un LLM
[JMLR 2026] "UQLM: A Python Package for Uncertainty Quantification in Large Language Models"
En bref
- De quoi s’agit-il ?
- La bibliothèque Python de CVS Health regroupe plusieurs familles de scoreurs d'incertitude, du calcul d'entropie sémantique aux juges LLM. Le choix se joue surtout sur ce que vous acceptez de payer en appels supplémentaires.
- À qui s’adresse-t-il ?
- Adoptez uqlm si vous avez besoin d'un score de confiance par réponse et que vous acceptez le coût en générations multiples des scoreurs boîte noire, ou si vous disposez déjà des logprobs pour les scoreurs boîte blanche.
- Puis-je l’utiliser commercialement ?
- Oui. Apache-2.0 est une licence permissive : vous pouvez utiliser, modifier et vendre un logiciel qui en dépend, à condition de conserver les mentions de droit d’auteur et de licence.
- Est-il encore maintenu ?
- Oui. Les derniers commits datent d’il y a 1 jour.
- En quel langage est-il écrit ?
- Principalement Python, d’après les statistiques de langage de GitHub.
Ces réponses reposent sur les données GitHub du projet (dernière synchronisation le 15 septembre 2026) et sur notre analyse. Elles ne constituent pas un avis juridique.
ANALYSE OPEN SOURCE APPROFONDIE
Le problème : une réponse fluide n'est pas une réponse fiable
Un LLM produit la même sortie confiante qu'il ait raison ou qu'il invente. Le README de uqlm part de ce constat et propose une couche de détection d'hallucination au niveau de la réponse, pas du token. Chaque scoreur renvoie une valeur entre 0 et 1, où une valeur élevée signale une probabilité plus faible d'erreur. Le paquet s'adresse donc à des équipes qui doivent décider quoi faire d'une sortie de modèle : la publier, la faire relire, ou la remplacer par une autre génération. C'est un outil d'arbitrage, pas un correcteur. La publication JMLR 2026 et les articles TMLR et EMNLP cités dans les badges situent le projet dans un travail de recherche appliquée, avec du code publié en Apache-2.0.
Quatre familles de scoreurs, quatre façons de payer
Le tableau du README classe les scoreurs selon la latence, le coût et la compatibilité. Les scoreurs boîte noire mesurent la cohérence entre plusieurs réponses générées à partir du même prompt : ils fonctionnent avec n'importe quel LLM, mais exigent plusieurs générations et des comparaisons, donc une latence moyenne à élevée et un coût élevé en appels. Les scoreurs boîte blanche s'appuient sur les probabilités de tokens déjà renvoyées par le modèle : latence minimale et coût nul en appels supplémentaires, à condition d'avoir accès à ces probabilités, ce qui exclut une partie des API. Les scoreurs juge LLM ajoutent un ou plusieurs modèles évaluateurs, avec une latence et un coût qui dépendent du nombre de juges. Les scoreurs d'ensemble combinent les précédents. Une cinquième catégorie, les scoreurs pour texte long, travaille au niveau des affirmations et affiche une latence élevée à très élevée. Le compromis est explicite dans la documentation : plus vous voulez de robustesse sans probabilités internes, plus vous payez en générations.
Mise en route : un LLM LangChain, une liste de scoreurs
L'installation se fait depuis PyPI avec pip install uqlm. Le README précise que le paquet requiert Python 3.10 ou supérieur. L'exemple fourni construit d'abord un modèle LangChain, ici ChatOpenAI avec le modèle gpt-4o-mini, puis instancie BlackBoxUQ avec le paramètre scorers positionné sur semantic_negentropy et use_best=True. L'appel se fait en asynchrone : results = await bbuq.generate_and_score(prompts=prompts, num_responses=5), et le résultat s'exporte via results.to_df(). Le paramètre num_responses fixe le nombre de générations comparées : c'est lui qui détermine directement la facture. use_best=True active la mitigation, c'est-à-dire la sélection de la réponse dont l'incertitude est la plus faible plutôt que la simple notation. La documentation indique que n'importe quel modèle de chat LangChain peut servir de base, l'exemple avec ChatOpenAI n'étant qu'une illustration.
Ce que le README ne tranche pas
Les scoreurs disponibles sont listés avec leurs références académiques, mais le README ne donne aucune indication sur la façon de choisir entre eux, ni sur le seuil à partir duquel une réponse doit être considérée comme suspecte. La valeur 0.5 n'est mentionnée nulle part comme frontière. Il faut donc calibrer soi-même sur un jeu de données annoté, ce que le README ne décrit pas. Autre point laissé ouvert : le comportement des scoreurs boîte noire sur des prompts à réponse unique et factuelle, où la diversité des générations est faible par construction. Un score élevé y signalera surtout que le modèle est déterministe, pas qu'il a raison. C'est une limite de la méthode d'ensemble par cohérence, pas un défaut d'implémentation, mais elle conditionne l'usage.
Le coût caché : les générations multiples
Un scoreur boîte noire avec num_responses=5 transforme un appel en cinq, plus les comparaisons nécessaires au calcul de l'entropie sémantique. Sur un volume important, la facture suit la même multiplication. Les scoreurs juge LLM ajoutent une couche : le coût dépend du nombre de juges configurés. Seuls les scoreurs boîte blanche échappent à cette logique, et le README signale une exception dans sa note de bas de tableau : les scoreurs boîte blanche à générations multiples restent coûteux et lents. La règle pratique est donc simple. Si votre fournisseur expose les probabilités de tokens, commencez par là. Sinon, vous financez la détection d'hallucination en appels d'inférence, et le budget devient le paramètre de conception principal, pas la qualité du score.
Face à une vérification par récupération
L'alternative la plus directe n'est pas un autre paquet de scoring, c'est une architecture différente : la vérification par récupération, où l'on confronte la réponse à des documents sources avant de la valider. uqlm ne fait pas cela. Il mesure la dispersion interne du modèle, sans corpus de référence. La différence de coût est nette : la récupération demande une base documentaire à jour et un pipeline d'indexation, mais un seul appel de génération. uqlm ne demande aucune base, mais plusieurs générations. La différence de couverture l'est tout autant : une réponse fausse que le modèle produit de façon stable sur cinq générations obtiendra un bon score de confiance, alors qu'une vérification par récupération la rejetterait. Inversement, uqlm fonctionne sur des questions ouvertes sans source disponible, là où la récupération n'a rien à interroger.
Maintenance, licence et rythme de publication
Trois versions sont listées entre le 26 juillet et le 3 septembre 2026, la dernière en date étant v0.6.6. Le dépôt n'est pas archivé et le dernier push correspond à la date de cette version. Ce rythme rapproché signifie que les interfaces peuvent bouger entre deux versions mineures : épinglez la version dans vos dépendances si vous intégrez le paquet dans un pipeline de production. La licence Apache-2.0 autorise l'usage commercial et la modification, avec les obligations habituelles de conservation des mentions et d'indication des changements. Elle inclut une clause de brevets. Le paquet dépend de LangChain pour l'accès aux modèles, ce qui ajoute une couche d'abstraction dont les évolutions peuvent aussi affecter votre code. Rien dans le matériel fourni ne permet de dire si les scoreurs sont couverts par des tests de non-régression sur leurs valeurs de sortie.
Conclusion éditoriale
Adoptez uqlm si vous avez besoin d'un score de confiance par réponse et que vous acceptez le coût en générations multiples des scoreurs boîte noire, ou si vous disposez déjà des logprobs pour les scoreurs boîte blanche. Ne l'adoptez pas si votre fournisseur ne renvoie pas de probabilités de tokens et que votre budget d'inférence est strictement limité à un appel par prompt, ni si vous cherchez un système de vérification par récupération documentaire : uqlm mesure la dispersion du modèle, il ne confronte pas la réponse à une source. Avant de vous engager, vérifiez trois choses : que votre version de Python est bien 3.10 ou supérieure, que le modèle LangChain que vous utilisez expose les informations dont dépend le scoreur retenu, et que votre fournisseur autorise l'envoi des réponses générées vers le modèle juge que vous comptez employer.
Notes de la communauté