🇺🇸 EN
Frontend
·9 min read·↗·🇺🇸 EN

Cómo crear un chatbot de IA local con Gemini Nano, Chrome Canary, Angular y Kendo AI Prompt

Portada principal del artículo: Cómo crear un chatbot de IA local con Gemini Nano, Chrome Canary, Angular y Kendo AI Prompt

La carrera de la IA continúa. Alternativas como Ollama nos ayudan a interactuar con modelos de IA en nuestras propias máquinas. Sin embargo, los equipos de Chrome y Google han dado un paso más allá al integrar Gemini Nano para ejecutarse directamente en el navegador.

Nota: Esta API es experimental y funciona en Chrome Canary.

El equipo de Chrome está trabajando para tener un LLM pequeño en nuestro navegador para realizar tareas comunes y sencillas sin necesidad de una API externa como OpenAI ni de ejecutar Ollama. La API nos ayuda con tareas como resumir, clasificar y reformular texto. Podemos leer la documentación sobre la API, pero un caso práctico es la mejor forma de aprender y verla en acción.

Caso de uso

Trabajamos en una empresa que quiere crear una prueba de concepto (POC) para interactuar con tareas comunes en un modelo LLM. Nuestro objetivo es tener un chat donde los usuarios puedan hacer preguntas o elegir entre una lista de preguntas sugeridas.

¿Cómo podemos lograrlo?

¡Manos a la obra!

Habilitar Gemini Nano en Chrome Canary

Primero, descarga e instala Chrome Canary desde https://www.google.com/chrome/canary/. Después de instalarlo, debemos habilitar la Prompt API para Gemini Nano.

Luego, activa Gemini Nano en el navegador mediante las siguientes flags:

  • chrome://flags/#prompt-api-for-gemini-nano
  • chrome://flags/#optimization-guide-on-device-model

Después de activar estas opciones, recuerda reiniciar Chrome.

Gemini Nano tarda un poco en descargarse. Para confirmar que ya está listo, abre Chrome Canary y navega a chrome://components. Comprueba si el componente Optimization Guide On Device Model muestra la versión 2024.6.5.2205.

Nota: Gracias al feedback de @Bezael Pérez, asegúrate de tener al menos 2 GB de espacio libre en tu equipo.

Con el modelo listo, ya podemos empezar a escribir código. ¡Vamos a ello!

Configurar el proyecto

Primero, crea la aplicación de Angular con el comando ng new gemini-nano-angular:

ng new gemini-nano-angular
cd gemini-nano-angular
npm install

Kendo UI ofrece un comando de schematics para registrar fácilmente su Conversational UI de Angular en nuestro proyecto.

Estoy usando Kendo UI con su prueba gratuita de 30 días, que incluye soporte técnico y formación sin necesidad de tarjeta de crédito.

ng add @progress/kendo-angular-conversational-ui
ℹ Using package manager: npm
✔ Found compatible package version: @progress/kendo-angular-conversational-ui@16.3.0.
✔ Package information loaded.
 
The package @progress/kendo-angular-conversational-ui@16.3.0 will be installed and executed.
Would you like to proceed? Yes
✔ Packages successfully installed.
UPDATE package.json (1663 bytes)
UPDATE angular.json (2893 bytes)
✔ Packages installed successfully.
UPDATE src/main.ts (295 bytes)
UPDATE tsconfig.app.json (455 bytes)
UPDATE tsconfig.spec.json (461 bytes)
UPDATE angular.json (2973 bytes)

Perfecto, ya tenemos todo configurado. Ahora pasemos a crear la interfaz de chat con Kendo AI Prompt.

Cómo usar AI Prompt

Queremos construir una interfaz limpia para interactuar con el LLM, por lo que decidí usar AI Prompt. Este componente de Kendo UI nos permite crear una interfaz moderna y atractiva para interactuar con modelos de lenguaje. Además, incluye acciones habituales listas para usar, como copiar, reintentar o calificar la respuesta.

Recomiendo revisar la documentación oficial, que cuenta con demos muy completas.

El componente kendo-aiprompt incluye un conjunto de subcomponentes y propiedades. Primero, abre app.component.html, elimina el marcado HTML por defecto y añade dos componentes: kendo-aiprompt-prompt-view y kendo-aiprompt-output-view.

Recuerda agregar AIPromptModule en la sección de imports del componente.

Personalizamos el botón de kendo-aiprompt-prompt-view con la propiedad buttonText configurada como "☺️ Ask your question".

 <h2>Free Local Gemini</h2>
