La confianza que reporta un LLM no es una probabilidadAn LLM’s reported confidence is not a probability
Antes de mostrar la «confianza» que devolvía el modelo, medí de dónde salía. No era una probabilidad: no se muestra, y el paso a revisión humana lo decide una regla con cita.Before showing the “confidence” the model returned, I measured where it came from. It wasn’t a probability: it isn’t shown, and a rule backed by a quote decides when a case goes to human review.
Para un cliente del sector legal en Colombia construyo un pipeline que convierte los documentos de una reclamación de seguro de tránsito en un dictamen. Una de sus ramas es médica: Claude, en Amazon Bedrock, lee la historia clínica y la clasifica, según el criterio jurídico de la firma, como compensable, no compensable o pendiente de revisión humana. La respuesta es un JSON, y en él venía un campo confidence.
La idea era mostrar ese número como un porcentaje junto al resultado. Antes de hacerlo, medí de dónde salía.
De dónde salía el número
- Lo pedía el código, y solo como hueco. La plantilla de salida que recibía el modelo traía un campo de confianza vacío, sin escala ni definición. Ninguna instrucción decía qué significaba.
- El criterio no la mencionaba. Busqué «confianza», «confidence», «certeza», «seguridad» y «probab» en el criterio jurídico desplegado: cero apariciones.
- Nadie la calculaba ni la validaba. El código guardaba tal cual el número que escribía el modelo. El único valor que ponía el propio código era un 0 de respaldo cuando la salida no se podía leer.
- Con temperatura 0, el mismo documento daba siempre el mismo número. Mirando un solo documento, al principio creí que era fijo; con 55 resultados se vio que no.
Lo que medí
Leí, sin escribir nada, los 55 resultados del análisis médico guardados en el entorno de pruebas:
| Clasificación | Resultados | Valores de confidence (valor × veces) |
|---|---|---|
| compensable | 25 | 95 × 25 |
| no compensable | 15 | 100 × 1 · 95 × 8 · 85 × 6 |
| pendiente de revisión | 15 | 0 × 7 · 3 × 1 · 75 × 4 · 85 × 3 |
El 95 aparece 33 veces, el 85 nueve y el 0 siete: 49 de los 55 resultados caen en esos tres valores. Eso no es una distribución de probabilidades: son tres etiquetas con forma de número. Ninguna versión del criterio definía una escala, y hay un 3 en lo que parece una escala de 0 a 100, lo que sugiere, como inferencia, que el modelo mezclaba escalas.
El 0 tenía dos orígenes posibles: lo escribía el modelo, o lo escribía el código cuando no podía leer la respuesta. De los siete ceros de la tabla, seis los escribió el modelo con seguridad: llevan anotada la versión del criterio con la que se analizaron, y el camino de respaldo no la anotaba. El séptimo no lleva esa anotación, y la medición no basta para atribuirlo. En el propio campo de confianza, el mismo número podía significar «el modelo lo marcó así» o «no hubo respuesta utilizable».
Un 95 equivocado
Después, en una prueba de regresión con historias clínicas sintéticas, una de ellas era adversa a propósito: una fractura de tibia en un accidente de trabajo, sin vehículo, con la frase «No hubo accidente de tránsito ni vehículo involucrado». El criterio de la firma es explícito: si el nexo con un accidente de tránsito falta, es dudoso o está contradicho, el caso va a revisión, nunca a no compensable.
El modelo respondió no compensable con confianza 95, en las 3 corridas y con las dos versiones del prompt que estaba comparando.
Un 95 en pantalla junto a una respuesta que contradice el criterio de quien la va a usar no informa: da una seguridad que no existe.
Qué cambió
La confianza no se muestra. Propuse no mostrarla o, como mucho, dejarla en segundo plano con el rótulo «autoevaluación del modelo, no es una probabilidad», porque un «95 %» grande sugiere una probabilidad calibrada que no lo es. Se decidió guardarla y no mostrarla, por ahora. Para mostrarla habría que calibrarla antes contra casos con resultado conocido.
El paso a revisión humana lo decide una regla. Para esa decisión, en vez de apoyarse en la seguridad que declara el modelo, se le pide un hecho concreto y comprobable: el nexo de la lesión con un accidente de tránsito, con uno de tres valores (presente, ausente o contradicho) y una cita del documento de 15 palabras o menos. Si el valor no es «presente», o falta, el código manda el resultado a revisión humana, conserva lo que había clasificado el modelo y pone primero una observación con el motivo y la cita.
La regresión de la regla (12 llamadas a temperatura 0: cuatro historias sintéticas, tres corridas cada una) dio el resultado final predicho en todos los casos; la historia de la tibia termina en revisión. La regla tiene sus propias pruebas, validadas con mutaciones.
La confianza que sí significa algo
En la rama de la póliza, Amazon Textract devuelve una confianza por cada bloque que lee, y esa sí tiene un significado definido: qué tan seguro está de haber leído bien un campo. Es confianza de lectura, no del veredicto; en esa rama, el veredicto lo dan reglas deterministas. Si alguna confianza merece estar en pantalla, es esa: por campo y con su nombre.
La regla general que saco: un número en pantalla necesita una definición, una escala y alguien que lo haya comprobado. La «confianza» autodeclarada de un LLM no tenía ninguna de las tres.
For a client in the legal sector in Colombia, I build a pipeline that turns the documents of a traffic-insurance claim into a legal opinion. One of its branches is medical: Claude, on Amazon Bedrock, reads the medical record and classifies it, under the firm’s legal criteria, as compensable, not compensable or pending human review. The answer is JSON, and it came with a confidence field.
The plan was to show that number as a percentage next to the result. Before doing so, I measured where it came from.
Where the number came from
- The code asked for it, and only as a blank. The output template the model received carried an empty confidence field, with no scale or definition. No instruction said what it meant.
- The criteria never mentioned it. I searched the deployed legal criteria for “confianza”, “confidence”, “certeza”, “seguridad” and “probab”: zero hits.
- Nobody computed or validated it. The code stored whatever number the model wrote. The only value the code set itself was a fallback 0 when the output couldn’t be parsed.
- At temperature 0, the same document always got the same number. Looking at a single document, I first thought it was fixed; with 55 results, it clearly wasn’t.
What I measured
I read, without writing anything, the 55 medical analysis results stored in the test environment:
| Classification | Results | confidence values (value × count) |
|---|---|---|
| compensable | 25 | 95 × 25 |
| not compensable | 15 | 100 × 1 · 95 × 8 · 85 × 6 |
| pending review | 15 | 0 × 7 · 3 × 1 · 75 × 4 · 85 × 3 |
95 appears 33 times, 85 nine times and 0 seven times: 49 of the 55 results fall on those three values. That isn’t a probability distribution: it is three labels shaped like numbers. No version of the criteria defined a scale, and there is a 3 on what looks like a 0–100 scale, which suggests, as an inference, that the model mixed scales.
The 0 had two possible origins: the model wrote it, or the code did when it couldn’t read the answer. Of the seven zeros in the table, six were certainly written by the model: they carry the version of the criteria they were analysed with, which the fallback path didn’t record. The seventh carries no such record, and the measurement isn’t enough to attribute it. In the confidence field itself, the same number could mean “the model marked it this way” or “there was no usable answer”.
A wrong 95
Later, in a regression test with synthetic medical records, one record was adversarial on purpose: a tibia fracture in a workplace accident, no vehicle involved, with the sentence “No hubo accidente de tránsito ni vehículo involucrado” (there was no traffic accident and no vehicle involved). The firm’s criteria are explicit: if the link to a traffic accident is missing, doubtful or contradicted, the case goes to review, never to not compensable.
The model answered not compensable with confidence 95, in all 3 runs and with both versions of the prompt I was comparing.
A 95 on screen next to an answer that contradicts the criteria of the people who will use it doesn’t inform: it conveys a certainty that isn’t there.
What changed
The confidence isn’t shown. I proposed not showing it or, at most, keeping it in the background labelled “the model’s self-assessment, not a probability”, because a large “95%” suggests a calibrated probability that it isn’t. The decision was to store it and not show it, for now. Showing it would first require calibrating it against cases with a known outcome.
A rule decides when a case goes to human review. For that decision, instead of relying on the certainty the model reports, the model is asked for a specific, checkable fact: the link between the injury and a traffic accident, with one of three values (present, absent or contradicted) and a quote from the document of 15 words or fewer. If the value isn’t “present”, or is missing, the code sends the result to human review, keeps what the model had classified and puts first an observation with the reason and the quote.
The regression for the rule (12 calls at temperature 0: four synthetic records, three runs each) produced the predicted final result in every case; the tibia record ends up in review. The rule has its own tests, validated with mutations.
The confidence that does mean something
In the policy branch, Amazon Textract returns a confidence for every block it reads, and that one does have a defined meaning: how sure it is that it read a field correctly. It is reading confidence, not verdict confidence; in that branch, the verdict comes from deterministic rules. If any confidence deserves a place on screen, it is that one: per field and under its real name.
The general rule I take from this: a number on screen needs a definition, a scale and someone who has checked it. An LLM’s self-reported “confidence” had none of the three.
EVIDENCIAEVIDENCE
- Caso «Del documento al dictamen»Case study “From document to ruling” · el pipeline completo, en la portadathe full pipeline, on the home page
- El código y los datos son del cliente y no son públicos. Las cifras salen de una medición de solo lectura en el entorno de pruebas y de regresiones con historias clínicas sintéticas.The code and data belong to the client and are not public. The figures come from a read-only measurement in the test environment and from regressions on synthetic medical records.