Introducción

Alguna vez quisiste construir un chat interactivo con un modelo de lenguaje como Llama usando Ollama? En este artículo, te mostraré cómo crear un proyecto full stack que incluye un frontend dinámico y un backend basado en SAP CAP (Cloud Application Programming Model). ¡Vamos a ello!

Instalar Ollama

Para instalar Ollama, sigue estos pasos:

1. Descargar e instalar Ollama

Ve al sitio oficial de Ollama: https://ollama.com.
Descarga el instalador correspondiente a tu sistema operativo:

  • macOS: Descarga el archivo .dmg y sigue las instrucciones para instalarlo.
  • Windows: Descarga el archivo .exe y sigue las instrucciones del instalador.

2. Verificar la instalación

Una vez instalado, abre una terminal y ejecuta el siguiente comando para verificar que Ollama esté instalado correctamente:

ollama --version

Deberías ver la versión instalada de Ollama.

3. Configurar Ollama

Si necesitas configurar Ollama para que funcione con tu proyecto, asegúrate de que el servicio esté ejecutándose en el puerto correcto (por defecto, http://localhost:11434).

Puedes iniciar el servicio Ollama con:

ollama serve

Yo estoy usando este modelo: https://ollama.com/library/llama3.2:3b
Esto iniciará el servidor Ollama en tu máquina local.

Crear Backend

Vamos a crear un servicio SAP CAP lo más simple posible.
Lo ideal sería crear una clase o módulo y servicio con action, recoger el body con el prompt y pasarlo a llama, finalmente devolver el stream de respuestas, en caso de no necesitar un preprocesado de respuestas.

service ChatService {

    action chat(prompt: String) returns String;

}
try {
      const ollamaRes = await axios({
        method: "POST",
        url: "http://localhost:11434/api/chat",
        responseType: "stream",
        headers: {
          "Content-Type": "application/json",
        },
        data: {
          model: "llama3.2:3b",
          stream: true,
          messages: [{ role: "user", content: prompt }],
        },
      });

      // Detectamos cuando realmente se termina el stream
      finished(ollamaRes.data, () => {
        console.log("🧠 PROMPT:", prompt);
        console.log("💬 RESPUESTA COMPLETA:", fullResponse);
        console.log("✅ Fin real del stream");
        safeEnd();
      });
      let fullResponse = "";
      ollamaRes.data.on("data", (chunk) => {
        if (closed || ended) return;

        const lines = chunk.toString().split("\n").filter(Boolean);
        for (const line of lines) {
          if (closed || ended) break;

          try {
            const json = JSON.parse(line);
            const content = json.message?.content;
            if (content) {
              fullResponse += content;
              safeWrite(`data: ${content}`);
            }
          } catch (_) {
            // Línea malformada (keep-alive o vacía)
          }
        }
      });

Prueba backend

Imagen de prueba backend

Crear Frontend

El objetivo es enviar los prompt del usuario, mostrar los mensajes del usuario y la respuesta que llega del servicio de SAP CAP de forma relativamente moderna.

Prueba frontend

imagen de frontend final

Conclusiones

Lo más jodido es aprender a tratar los streams, personalmente no suelo trabajar con streams, es mas usual trabajar de forma en la que obtienes la respuesta completa, ollama tiene una cabecera para que se devuelva la respuesta de esta forma sin embargo me apetecía montar ese efecto de escritura cuando responde el bot.

Repo con mi código por si te sirve de algo :D https://github.com/Betheval/sap-cap-ollama-iachat