RAG en ColdFusion: chatea con tus propios documentos

Desarrollador programando un chat con RAG en ColdFusion
Foto: Nicole Wolf / Unsplash

Para hacer RAG (Retrieval-Augmented Generation) en ColdFusion necesitas tres piezas: un vector store donde guardar tus documentos convertidos en embeddings, una función que busque los fragmentos más relevantes según la pregunta del usuario, y una llamada a un LLM que responda usando ese contexto. Desde ColdFusion 2025 Update 8, Adobe integró un framework de IA nativo que incluye cfai y soporte directo para vector stores, así que ya no necesitas librerías externas para armar tu propio "chat con tus documentos".

¿Qué es RAG y para qué sirve en tus proyectos CFML?

RAG combina búsqueda semántica con generación de texto: en vez de que el modelo invente respuestas, primero buscás en tu propia base de conocimiento (manuales, PDFs, tickets de soporte, documentación interna) y le pasás esos fragmentos como contexto al LLM. Esto reduce alucinaciones y te permite construir asistentes que responden con datos reales de tu empresa, no con lo que el modelo "recuerda" de su entrenamiento.

  • Chatbots de soporte que responden con tu documentación real.
  • Buscadores internos que entienden lenguaje natural, no solo palabras clave.
  • Asistentes que resumen contratos, políticas o manuales técnicos.

¿Qué necesitas antes de empezar?

  • ColdFusion 2025 Update 8 o superior (o BoxLang con ColdBox 8, si preferís JVM moderna).
  • Una API key de OpenAI, Claude, Gemini, Mistral o Azure OpenAI (también funciona con Ollama local si querés todo on-premise).
  • Tus documentos en texto plano, PDF o Markdown.

¿Cómo armar el vector store con tus documentos?

El vector store es donde se guardan los embeddings —representaciones numéricas del significado de cada fragmento de texto—. ColdFusion 2025 Update 8 trae funciones nativas para crear y poblar un vector store sin depender de servicios externos como Pinecone.

Paso a paso para crear el vector store

  1. Configura tu proveedor de IA en el archivo de configuración de la aplicación.
  2. Divide tus documentos en fragmentos ("chunks") manejables.
  3. Genera los embeddings de cada fragmento.
  4. Guarda los embeddings en el vector store junto con el texto original.
<cfscript>
// Configuración del proveedor de IA (Application.cfc o config central)
aiConfig = {
 provider: "openai",
 apiKey: application.openaiKey,
 embeddingModel: "text-embedding-3-small"
};

// Crear el vector store
vectorStore = cfai.createVectorStore(
 name = "manual_soporte",
 config = aiConfig
);
</cfscript>

Este bloque configura la conexión al proveedor y crea un vector store vacío llamado manual_soporte, listo para recibir documentos.

<cfscript>
// Leer y dividir un documento en fragmentos
contenido = fileRead("/docs/manual_producto.txt");
fragmentos = cfai.splitText(
 text = contenido,
 chunkSize = 500,
 overlap = 50
);

// Insertar cada fragmento en el vector store
for (fragmento in fragmentos) {
 vectorStore.addDocument(
 text = fragmento,
 metadata = { "fuente": "manual_producto.txt" }
 );
}
</cfscript>

Aquí dividimos el texto en fragmentos de 500 caracteres con un solape de 50 (para no perder contexto entre cortes) y los agregamos uno por uno al vector store, junto con metadatos que te sirven para saber de dónde vino cada respuesta.

¿Cómo hacer la búsqueda semántica y responder con el LLM?

Una vez que tu vector store tiene contenido, el flujo de una consulta RAG es: convertir la pregunta del usuario en embedding, buscar los fragmentos más parecidos semánticamente, y armar un prompt que incluya ese contexto antes de mandarlo al modelo.

Paso a paso para responder preguntas con RAG

  1. Recibe la pregunta del usuario.
  2. Busca los fragmentos relevantes en el vector store.
  3. Construye el prompt combinando contexto + pregunta.
  4. Envía el prompt al LLM y muestra la respuesta.
<cfscript>
component {

 function responderPregunta(required string pregunta) {

 // 1. Buscar fragmentos relevantes (top 3 más parecidos)
 resultados = vectorStore.search(
 query = arguments.pregunta,
 topK = 3
 );

 // 2. Armar el contexto con los fragmentos encontrados
 contexto = "";
 for (r in resultados) {
 contexto &= r.text & chr(10) & "---" & chr(10);
 }

 // 3. Construir el prompt para el LLM
 prompt = "Responde usando SOLO el siguiente contexto. " &
 "Si no encuentras la respuesta, dilo claramente." &
 chr(10) & chr(10) &
 "Contexto:" & chr(10) & contexto &
 chr(10) & "Pregunta: " & arguments.pregunta;

 // 4. Llamar al modelo de IA
 respuesta = cfai.chat(
 provider = "openai",
 model = "gpt-4o-mini",
 prompt = prompt
 );

 return respuesta.text;
 }
}
</cfscript>

Esta función recibe la pregunta, busca los 3 fragmentos más relevantes del vector store, los concatena como contexto, y arma un prompt que le pide al modelo responder solo con esa información (esto es clave para evitar alucinaciones). Podés llamarla desde un endpoint REST o desde un componente de tu app.

¿Cómo exponerlo como un endpoint para tu chat?

Para que un frontend (React, Vue o incluso una página CFML simple) pueda consumir esto, exponelo como un servicio REST:

<cfscript>
component rest="true" restpath="/chat" {

 remote string function preguntar(required string mensaje)
 httpmethod="POST" restpath="/preguntar" produces="application/json" {

 asistente = new components.AsistenteRAG();
 return asistente.responderPregunta(arguments.mensaje);
 }
}
</cfscript>

Con esto ya tenés un endpoint POST /chat/preguntar que recibe un mensaje y devuelve la respuesta generada con contexto de tus propios documentos.

¿Funciona esto también en BoxLang?

Sí. BoxLang (el lenguaje moderno de Ortus compatible con CFML) permite el mismo enfoque usando módulos de IA compatibles y ColdBox 8 para estructurar la aplicación en capas (handlers, services, models), lo que facilita separar la lógica de RAG del resto de tu app si el proyecto crece.

Preguntas frecuentes

¿Necesito una base de datos vectorial externa como Pinecone o Weaviate?

No es obligatorio. Desde ColdFusion 2025 Update 8 podés usar el vector store nativo para proyectos pequeños y medianos. Si tu volumen de documentos crece mucho (millones de fragmentos), sí conviene migrar a una solución externa especializada.

¿Puedo usar un modelo local en vez de OpenAI o Claude?

Sí, el framework de IA de ColdFusion soporta Ollama para correr modelos localmente, útil si manejás datos sensibles y no querés enviarlos a un proveedor externo.

¿Qué tamaño de chunk debo usar al dividir mis documentos?

Depende del contenido, pero 300-500 caracteres con solape de 10-15% suele funcionar bien para manuales y documentación técnica. Fragmentos muy grandes diluyen la relevancia; muy pequeños pierden contexto.

¿RAG reemplaza el fine-tuning de un modelo?

No, son complementarios. RAG es más rápido de implementar y actualizar (solo cambiás los documentos), mientras que el fine-tuning ajusta el comportamiento del modelo en sí. Para la mayoría de los casos de negocio, RAG es suficiente y más económico.