<kendo-aiprompt>
  <kendo-aiprompt-prompt-view
    [buttonText]="'☺️ Ask your question'"
 />
  <kendo-aiprompt-output-view/>
</kendo-aiprompt>

Guarda los cambios y ejecuta ng serve -o. ¡Y listo! 🎉 Ya tenemos nuestra interfaz limpia de chatbot en marcha:

Ahora toca personalizar el componente kendo-aiprompt para permitir alternar entre vistas, definir sugerencias predeterminadas y, por supuesto, manejar las respuestas (promptOutputs) y peticiones (promptRequest).

Personalizar AIPrompt

Abre app.component.ts. Aquí realizaremos los siguientes pasos. Primero, declaramos las propiedades que vincularemos al componente <kendo-aiprompt> para configurarlo y reaccionar a los eventos:

  • view: para cambiar entre las distintas vistas.
  • promptOutputs: para almacenar y mostrar las respuestas generadas por el LLM.
  • suggestions: una lista de sugerencias de texto predeterminadas para el usuario.

Por último, creamos un método vacío llamado onPromptRequest para capturar el texto emitido por kendo-aiprompt. El código queda de la siguiente manera:

export class AppComponent {
 
  public view: number = 0;
  public promptOutputs: Array<PromptOutput> = [];
 
  public suggestions: Array<string> = [
    'Tell me a short joke',
    'Tell me about Dominican Republic'
  ]
 
 
  public onPromptRequest(ev: PromptRequestEvent): void {
      console.log(ev)
  }
}

Ahora pasamos a app.component.html y vinculamos kendo-aiprompt con las propiedades y el método que acabamos de crear:

<h2>Free Local Gemini</h2>
<kendo-aiprompt
  [(activeView)]="view"
  [promptSuggestions]="suggestions"
  [promptOutputs]="promptOutputs"
  (promptRequest)="onPromptRequest($event)"
>
  <kendo-aiprompt-prompt-view
    [buttonText]="' ☺️ Ask your question'"
 />
 
  <kendo-aiprompt-output-view/>
</kendo-aiprompt>

Ya tenemos el componente visual listo, pero ¿qué hay de Gemini y el LLM? Para conectar con el modelo local, necesitamos crear un servicio de Angular que interactúe con la nueva API window.ai.

Cómo usar la API window.ai

Primero, crea un servicio usando el CLI de Angular con ng g s services/gemini-nano y abre el archivo gemini-nano.service.ts.

A continuación, declaramos una variable privada #system_prompt. Esta variable añade instrucciones adicionales al prompt para guiar al LLM:

import {Injectable} from '@angular/core';
 
@Injectable({providedIn: 'root'})
export class GeminiNanoService {
 
  #system_prompt = 'answer in plain text without markdown style'
 
}

Después creamos el método generateText, que recibe una pregunta en formato string. Este método devolverá una promesa con la respuesta de la API window.ai. Envolvemos el cuerpo del método en un bloque try-catch para capturar cualquier error si el usuario no está usando Chrome Canary o no tiene la API activa.

La API window.ai ofrece varios métodos, pero en este ejemplo utilizo createTextSession para iniciar una sesión con el modelo local, la cual nos devuelve una instancia para enviarle prompts.

Creamos una variable textSession para almacenar el resultado de window.ai.createTextSession():

try {
     const textSession = await window.ai.createTextSession();
     
   }
   catch (err){
     return 'Ups! please use chrome canary and enable IA features'
   }

Al intentar compilar, me encontré con un problema: TypeScript no reconoce window.ai y muestra el error: Property 'ai' does not exist on type 'Window & typeof globalThis'.

El error: Property does not exist on type Window & typeof globalThis

Al trabajar con el tipo global Window, su definición proviene de lib.dom. Como la propiedad ai aún no existe en los tipos oficiales de TypeScript, obtenemos el error TS2339: Property ai does not exist on type Window & typeof globalThis.

Para solucionarlo, solo debemos seguir estos dos pasos:

  1. Crear un archivo index.d.ts dentro de la carpeta src/types.
  2. Extender la interfaz global Window y declarar los tipos necesarios para la API de IA. En mi caso, declaré los métodos indispensables para este ejemplo.

¿Cuáles son los métodos disponibles en window.ai? Si abres las herramientas de desarrollo en Chrome Canary y escribes window.ai, verás la lista completa:

A partir de esa lista, definimos las interfaces para cada método. Para ahorrarte tiempo, aquí tienes la declaración de tipos completa:

