Saltar al contenido
Aguiar Labs

RAG en producción: qué cambia cuando existe un SLA

Presupuesto de latencia, costo por token y calidad de contexto. Lo que separa un RAG de demostración de uno que aguanta producción — con números de un asistente real.

Publicado
Lectura
6 min
Render 3D oscuro de un campo de placas finas acostadas en cuadrícula, con exactamente tres placas de pie entre ellas, captando un poco más de luz.

Montar un RAG hoy es una tarde de trabajo: LangChain, una base de datos Postgres con pgvector, un modelo de embedding y listo, el chat responde citando tus documentos. La demo funciona. Siempre funciona.

Lo que separa esa demo de un sistema en producción son tres números que la demo nunca te obliga a mirar: la latencia p95, el costo por consulta y cuánto de la respuesta vino de verdad del contexto recuperado.

Los números de abajo son de un asistente interno que responde con base en las reglas de producto de una plataforma en producción. No cito nombres ni montos de cliente — lo que importa aquí son los órdenes de magnitud y las decisiones.

La latencia es presupuesto, no suerte

Cuando alguien promete "respuesta en hasta 2 segundos", eso deja de ser una métrica y pasa a ser un presupuesto a repartir entre las etapas:

EtapaPresupuesto p95
Embedar la pregunta40 ms
Buscar en el índice vectorial120 ms
Reordenar los fragmentos80 ms
Generar la respuesta1.400 ms

Si la suma se pasa del SLA, no sirve de nada cambiar el modelo: la arquitectura es lo que está mal. Y la etapa que casi todo el mundo subestima es la búsqueda.

En pgvector, la elección del índice es la primera palanca. El HNSW entrega mejor relación entre velocidad y recall, pero tarda más en construirse y ocupa más memoria. El IVFFlat se construye rápido y ocupa poco, con peor recall para el mismo tiempo de búsqueda. En producción, en la práctica, el HNSW gana casi siempre — el costo es la construcción del índice, que pagas una vez.

El botón que controla el trade-off está en el tiempo de consulta: hnsw.ef_search (por defecto 40) en el HNSW e ivfflat.probes (por defecto 1) en el IVFFlat. Subir estos valores mejora el recall y cuesta latencia. Ahí, y no en el modelo, es donde se compra calidad de búsqueda.

-- índice HNSW por similitud de coseno
CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops)
  WITH (m = 16, ef_construction = 64);

-- recall x latencia: ajusta por consulta, no en toda la base de datos
SET LOCAL hnsw.ef_search = 100;

SELECT id, contenido
FROM chunks
WHERE tenant_id = $1 AND doc_type = 'regla'
ORDER BY embedding <=> $2
LIMIT 3;

Fíjate en el WHERE de esa consulta, porque ahí está la trampa más cara de pgvector: con índice aproximado, el filtro se aplica después del recorrido del índice. Pides 3 resultados, el índice devuelve los vecinos más cercanos, el filtro tira la mayor parte y queda 1 — o ninguno. La respuesta viene vacía y parece bug de modelo. La salida es el iterative scan (hnsw.iterative_scan), que hace que la base de datos busque más candidatos hasta completar el LIMIT. Descubrir esto en producción, con un cliente preguntando por qué el asistente "olvidó" la regla, es caro.

El token es contexto, y el contexto es una elección

El tutorial estándar manda los 10 fragmentos más cercanos al modelo. Es el mayor desperdicio silencioso de un RAG: pagas entrada por 10 fragmentos, el modelo lee 10 fragmentos y la respuesta sale de 2.

En el asistente que medí, el corpus es pequeño y bien delimitado: 16 documentos de reglas se vuelven 384 chunks, cerca de 530 mil caracteres, algo cercano a 133 mil tokens. Cada pregunta lleva 3 fragmentos, alrededor de 1.400 tokens de contexto, más la pregunta embedada. La indexación entera, en un modelo de embedding de USD 0,02 por millón de tokens, cuesta menos de un centavo de dólar. Y reindexar toca solo lo que cambió, porque el hash del contenido decide qué es nuevo.

