Documentation

Confiance

Comment TypeSafe exprime la certitude, en quoi elle diffère de la probabilité et comment l’utiliser pour piloter le comportement du système.

Toutes les réponses Score et Choice de TypeSafe incluent une propriété probabilities qui représente la distribution de probabilité sur les options (pour Choice) ou les niveaux (pour Score). C’est la forme de cette distribution qui t’indique à quel point le modèle est sûr : concentrée sur un résultat, elle signale une réponse assurée ; étalée, une réponse incertaine.

La propriété confidence de la réponse réduit cette forme à un seul nombre entre 0 et 1, pour que tu puisses y appliquer un seuil sans faire le calcul toi-même. Elle vaut 1 quand toute la probabilité porte sur un seul résultat, et 0 quand la probabilité est répartie uniformément. (Les réponses Noul n’en ont pas ; voir plus bas Noul.)

La confiance est dérivée des probabilités

confidence est une statistique calculée à partir de la distribution de probabilité que la réponse te donne déjà. TypeSafe la calcule pour toi et la renvoie sur chaque réponse Choice et Score, donc le cas courant ne demande aucun travail supplémentaire de ton côté.

Exemple : question choice à trois options

Vois comment la distribution de probabilité change la confiance

Confiance

0.85

Déplace un curseur pour changer la probabilité d'une option. Les autres s'ajustent automatiquement pour que le total reste à 100 %.

Sélectionné : Option A

Comment cette démo calcule la confiance

TypeSafe calcule la confiance à partir de la répartition de la probabilité entre les options. Tout sur une seule option donne 1.0 ; plus la répartition est uniforme, plus la confiance est basse. Cette démo utilise (3 × probabilité maximale − 1) / 2 pour approcher la confiance avec trois options.

Pour un Choice, la distribution est celle des probabilities sur tes options. Pour un Score, c’est la distribution sur tes niveaux. Dans les deux cas, une distribution plus plate signifie une confiance plus faible : une faible confiance sur un Choice veut souvent dire qu’aucune option ne se détache clairement des autres, et une faible confiance sur un Score veut souvent dire que les niveaux sont ambigus, multidimensionnels, ou que l’état n’en dit pas assez pour trancher.

La formule exacte de chaque type de question se trouve dans Comment la confiance est calculée, pour que tu voies comment toute valeur de confidence découle des probabilities propres à la réponse.

« Je ne sais pas » est un signal utile

Si un système intelligent, humain ou machine, ne peut pas exprimer une incertitude honnête, on ne peut pas lui faire confiance.

La confiance offre un mécanisme intégré qui permet au modèle de dire « je ne suis pas sûr pour celle-ci ». Ton code peut alors adopter un comportement différent selon le degré de certitude, ce qui est la base de systèmes sur lesquels tu peux réellement compter.

Trois voies pour utiliser la confiance dans ton code

Un bon motif de départ consiste à diviser la confiance en trois plages, chacune produisant un comportement système différent :

Confiance élevée : Agis automatiquement. Le modèle a une lecture claire et tu peux continuer sans intervention humaine.

Confiance moyenne : Avance avec prudence. Le modèle a une réponse raisonnable mais n’est pas certain. Selon le contexte, tu peux demander confirmation à l’utilisateur, signaler pour revue, ou rassembler plus d’informations avant d’agir.

Confiance faible : N’agis pas. Route vers un humain, demande une clarification ou bascule vers un autre système. Le modèle t’indique qu’il n’a pas assez d’informations ou que la question ne convient pas.

L’endroit où tu places ces frontières dépend des enjeux.

Les seuils s’adaptent au risque

Un seuil de confiance n’est pas un nombre unique. Différentes actions au sein d’un même système doivent être conditionnées à des niveaux différents selon les conséquences d’une erreur.

response = client.system_one(
    state=user_message,
    questions={
        "action": Choice(
            instructions="What is the user trying to do?",
            criteria={
                "check_balance": "View account balance",
                "approve_transfer": "Approve the pending withdrawal request",
                "support": "Get help with an issue",
            },
        ),
    },
)

action = response.answers["action"]
confidence = action.confidence

if confidence < 0.5:
    # Model is genuinely unsure. Don't guess.
    route_to_human(user_message)

elif action.choice == "check_balance":
    # Low stakes. Showing the wrong screen is recoverable.
    show_balance(account_id)

elif action.choice == "approve_transfer":
    if confidence > 0.9:
        # High stakes, high confidence. Proceed with confirmation.
        confirm_then_execute(account_id)
    else:
        # High stakes, moderate confidence. Verify first.
        ask_user_to_confirm(account_id)

Le plancher de confiance à 0.5 intercepte tout ce que le modèle signale comme réellement incertain. Au-dessus, le seuil pour agir sans confirmation est plus élevé pour une opération destructive que pour une opération en lecture seule. Ton code encode la tolérance au risque.

Comment la confiance est calculée

Chaque type de question résume sa distribution un peu différemment. Un Noul a deux résultats, un Choice a un nombre quelconque d’options dans un ordre quelconque, et les niveaux d’un Score sont ordonnés, donc chaque formule ci-dessous s’appuie sur la précédente.

La confidence de TypeSafe est une façon raisonnable de résumer une distribution, pas la seule. Nous renvoyons une mesure fixe pour que chaque réponse vienne avec une valeur par défaut sensée : tu peux conditionner sur confidence dès ton premier appel, sur la même échelle de 0 à 1 pour chaque question, sans avoir à choisir et valider d’abord une statistique personnelle. Comme les formules ci-dessous sont exactes et que chaque réponse inclut ses probabilities complètes, tu peux à la place calculer la mesure qui compte le plus pour ton application.

