Cómo construí Tuki: el cotizador con RAG que ya está en producción
Soy Esteban Burgos, Forward Deployed Engineer, y este es el post que me hubiera gustado leer antes de meter un asistente con IA en producción. No es un tutorial de "cómo hacer RAG en 10 minutos". Es lo que decidí, lo que me salió bien y lo que se rompió construyendo Tuki, el cotizador que hoy vive en estebanburgos.com.ar/quote y da rangos de precio basados en el mercado freelance argentino.
Si estás evaluando sumar un asistente conversacional a tu producto, este post es para vos: no para que copies código, sino para que anticipes las decisiones que realmente importan cuando el asistente deja de ser una demo y empieza a recibir tráfico real.
Qué es Tuki y por qué existe
Tuki responde una pregunta muy concreta: "¿cuánto cuesta un proyecto como el que estoy pensando?". En lugar de un formulario estático o una tabla de precios genérica, es una conversación que usa una base de conocimiento propia sobre cómo se cotiza trabajo freelance en Argentina, y devuelve un rango razonable ajustado a lo que el visitante describe.
La restricción de diseño más importante fue esta: tenía que ser útil sin ser una fuente de gastos impredecibles ni un vector de abuso. Un asistente que "funciona" en una demo y un asistente que sobrevive a tráfico real, bots y usuarios creativos probando los límites del prompt son dos productos distintos. Todo lo que sigue está pensado desde esa tensión.
Arquitectura: Next.js, AI SDK y tool calling
Tuki corre sobre Next.js, que ya usaba para el resto del sitio, así que no sumé un sistema nuevo: el chat vive como una ruta más de la misma app. Para la capa de IA usé el AI SDK de Vercel, que hoy es básicamente el estándar para no acoplarse a un solo proveedor de modelos. Eso me da dos cosas que valoro como Forward Deployed Engineer: poder cambiar de modelo sin reescribir la lógica de negocio, y una API de streaming y tool calling que no tengo que reinventar.
El modelo no cotiza "de memoria". Cotiza usando herramientas: cuando detecta que tiene suficiente información sobre el proyecto (tipo de trabajo, alcance, urgencia), llama a una función que busca en la base de conocimiento y otra que arma la respuesta con el rango correspondiente. Esto es clave para el punto siguiente: el modelo no inventa números, los busca.
Separar "razonar sobre la conversación" de "obtener el dato correcto" es la decisión de arquitectura que más repetiría si tuviera que hacerlo de nuevo. El LLM es bueno entendiendo lo que pide el usuario y llevando la conversación; es mucho menos confiable inventando cifras. Tool calling resuelve esa división de responsabilidades sin necesidad de fine-tuning ni trucos de prompt engineering frágiles.
RAG sobre una base de conocimiento propia
La base de conocimiento de Tuki no es un PDF gigante ni scraping de internet: es contenido propio sobre cómo se estructura una cotización freelance en Argentina, con sus matices (tipo de proyecto, complejidad, plazos). Ese contenido se parte en chunks, se embebe y se guarda en Postgres con pgvector.
Cuando llega una consulta, se embebe también y se busca similitud contra esos vectores para traer solo el contexto relevante antes de que el modelo genere la respuesta final. Es RAG en su forma más aburrida y, para este caso, más correcta: nada de pipelines multi-etapa, nada de re-ranking sofisticado. La base de conocimiento es acotada y curada por mí, así que la recuperación no necesita ser heroica para ser precisa.
pgvector sin índice HNSW: una decisión consciente, no un olvido
Esta es la parte que más preguntas genera cuando la cuento: uso pgvector sin índice HNSW. No es que no sepa que existe, es que decidí no usarlo, por ahora.
HNSW (y su alternativa IVFFlat) existen para acelerar búsquedas de similitud cuando tenés millones de vectores y necesitás evitar un escaneo secuencial completo. El problema es que ese índice no es gratis: consume memoria, agrega complejidad de mantenimiento y, en volúmenes chicos, la mejora de latencia es marginal frente a un escaneo secuencial sobre una tabla que cabe cómoda en RAM.
La base de conocimiento de Tuki es del tamaño de "todo lo que necesito para cotizar bien", no de "todo internet". Con ese volumen, una búsqueda exacta por similitud coseno sin índice aproximado responde en milisegundos que ni se notan al lado de la latencia del modelo generativo, que siempre va a ser el cuello de botella real. Agregar HNSW hoy sería optimizar la parte del sistema que no es el problema, a costa de sumar una pieza más para mantener y de introducir aproximación donde hoy tengo exactitud.
La lección para un CTO que evalúa esto: no adoptes la infraestructura de "escala de LLM startup con millones de documentos" si tu base de conocimiento es curada y chica. Medí el volumen real antes de copiar la arquitectura de un blog post que resuelve un problema diez veces más grande que el tuyo.
Límites por IP y por conversación para controlar costos y abuso
Un asistente conectado a un modelo pago es, ni bien lo publicás, una superficie de costo variable que no controlás del todo si no le ponés límites explícitos. En Tuki los límites son simples y están puestos a propósito:
- 30 mensajes cada 10 minutos por IP.
- 40 mensajes por conversación.
El primero corta abuso y bots que intentan hacer flood de requests. El segundo evita que una sola conversación se vaya extendiendo indefinidamente, ya sea por un usuario legítimo dando vueltas sin llegar a un cierre o por alguien tratando de hacer que el modelo se salga de tema a fuerza de mensajes.
Ninguno de los dos límites reemplaza monitoreo de costos, pero funcionan como un piso: son la diferencia entre "un pico de tráfico raro me cuesta un poco más ese día" y "un pico de tráfico raro me genera una factura que tengo que explicar". Para cualquiera que esté evaluando meter un chat con IA en su producto, esto no es opcional ni es un detalle de implementación: es lo primero que hay que diseñar, antes de escribir el primer prompt.
Precio en la moneda del visitante: dólar MEP para Argentina
Tuki detecta el país del visitante y ajusta la moneda de la cotización en consecuencia. Para Argentina, eso significa mostrar el rango usando el dólar MEP como referencia, en lugar de forzar a cada usuario a convertir mentalmente un número en otra moneda.
Esto suena a detalle cosmético pero no lo es: un cotizador que muestra un precio en la moneda "equivocada" para el contexto del visitante genera fricción y desconfianza antes de que la conversación siquiera empiece. Detectar el país y elegir la referencia de conversión correcta es parte de que el rango se perciba como algo pensado para esa persona y no como una tabla genérica traducida a la fuerza.
Qué falló en producción y cómo se resolvió
Ningún sistema con un LLM en el medio se comporta en producción exactamente como en el ambiente de pruebas, y Tuki no fue la excepción. Los límites de rate limiting por IP y por conversación que mencioné antes no nacieron en el diseño inicial con esos números exactos: se ajustaron después de ver comportamiento real de tráfico, que es justamente el tipo de señal que no se puede simular del todo antes de salir a producción.
La otra fuente constante de ajuste fue la separación entre razonamiento del modelo y obtención del dato de precio a través de tools. Cualquier cotizador conversacional que deje que el modelo "calcule" o "recuerde" un número en lugar de ir a buscarlo a una fuente controlada tarde o temprano va a mostrar inconsistencias entre dos respuestas parecidas. Reforzar que el precio siempre salga de la herramienta y nunca de la generación libre del modelo fue, más que un fix puntual, el criterio que uso para revisar cualquier cambio que le hago a Tuki desde entonces.
Si estás por lanzar algo similar, el consejo concreto es: instrumentá desde el día uno para poder ver volumen de mensajes por IP, por conversación y la proporción de respuestas que vienen de tool calls versus generación libre. Sin esa visibilidad, cualquier ajuste post-lanzamiento es a ciegas.
Retomar conversaciones: navegador o link
Una conversación de cotización rara vez se cierra en un solo intercambio. La gente vuelve, compara, consulta con alguien más. Por eso Tuki permite retomar la conversación de dos formas: automáticamente desde el navegador, si volvés al mismo dispositivo, o compartiendo el link con el formato ?tuki=<id>, que te lleva directo al estado exacto donde la dejaste.
Es una decisión chica en apariencia, pero cambia la percepción del asistente: deja de ser un chat efímero que se resetea cada vez y empieza a comportarse como parte de un proceso de cotización real, algo que uno retoma en el tiempo, no algo que se usa una sola vez y se descarta.
Lo que le diría a un tech lead antes de empezar
Si estás evaluando sumar un asistente con IA a tu producto, la parte fácil es conectar un modelo y hacer que responda algo coherente. La parte difícil, y la que decide si el proyecto sobrevive en producción, es todo lo que rodea a eso: separar lo que el modelo razona de lo que el modelo busca en una fuente confiable, poner límites de uso desde el primer día aunque parezcan conservadores, y elegir infraestructura acorde al volumen real que vas a tener, no al volumen que tendría un caso de uso diez veces más grande.
Tuki es chico a propósito. Esa es, en buena medida, la razón por la que funciona.
Si querés ver todo esto funcionando en un caso real, entrá a https://estebanburgos.com.ar/quote y probá cotizar un proyecto.

