← Volver
IA aplicada 12 min de lectura

LLMs: el modelo mental correcto

Meter un LLM es cambiar una función determinista por una probabilística, de costo y latencia variables, que falla devolviendo algo plausible y equivocado. Esas cuatro propiedades son la especificación del componente, y de ellas salen los cuatro ejes sobre los que conviene decidir.

Datos verificados al 6 de agosto de 2026. Precios, límites y nombres de flags de proveedores cambian.

Diagrama de la arquitectura Transformer completa: el bloque encoder a la izquierda y el decoder a la derecha, con las capas de self-attention, atención cruzada y feed-forward.
dvgodoy vía Wikimedia Commons — CC BY 4.0

"Metamos un LLM acá" se discute como una decisión sobre IA. Es una decisión de arquitectura, y bastante más específica de lo que suena: estás cambiando una función determinista, de costo fijo y latencia acotada, por una probabilística, de costo variable, latencia variable, y cuyo modo de falla es devolver una respuesta plausible y equivocada sin señalarlo.

Todo lo demás es implementación. Este artículo es el mecanismo del que se deduce esa frase, y los cuatro ejes que salen de ahí.

Qué estás cambiando

Cada una de esas cuatro propiedades tiene consecuencias que se pagan en momentos distintos, y ese desfasaje es lo que hace que la decisión se sienta gratis cuando se toma. El costo variable aparece en la factura del tercer mes, cuando el volumen ya creció. La latencia variable aparece cuando alguien mide el p99 y no la mediana. Y el modo de falla aparece en producción, porque una respuesta plausible y equivocada no dispara una alerta: pasa los tests de forma, se ve bien en la demo y solo la detecta alguien que sabe la respuesta correcta.

El punto no es que un LLM sea mala idea. Es que las cuatro propiedades son la especificación del componente, no defectos a corregir, y conviene decidir con ellas a la vista.

Lo que hace falta no es saber entrenar un transformer, sino saber qué garantías da y cuáles no. De ahí salen los cuatro ejes.

El mecanismo

Un LLM es un predictor autorregresivo de próximo token sobre una ventana de contexto. Son tres pasos, en loop.

Uno: tokenización. Tu texto se parte contra un vocabulario BPE fijo —decidido antes del entrenamiento, inmutable después— y cada pieza se convierte en un entero. El modelo nunca ve caracteres. Ve índices.

Dos: forward pass. Esos enteros se convierten en vectores y atraviesan una pila de bloques idénticos. En cada bloque, self-attention hace que cada posición mire a todas las anteriores: costo cuadrático en el largo de la secuencia. Eso no es memoria. Es un producto punto entre todas las posiciones, recalculado desde cero en cada request.

Tres: softmax y sampler. La última capa devuelve un número por cada token del vocabulario. Softmax los convierte en una distribución de probabilidad. Un sampler elige uno. Ese token se agrega a la secuencia y se vuelve al paso uno.

No hay base de datos. No hay lookup. Hay una multiplicación de matrices gigante y un dado cargado.

De ahí salen tres consecuencias que gobiernan la decisión.

No tiene memoria. La API es stateless. Cada turno de una conversación reenvía el historial completo. Si tu chat tiene 20 turnos, el turno 20 paga por todo lo anterior otra vez. El costo de input de una conversación crece cuadráticamente con la cantidad de turnos, no linealmente. Nadie lo modela así cuando estima el presupuesto.

Opera sobre tokens, no sobre hechos ni caracteres. Un token no es una palabra ni una letra. Por eso el modelo falla en contar letras de una palabra y es excelente resumiendo un contrato: no son tareas del mismo tipo para él, aunque a vos te parezcan igual de fáciles. Y si querés saber cuántos tokens ocupa tu prompt, contalos con count_tokens contra el modelo que vas a usar — el vocabulario cambia entre familias de modelos, así que un tokenizer de otro proveedor te va a dar un número que no es el que te facturan.

No tiene una primitiva de "no sé". Siempre hay un token más probable. Cuando no tiene la información, no devuelve un error — devuelve la continuación más plausible. Eso que llamamos alucinación no es un bug: es el comportamiento correcto del mecanismo aplicado a una entrada para la que no había respuesta en la distribución.

Los cuatro ejes

