Resumen

Conectar un chatbot a un modelo de inteligencia artificial es donde async await muestra todo su potencial. Cada pregunta del usuario dispara una llamada a un servicio externo que puede tardar segundos, y el código necesita esperarla sin bloquear el resto de la aplicación. Aquí se integra todo lo aprendido sobre asincronía en un flujo real: el usuario pregunta, el servidor envía la consulta a la API de Gemini con contexto y devuelve la respuesta generada por el modelo.

¿Cómo se configura la API de Gemini para el chatbot?

Para que el chatbot funcione se necesita una API Key de Gemini [1:30]. Se eligió Gemini porque ofrece una capa gratuita ideal para proyectos de aprendizaje, aunque el mismo patrón aplica con cualquier otro proveedor de modelos de lenguaje.

El proceso de configuración es directo:

  • Crear una nueva API Key desde la consola de Gemini.
  • Copiar la clave y pegarla en un archivo .env del proyecto.
  • Nunca exponer la API Key públicamente, ya que representa un riesgo de seguridad.

El archivo .env.example sirve como plantilla. Se elimina la extensión .example, se pega la clave y el servidor la lee automáticamente [2:00].

¿Qué responsabilidades tiene el servidor en este proyecto?

El archivo server.js cumple dos funciones principales [2:22]. Primero, sirve los archivos estáticos del proyecto: HTML, CSS y JavaScript. Segundo, expone un endpoint en /api/chat que recibe la pregunta del usuario, la envía a Gemini con el contexto de Colombia y devuelve la respuesta.

¿Por qué el manejo de la API Key ocurre en el servidor?

Todo el manejo de la clave se realiza del lado del servidor para que nunca quede expuesta al front end [2:40]. Este es un principio fundamental de seguridad: las credenciales sensibles viven únicamente en el entorno del servidor.

La función principal del archivo es asíncrona porque debe esperar que Gemini devuelva un resultado [3:00]. Al inicio se valida que la API Key exista; si no, se arroja un error descriptivo. Después se construye un prompt de sistema que define el comportamiento del modelo: responder en español, usar cifras cuando aplique, basarse solo en el contexto recibido y ser conciso pero informativo.

¿Cómo se estructuran las funciones del módulo LLM?

El archivo de LLM contiene dos funciones clave [3:40]:

  • askGeminiAPI: función asíncrona que envía la pregunta al endpoint /api/chat junto con los datos del país y los departamentos. Valida que la respuesta sea exitosa y contenga texto; si algo falla, lanza errores descriptivos como "no se pudo generar respuesta del chatbot" o "el servicio devolvió una respuesta vacía".
  • generateChatResponse: también asíncrona y exportada como función pública. Aplica dos validaciones antes de llamar a la API: que la pregunta no esté vacía y que los datos estén listos. Si todo está bien, delega en askGeminiAPI y retorna la respuesta.

Esta separación de responsabilidades es intencional. Una función se encarga de la comunicación HTTP y otra de la validación y orquestación, lo que hace el código más mantenible y testeable.

¿Qué conceptos de asincronía se aplican en todo el proyecto?

El chatbot es la pieza final de un recorrido completo por la asincronía en JavaScript [4:50]. Todo parte de entender que JavaScript tiene un solo hilo de ejecución, y eso no es una limitación sino una decisión de diseño. El call stack, el event loop y las dos colas de tareas permiten que una sola línea de ejecución maneje peticiones, eventos y animaciones sin bloquearse.

El proyecto aplica cada concepto en su lugar correcto:

  • await donde hay que esperar una respuesta externa.
  • Lógica síncrona donde no hay que esperar.
  • Promise.all para ejecutar en paralelo y no desperdiciar tiempo.
  • try-catch para capturar errores sin dejar fallos sin manejar.

Los callbacks fueron el primer intento para manejar asincronía, pero el callback hell era una limitación estructural del patrón [5:10]. Las promesas resolvieron esto con ciclo de vida, encadenamiento y manejo centralizado de errores. Y async await no reemplazó las promesas, las envolvió: es el sugar syntax que hace que el código asíncrono se lea de arriba hacia abajo como si fuera síncrono.

Lo más valioso es que este modelo no se queda en JavaScript. Async await existe en Python, C#, Rust y Swift [6:00]. El concepto es universal: iniciar una tarea, registrar qué hacer cuando esté lista y no bloquear mientras tanto.

¿Has conectado algún modelo de AI a tus proyectos? Comparte tu experiencia y las decisiones de arquitectura que tomaste.