시작하기
Copy a setup prompt with the install steps and the full markdown guide for this plugin.
Set up this Capacitor plugin in the project.
Use the package manager already used by the project.
Install these package(s): `@capgo/capacitor-llm`
Run the required Capacitor sync/update step after installation.
Read this markdown guide for the full setup steps: https://raw.githubusercontent.com/Cap-go/website/refs/heads/main/apps/docs/src/content/docs/ko/docs/plugins/llm/getting-started.mdx
Use that guide for platform-specific steps, native file edits, permissions, config changes, imports, and usage setup.
If that guide references other docs pages, read them too.
npm install @capgo/capacitor-llmnpx cap syncyarn add @capgo/capacitor-llmnpx cap syncpnpm add @capgo/capacitor-llmnpx cap syncbun add @capgo/capacitor-llmnpx cap sync플랫폼 구성
Section titled “플랫폼 구성”iOS 구성
Section titled “iOS 구성”- iOS 26.0+: 기본적으로 Apple Intelligence 사용 (모델 불필요) - 권장
- iOS < 26.0: MediaPipe 사용자 지정 모델 필요 (실험적, 호환성 문제가 있을 수 있음)
구형 iOS 버전의 사용자 지정 모델의 경우, Xcode의 “Copy Bundle Resources”를 통해 iOS 앱 번들에 모델 파일을 배치하세요.
Android 구성
Section titled “Android 구성”Android assets 폴더에 모델 파일을 배치하세요:
android/app/src/main/assets/Android용 두 파일 모두 필요:
.task파일 (주 모델).litertlm파일 (동반 파일)
Kaggle Gemma 모델에서 다운로드 → “LiteRT (이전 TFLite)” 탭
Android용 (Gemma-3 모델)
Section titled “Android용 (Gemma-3 모델)”- Gemma 3 270M - 모바일용 가장 작고 효율적 (~240-400MB) - 권장
- Gemma 3 1B - 더 큰 텍스트 생성 모델 (~892MB-1.5GB)
Kaggle Gemma 모델에서 다운로드 → “LiteRT (이전 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);
// 플랫폼에 따라 모델 설정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 응답:', event.text);});
// 완료 수신CapgoLLM.addListener('aiFinished', (event) => { console.log('AI가 응답을 완료했습니다');});
// 메시지 보내기await CapgoLLM.sendMessage({ chatId, message: '안녕하세요! 오늘 어떻게 지내세요?'});모델 다운로드
Section titled “모델 다운로드”// 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(`다운로드 진행률: ${event.progress}%`); console.log(`다운로드됨: ${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('준비 상태 변경:', event.readiness);});API 메서드
Section titled “API 메서드”createChat()
Section titled “createChat()”새 채팅 세션을 생성합니다.
const { id: chatId } = await CapgoLLM.createChat();반환값: Promise<{ id: string; instructions?: string }>
sendMessage(…)
Section titled “sendMessage(…)”LLM에 메시지를 보냅니다.
await CapgoLLM.sendMessage({ chatId: 'chat-id', message: '날씨는 어때요?'});| 매개변수 | 타입 | 설명 |
|---|---|---|
chatId | string | 채팅 세션 ID |
message | string | 보낼 메시지 |
getReadiness()
Section titled “getReadiness()”LLM이 사용할 준비가 되었는지 확인합니다.
const { readiness } = await CapgoLLM.getReadiness();반환값: Promise<{ readiness: string }>
가능한 값:
ready- 모델이 로드되고 준비됨loading- 모델이 로드 중not_ready- 모델이 아직 로드되지 않음error- 모델 로드 오류
setModel(…)
Section titled “setModel(…)”모델 구성을 설정합니다.
// 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});| 매개변수 | 타입 | 설명 |
|---|---|---|
path | string | 모델 경로 또는 iOS 시스템용 “Apple Intelligence” |
modelType | string | 선택 사항: 모델 파일 타입 (예: “task”, “bin”) |
maxTokens | number | 선택 사항: 모델이 처리하는 최대 토큰 |
topk | number | 선택 사항: 각 단계에서 고려되는 토큰 수 |
temperature | number | 선택 사항: 생성의 무작위성 (0.0-1.0) |
randomSeed | number | 선택 사항: 생성을 위한 랜덤 시드 |
downloadModel(…)
Section titled “downloadModel(…)”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'});| 매개변수 | 타입 | 설명 |
|---|---|---|
url | string | 다운로드할 URL |
companionUrl | string | 선택 사항: 동반 파일 (.litertlm) URL |
filename | string | 선택 사항: 저장할 파일 이름 |
반환값: Promise<{ path: string; companionPath?: string }>
textFromAi
Section titled “textFromAi”AI가 텍스트를 생성할 때 발생 (스트리밍 응답).
CapgoLLM.addListener('textFromAi', (event) => { console.log('AI 텍스트:', event.text); console.log('채팅 ID:', event.chatId); console.log('청크인가:', event.isChunk);});이벤트 데이터:
text(string) - AI의 증분 텍스트 청크chatId(string) - 채팅 세션 IDisChunk(boolean) - 완전한 청크인지 부분 스트리밍 데이터인지 여부
aiFinished
Section titled “aiFinished”AI가 응답을 완료할 때 발생.
CapgoLLM.addListener('aiFinished', (event) => { console.log('채팅 완료:', event.chatId);});이벤트 데이터:
chatId(string) - 채팅 세션 ID
downloadProgress
Section titled “downloadProgress”모델 다운로드 중 진행률을 보고하기 위해 발생.
CapgoLLM.addListener('downloadProgress', (event) => { console.log('진행률:', event.progress, '%'); console.log('다운로드됨:', event.downloadedBytes, '/', event.totalBytes);});이벤트 데이터:
progress(number) - 다운로드 완료 백분율 (0-100)downloadedBytes(number) - 지금까지 다운로드된 바이트totalBytes(number) - 다운로드할 총 바이트
readinessChange
Section titled “readinessChange”LLM의 준비 상태가 변경될 때 발생.
CapgoLLM.addListener('readinessChange', (event) => { console.log('준비 상태가 다음으로 변경됨:', event.readiness);});이벤트 데이터:
readiness(string) - 새로운 준비 상태
완전한 예제
Section titled “완전한 예제”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('모델 로드 실패'); } 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('채팅이 초기화되지 않았습니다'); }
await CapgoLLM.sendMessage({ chatId: this.chatId, message }); }
onTextReceived(text: string) { // 스트리밍 텍스트로 UI 업데이트 console.log('수신:', text); }
onMessageComplete(fullMessage: string) { // 완전한 메시지 처리 console.log('완전한 메시지:', fullMessage); }}
// 사용법const ai = new AIService();await ai.initialize();await ai.sendMessage('AI에 대해 말해주세요');플랫폼 지원
Section titled “플랫폼 지원”| 플랫폼 | 지원됨 | 요구 사항 |
|---|---|---|
| iOS | ✅ | iOS 13.0+ (Apple Intelligence는 26.0+) |
| Android | ✅ | API 24+ |
| Web | ❌ | 지원되지 않음 |
-
모델 선택: 장치 기능에 따라 모델 선택
- 대부분의 모바일 장치에는 270M 사용
- RAM이 더 많은 고급 장치에는 1B 사용
- 대상 장치에서 성능 테스트
-
메모리 관리: 완료 시 채팅 세션 지우기
// 새 대화를 위한 새 채팅 생성const { id } = await CapacitorLLM.createChat(); -
오류 처리: 사용하기 전에 항상 준비 상태 확인
const { readiness } = await CapacitorLLM.getReadiness();if (readiness !== 'ready') {// 준비되지 않은 상태 처리} -
스트리밍 UI: 스트리밍 텍스트로 UI를 점진적으로 업데이트
onAiText를 통해 도착하는 텍스트 표시onAiCompletion으로 완료 표시
-
모델 다운로드: 첫 사용 시가 아닌 앱 설정 중에 모델 다운로드
// 앱 초기화 중await CapacitorLLM.downloadModel({url: 'https://your-cdn.com/model.task',filename: 'model.task'});
모델이 로드되지 않음
Section titled “모델이 로드되지 않음”- 모델 파일이 올바른 위치에 있는지 확인
- 모델 형식이 플랫폼과 일치하는지 확인 (iOS는 .gguf, Android는 .task)
- 충분한 장치 스토리지 확인
- 더 작은 모델 시도 (1B 대신 270M)
- 메모리를 확보하기 위해 다른 앱 닫기
- 시뮬레이터가 아닌 실제 장치에서 테스트
- 준비 상태가 ‘ready’인지 확인
- 메시지를 보내기 전에 이벤트 리스너가 설정되어 있는지 확인
- 콘솔에서 오류 확인