Cuatro ejes, y el orden importa: los dos primeros son eliminatorios.

  • ¿La salida es verificable por código? Si podés escribir un assert sobre la respuesta, el LLM es un candidato razonable. Pero fijate qué verifica ese assert: un schema restringe la forma, no la existencia. Un CUIT inventado con el dígito verificador bien calculado pasa cualquier validación de formato y no está en el padrón. Un SKU con el prefijo correcto parsea perfecto y no existe en tu catálogo. La verificación que sirve es contra un sistema que sepa la verdad —tu base, el padrón, la API del proveedor—, no contra una expresión regular. Si la verificación requiere que un humano lea y opine, estás comprando un problema de escala.
  • ¿Cuál es el blast radius de una respuesta plausible y equivocada? No de una respuesta obviamente mal. De una que se ve bien. Clasificar tickets de soporte: bajo. Decidir si aprobás una transferencia: alto. Redactar un mail que se manda solo: alto y silencioso, que es el peor.
  • ¿Qué porcentaje del input es prefijo repetido? Este eje decide la economía completa, y lo desarrollo abajo.
  • ¿La latencia entra en el presupuesto del path? Un LLM en el path síncrono de un checkout es una decisión de arquitectura distinta a un LLM en un job nocturno. Si el caso tolera minutos en vez de milisegundos, la Batch API te lo cobra a mitad de precio.

Si los primeros dos te dan mal, los otros dos no importan. No sigas.

Los números

Precios públicos de la API de Anthropic, por millón de tokens:

  • Claude Opus 5: 5 dólares de input, 25 de output. Ventana de 1M tokens, hasta 128K de salida.
  • Claude Haiku 4.5: 1 dólar de input, 5 de output. Ventana de 200K.

Ahora la parte que cambia el orden de magnitud. Prompt caching: una lectura de caché cuesta cerca del 10% del precio base de input, y una escritura cuesta 1,25× con TTL de 5 minutos (2× si elegís TTL de una hora). El punto de equilibrio con TTL de 5 minutos son dos requests.

Tomá un asistente sobre documentación interna: 40.000 tokens de prefijo estable (system prompt más manual operativo), 200 tokens de pregunta, 800 de respuesta, 50.000 requests por mes, sobre Opus 5.

Sin caching: 2.010 millones de tokens de input a 5 dólares el millón son 10.050 dólares, más 1.000 de output. Unos 11.050 dólares al mes.

Con caching y un 95% de hit rate: 625 dólares de escrituras, 950 de lecturas, 50 del sufijo variable, 1.000 de output. Unos 2.625 dólares al mes.

La misma aplicación, el mismo modelo, la misma calidad de respuesta. Una diferencia de 8.400 dólares mensuales que depende enteramente de dónde ponés un campo en el prompt.

Lo que se rompe

El caching es prefix match. Cualquier byte que cambie en el prefijo invalida todo lo que viene después. Y este es el error que se comete siempre:

# Mal. El timestamp está adentro del prefijo cacheado.
system = [{
    "type": "text",
    "text": f"Hoy es {datetime.now().isoformat()}\n\n{MANUAL_OPERATIVO}",
    "cache_control": {"type": "ephemeral"},
}]

Ese datetime.now() hace que el prefijo sea distinto en cada request. La caché nunca se lee. No hay error, no hay warning, no hay log. Simplemente pagás precio completo para siempre y la factura te lo cuenta 30 días después.

# Bien. El prefijo es byte-idéntico entre requests; lo volátil va al final.
system = [{
    "type": "text",
    "text": MANUAL_OPERATIVO,           # 40.000 tokens, congelado
    "cache_control": {"type": "ephemeral"},
}]
messages = [{"role": "user", "content": [
    {"type": "text", "text": f"Fecha: {datetime.now().isoformat()}"},
    {"type": "text", "text": pregunta},
]}]

La verificación es una línea, y tiene que estar en tu dashboard, no en tu cabeza:

r = client.messages.create(...)
print(r.usage.cache_read_input_tokens)   # si es 0 request tras request, no estás cacheando
print(r.usage.cache_creation_input_tokens)
print(r.usage.input_tokens)              # ojo: esto es SOLO el resto no cacheado

Ese último campo engaña, y engaña en la dirección cómoda. input_tokens no es el tamaño del prompt: es el remanente que quedó afuera de la caché. El prompt total es la suma de los tres campos. Si mirás solo input_tokens para estimar consumo, vas a creer que estás procesando una fracción de lo que realmente procesás.

Hay más cosas que se rompen por la misma razón. Cambiar el set de tools invalida todo, porque los tools se renderizan en la posición cero del prompt —sigue siendo cierto por defecto, aunque en Opus 5 ya existe un camino en beta (mid-conversation-tool-changes-2026-07-01) que agrega y saca tools a mitad de conversación sin tirar el prefijo cacheado—. Cambiar de modelo a mitad de conversación invalida todo, porque las cachés son por modelo. Y el prefijo mínimo cacheable no es uniforme: son 512 tokens en Opus 5, 1024 en Sonnet 5 y Opus 4.8, 2048 en Opus 4.7, 4096 en Opus 4.6 y Haiku 4.5. La escala no es monótona entre generaciones. Un prompt de 3.000 tokens cachea en un modelo y silenciosamente no cachea en otro.