Sobre el autor
ESTEBAN BURGOS · Forward Deployed Engineer
Construyo software de punta a punta para pymes y empresas: webs, plataformas y soluciones con IA. Escribo sobre lo que aprendo en proyectos reales.
Conocé mi trayectoria¿Querés algo así en tu empresa?
Contale tu idea a Tuki y en minutos tenés un rango de precio en tu moneda.
Seguí leyendo
- LangChain en 2026: la clave para chatbots inteligentes con RAG, herramientas y una UX imbatibleDescubrí qué es LangChain y por qué se convirtió en una de las piezas centrales para construir chatbots inteligentes modernos. Repasamos cómo combinar RAG, chat-tools y una experiencia de usuario fluida para crear asistentes que realmente resuelven problemas, no que solo responden preguntas.
- ¿Tiemblan los devs? La ilusión del usuario técnico y el verdadero techo de la IAEl debate sobre si la inteligencia artificial reemplazará a los desarrolladores suele plantearse desde un falso dilema: **el experto técnico tradicional contra el usuario de a pie empoderado por un agente inteligente**. Sin embargo, la fricción real no es sintáctica ni superficial. No se trata de quién escribe más rápido una función en Python o quién arma un flujo de automatización en media hora. La verdadera brecha es **arquitectónica y lógica**.
- Podcast: Adiós al código espagueti, cómo SDD-Harness pone orden al desarrollo con IALa velocidad a la que las inteligencias artificiales pueden escribir código hoy en día es asombrosa, pero tiene un costo oculto altísimo: **la anarquía técnica**. Cuando múltiples desarrolladores integran agentes de IA en sus flujos diarios de forma improvisada, el resultado suele ser código inconsistente, regresiones silenciosas, parches indocumentados y una alarmante pérdida de trazabilidad. En definitiva, un nuevo tipo de **"código espagueti agéntico"** que asfixia la mantenibilidad del software a largo plazo. Para resolver este problema de raíz, diseñé **SDD-Harness**, un framework de línea de comandos (CLI) portable y agnóstico del lenguaje que implementa la metodología **Spec-Driven Development (SDD)**. La premisa es tan simple como inflexible: **ninguna línea de código se escribe sin una especificación técnica formal, estructurada y validada previamente**. A continuación, les comparto un desglose profundo de cómo funciona la herramienta y por qué la gobernanza de agentes es el paso indispensable para escalar la ingeniería de software asistida por IA.
Comentarios
Sé el primero en comentar.