Noul

Une réponse Noul est une unique probabilité $p$ que la réponse soit oui, et TypeSafe ne renvoie pas de confidence distinct pour elle. La probabilité porte déjà l’incertitude : une valeur proche de 0.5, c’est le modèle qui dit qu’il n’est pas sûr, et la page Noul explique comment y appliquer un seuil directement.

Si tu veux quand même un nombre au format confiance, par exemple pour conditionner Nouls et Choices avec le même code, utilise la distance à 0.5 :

$$ \text{confidence} = |2p - 1| $$

Cela donne 0 quand $p = 0.5$ et 1 quand $p = 0$ ou $p = 1$. C’est aussi la formule Choice ci-dessous appliquée à un Choice oui/non, donc elle se place sur la même échelle que la confiance d’un Choice.

Choice

Un Choice étend la même idée à un nombre quelconque d’options. Pour un Choice à $n$ options, où $p_{\max}$ est la probabilité de l’option sélectionnée :

$$ \text{confidence} = \frac{p_{\max} - \frac{1}{n}}{1 - \frac{1}{n}} $$

Cela mesure de combien la probabilité la plus haute se situe au-dessus d’un partage égal de $\frac{1}{n}$ par option, sur une échelle où le partage égal vaut 0 et la certitude vaut 1. Seule la probabilité la plus haute compte, donc $(0.6, 0.3, 0.1)$ et $(0.6, 0.2, 0.2)$ ont toutes deux une confiance de 0.4.

def choice_confidence(probabilities: list[float]) -> float:
    n = len(probabilities)
    return (max(probabilities) - 1 / n) / (1 - 1 / n)

choice_confidence(list(answer.probabilities.values()))

L’explorateur en haut de cette page utilise cette formule avec trois options.

Deux mesures plus simples, calculées à partir des mêmes probabilities, sont souvent très efficaces en pratique et valent la peine d’être essayées à côté de confidence :

  • Probabilité la plus haute, $p_{\max}$. Elle se lit directement comme « quelle est la probabilité de l’option sélectionnée », ce qui rend les seuils faciles à raisonner. Sa signification dépend du nombre d’options, car 0.5 est une réponse faible entre deux options et forte entre dix, donc fixe son seuil par question.
  • Rapport entre la plus haute et la deuxième, $p_{\max} / p_{\text{second}}$. Il mesure avec quelle netteté l’option sélectionnée bat le dauphin et ignore comment le reste se répartit. Beaucoup de décisions réelles se ramènent aux deux meilleurs candidats, et ce rapport vise exactement cela.

Score

Les niveaux d’un Score sont ordonnés, donc sa formule compte aussi à quelle distance se trouve la probabilité du niveau le plus probable. Pour un Score à $n$ niveaux numérotés de $0$ à $n - 1$, où $p_i$ est la probabilité du niveau $i$ et $m$ le niveau le plus probable :

$$ \text{confidence} = \max\left(0,\ 1 - \frac{\sum_i p_i , |i - m|}{\text{MAD}{\text{unif}}}\right) \qquad \text{MAD}{\text{unif}} = \frac{1}{n} \sum_i \left| i - \frac{n - 1}{2} \right| $$

La somme du numérateur est la distance moyenne pondérée par les probabilités, en niveaux, entre la réponse et le niveau le plus probable. $\text{MAD}_{\text{unif}}$ est le même type de distance moyenne pour un partage égal entre tous les niveaux, mesurée depuis le niveau médian. La confiance compare les deux, et est plancher à 0 quand la réponse est au moins aussi étalée qu’un partage égal.

Une probabilité sur un niveau voisin fait baisser la confiance moins que la même probabilité sur un niveau plus éloigné. Avec trois niveaux, $(0, 0.5, 0.5)$ a une confiance de 0.25, car le modèle est tiraillé entre deux niveaux adjacents. $(0.5, 0, 0.5)$ a une confiance de 0, car il est tiraillé entre des extrémités opposées. La formule Choice donnerait 0.25 aux deux distributions.

Question de score à cinq niveaux

Voir comment la distance entre les niveaux change la confiance

Confiance

0.92

Déplacez un curseur pour changer la probabilité d'un niveau. Les autres s'ajustent pour que le total reste à 100 %.

Score
2.00
Formule Choice sur les mêmes probabilités
0.88
Comment cette démo calcule la confiance

Cette démo utilise la formule Score : elle prend la distance moyenne, en niveaux, entre la réponse et le pic, pondérée par la probabilité. Elle la divise par 1.2, la même moyenne pour une répartition uniforme sur cinq niveaux mesurée depuis le niveau central, puis retranche le résultat de 1, sans descendre sous 0. Une probabilité sur un niveau voisin du pic fait moins baisser la confiance qu'une probabilité éloignée, ce que la formule Choice ne prend pas en compte.

def score_confidence(probabilities: list[float]) -> float:
    n = len(probabilities)
    m = probabilities.index(max(probabilities))
    spread = sum(p * abs(i - m) for i, p in enumerate(probabilities))
    even_spread = sum(abs(i - (n - 1) / 2) for i in range(n)) / n
    return max(0.0, 1 - spread / even_spread)

levels = sorted(answer.probabilities)
score_confidence([answer.probabilities[level] for level in levels])

La réponse bug_severity dans l’exemple de réponse Score a pour probabilités $(0, 0.57, 0.43)$. Le niveau le plus probable est 1, la distance est $0.43$, et $\text{MAD}_{\text{unif}}$ pour trois niveaux est $\frac{2}{3}$, donc la confiance est $1 - 0.43 / \frac{2}{3} \approx 0.35$.