Los límites del modelo
En resumen: Un modelo de lenguaje alucina: escribe con seguridad cosas plausibles pero falsas, porque predice texto probable en lugar de comprobar la verdad; por eso la respuesta se contrasta con la fuente.
Problema
Treinta días que no existen
El asistente de soporte le responde a un cliente: «La chaqueta se puede devolver dentro de 30 días desde la entrega». La respuesta es amable, fluida y segura. La política de la tienda dice 14 días.
El día veinte el cliente envía la chaqueta de vuelta. El almacén rechaza la devolución, y el cliente escribe una reseña de una estrella citando al asistente.
Nadie programó «30 días». ¿De dónde salió el número y cómo te proteges del siguiente?
La idea
El modelo escribe texto probable, no hechos comprobados
Un modelo de lenguaje se entrena para continuar un texto con una palabra siguiente probable. No guarda una tabla de hechos y no comprueba su respuesta. Si en su texto de entrenamiento a «en» le sigue siempre un número, pondrá un número ahí. Cuál, lo decide la probabilidad, no la política de la tienda.
Una respuesta fluida y segura que es falsa o inventada se llama alucinación. No es un error que un solo parche arregle. Viene de la propia forma en que el modelo escribe: para él, la frase verdadera y la falsa son solo texto más probable y menos probable.
Míralo
Un modelo pequeño que promete lo que no es
El modelo de la lección sobre el siguiente token, en su forma más pequeña: para cada palabra guarda las palabras que la siguieron en el texto. Las repeticiones se quedan, así que una palabra más frecuente se sortea más a menudo.
# para cada palabra: las palabras que la siguieron en el textodef train(corpus): follows = {} for sentence in corpus: words = (sentence + " .").split(" ") for word, after in zip(words, words[1:]): follows.setdefault(word, []).append(after) return followsEl texto son diez frases del soporte de la tienda:
corpus = [ "la devolución es en 14 días", "la entrega a valencia es en 2 días", "el reembolso es en 5 días hábiles", "la garantía es de 24 meses", "el pago con tarjeta es seguro", "un pedido de más de 50 euros se envía gratis", "un paquete rechazado vuelve en 7 días", "la entrega a sevilla es en 3 días", "el mensajero llama antes de la entrega", "la entrega a madrid es en 2 días",]La palabra más probable cada vez:
# la más común (en caso de empate, la primera del texto)def most_common(options): return max(options, key=options.count)
def greedy(follows, start): words = start.split(" ") while len(words) < 12: last = words[-1] word = most_common(follows[last]) if word == ".": break words.append(word) return " ".join(words)Y sorteada por probabilidad, con un generador de números aleatorios de semilla fija, para que la salida sea la misma en cada ejecución:
def sample(follows, start, rng): words = start.split(" ") while len(words) < 12: options = follows[words[-1]] word = options[int(rng.next() * len(options))] if word == ".": break words.append(word) return " ".join(words)follows = train(corpus)print("la palabra más probable cada vez:")print(" " + greedy(follows, "la devolución"))print("seis ejecuciones, la palabra se sortea por probabilidad:")rng = Rng(3876)for i in range(1, 7): answer = sample(follows, "la devolución", rng) mark = "está en el texto" if answer in corpus else "no está en el texto" print(f" {i}. {answer} ({mark})")la palabra más probable cada vez: la devolución es en 2 díasseis ejecuciones, la palabra se sortea por probabilidad: 1. la devolución es seguro (no está en el texto) 2. la devolución es en 2 días (no está en el texto) 3. la devolución es en 14 días (está en el texto) 4. la devolución es en 5 días (no está en el texto) 5. la devolución es seguro (no está en el texto) 6. la devolución es de 24 meses (no está en el texto)La respuesta más probable es «la devolución es en 2 días», y el texto dice 14. De las seis respuestas sorteadas solo una es una frase del texto (la tercera). Las otras cinco son falsas, y suenan bien casi todas: «en 5 días» es del reembolso, «de 24 meses» de la garantía, «en 2 días» de la entrega, y «es seguro» (salió dos veces) viene del pago con tarjeta, aunque ni siquiera concuerda con «la devolución».
Míralo
De dónde salió el número
# la más común (en caso de empate, la primera del texto)def most_common(options): return max(options, key=options.count)
def greedy(follows, start): words = start.split(" ") while len(words) < 12: last = words[-1] word = most_common(follows[last]) if word == ".": break words.append(word) return " ".join(words)# la más común (en caso de empate, la primera del texto)def most_common(options): return max(options, key=options.count)
def greedy(follows, start): words = start.split(" ") while len(words) < 12: last = words[-1] word = most_common(follows[last]) if word == ".": break words.append(word) return " ".join(words)# cada número de la respuesta debe estar en la fuentedef check(answer, source): known = numbers(source) claimed = numbers(answer) if not claimed: return "? no hay número que comprobar" for n in claimed: if n not in known: return f"✗ {n} no está en la fuente" return "✓ los números están en la fuente"
def numbers(text): words = [w.strip(".,") for w in text.split(" ")] return [w for w in words if w.isdigit()]Paso a paso, en palabras
- El modelo continúa «la devolución» cada vez con la palabra siguiente más común.
- «es en» está en 5 frases, una de ellas sobre la devolución. Hasta aquí es verdad.
- Después de «en» la palabra más común es «2»: viene de las dos frases sobre la entrega.
- Luego el punto. Una frase fluida que no está en el texto: «la devolución es en 2 días».
- La comprobación toma los números de la respuesta y de la política de devoluciones.
- 2 no está en la política. Dice 14 días.
- Cada par de palabras sale del texto de la tienda. La frase entera es falsa, y suena tan segura como una verdadera.
Cada par de palabras de la respuesta es verdadero en algún lugar del texto. La frase entera no es verdadera en ninguno. Los modelos grandes miran mucho más que una palabra atrás y se equivocan bastante menos, pero el principio es el mismo: escriben lo probable, no lo comprobado.
Pruébalo
Predice la salida
El modelo se entrena con tres frases. ¿Qué escribirá con la palabra más probable cada vez, si empieza por las palabras de la entrega?
corpus = [ "la entrega a madrid es en 2 días", "la entrega a sevilla es en 3 días", "el cambio de talla es en 3 días",]print(greedy(train(corpus), "la entrega"))Después de «entrega» viene «a» las dos veces. Después de «a» vienen «madrid» y «sevilla» una vez cada una: en caso de empate gana la primera del texto, «madrid». Luego «es» y «en», y después de «en» el «3» aparece dos veces (Sevilla y el cambio de talla) y el «2» una. Obtienes «la entrega a madrid es en 3 días», una frase que no está en el texto y es falsa: a Madrid son 2 días.
La idea
La misma pregunta, otra respuesta
Cuando la palabra se sortea por probabilidad, cada ejecución puede dar otra respuesta. En el programa las seis ejecuciones dieron cinco frases distintas. Eso es el no determinismo: la misma entrada, otra salida. Las pruebas, los registros y las quejas de clientes se vuelven más difíciles, porque «en mi máquina funciona» ya no significa nada.
La temperatura 0 (la palabra más probable cada vez) hace la respuesta repetible, pero no correcta. Con la palabra más probable, el programa dio «la devolución es en 2 días» cada vez. Con proveedores reales, ni la temperatura 0 promete una respuesta del todo idéntica: los cálculos en el servidor no siempre se ejecutan en el mismo orden.
La idea
La fecha de corte del conocimiento
El modelo solo conoce el texto con el que se entrenó. Ese texto se reunió hasta cierta fecha, la fecha de corte del conocimiento. Lo que pasó después, el modelo no lo sabe: la política de devoluciones nueva, el producto nuevo, el precio de hoy.
Y no sabe nada de lo que nunca estuvo en su texto: el estado del pedido 1042 está en la base de datos de la tienda, no en el modelo. Por defecto el modelo no dice «No lo sé». Escribe una respuesta probable, y de ahí sale un «llega mañana» que nadie comprobó.
Por eso los hechos van en la petición: la política como texto en el prompt, el estado del pedido desde el programa. Cómo pide el modelo el estado por sí mismo está en la lección sobre tool use.
La idea
Comprobar la respuesta con la fuente
Cuando la respuesta debe apoyarse en un documento, el programa puede comprobar al menos una parte. La comprobación más tosca: cada número de la respuesta debe estar en la fuente.
# cada número de la respuesta debe estar en la fuentedef check(answer, source): known = numbers(source) claimed = numbers(answer) if not claimed: return "? no hay número que comprobar" for n in claimed: if n not in known: return f"✗ {n} no está en la fuente" return "✓ los números están en la fuente"
def numbers(text): words = [w.strip(".,") for w in text.split(" ")] return [w for w in words if w.isdigit()]Las seis respuestas del programa anterior contra la política de devoluciones:
source = "La devolución es en 14 días. El reembolso es en 5 días hábiles."answers = [ "la devolución es seguro", "la devolución es en 2 días", "la devolución es en 14 días", "la devolución es en 5 días", "la devolución es seguro", "la devolución es de 24 meses",]for a in answers: print(f"{a} → {check(a, source)}")la devolución es seguro → ? no hay número que comprobarla devolución es en 2 días → ✗ 2 no está en la fuentela devolución es en 14 días → ✓ los números están en la fuentela devolución es en 5 días → ✓ los números están en la fuentela devolución es seguro → ? no hay número que comprobarla devolución es de 24 meses → ✗ 24 no está en la fuenteLa comprobación atrapó dos respuestas falsas: la de 2 días (segunda ejecución) y la de 24 meses (sexta). Pero dejó pasar «la devolución es en 5 días» (cuarta ejecución): el 5 está en la política, solo que es para el reembolso. Esa ejecución pasa la comprobación por la razón equivocada. Y sobre «la devolución es seguro» (primera y quinta) no puede decir nada, porque no tiene ningún número. Solo la tercera ejecución (14) pasa con razón. Una comprobación tosca baja el riesgo sin eliminarlo. Por eso los sistemas reales tienen varias comprobaciones, y donde un error sale caro, mira una persona.
Pruébalo
Encuentra el error
Un colega simplifica la comprobación. Ahora la respuesta «la devolución es en 4 días» pasa como correcta, aunque la política dice 14. ¿Qué línea tiene el error?
Elige la línea con el error.
El número se busca como un trozo del texto de la fuente. «4» es parte de «14», así que la comprobación lo encuentra. Los números deben compararse enteros: primero se sacan los números de la fuente y luego se busca el mismo número entre ellos.
Pruébalo
Completa
El modelo termina la frase cuando la palabra siguiente más probable es el final. ¿Cómo se ve el final en el texto de entrenamiento?
def greedy(follows, start):
words = start.split(" ")
while len(words) < 12:
last = words[-1]
word = most_common(follows[last])
if word == :
break
words.append(word)
return " ".join(words)Durante el entrenamiento cada frase recibe " ." al final, así que el punto es una palabra aparte. Cuando el modelo lo elige, la frase termina. Sin esta comprobación el modelo escribe hasta el límite de 12 palabras.
La idea
Cuándo un modelo de lenguaje es la herramienta equivocada
- Hay una respuesta exacta que se puede calcular. El total del pedido, el IVA, el saldo de una cuenta. Una línea de código no se equivoca; el modelo puede equivocarse en un dígito.
- Los datos están en vivo. El estado del pedido, el stock, el precio de hoy. Están en la base de datos. El modelo puede pedirlos mediante una herramienta, pero no debe «recordarlos».
- La regla es firme. «Devolución en 14 días» es un
if, no un prompt. Lo que siempre debe ser igual se escribe en el código. - La decisión debe poder explicarse y revisarse después. Un pago o un préstamo rechazado necesita una razón que se repita. Para esas decisiones hay modelos como la regresión logística, y las reglas se escriben de forma explícita.
- Un error cuesta más que el silencio. Respuestas médicas, legales o financieras a un cliente. Entonces el modelo escribe un borrador y una persona decide.
Donde el modelo es fuerte: borradores, resúmenes, traducción, clasificar texto libre (para qué área es el correo), extraer datos de un texto, respuestas a partir de un documento que se comprueban. Tareas donde una pequeña imprecisión se detecta fácilmente y no cuesta mucho.
Más precisamente, para curiosos
Por qué alucinan también los modelos grandes. Se entrenan con un texto enorme, y después un poco más para seguir instrucciones y decir «No lo sé». Eso baja los errores pero no los elimina: el modelo sigue eligiendo texto probable. Son especialmente peligrosos los datos raros (el número de un artículo de ley, una cita, el nombre de una función en una biblioteca pequeña), de los que el texto de entrenamiento tiene pocos ejemplos.
Qué ayuda, por capas. Hechos en la petición (la política como texto; el módulo posterior del curso sobre búsqueda semántica y RAG hace justamente eso). Salida con un esquema y una comprobación en el código (salida estructurada). Un conjunto de pruebas de preguntas con respuestas correctas, que se ejecuta en cada cambio (evaluación). Una respuesta «No lo sé, te paso con un colega» cuando la comprobación falla. Y una persona donde un error sale caro.
Qué tan pequeño es el modelo de aquí. El modelo de bigramas recuerda una palabra hacia atrás y está entrenado con diez frases. Un modelo grande mira miles de tokens hacia atrás y está entrenado con billones. Por eso rara vez arma «la devolución es en 2 días» a partir de dos frases. Pero cuando el contexto no tiene respuesta, igual escribe la continuación más probable, no «No lo sé».
Medir las alucinaciones. La proporción de respuestas falsas depende de la tarea y de los datos. Los números de pruebas ajenas no dicen nada de tu asistente. Los mides tú, con tus preguntas, como en la lección sobre evaluación.
Ejercicio
Las respuestas sobre la entrega
Resuelve la tarea en tu editor.
El asistente responde sobre la entrega, y la fuente dice: «La entrega a Madrid tarda hasta 2 días hábiles. A Sevilla tarda hasta 3 días hábiles. Desde 50 euros la entrega es gratis». Comprueba cinco respuestas con la misma regla (cada número de la respuesta debe estar en la fuente) e imprime el veredicto de cada una:
- La entrega a Madrid tarda hasta 2 días.
- La entrega a Sevilla tarda hasta 4 días.
- La entrega es gratis desde 30 euros.
- La entrega a Valencia tarda hasta 1 día.
- La entrega es gratis para todos los pedidos.
La entrega a Madrid tarda hasta 2 días. → ✓ los números están en la fuenteLa entrega a Sevilla tarda hasta 4 días. → ✗ 4 no está en la fuenteLa entrega es gratis desde 30 euros. → ✗ 30 no está en la fuenteLa entrega a Valencia tarda hasta 1 día. → ✗ 1 no está en la fuenteLa entrega es gratis para todos los pedidos. → ? no hay número que comprobarLa última respuesta es falsa, y la comprobación no puede atraparla: no tiene ningún número.
Más tareas
- El número en su lugar. Comprueba no solo que el número esté, sino también la palabra anterior: «hasta 2» para Madrid. ¿Qué respuestas atrapa ahora?
- Rechazo. Cuando la comprobación falla, el programa devuelve «Te comunico con un colega.» en lugar de la respuesta del modelo.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Listas por comprensión y generadores · El texto en trozos: tokens · Predecir el siguiente token · La ventana de contexto
- Continúa en: Llamar a un modelo a través de una API · El prompt es código · Salida estructurada: JSON según un esquema · Uso de herramientas: el modelo pide, el programa actúa
- Ejercicios sobre el tema: Cómo funciona un modelo de lenguaje