コンテンツへスキップ

はじめに

Terminal window
npm install @capgo/capacitor-llm
npx cap sync
  • iOS 26.0+: デフォルトでApple Intelligenceを使用(モデル不要) - 推奨
  • iOS < 26.0: MediaPipeカスタムモデルが必要(実験的、互換性の問題がある場合があります)

古いiOSバージョンでカスタムモデルを使用する場合は、XcodeのCopy Bundle Resourcesを通じてモデルファイルをiOSアプリバンドルに配置します。

モデルファイルをAndroidアセットフォルダーに配置します:

android/app/src/main/assets/

Androidには両方のファイルが必要です:

  • .taskファイル(メインモデル)
  • .litertlmファイル(コンパニオンファイル)

Kaggle Gemmaモデルからダウンロード → “LiteRT (formerly TFLite)“タブ

  • Gemma 3 270M - 最小、モバイルに最も効率的(約240-400MB) - 推奨
  • Gemma 3 1B - より大きなテキスト生成モデル(約892MB-1.5GB)

Kaggle Gemmaモデルからダウンロード → “LiteRT (formerly TFLite)“タブをクリック

  • Apple Intelligence (iOS 26.0+) - 組み込み、ダウンロード不要 - 推奨
  • Gemma-2 2B (実験的) - .task形式との互換性の問題がある場合があります

カスタムiOSモデルの場合は、Hugging Face MediaPipeモデルからダウンロード

プラグインをインポートして初期化:

import { CapgoLLM } from '@capgo/capacitor-llm';
import { Capacitor } from '@capacitor/core';
// LLMが準備できているか確認
const { readiness } = await CapgoLLM.getReadiness();
console.log('LLM readiness:', readiness);
// プラットフォームに基づいてモデルを設定
const platform = Capacitor.getPlatform();
if (platform === 'ios') {
// iOS: Apple Intelligenceを使用(デフォルト)
await CapgoLLM.setModel({ path: 'Apple Intelligence' });
} else {
// Android: MediaPipeモデルを使用
await CapgoLLM.setModel({ path: '/android_asset/gemma-3-270m-it-int8.task' });
}
// チャットセッションを作成
const { id: chatId } = await CapgoLLM.createChat();
// AI応答をリッスン
CapgoLLM.addListener('textFromAi', (event) => {
console.log('AI response:', event.text);
});
// 完了をリッスン
CapgoLLM.addListener('aiFinished', (event) => {
console.log('AI completed response');
});
// メッセージを送信
await CapgoLLM.sendMessage({
chatId,
message: 'Hello! How are you today?'
});
// URLからモデルをダウンロード
await CapgoLLM.downloadModel({
url: 'https://example.com/model.task',
filename: 'model.task'
});
// Androidの場合、.taskと.litertlmの両方のファイルをダウンロード
await CapgoLLM.downloadModel({
url: 'https://example.com/gemma-3-270m-it-int8.task',
companionUrl: 'https://example.com/gemma-3-270m-it-int8.litertlm',
filename: 'gemma-3-270m-it-int8.task'
});
// ダウンロード進行状況をリッスン
CapgoLLM.addListener('downloadProgress', (event) => {
console.log(`Download progress: ${event.progress}%`);
console.log(`Downloaded: ${event.downloadedBytes} / ${event.totalBytes}`);
});
// 設定付きで特定のモデルを設定
await CapgoLLM.setModel({
path: '/android_asset/gemma-3-270m-it-int8.task',
maxTokens: 2048,
topk: 40,
temperature: 0.8
});
// 準備状態をチェック
const { readiness } = await CapgoLLM.getReadiness();
if (readiness === 'ready') {
// モデルが読み込まれて準備完了
}
// 準備状態の変更をリッスン
CapgoLLM.addListener('readinessChange', (event) => {
console.log('Readiness changed:', event.readiness);
});

新しいチャットセッションを作成します。

const { id: chatId } = await CapgoLLM.createChat();

戻り値: Promise<{ id: string; instructions?: string }>

LLMにメッセージを送信します。

await CapgoLLM.sendMessage({
chatId: 'chat-id',
message: 'What is the weather like?'
});
パラメータタイプ説明
chatIdstringチャットセッションID
messagestring送信するメッセージ

LLMが使用可能かチェックします。

const { readiness } = await CapgoLLM.getReadiness();

戻り値: Promise<{ readiness: string }>

可能な値:

  • ready - モデルが読み込まれて準備完了
  • loading - モデルを読み込み中
  • not_ready - モデルがまだ読み込まれていない
  • error - モデルの読み込みエラー

モデル設定を設定します。

// iOS: Apple Intelligenceを使用(推奨)
await CapgoLLM.setModel({
path: 'Apple Intelligence'
});
// iOS: カスタムMediaPipeモデルを使用(実験的)
await CapgoLLM.setModel({
path: 'Gemma2-2B-IT_multi-prefill-seq_q8_ekv1280',
modelType: 'task',
maxTokens: 1280
});
// Android: MediaPipeモデルを使用
await CapgoLLM.setModel({
path: '/android_asset/gemma-3-270m-it-int8.task',
maxTokens: 2048,
topk: 40,
temperature: 0.8
});
パラメータタイプ説明
pathstringモデルパスまたはiOSシステム用の”Apple Intelligence”
modelTypestringオプション: モデルファイルタイプ(例: “task”、“bin”)
maxTokensnumberオプション: モデルが処理する最大トークン
topknumberオプション: 各ステップで考慮されるトークンの数
temperaturenumberオプション: 生成のランダム性(0.0-1.0)
randomSeednumberオプション: 生成用のランダムシード

URLからモデルをダウンロードしてデバイスストレージに保存します。

