Untuk menggunakan Gemini Nano di aplikasi Capacitor, instal @capgo/capacitor-llm, panggil setModel({ path: 'Gemini Nano' }) di Android, lalu buat chat dan stream balasannya melalui textFromAi event. Plugin ini berkomunikasi dengan Gemini Nano melalui Google ML Kit GenAI Prompt API, yang menjalankan model di dalam sistem service AICore Android, sehingga teks tidak pernah keluar dari ponsel.
Panduan ini membahas cara kerja Gemini Nano, perangkat yang mendukungnya, pemanggilan plugin secara spesifik, streaming, kuota dan limit, fallback Gemma untuk ponsel yang tidak didukung, serta bagaimana code yang sama menjangkau Apple Intelligence di iOS.
Cara kerja Gemini Nano di Android
Gemini Nano adalah model Gemini terkecil dari Google, yang dirancang untuk ponsel. Aplikasi tidak perlu melakukan bundle model ini. Service AICore Android akan mengunduh, memperbarui, dan menjalankan inference, dan aplikasi dapat mengaksesnya melalui API ML Kit GenAI:
- Prompt API: prompt teks bebas, API yang digunakan plugin ini (
com.google.mlkit:genai-prompt). - Fitur API: tugas tetap seperti ringkasan, proofreading, rewriting, dan deskripsi gambar.
Google merilis Prompt API sebagai versi beta, tanpa SLA atau kebijakan deprecation, jadi antisipasi adanya perubahan perilaku antar rilis dan bungkus integrasi Anda dengan wrapper sendiri.
Karena inferensi dilakukan secara lokal, Anda mendapatkan tiga hal yang tidak bisa diberikan model cloud: bisa bekerja offline, tanpa biaya per-token, dan teks pengguna tetap di perangkat. Kompensasinya adalah model yang lebih kecil dengan context dan output yang terbatas, jadi pilih tugas yang sesuai: menulis ulang, meringkas catatan, klasifikasi pesan, ekstraksi field, atau membuat draf balasan singkat.
Perangkat yang didukung dan persyaratan
Google memublikasikan daftar perangkat yang didukung per API di situs ML Kit GenAI, dikelompokkan berdasarkan versi Gemini Nano (nano-v2, nano-v3, nano-v4). Untuk Prompt API, ini mencakup Pixel 9 ke atas, flagship Samsung Galaxy S dan Z terbaru, serta flagship terbaru dari OnePlus, OPPO, Xiaomi, vivo, Honor, realme, Motorola, dan lainnya. Cek daftar terbarunya sebelum menjanjikan fitur pada perangkat tertentu.
Setiap perangkat yang didukung juga memerlukan:
| Persyaratan | Detail |
|---|---|
| Versi Android | API level 26 atau lebih tinggi (plugin akan mengecek ini) |
| Bootloader | Locked. Google tidak mendukung GenAI API pada bootloader yang unlocked |
| AICore | Sudah ada dan disiapkan. Tepat setelah setup atau reset perangkat, proses ini bisa memakan waktu. |
| Status aplikasi | Aplikasi Anda harus berada di foreground teratas saat inference |
Versi Nano yang berbeda bisa menghasilkan output berbeda untuk prompt yang sama. Uji prompt Anda di minimal satu perangkat untuk tiap versi yang Anda pakai.
Instal plugin
bun add @capgo/capacitor-llm
bunx cap sync
Plugin ini mengikuti versi mayor Capacitor: gunakan 8.x dengan Capacitor 8. Tidak ada perubahan Android manifest yang diperlukan untuk Gemini Nano. Referensi lengkap: dokumentasi plugin dan halaman plugin.
Langkah 1: Muat Gemini Nano dan cek kesiapan
setModel dengan path khusus 'Gemini Nano' meminta status model ke ML Kit. Promise-nya resolve saat status tersedia dan reject jika tidak, dengan pesan yang menyertakan status tersebut:
| Status dari AICore | Perilaku plugin |
|---|---|
| tersedia | setModel selesai, readinessChange mengeluarkan ready |
| dapat diunduh | Ditolak: “Gemini Nano dapat diunduh tetapi belum diunduh di perangkat ini” |
| sedang mengunduh | Rejects dengan status downloading |
| tidak tersedia | Ditolak: “Gemini Nano tidak tersedia di perangkat ini” |
import { Capacitor } from '@capacitor/core';
import { CapgoLLM } from '@capgo/capacitor-llm';
export async function loadGeminiNano(): Promise<boolean> {
if (Capacitor.getPlatform() !== 'android') return false;
try {
await CapgoLLM.setModel({
path: 'Gemini Nano',
temperature: 0.3,
topk: 16,
});
} catch (error) {
console.warn('Gemini Nano not ready:', error);
return false;
}
const { readiness } = await CapgoLLM.getReadiness();
return readiness === 'ready';
}
Plugin tidak memulai download model AICore sendiri. Jika perangkat melaporkan downloadable, model biasanya akan tersedia setelah aplikasi lain atau sistem memintanya, jadi cek kembali saat peluncuran berikutnya daripada menyembunyikan fitur ini secara permanen.
Langkah 2: Buat chat dan stream jawabannya
Chat menyimpan riwayat percakapan. Di Android, sendMessage resolve segera setelah generasi dimulai, dan teks masuk melalui event. Bungkus dalam promise yang resolve saat aiFinished:
import { CapgoLLM } from '@capgo/capacitor-llm';
// Android sends deltas. iOS Apple Intelligence sends the full text so far.
// This merge handles both.
function mergeChunk(current: string, chunk: string) {
return chunk.startsWith(current) ? chunk : current + chunk;
}
export async function ask(
chatId: string,
message: string,
onText: (textSoFar: string) => void,
): Promise<string> {
let text = '';
let finish!: (value: string) => void;
let fail!: (error: Error) => void;
const done = new Promise<string>((resolve, reject) => {
finish = resolve;
fail = reject;
});
const handles = await Promise.all([
CapgoLLM.addListener('textFromAi', (event) => {
if (event.chatId !== chatId) return;
text = mergeChunk(text, event.text);
onText(text);
}),
CapgoLLM.addListener('aiFinished', (event) => {
if (event.chatId === chatId) finish(text);
}),
CapgoLLM.addListener('generationError', (event) => {
if (!event.chatId || event.chatId === chatId) fail(new Error(event.error));
}),
]);
// If the app is backgrounded mid-answer, neither event may arrive
const timeout = setTimeout(() => fail(new Error('Generation timed out')), 60_000);
try {
await CapgoLLM.sendMessage({ chatId, message });
return await done;
} finally {
clearTimeout(timeout);
await Promise.all(handles.map((h) => h.remove()));
}
}
Gunakan untuk fitur nyata, misalnya membuat draf balasan ulasan pelanggan:
const INSTRUCTIONS =
'You write short, polite replies to customer reviews for a small shop. ' +
'Answer each point, stay under 60 words, never promise refunds.';
export async function draftReply(review: string, render: (t: string) => void) {
const { id } = await CapgoLLM.createChat();
return ask(id, `${INSTRUCTIONS}\n\nReview:\n${review}\n\nReply:`, render);
}
createChat() tidak memerlukan opsi, jadi masukkan instruksi di awal pesan pertama. Buat chat baru per tugas. Pada jalur Gemini Nano, plugin menyimpan riwayat di memori dan mengirimnya di setiap pesan, sehingga chat panjang akan menghabiskan kuota input dengan cepat.
Batasan desain untuk
| Limit | Nilai | What to do |
|---|---|---|
| Input | Sekitar 4.000 token per request (Google) | Jaga chat tetap pendek, ringkas dokumen panjang |
| Output | Plugin ini membatasi respons Gemini Nano hingga 256 token | Minta output pendek, bagi tugas panjang |
| Foreground | Inferensi hanya saat aplikasi di foreground | Jangan jalankan dari background task |
| Kuota | Kuota per aplikasi, BUSY dan error kuota baterai |
Gunakan debounce, hindari generate di setiap keystroke |
| Concurrency | Satu generasi per chat | Nonaktifkan tombol kirim saat streaming |
| Kecepatan | Beberapa detik per paragraf | Selalu stream ke UI |
Anggap error kuota sebagai masalah sementara. Tampilkan opsi retry alih-alih dialog error.
Fallback: Gemma 4 jika Gemini Nano tidak ada
Kebanyakan ponsel Android saat ini belum memiliki Gemini Nano. Plugin yang sama dapat menjalankan model open Gemma melalui LiteRT-LM, jadi Anda tetap menggunakan satu API. Modelnya berukuran besar, sering kali lebih dari satu gigabyte, jadi download hanya setelah user setuju, idealnya via Wi-Fi.
import { Preferences } from '@capacitor/preferences';
import { CapgoLLM } from '@capgo/capacitor-llm';
const GEMMA_URL =
'https://huggingface.co/litert-community/gemma-4-E2B-it-litert-lm/resolve/main/gemma-4-E2B-it.litertlm?download=true';
export async function loadGemma(onProgress: (pct: number) => void) {
const saved = await Preferences.get({ key: 'gemmaPath' });
if (saved.value) {
try {
await CapgoLLM.setModel({ path: saved.value, modelType: 'litertlm', maxTokens: 4096 });
return;
} catch {
// File missing or corrupt, download again
}
}
const sub = await CapgoLLM.addListener('downloadProgress', (e) => onProgress(e.progress));
try {
const { path } = await CapgoLLM.downloadModel({
url: GEMMA_URL,
filename: 'gemma-4-E2B-it.litertlm',
});
await Preferences.set({ key: 'gemmaPath', value: path });
await CapgoLLM.setModel({ path, modelType: 'litertlm', maxTokens: 4096 });
} finally {
await sub.remove();
}
}
Lalu pilih engine saat startup:
export async function initOnDeviceAI(userAcceptedDownload: boolean, onProgress: (p: number) => void) {
if (await loadGeminiNano()) return 'gemini-nano';
if (userAcceptedDownload) {
await loadGemma(onProgress);
return 'gemma';
}
return 'none';
}
Jika keduanya tidak memungkinkan, sembunyikan fitur atau panggil model cloud. Jangan sampai local AI menghambat alur utama.
code yang sama di iOS
Di iOS, plugin menggunakan Apple Intelligence melalui framework Foundation Models. Ubah satu baris:
await CapgoLLM.setModel({ path: 'Apple Intelligence' });
createChat, sendMessage, dan event tetap sama, serta mergeChunk helper di atas sudah menangani format streaming iOS. Persyaratan perangkat berbeda (iOS 26 dan perangkat dengan Apple Intelligence). Panduan kami tentang Apple Intelligence di aplikasi Capacitor membahas bagian tersebut.
Pengujian
- Gunakan ponsel asli yang didukung. Emulator tidak menyediakan AICore dengan Gemini Nano.
- Catat
setModelpesan penolakan. Ini akan memberi tahu Anda status persis yang dilaporkan AICore. - Pada perangkat yang baru diatur atau di-reset, tunggu AICore menyelesaikan setup awal saat online, lalu coba lagi.
- Uji prompt Anda pada versi Nano terendah yang Anda dukung. Prompt yang lebih pendek dan eksplisit lebih stabil di berbagai versi.
Troubleshooting
“Gemini Nano tidak tersedia di perangkat ini”. Perangkat tidak ada dalam daftar Google, bootloader tidak terkunci, atau AICore belum diatur.
“Gemini Nano tersedia untuk diunduh, tapi belum diunduh”. Perangkat mendukungnya, tetapi model belum ada. Gunakan fallback Gemma atau coba lagi nanti.
“Sesi chat tidak ditemukan”. Anda memanggil sendMessage dengan chat yang dibuat sebelum setModelbaru. Memuat model akan menghapus chat yang ada, jadi buatlah chat baru.
“Model belum siap”. setModel gagal atau tidak dipanggil sebelum createChat.
Output terhenti di tengah kalimat. Anda mencapai batas output. Minta jawaban yang lebih pendek atau bagi tugasnya.
Error saat aplikasi masuk ke background. Inference hanya berjalan di foreground. Batalkan state UI saat pause dan biarkan user mencoba lagi.
Privasi dan peninjauan toko
Prompt dan respons tetap berada di perangkat dengan Gemini Nano, yang menyederhanakan formulir keamanan Data Anda. Ketentuan ML Kit Google masih menyebutkan pemrosesan metrik, jadi jelaskan penggunaan AI on-device di kebijakan privasi Anda. Jika Anda menambahkan fallback Gemma, pengunduhan model berasal dari Hugging Face, jadi sebutkan juga permintaan jaringan tersebut.
Prompt dan UI copy untuk fitur AI sering berubah. Jika Anda perlu menyesuaikannya setelah rilis, live updates Capgo memungkinkan Anda merilis web code baru tanpa menunggu peninjauan toko. Untuk gambaran lebih luas tentang AI di aplikasi hybrid, baca mengapa Capacitor bekerja baik untuk aplikasi mobile AI.
Kesimpulan
Gemini Nano memberikan aplikasi Capacitor kemampuan teks generation gratis, privat, dan offline di ponsel Android yang didukung. Muat dengan setModel({ path: 'Gemini Nano' }), stream melalui textFromAi, jaga prompt dan output tetap pendek, patuhi aturan foreground dan kuota, serta sediakan fallback Gemma atau cloud untuk banyak perangkat yang belum mendukungnya.