El determinismo tampoco existe. Esto tiene exactamente la misma forma que los fallos de caching, y por eso va acá. temperature=0 no significa "el modelo es determinista": significa greedy decoding, elegir el argmax de los logits. Y los logits dependen de cómo se agrupó tu request con otras en el batch del proveedor, porque las reducciones en punto flotante no son asociativas — sumar los mismos números en distinto orden da resultados que difieren en el último bit. Con dos candidatos casi empatados, ese último bit da vuelta el argmax y la respuesta cambia. Mismo prompt, misma temperatura, salida distinta. En los modelos actuales de Anthropic el punto es todavía más terminal: temperature, top_p y top_k fueron removidos a partir de Opus 4.7 y mandarlos devuelve 400. La palanca ya no está. Si escribiste un test de regresión que compara la salida byte a byte, no tenés un test: tenés un generador de flaky builds que se va a comer días de equipo antes de que alguien lo entienda.

El otro modo de falla predecible es posicional. En Lost in the Middle (Liu et al., TACL 2024) los autores midieron recuperación de información en función de dónde estaba el dato dentro del contexto: la precisión es más alta cuando el dato está al principio o al final, y cae de forma marcada cuando está en el medio — incluso en modelos explícitamente diseñados para contexto largo. Si tu retrieval mete 30 documentos y el relevante queda decimoquinto, la falla es estructural, no del prompt.

Y hay uno más que cambia el modelo mental de golpe. En The Reversal Curse (Berglund et al., 2023) los autores mostraron que un modelo entrenado sobre "A es B" no aprende "B es A". El ejemplo del paper es el que se te queda: el modelo responde correctamente quién es la madre de Tom Cruise y falla cuando le preguntás de quién es hijo Mary Lee Pfeiffer. Es el mismo hecho, en la dirección inversa, y la asimetría es enorme. No hay grafo de conocimiento adentro. Hay una función de continuación entrenada sobre un orden de palabras, y ese orden importa.

Cuándo no hacerlo

Cuatro casos donde la respuesta es no, y los defiendo:

  • Cuando existe una regla. Si el requerimiento se puede escribir como if, escribilo como if. Un LLM clasificando por un criterio que ya tenés especificado es más caro, más lento y menos confiable que el if. Suena obvio, y sin embargo es el error de la lista que más tarda en detectarse: un if mal reemplazado no falla, solo cuesta y demora.
  • Cuando la salida no es verificable y el error es caro. Sin verificación automática, tu sistema de calidad es la esperanza. La esperanza no escala a 50.000 requests por mes.
  • Cuando el volumen es alto y el valor por request es bajo. Correr un LLM sobre cada evento de un stream de alto volumen es una decisión que se paga en dólares reales. Hacé la cuenta antes, no después.
  • Cuando lo estás usando de orquestador de un plan determinista. Si mirás la traza de tu agente y es el mismo loop N veces con inputs que determinan completamente los outputs, eso es código con pasos extra y una factura. Dejá una sola llamada al modelo donde el trabajo es genuinamente ambiguo, y devolvé el resto a funciones.

El modelo mental correcto no te dice qué podés construir. Te dice qué va a fallar, y eso vale más.

Un LLM es un componente con garantías raras: probabilístico, sin estado, caro en prefijos repetidos, ciego al medio de su propio contexto, asimétrico respecto de los hechos que le enseñaron, e incapaz de decir que no sabe. Ninguna de esas propiedades es un defecto a corregir. Son la especificación.

Un sistema diseñado contra esa especificación se comporta como se espera. Uno diseñado contra la especificación imaginada también se comporta como corresponde — solo que la sorpresa llega en producción, y con plata de verdad.

Para seguir

Lecturas

  • Attention Is All You Need — la fuente primaria del mecanismo: la salida es una distribución sobre el próximo token calculada por atención, y de ahí se deduce casi todo lo demás.
  • Lost in the Middle: How Language Models Use Long Contexts — la evidencia empírica de que el rendimiento cae cuando el dato relevante está en el medio del contexto, con traducción directa a cómo armás un prompt y un RAG.
  • Why Language Models Hallucinate — explica la alucinación como consecuencia del entrenamiento y la evaluación, no como un bug que se arregla con más datos. Rompe la expectativa de que la próxima versión ya no va a inventar.
  • Tracing the thoughts of a large language model — interpretabilidad sobre un modelo en producción, incluyendo casos donde el razonamiento que el modelo verbaliza no es el que ejecuta. Buen antídoto contra confiar en el chain-of-thought como explicación.
  • Effective context engineering for AI agents — el puente entre el mecanismo y la práctica: el contexto como recurso finito y degradable, con tácticas concretas.

Videos

Siguiente · IA aplicada · 16 min RAG sin humo: el mecanismo decide los modos de falla Leer siguiente →