await CapgoLLM.downloadModel({
url: 'https://example.com/gemma-3-270m-it-int8.task',
companionUrl: 'https://example.com/gemma-3-270m-it-int8.litertlm',
filename: 'gemma-3-270m-it-int8.task'
});
パラメータタイプ説明
urlstringダウンロード元のURL
companionUrlstringオプション: コンパニオンファイルのURL(.litertlm)
filenamestringオプション: 保存するファイル名

戻り値: Promise<{ path: string; companionPath?: string }>

AIがテキストを生成したときに発火(ストリーミング応答)。

CapgoLLM.addListener('textFromAi', (event) => {
console.log('AI text:', event.text);
console.log('Chat ID:', event.chatId);
console.log('Is chunk:', event.isChunk);
});

イベントデータ:

  • text (string) - AIからの増分テキストチャンク
  • chatId (string) - チャットセッションID
  • isChunk (boolean) - 完全なチャンクか部分的なストリーミングデータか

AIが応答を完了したときに発火。

CapgoLLM.addListener('aiFinished', (event) => {
console.log('Completed for chat:', event.chatId);
});

イベントデータ:

  • chatId (string) - チャットセッションID

モデルのダウンロード中に進行状況を報告するために発火。

CapgoLLM.addListener('downloadProgress', (event) => {
console.log('Progress:', event.progress, '%');
console.log('Downloaded:', event.downloadedBytes, '/', event.totalBytes);
});

イベントデータ:

  • progress (number) - ダウンロード完了のパーセンテージ(0-100)
  • downloadedBytes (number) - これまでにダウンロードされたバイト
  • totalBytes (number) - ダウンロードする総バイト

LLMの準備状態が変更されたときに発火。

CapgoLLM.addListener('readinessChange', (event) => {
console.log('Readiness changed to:', event.readiness);
});

イベントデータ:

  • readiness (string) - 新しい準備状態
import { CapgoLLM } from '@capgo/capacitor-llm';
import { Capacitor } from '@capacitor/core';
class AIService {
private chatId: string | null = null;
private messageBuffer: string = '';
async initialize() {
// プラットフォームに基づいてモデルを設定
const platform = Capacitor.getPlatform();
if (platform === 'ios') {
// iOS: Apple Intelligenceを使用(推奨)
await CapgoLLM.setModel({ path: 'Apple Intelligence' });
} else {
// Android: MediaPipeモデルを使用
await CapgoLLM.setModel({
path: '/android_asset/gemma-3-270m-it-int8.task',
maxTokens: 2048,
topk: 40,
temperature: 0.8
});
}
// モデルの準備を待つ
let isReady = false;
while (!isReady) {
const { readiness } = await CapgoLLM.getReadiness();
if (readiness === 'ready') {
isReady = true;
} else if (readiness === 'error') {
throw new Error('Failed to load model');
}
await new Promise(resolve => setTimeout(resolve, 500));
}
// チャットセッションを作成
const { id } = await CapgoLLM.createChat();
this.chatId = id;
// イベントリスナーを設定
this.setupListeners();
}
private setupListeners() {
CapgoLLM.addListener('textFromAi', (event) => {
if (event.chatId === this.chatId) {
this.messageBuffer += event.text;
this.onTextReceived(event.text);
}
});
CapgoLLM.addListener('aiFinished', (event) => {
if (event.chatId === this.chatId) {
this.onMessageComplete(this.messageBuffer);
this.messageBuffer = '';
}
});
}
async sendMessage(message: string) {
if (!this.chatId) {
throw new Error('Chat not initialized');
}
await CapgoLLM.sendMessage({
chatId: this.chatId,
message
});
}
onTextReceived(text: string) {
// ストリーミングテキストでUIを更新
console.log('Received:', text);
}
onMessageComplete(fullMessage: string) {
// 完全なメッセージを処理
console.log('Complete message:', fullMessage);
}
}
// 使用法
const ai = new AIService();
await ai.initialize();
await ai.sendMessage('Tell me about AI');
プラットフォームサポート要件
iOSiOS 13.0+ (Apple Intelligenceの場合は26.0+)
AndroidAPI 24+
Webサポートされていません
  1. モデル選択: デバイスの能力に基づいてモデルを選択

    • ほとんどのモバイルデバイスには270Mを使用
    • より多くのRAMを持つハイエンドデバイスには1Bを使用
    • ターゲットデバイスでパフォーマンスをテスト
  2. メモリ管理: 完了時にチャットセッションをクリア

    // 新しい会話のために新しいチャットを作成
    const { id } = await CapacitorLLM.createChat();
  3. エラーハンドリング: 使用前に常に準備状態をチェック

    const { readiness } = await CapacitorLLM.getReadiness();
    if (readiness !== 'ready') {
    // 準備ができていない状態を処理
    }
  4. ストリーミングUI: ストリーミングテキストで段階的にUIを更新

    • onAiText経由で到着したテキストを表示
    • onAiCompletionで完了をマーク
  5. モデルのダウンロード: 最初の使用時ではなく、アプリのセットアップ中にモデルをダウンロード

    // アプリの初期化中
    await CapacitorLLM.downloadModel({
    url: 'https://your-cdn.com/model.task',
    filename: 'model.task'
    });
  • モデルファイルが正しい場所にあることを確認
  • モデル形式がプラットフォームと一致することを確認(iOSは.gguf、Androidは.task)
  • デバイスに十分なストレージがあることを確認
  • より小さなモデルを試す(1Bの代わりに270M)
  • メモリを解放するために他のアプリを閉じる
  • シミュレーターではなく実機でテスト
  • 準備状態が’ready’であることを確認
  • メッセージを送信する前にイベントリスナーが設定されていることを確認
  • コンソールでエラーをチェック