export {};
 
declare global {
  interface AISession {
    promptStreaming: (prompt: string) => AsyncIterableIterator<string>;
    prompt: (prompt: string) => Promise<string>;
    destroy: () => void;
  }
  interface AI {
    canCreateGenericSession: () => Promise<string>;
    canCreateTextSession: () => Promise<string>;
    createGenericSession: () => Promise<AISession>;
    createTextSession: () => Promise<AISession>;
    defaultGenericSessionOptions: () => object;
    defaultTextSessionOptions: () => object;
  }
  interface Window {
    ai: AI
  }
}

Por último, agregamos la referencia a la carpeta de tipos en tsconfig.json:

  "typeRoots": [
      "src/types"
    ]

Con los tipos listos en TypeScript, podemos continuar completando nuestro servicio.

El objeto textSession nos proporciona el método prompt para interactuar con el modelo. Antes de enviar la pregunta del usuario, la combinamos con el prompt del sistema (#system_prompt) para obtener una respuesta en texto plano. Luego enviamos el texto a session.prompt y retornamos la promesa.

El código final del servicio queda así:

import {Injectable} from '@angular/core';
 
@Injectable({providedIn: 'root'})
export class GeminiNanoService {
 
  #system_prompt = 'answer in plain text without markdown style'
 
 async generateText(question: string): Promise<string> {
   try {
     const textSession = await window.ai.createTextSession();
      const prompt_question = `${question} ${this.#system_prompt}`;
     return await textSession.prompt(prompt_question);
   }
   catch (err){
     return 'Ups! please use chrome canary and enable IA features'
   }
 
  }
}

Ya tenemos nuestro servicio preparado, así que llegó el momento de conectarlo con la interfaz de Kendo AI Prompt para darle vida al chat.

Interactuar con el LLM

Estamos en el paso final, así que solo necesitamos hacer un par de ajustes en app.component.ts. Primero, inyectamos el servicio GeminiNanoService.

Luego, modificamos el método onPromptRequest: llamamos a generateText pasando la pregunta del usuario y esperamos la respuesta. Cuando la promesa se resuelve, creamos un objeto PromptOutput, lo agregamos al inicio del arreglo promptOutputs con unshift y cambiamos la vista activa a 1 para mostrar el resultado.

El código final queda de la siguiente manera:

import {Component, inject} from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {GeminiNanoService} from "./services/gemini-nano.service";
import {
  AIPromptModule, PromptOutput,
  PromptRequestEvent
} from "@progress/kendo-angular-conversational-ui";
 
@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, AIPromptModule],
  templateUrl: './app.component.html',
  styleUrl: './app.component.css'
})
export class AppComponent {
 
  public view: number = 0;
  public promptOutputs: Array<PromptOutput> = [];
 
  public suggestions: Array<string> = [
    'Tell me a short joke',
    'Tell me about dominican republic'
  ]
    private nanoService = inject(GeminiNanoService)
 
  public onPromptRequest(ev: PromptRequestEvent): void {
    this.nanoService.generateText(ev.prompt).then((v) => {
      const output: PromptOutput = {
        id: Math.random(),
        prompt: ev.prompt,
        output: v,
      }
      this.promptOutputs.unshift(output);
      this.view = 1;
    }
 
  )
  }
 
}

Guarda los cambios en el proyecto. ¡Ahora ya puedes interactuar con Gemini Nano directamente en Chrome Canary!

Conclusión

En este artículo aprendimos a usar Gemini Nano, un modelo LLM local y experimental que corre directamente dentro de Chrome Canary. Construimos una aplicación de chat con Angular 18 y el componente Conversational AI Prompt de Kendo UI, logrando ejecutar un chatbot local con muy pocas líneas de código.

Esto es solo el comienzo. Te recomiendo consultar los recursos oficiales para conocer más detalles sobre la API de IA integrada en el navegador:

Parte de la serie Frontend

Modern frontend development — Angular, React, TypeScript, accessibility, and performance.

Ver serie completa

Artículos Relacionados

Compartir este artículo

Si esta guía te resultó útil, compártela con tu equipo o con otros desarrolladores.


Software real. Lecciones reales.

Comparto las lecciones que aprendí por las malas, para que puedas evitarlas o estar preparado cuando ocurran.

User avatar
User avatar
User avatar
User avatar
+13K

Únete a 13,800+ desarrolladores y lectores.

Cero spam. Cancela tu suscripción en cualquier momento.