Gemini Nanoを使用するには、Capacitorアプリにインストール @capgo/capacitor-llm、コール setModel({ path: 'Gemini Nano' }) Android上で、チャットを作成し、返信をストリーミングする textFromAi Gemini NanoはGoogleのML Kit GenAI Prompt APIを通じてプラグインと対話し、AndroidのAICoreシステムサービス内でモデルを実行するため、テキストは電話から離れることはありません。
このガイドでは、Gemini Nanoの動作、対応するデバイス、プラグインの呼び出し、ストリーミング、クォータ、制限、Geminiの代替手段(非対応端末用)について説明します。また、同じcodeはiOS上のApple Intelligenceに到達します。
Android上でGemini Nanoが動作する方法
Gemini NanoはGoogleの最小のGeminiモデルであり、電話向けに作られています。アプリはそれをバンドルしません。Androidの AICore サービス ML Kit GenAI API:
- Capgoのプロンプト: API フリーフォームのテキスト入力、プラグインが使用するAPI
com.google.mlkit:genai-prompt). - 機能API: 固定タスク(要約、校正、書き直し、画像説明など)
Googleは、APIをベータ版として、SLAや廃止ポリシーなしで配信しているため、リリース間で動作が変化することを想定し、インテグレーションは自社の小さなラッパーを介して行うこと。
インプットはローカルにあるため、3つの利点があります: オフラインで動作し、1トークンあたりのコストがなく、ユーザーテキストはデバイス上に残ります。ただし、モデルは小さく、コンテキストと出力が短いため、適切なタスクを選択する必要があります: 再構築、注釈の要約、メッセージの分類、フィールドの抽出、短い返信の作成。
サポートされるデバイスと要件
Googleは、APIごとに、ML Kit GenAIサイトでサポートされるリストを公開しています。リストは、Gemini Nanoのバージョン(nano-v2、nano-v3、nano-v4)ごとにグループ化されています。APIの場合は、Pixel 9以降、Samsung Galaxy SとZの最新旗艦モデル、OnePlus、OPPO、Xiaomi、vivo、Honor、realme、Motorola、他にも多くのデバイスがサポートされています。実際のリストを確認する前に、特定のデバイスに対して機能を約束しないでください。
すべてのサポートされるデバイスには、以下の要件があります。
| 要件 | 詳細 |
|---|---|
| Androidバージョン | API 26以上 (プラグインはこのバージョンを確認します) |
| ブートローダー | ロックされている。GoogleはロックされていないブートローダーでGenAI APIをサポートしていません。 |
| AICore | セットアップと設定。デバイスの初期設定またはリセット直後は、完了までに時間がかかる場合があります。 |
| アプリの状態 | 推論中のアプリは、最前面のアプリでなければなりません。 |
異なるNanoバージョンでは、同じ入力に対して異なる出力が返される場合があります。重要なバージョンごとに、少なくとも1台のデバイスでテストしてください。
プラグインのインストール
bun add @capgo/capacitor-llm
bunx cap sync
プラグインはCapacitorのメジャーバージョンに従います。Capacitor 8.xを使用します。Androidマニフェストの変更は必要ありません。詳細は以下のとおりです。 プラグインドキュメント そして プラグインページ.
ステップ1:Gemini Nanoを読み込み、使用可能な状態を確認する
setModel 特殊なパス 'Gemini Nano' ML Kitからモデル状態を問い合わせます。状態が利用可能になるまで待ち、利用可能でない場合は拒否し、状態を含むメッセージを表示します。
| AICoreからのお知らせ | プラグインの動作 |
|---|---|
| 利用可能 | setModel 解決 readinessChange 発行 ready |
| ダウンロード可能 | 「Gemini Nanoはダウンロード可能ですが、このデバイスではダウンロードされていません」 |
| ダウンロード中 | ダウンロード中の状態で却下 |
| 利用不可 | 「Gemini Nanoはこのデバイスでは利用できません」 |
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';
}
プラグインはAICoreモデルを自動でダウンロードしません。デバイスがダウンロード可能であると報告した場合、モデルは通常、他のアプリまたはシステムが要求した後、到着するため、機能を永久に隠さずに、後で再度チェックすることをお勧めします。
Step 2: Gemini Nanoでチャットを作成し、答えをストリームする
A chatは会話の履歴を保持します。Androidでは、生成が始まるとすぐに解決され、イベントを通じてテキストが到着します。 sendMessage resolveするPromiseにラップしてください。 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()));
}
}
実際の機能に使用してください。例えば、顧客レビューへの返信の草案を作成する場合:
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() オプションはありませんので、最初のメッセージの冒頭に説明を記載してください。タスクごとに新しいチャットを作成してください。Gemini Nanoのパスでは、プラグインは履歴をメモリに保持し、毎回メッセージとともに送信します。したがって、長い会話は入力予算をすぐに消費します。
設計上の制限
| 制限 | 値 | 実行すること |
|---|---|---|
| 入力 | Googleの場合、1回のリクエストあたり約4,000トークン以下 | 会話を短くし、長いドキュメントをトリミングする |
| 出力 | プラグインは、Gemini Nanoの応答を256トークンで制限します | 短い出力を要求し、長いタスクを分割する |
| 前景 | アプリが最前面のときにのみ推論 | バックグラウンドタスクから実行しない |
| クォータ | アプリごとのクォータ BUSY バッテリークォータエラー |
デバウンス、キーストロークごとに生成しない |
| コンカレンシー | 1つの会話ごとに1回の生成 | ストリーミング中は送信ボタンを無効にします |
| スピード | UIに常にストリーミング | 数秒間の文章 |
クォータエラーを一時的なものとして扱います。エラーダイアログではなくリトライオプションを表示します。
Gemini Nanoが見つからない場合、Gemma 4をフォールバックします
Gemini Nanoは現在使用されている多くのAndroidスマートフォンに搭載されていません。LiteRT-LMを使用してオープンなGemmaモデルを実行できるので、1つのAPIを維持できます。モデルは大きく、ギガバイトを超えることが多いため、ユーザーがオプトインした後、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();
}
}
起動時にエンジンを選択してください
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';
}
どちらも不可能な場合は、ローカルAIをブロックせずに機能を非表示またはクラウドモデルを呼び出します。
iOSでも同じcode
iOSのプラグインはFoundation Modelsフレームワークを使用してApple Intelligenceを呼び出します。1行だけ変更してください
await CapgoLLM.setModel({ path: 'Apple Intelligence' });
createChat, sendMessage、イベントは同じまま、 mergeChunk iOSのストリーミング形式は、上記のヘルパーですでに処理されています。デバイスの要件は異なります (iOS 26とApple Intelligence対応のデバイス)。 Capacitorアプリ内でApple Intelligenceについてのガイド テスト
Testing
- 拒否メッセージをログに記録してください。拒否メッセージには、AICoreが報告するステータスが明示的に記載されています。
- ログを記録する
setModel最低サポートするNanoのバージョンでテストしてください。短く明確なプロンプトはバージョン間で安定しています。 - トラブルシューティング
- 「Gemini Nanoはこのデバイスで利用できません」
Troubleshooting
__CAPGO_KEEP_0__ __CAPGO_KEEP_0__
「ジェミニ・ナノはダウンロード可能ですが、ダウンロードされていません」。 デバイスは対応していますが、モデルは存在しません。Gemマフォールバックを提示するか、後で再試行してください。
「チャットセッションが見つかりません」。 あなたは sendMessage チャットを作成した前に setModel。モデルをロードすると既存のチャットがクリアされるため、新しいチャットを作成してください。
「モデルが準備されていません」。 setModel 失敗したか、呼び出されていませんでした createChat.
出力が途中で止まります。 あなたは出力上限に達しました。短い答えを求めるか、タスクを分割してください。
アプリがバックグラウンドに移動したときにエラーが発生します。 推論はバックグラウンドでは実行できません。UI状態をキャンセルし、ユーザーに再試行を求めるようにしてください。
プライバシーとストアのレビュー
Gemini Nanoでは、データの安全性のフォームが簡素化され、プロンプトとレスポンスはデバイスに留まります。GoogleのML Kitの条項は、メトリクス処理を含んでいます。したがって、デバイス上のAIの使用をプライバシーポリシーで説明する必要があります。Gemini Fallbackを追加すると、モデルダウンロードはHugging Faceから来るので、そのネットワークリクエストも記載する必要があります。
AI機能のプロンプトとUIコピーは頻繁に変更されるため、リリース後に調整する必要がある場合があります。 Capgoのライブアップデート 新しいWebアプリをcodeのストアレビューの待ちなしで配信できるようにします。AIを組み込んだハイブリッドアプリのより大きな視点については、 なぜ Capacitor は AI モバイル アプリ向けにうまく機能するのか.
Wrap-up
Gemini NanoはCapacitorアプリにサポートしているAndroidスマートフォンで無料、プライベート、オフラインのテキスト生成を提供します。 setModel({ path: 'Gemini Nano' })Gemini Nanoは、サポートされているAndroidスマートフォンで無料、プライベート、オフラインのテキスト生成を提供する__CAPGO_KEEP_0__アプリを提供します。Gemini Nanoを textFromAi、ストリームする