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?
- Usar Angular 18 y Kendo AI Prompt para construir una interfaz limpia.
- Usar Gemini Nano en Chrome Canary para interactuar con el LLM.
¡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-nanochrome://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 installKendo 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
AIPromptModuleen 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:
- Crear un archivo
index.d.tsdentro de la carpetasrc/types. - Extender la interfaz global
Windowy 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:
Modern frontend development — Angular, React, TypeScript, accessibility, and performance.
Artículos Relacionados
Dockerizar Next.js: Los desafíos ocultos
Vercel oculta la complejidad de las variables de entorno. Cuando pasas a Docker, estos desafíos ocultos salen a la luz. Aprende la arquitectura para escalar tu aplicación correctamente.
Cómo crear un ChatBot con Gemini, Kendo UI y Angular 17
Un amigo me dijo una vez que conectar un chat con IA era difícil, pero no es así. Hoy quiero mostrarte lo fácil que resulta construir tu propio chat con Gemini, Kendo UI y Angular 17 usando solo unas pocas líneas de código.
Lo que aprendí: de demos de chat con IA a productos reales de IA
En 2025 creé varias demos combinando Gemini y Kendo UI para prototipar experiencias de chat rápidas. Aquí comparto lo que aprendí al pasar de simples demos a productos reales con IA.
Cómo usar ng-template, ng-container y ng-content en Angular (Guía completa)
Aprende las diferencias exactas entre ng-template, ng-container y ng-content en Angular, cómo pasar contexto con ngTemplateOutlet, proyección con múltiples slots y cómo evolucionan con el control flow moderno de @if, @for y @defer.
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.
Únete a 13,800+ desarrolladores y lectores.
Cero spam. Cancela tu suscripción en cualquier momento.