Tres decisiones hacen que ese número siga siendo pequeño sin perder respuesta:

  • Chunk con frontera semántica. Cortar cada mil caracteres es simple y parte tabla, lista y regla por la mitad. Cortar por sección cuesta un día de trabajo y mejora el recall y la respuesta al mismo tiempo.
  • Rerank antes de mandar. Traer 20 candidatos de la búsqueda y mandar 3 al modelo es más barato y más preciso que mandar 10 directo.
  • Metadato como filtro, no como texto. Tenant, tipo de documento y versión entran en el WHERE, no en el prompt.

La ganancia del RAG no es ahorro, es acertar con fuente

Existe un argumento de venta común: "el RAG ahorra tokens porque no necesitas mandar el manual entero en el prompt". La cuenta parece buena — mandar 133 mil tokens en cada pregunta, a un precio típico de USD 3 por millón de tokens de entrada, daría unos USD 0,40 por pregunta.

Solo que esa no es la alternativa real. Nadie iba a mandar el manual entero en cada pregunta. Sin RAG, la alternativa es que el asistente no sepa responder — o peor, que invente una regla que suena plausible.

La ganancia del RAG es otra: acertar con fuente citada. Una respuesta que señala de qué documento y de qué fragmento salió puede ser verificada por quien la recibió. Eso es lo que permite usar el asistente encima de regla de negocio, precio y política. El ahorro de tokens es consecuencia de un contexto bien elegido, no el objetivo.

El dinero casi nunca está donde lo buscas

Al medir el costo de esa plataforma, el RAG no era el problema. La indexación cuesta centavos, y el contexto por pregunta es pequeño.

Lo que apareció fue otra cosa: en decenas de miles de llamadas al modelo, el cache de prompt estaba apagado — el contador de tokens leídos del cache estaba en cero en todas ellas. La feature más cara, responsable de la mayor parte de la cuenta, manda cerca de 8,5 mil tokens de entrada por llamada, y buena parte de eso es prefijo estable: reglas de seguridad, instrucciones de sistema, datos de la oferta.

La lectura de cache cuesta cerca del 10 % del precio de la entrada normal (grabar cuesta alrededor de 25 % más que una entrada común, una vez). En un ítem que domina la cuenta y repite el mismo prefijo miles de veces al día, el orden de magnitud del ahorro es de cientos de dólares al mes.

Tres detalles deciden si esto funciona:

  • El cache es por prefijo. Un byte que cambia al comienzo invalida todo lo que viene después. Un timestamp en el system prompt, JSON con claves en orden aleatorio y una lista de herramientas que cambia de orden tiran abajo el cache entero.
  • Existe un tamaño mínimo. El prefijo necesita tener entre 512 y 4.096 tokens, según el modelo. Por debajo de eso simplemente no se cachea, en silencio.
  • Se puede verificar. El campo de tokens leídos del cache en la respuesta responde en un minuto lo que una discusión de arquitectura tarda una semana en especular.

La lección que me llevo: antes de prometer ahorro, mide qué porción del prompt es realmente fija. El número honesto viene de la medición, no de la estimación.

Hay además una trampa de observabilidad que vale la pena registrar. El gasto con embedding puede no aparecer en tu panel de costo de IA, porque el registro suele ser un middleware que envuelve el modelo de lenguaje — y el proveedor de embedding no pasa por ahí. El costo es pequeño, pero el panel queda mintiendo, y un panel que miente es peor que un panel que no existe — el mismo patrón de los controles que nadie probó.

Lo que mido antes de decir que está listo

  1. Presupuesto de latencia por etapa, con p95 medido en producción, no en promedio local.
  2. Recall de la búsqueda en un conjunto de preguntas reales, antes de culpar al modelo por la mala respuesta.
  3. Tokens por respuesta, separando prefijo fijo de contexto recuperado.
  4. Tasa de lectura del cache, que necesita ser mayor que cero.
  5. Cuánto de la respuesta se sostiene en el contexto, con la cita del fragmento de origen visible para quien lee.
  6. Un camino de fallback determinístico para cuando el modelo esté caído — aunque sea una búsqueda por patrones explícitos, respondiendo menos y equivocándose menos.

Nada de esto aparece en la demo. Todo aparece en la primera semana de producción.

Lectura complementaria

Fuentes

Newsletter mensual de Aguiar Labs.

Una idea técnica al mes. Breve y sin rodeos.

Al suscribirte, aceptas recibir nuestra newsletter y nuestra Política de Privacidad. Cancela cuando quieras.

Sigue leyendo