Documentation

Ce qui doit vivre dans le code

La page sur le gating soutenait que le code doit posséder le seuil. Cette page va un cran plus loin : certaines vérifications ne devraient pas être demandées au modèle du tout.

L’énoncé de frontière le plus fort en public

La ligne la plus dure vient d’une implémentation de boucle d’agent :

Un appel d’outil avec un score de risque élevé force une autorisation humaine, et aucune probabilité ne peut l’annuler.

« Aucune probabilité ne peut l’annuler » mérite d’être isolé. Cela ne dit pas « la confiance doit être très élevée » — cela dit cette règle n’est pas dans l’espace des probabilités. La distinction compte :

  • « Approuver automatiquement à ≥ 0.95 » est une règle de seuil — en principe une probabilité suffisamment élevée la franchirait.
  • « Un risque élevé exige une approbation humaine » est une règle structurelle — vraie quel que soit ce que dit le modèle.

Ce n’est pas également fiable. Ton système doit dire explicitement quelles vérifications relèvent de l’une ou de l’autre, et il devrait y avoir autant de règles structurelles que possible.

Exécute d’abord les règles déterministes, ne donne au modèle que la zone grise

Une autre formulation du même patron :

Exécute d’abord les règles déterministes : tout ce qui peut être décidé est bloqué ou autorisé d’emblée, et le modèle n’est qu’un backend optionnel. Les commandes de routine sont décidées localement et ne sont jamais envoyées au modèle du tout.

Exécuter d’abord les règles a un bénéfice sous-estimé : cela réduit la surface d’attaque. Un juge qui dépend purement du modèle se comporte de façon imprévisible sous injection de prompt ; un juge qui exécute d’abord les règles confine l’injection à la petite tranche que les règles ne peuvent pas décider.

Un test d’injection publié rapporte 300 tentatives d’injection et dit franchement ce que la barrière a attrapé et ce qui est passé. C’est bien plus utile qu’une simple affirmation de « protection contre l’injection ».

Secrets et données sensibles : bloquer localement d’abord

Un détecteur de secrets expose clairement l’ordre :

Cas Traitement
Formats de secrets connus Bloqués localement, jamais envoyés au modèle
Chaînes à haute entropie inconnues Masquées d’abord, puis le texte masqué va au modèle
Le modèle dit ≥ 0.80 Bloquer
Le modèle dit ≥ 0.30 Demander à un humain
Modèle indisponible Demander à un humain quand même

Deux décisions à retenir :

  • Le masquage vient d’abord. Tu ne peux pas envoyer quelque chose à un service externe pour découvrir s’il s’agit d’un secret. La vérification elle-même fuit.
  • Un modèle mort demande quand même à un humain, plutôt que d’autoriser. C’est le fail-closed sous forme concrète — l’indisponibilité du service n’est pas une raison d’abaisser discrètement la barre de sécurité.

Mesuré : 6/6 secrets bloqués, 0/6 entrées bénignes bloquées à tort.

Plafonds budgétaires, reçus signés, audit

Certaines vérifications n’ont rien à voir avec ce que dit le modèle, mais doivent vivre dans le même système :

  • Un runtime confie le blocage des commandes dangereuses et les plafonds budgétaires à du code déterministe, et consigne chaque verdict dans une chaîne de reçus signés Ed25519.
  • Un autre confine le score de risque à une échelle 0–100 contrôlée par le code et signe chaque verdict avec ES256 (540 appels, 99.76% et 0 faux positifs à un seuil de 65–75).

Le but de la signature n’est pas de protéger contre le modèle — c’est qu’après coup tu puisses dire ce qui s’est passé. Quand une décision automatisée provoque un incident, « ce que le modèle a dit et ce que le code en a fait » doit être vérifiable indépendamment plutôt que relever de la confiance dans les journaux.

Filtrer l’injection à deux endroits

La conception d’une couche de garde mérite sa propre mention parce qu’elle nomme deux endroits facilement oubliés :

Filtre une fois avant l’exécution d’un appel d’outil, et de nouveau avant qu’un résultat d’outil ne soit lu par l’agent.

Le second est celui qu’on oublie. Filtre seulement l’entrée et une attaque peut se cacher dans ce que l’outil renvoie — une page récupérée, le contenu d’un fichier — qui entre dans le contexte en ayant contourné entièrement la vérification côté entrée.

Une règle apparentée d’une implémentation augmentée par la recherche : ne jamais produire un nombre qui n’apparaît pas dans les sources citées.

Isolation et permissions

Outre le filtrage du contenu, l’autre couche consiste à limiter le rayon d’impact : les chemins protégés passent toujours par une confirmation humaine ; l’exécution de l’agent s’exécute dans des espaces de travail isolés (une implémentation utilise Docker) ; les permissions des sous-agents sont séparées de celles du parent.

Un tableau de référence

Vérification De quel type De quel côté elle tombe en cas d’erreur
Formats de secrets connus Règle déterministe Bloquer
Autorisation d’opération à risque élevé Règle structurelle Refuser (un humain doit approuver)
Approbation automatique des commandes en lecture seule Règle de seuil Retomber sur l’invite
Injection dans la sortie d’un outil Filtre déterministe + modèle Bloquer
« L’agent a-t-il fini ? » Barrière d’efficacité Autoriser (fail-open)
Vérifications de format et de style Barrière d’efficacité Autoriser

La colonne du milieu est le point : plus on est près du haut, moins le modèle doit être impliqué.

En une phrase

Une vérification qui peut être annulée par une probabilité finira par l’être. Décide d’abord quelles vérifications n’ont pas le droit d’être annulées ; ne règle les seuils qu’ensuite.