Citations vérifiées et abstention en RAG pour la finance

À RETENIR
- Un système RAG incapable de dire 'je ne sais pas' est un risque. Le but près des comptes d'un fonds est zéro réponse fausse et confiante, pas une couverture maximale.
- Une citation vérifiée est un extrait source dont le système a prouvé qu'il étaye l'affirmation, pas un lien collé à côté de la réponse en espérant qu'il soit pertinent.
- L'abstention fondée sur la preuve transforme les échecs résiduels en refus visibles plutôt qu'en fabrications confiantes. C'est ce qui rend le RAG sûr près de l'argent régulé.
- J'ai construit ceci dans un fonds de private equity immobilier américain gérant environ 3 Md$ d'actifs : récupération, contrôles de citation NLI et numériques, abstention, évals et red-teaming.
- Il n'existe pas de chiffre de précision unique et honnête pour un tel système. Le vrai artefact est le comportement d'abstention et la grille d'évaluation, pas un pourcentage en titre.
Un système RAG incapable de dire 'je ne sais pas' est un risque, pas une fonctionnalité. Dans un fonds de private equity immobilier américain gérant environ 3 Md$ d'actifs, j'en ai livré un qui vérifie chaque citation et s'abstient quand la preuve est mince, car une réponse fausse et confiante près des comptes coûte plus cher qu'une réponse lente.
La leçon est tombée le jour où une démo a halluciné devant une responsable conformité. L'assistant a répondu à une question sur un document du fonds, a cité une source, et semblait totalement sûr de lui. La citation était réelle. Elle ne disait simplement pas ce que la réponse prétendait.
Le silence s'est fait dans la salle, et la personne dont le métier est d'attraper exactement ce genre d'erreur venait de voir une machine la produire sans sourciller. J'ai donc arrêté d'optimiser la couverture pour optimiser quelque chose de plus étroit et de plus dur : ne jamais avoir tort avec assurance. Voici la conception qui en est sortie, et pourquoi je la referais à l'identique.
Ce qu'est vraiment une citation vérifiée
Commençons par le mot que tout le monde emploie à la légère. Dans la plupart des systèmes RAG, une citation est un lien que le modèle a placé à côté de sa réponse. Personne n'a vérifié que ce lien étaye l'affirmation. Ça ressemble à une preuve, ce qui est pire que pas de preuve, car ça gagne une confiance qui n'a pas été méritée.
Le pipeline : récupérer, citer, vérifier, s'abstenir
Le système exécute les mêmes quatre étapes sur chaque question, et la dernière est un embranchement, pas une ligne d'arrivée.
Cette couche servait de couche de réponse partagée sous la plateforme à 11 agents du fonds, si bien que chaque agent qui lisait un document héritait des mêmes contrôles de citation au lieu de les réinventer.
Quand le système a le droit de refuser
L'abstention est une politique, pas une impression. Le système ne refuse pas parce qu'il se sent incertain. Il refuse quand la preuve est dans un état précis, et ces états sont écrits noir sur blanc. Voici chaque état, à côté de ce qu'en fait un bot de prestataire.
Comment on vérifie une citation, au lieu de juste l'attacher
Attacher une citation est facile. La vérifier, c'est le vrai travail, et c'est deux contrôles, pas un.
Le premier est l'implication, ou NLI : étant donné l'affirmation et l'extrait cité, l'extrait étaye-t-il l'affirmation, la contredit-il, ou ni l'un ni l'autre ? Un 'ni l'un ni l'autre' ne suffit pas. Neutre veut dire non étayé, et non étayé mène à l'abstention.
Le second, ce sont les chiffres. Les modèles de langage sont fluides avec les chiffres et faux avec eux. Si une affirmation énonce un montant, une date ou un décompte, il doit correspondre exactement à la source, pas 'à peu près'. En finance, 'à peu près' est la façon d'enregistrer un chiffre faux avec assurance.
type Verdict = 'supported' | 'contradicted' | 'insufficient'
// A claim ships only if the cited span survives BOTH checks.
async function verifyClaim(claim: Claim, span: SourceSpan): Promise<Verdict> {
// 1. Entailment (NLI): does the source actually support the
// sentence, or does it just sit near it and look relevant?
const relation = await nliCheck(claim.text, span.text)
if (relation === 'contradiction') return 'contradicted'
if (relation === 'neutral') return 'insufficient'
// 2. Numbers: a figure in the claim must match the source to the
// digit. "Close" is a fabrication with good manners.
if (claim.hasNumber && !numbersMatch(claim, span)) {
return 'contradicted'
}
return 'supported'
}
// One failing claim abstains the WHOLE answer. No partial credit.
function decide(verdicts: Verdict[]): 'answer' | 'abstain' {
return verdicts.every((v) => v === 'supported') ? 'answer' : 'abstain'
}Deux lignes portent toute la conception. L'appel d'implication est ce qui sépare une citation vérifiée d'une citation décorative. Le contrôle numérique est ce qui empêche un paragraphe fluide de changer discrètement un chiffre.
Et la fonction de décision est volontairement intraitable. Une seule affirmation non étayée fait s'abstenir la réponse entière. Pas de 'répondre à la partie facile et nuancer le reste', car une demi-réponse avec une erreur confiante est exactement l'échec que la responsable conformité était payée pour attraper.
Chaque affirmation remonte à un extrait qui l'implique. On livre la réponse avec la citation attachée.
L'extrait contredit l'affirmation, ou un chiffre ne correspond pas à la source. On bloque la réponse et on signale l'écart.
L'extrait est neutre, il n'étaye ni ne réfute. On s'abstient, et on escalade vers une personne.
Les modes d'échec qui subsistent, et comment on les a évalués
Rien de tout cela n'est fiable parce que je le dis. C'est fiable parce que ça a été évalué et red-teamé avant d'approcher une vraie question, et l'évaluation a noté ce qui échoue réellement.
L'artefact utile, c'est la grille : ce qu'on a mesuré, et pourquoi chaque dimension conditionne une mise en production.
La version de cette grille qui décide si une release part, seuils compris, c'est la suite d'évals qui transforme l'abstention en verrou de mise en production. Ce post, c'est le mécanisme ; celui-là, c'est le verdict.
La citation existe et paraît parfaite. Elle n'étaye simplement pas l'affirmation à laquelle elle est rattachée. Attacher un lien ne peut pas attraper ça ; seul le contrôle d'implication le peut. C'est l'échec exact qui a gêné la démo, et la raison pour laquelle la vérification est un contrôle, pas une étape de mise en forme.
Le modèle voit deux chiffres dans les sources et en produit un troisième plausible qui n'est ni l'un ni l'autre. Ça se lit très bien. Le contrôle numérique au chiffre près est la seule chose entre cette phrase et les registres du fonds.
L'échec dans l'autre sens. Un système réglé pour refuser refusera des choses qu'il aurait pu répondre depuis une source juste là. Ce n'est pas sûr, c'est inutile, et c'est pourquoi la justesse de l'abstention se note dans les deux sens, pas seulement comme 'refuser plus'.
Pourquoi la finance régulée est le banc d'essai
Vous pourriez demander pourquoi s'embêter, alors que la plupart des assistants RAG répondent et passent à autre chose. La réponse est le contexte. La finance régulée est le banc d'essai précisément parce que le coût d'une réponse fausse et confiante n'est pas la gêne, c'est une observation dans un audit.
Cette contrainte est un cadeau. Elle force la version honnête du système, celle qui survivrait partout où le coût de l'erreur est réel.
RAG de prestataire
RAG qu'on peut mettre près des comptes
Si vous devez prouver cette exactitude à un régulateur plutôt que l'affirmer, le journal d'abstention et les contrôles de citation sont la preuve, ce qui est le même argument que je défends à propos de prouver l'exactitude sous le règlement IA européen.
FAQ
C'est le système qui refuse de répondre quand la preuve récupérée n'étaye pas de réponse, au lieu d'en générer une plausible de mémoire. Le refus est déclenché par l'état de la preuve : aucune source pertinente, des sources en conflit, ou une citation qui échoue à la vérification. En contexte régulé, un refus sur lequel vous pouvez agir vaut mieux qu'une réponse fluide à laquelle vous ne pouvez pas vous fier.
Une citation normale est un lien placé à côté d'une réponse ; personne n'a vérifié qu'il étaye l'affirmation. Une citation vérifiée a passé un contrôle d'implication confirmant que l'extrait cité soutient bien la phrase, plus un contrôle numérique quand l'affirmation contient un chiffre. Si elle échoue à l'un des deux, l'affirmation compte comme non étayée et la réponse s'abstient.
Seulement s'il s'abstient sans en avoir besoin, ce qui est un vrai échec que je note. Le but est de refuser quand, et seulement quand, la preuve est mince. Un système qui répond à tout est plus utile en démo et moins utile en production, car vous ne pouvez pas séparer ses bonnes réponses de ses réponses fausses et confiantes. Les escalades sont aussi les cas qui avaient vraiment besoin d'un humain.
Parce qu'un chiffre de précision unique en titre est exactement le nombre à l'air confiant qui masque le mode d'échec que j'ai construit ceci pour éviter. Il n'y a pas de score honnête en une ligne pour un système dont tout le travail est de se comporter différemment selon l'état de la preuve. Les vrais artefacts sont le comportement d'abstention et la grille d'évaluation, pas un pourcentage. J'ai aussi conçu le système en partant du principe que la récupération réduit sans éliminer la fabrication, donc les échecs résiduels devaient devenir visibles comme des refus plutôt que cachés comme des réponses confiantes.
Oui. Le schéma, vérifier les citations puis s'abstenir sur preuve mince, se transpose partout où une réponse fausse et confiante coûte cher : juridique, médical, ou tout endroit où un humain agira sur la sortie. La finance rend juste le coût évident. Si se tromper dans votre domaine est bon marché, vous n'en avez probablement pas besoin, et c'est une raison valable de ne pas le construire.
Cet article vous a plu ?
Recevez les suivants dans votre boîte mail chaque mardi.
