본문 바로가기

Capacitor 앱에서 Apple Intelligence 사용하는 방법

Capacitor 앱에서 iOS 26의 Foundation Models framework를 통해 Apple Intelligence 사용하기: 디바이스 체크, 스트리밍, 컨텍스트 제한, 오류

iPhone에서 Capacitor 앱 내 온디바이스 AI 기능 일러스트

Capacitor 앱에서 Apple Intelligence를 사용하려면 설치하세요 @capgo/capacitor-llm, 호출 setModel({ path: 'Apple Intelligence' }), 확인하세요 getReadiness(), 그리고 채팅을 생성하여 응답을 스트리밍하세요 textFromAi 이벤트. 내부적으로 이 플러그인은 iOS 26과 함께 도입된 Apple의 Foundation Models 프레임워크를 사용하며, API 키 없이, 요청당 비용 없이, 데이터가 기기를 벗어나지 않는 방식으로 Apple의 온디바이스 언어 모델을 실행합니다.

이 가이드는 프레임워크가 제공하는 기능, 기기 요구 사항, 완전한 TypeScript 통합, 4,096-token 컨텍스트 윈도우, 오류 처리, App Review 참고 사항, 그리고 동일한 code이 Android에서 실행되는 방식을 다룹니다.

Apple Intelligence가 앱 개발자에게 제공하는 것

iOS 26에서 Apple은 Foundation Models를 통해 Foundation Models 프레임워크입니다. Swift에서는 SystemLanguageModel 및 LanguageModelSession을(를) 사용합니다. 이 플러그인은 이를 래핑하여 웹 code에서도 사용할 수 있게 합니다:

Foundation Models 개념 플러그인 대응
SystemLanguageModel.default.availability getReadiness()
LanguageModelSession createChat() id 반환
session.streamResponse(to:) sendMessage() 및 textFromAi 이벤트
생성 중 발생하는 에러 generationError 이벤트와 거부된 sendMessage

모델은 약 30억 개의 파라미터를 가집니다. 요약, 재작성, 추출, 분류 및 짧은 형식의 생성에 강점이 있습니다. 개방형 지식 질문에서 대형 클라우드 모델을 대체할 수는 없으며, Apple도 자체 가이드에서 이를 명시하고 있습니다. 사용자가 이미 보유한 텍스트를 중심으로 기능을 설계하세요.

기기 및 OS 요구 사항

요구 사항 세부 정보
iPhone iPhone 15 Pro, 15 Pro Max 및 iPhone 16 모델 이상
iPad iPad mini (A17 Pro), M1 이상 칩 탑재 iPad
Mac Apple silicon Mac (Simulator에서 테스트 시 관련)
OS iOS 26 / iPadOS 26 이상
설정 설정 > Apple Intelligence & Siri에서 Apple Intelligence가 켜져 있어야 합니다
언어 기기 및 Siri 언어가 Apple Intelligence가 지원하는 언어로 설정되어 있어야 합니다
스토리지 Apple은 Apple Intelligence 모델을 위해 약 7GB의 여유 공간을 권장합니다
Toolchain 2026년 4월부터 App Store Connect 업로드에도 필수인 Xcode 26

프로젝트가 이전 버전의 Xcode로 빌드되는 경우, 다음을 참조하세요 Capacitor 앱을 위한 Apple의 Xcode 26 요구사항. 앱의 최소 배포 대상은 변경할 필요가 없습니다. 이 플러그인은 iOS 15 이상을 지원하며, iOS 26에서는 Foundation Models에만 영향을 줍니다.

플러그인 설치

bun add @capgo/capacitor-llm
bunx cap sync ios

Capacitor 8과 함께 플러그인 8.x를 사용하세요. Apple Intelligence를 위해 Info.plist 키나 권한(entitlements)이 필요하지 않습니다. 아직 Capacitor 7을 사용 중이라면 Capacitor 8 업그레이드 가이드 가 먼저입니다. 참고 문서: /docs/plugins/llm/.

1단계: 모델 선택 및 사용 가능 여부 확인

setModel({ path: 'Apple Intelligence' }) 시스템 모델을 선택하고 즉시 해결합니다. 실제 사용 가능 여부는 getReadiness()에서 가져오며, Apple의 사용 가능 열거형(enum)을 읽기 쉬운 문자열로 매핑합니다:

readiness 값 의미 표시할 내용
ready 모델 사용 가능 해당 기능
Device is not eligible for Apple Intelligence 하드웨어 미지원 기능 숨기기 또는 클라우드 폴백 사용
Apple Intelligence is not enabled 사용자가 비활성화함 설정에서 활성화하도록 안내
Model is not ready 모델이 아직 다운로드 중이거나 준비 중 “준비 중”, 나중에 재시도
Apple Intelligence requires iOS 26.0 or later 구형 iOS 기능 숨기기
import { Capacitor } from '@capacitor/core';
import { CapgoLLM } from '@capgo/capacitor-llm';

export type AIState = 'ready' | 'enable-in-settings' | 'preparing' | 'unsupported';

export async function initAppleIntelligence(): Promise<AIState> {
  if (Capacitor.getPlatform() !== 'ios') return 'unsupported';

  await CapgoLLM.setModel({ path: 'Apple Intelligence' });
  const { readiness } = await CapgoLLM.getReadiness();

  if (readiness === 'ready') return 'ready';
  if (readiness.includes('not enabled')) return 'enable-in-settings';
  if (readiness.includes('not ready')) return 'preparing';
  return 'unsupported';
}

앱이 포그라운드로 돌아올 때 다시 확인하세요. 사용자는 안내를 보고 Apple Intelligence를 활성화하는 경우가 많으며, 앱이 백그라운드에 있을 때 모델 다운로드가 완료될 수 있습니다.

import { App } from '@capacitor/app';

App.addListener('appStateChange', async ({ isActive }) => {
  if (isActive) updateAIState(await initAppleIntelligence());
});

2단계: 지시사항이 포함된 채팅 생성

채팅 하나가 하나에 매핑됩니다 LanguageModelSession, 대화 기록을 유지합니다. 입력한 createChat() 옵션을 받지 않으므로, 첫 번째 메시지의 시작 부분에 지시문을 넣으세요:

const INSTRUCTIONS =
  'You summarize meeting notes. Reply with at most 5 bullet points. ' +
  'Keep names and dates exactly as written. Do not add information.';

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

작업별로 하나의 채팅을 사용하세요. 계속 커지는 채팅은 아래 설명된 컨텍스트 한도에 도달하게 됩니다.

3단계: 응답을 UI에 스트리밍

iOS에서 각 textFromAi 이벤트는 Foundation Models의 스트리밍 방식에 따라 현재까지의 응답 스냅샷을 포함합니다. Gemini Nano를 사용하는 Android에서는 이벤트가 새 텍스트만 포함합니다. 이 헬퍼는 두 경우 모두를 처리하고 최종 텍스트로 resolve합니다:

import { CapgoLLM } from '@capgo/capacitor-llm';

function mergeChunk(current: string, chunk: string) {
  return chunk.startsWith(current) ? chunk : current + chunk;
}

export async function ask(chatId: string, message: string, onText: (t: string) => void) {
  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', (e) => {
      if (e.chatId !== chatId) return;
      text = mergeChunk(text, e.text);
      onText(text);
    }),
    CapgoLLM.addListener('aiFinished', (e) => {
      if (e.chatId === chatId) finish(text);
    }),
    CapgoLLM.addListener('generationError', (e) => {
      if (!e.chatId || e.chatId === chatId) fail(new Error(e.error));
    }),
  ]);

  try {
    await CapgoLLM.sendMessage({ chatId, message });
    return await done;
  } finally {
    await Promise.all(handles.map((h) => h.remove()));
  }
}

모두 합치기: 기기에 메모 요약

export async function summarizeNotes(notes: string, render: (t: string) => void) {
  const state = await initAppleIntelligence();
  if (state !== 'ready') throw new Error(`AI unavailable: ${state}`);

  const { id } = await CapgoLLM.createChat();
  const prompt = `${INSTRUCTIONS}\n\nNotes:\n${notes.slice(0, 8000)}\n\nSummary:`;
  return ask(id, prompt, render);
}

이 slice 은 거대한 입력에 대한 단순한 가드입니다. 더 나은 방법은 긴 문서를 청크로 나눠 요약한 후, 각 요약을 새 채팅에서 다시 요약하는 것입니다.

프레임워크 컴포넌트에서 ask 가 실행되는 동안 버튼을 비활성화하세요. 플러그인은 같은 채팅에서 두 번째 sendMessage 요청을 "채팅이 응답 중입니다. 새 질문을 하기 전에 기다려 주세요."라는 메시지로 거부합니다.

4,096 토큰 컨텍스트 윈도우

온디바이스 모델의 컨텍스트 윈도우는 4,096 토큰입니다. 모든 것이 여기에 포함됩니다: 지시사항, 채팅의 모든 이전 턴, 새로운 프롬프트, 그리고 생성 중인 응답. 세션이 이를 초과하면 Foundation Models가 “exceeded context window size” 오류를 발생시키며, 이는 generationError 이벤트와 거부된 sendMessage.

실용적인 규칙:

  • 화면마다가 아니라 작업마다 하나의 채팅을 사용하세요.
  • 지시사항은 짧고 구체적으로 유지하세요.
  • 멀티턴 채팅의 경우, 길어지면 새 채팅을 시작하고 이전 대화의 짧은 요약을 전달하세요.
  • 간결한 출력을 요청하세요. 긴 답변도 동일한 예산을 사용합니다.

출력 조정

Apple Intelligence 경로에서 플러그인은 시스템의 기본 생성 설정을 사용합니다. temperature, topk, 그리고 maxTokens 에서 setModel 커스텀 LiteRT-LM 및 MediaPipe 모델 경로에 적용됩니다. Apple 모델의 동작을 제어하려면 프롬프트에 의존하세요. 답변 길이를 지정하고, 형식(불릿, JSON, 한 문장)을 명시하며, 형식이 중요한 경우 짧은 예시 하나를 포함하세요.

Android에서도 동일한 code

모델 선택만 다릅니다:

const path = Capacitor.getPlatform() === 'ios' ? 'Apple Intelligence' : 'Gemini Nano';
await CapgoLLM.setModel({ path });

Android에서는, setModel Gemini Nano가 사용 불가능하면 거부하며, 동일한 플러그인을 통해 다운로드 가능한 Gemma 모델로 폴백할 수 있습니다. 자세한 내용은 Capacitor 앱에서 Gemini Nano 사용법.

테스트

  • 실기기: 안정적인 경로입니다. Apple Intelligence가 켜진 iOS 26 지원 iPhone을 사용하세요.
  • 시뮬레이터: 호스트 Mac이 Apple silicon 기반 macOS 26에서 Apple Intelligence를 활성화한 경우 모델을 사용할 수 있습니다. 동작과 속도가 휴대폰과 다르므로 하드웨어에서 확인하세요.
  • 지원되지 않는 상태: Apple Intelligence를 끄고 '설정에서 활성화' UI를 확인하세요. 또한 구형 iPhone이나 iOS 버전에서 기능이 깔끔하게 숨겨지는지 확인하세요.

앱 심사 및 개인정보 보호

프롬프트와 응답은 기기에 머물러 있으므로, 온디바이스 생성 자체는 개인정보 보호 라벨에 데이터 수집 항목을 추가하지 않습니다. 다만 두 가지는 개발자가 직접 관리해야 합니다:

  1. Apple은 Foundation Models 프레임워크의 허용 사용 요구사항을 공개합니다. 특히 다른 사용자에게 표시되는 콘텐츠를 생성하는 기능의 경우, 배포 전에 반드시 확인하세요.
  2. 모델에는 내장된 가드레일이 있어 일부 프롬프트나 출력을 거부할 수 있습니다. 거부는 정상적인 결과로 간주하고 명확한 메시지를 표시하세요.

프롬프트는 웹 code의 일반 문자열이므로, 출시 후에도 Capgo Live Update 사용하기 를 통해 개선할 수 있으며, 새로운 App Store 빌드를 기다릴 필요가 없습니다. 플러그인 업그레이드를 포함한 네이티브 code 변경 사항은 여전히 스토어 릴리스가 필요하며, 이는 Capgo 빌드.

자주 발생하는 오류 및 해결 방법

증상 예상 원인 해결 방법
readiness “Device is not eligible” 상태 iPhone 15 Pro 이전 모델 또는 미지원 iPad 기능 숨기기 또는 서버 모델 사용
readiness “not enabled” 상태 사용자가 Apple Intelligence를 꺼둔 경우 설정 안내 표시, 재개 시 재확인
readiness “Model is not ready” 상태 모델 다운로드 중 준비 중 상태 표시, 나중에 재시도
sendMessage “error deviceNotEligible error” 거부 준비 상태 확인 없이 전송 게이트 켜기 getReadiness() 먼저
“채팅을 찾을 수 없음” 새 채팅 전에 생성된 채팅 setModel 호출 호출 시 setModel 채팅이 지워지면 새로 만드세요
채팅 응답 중 스트리밍 중 두 번째 메시지 전송 ~까지 입력 비활성화 aiFinished
generationError 컨텍스트 윈도우 언급 채팅이 너무 깁니다 요약과 함께 새 채팅 시작
Foundation Models 관련 빌드 오류 Xcode 26보다 오래된 버전 Xcode 업데이트 또는 클라우드 빌드

마무리

Apple Intelligence는 iOS 26의 모든 지원 iPhone에 무료, 프라이빗, 오프라인 언어 모델을 제공합니다. Capacitor 앱은 몇 줄의 TypeScript로 이를 사용할 수 있습니다. 모델을 선택하고 UI를 조건부로 getReadiness() 제어하고, 각 작업을 짧은 개별 채팅으로 유지하며, 스냅샷을 UI에 스트리밍하고, 거부 및 컨텍스트 오류를 일반적인 결과로 처리하세요. 하이브리드 앱에서 AI 기능 배포에 대한 더 넓은 관점은 여기서 확인하세요. 왜 Capacitor가 AI 모바일 앱에 적합한지.

Capacitor 앱용 Live updates

웹 레이어 버그가 라이브 상태라면, 앱 스토어 승인을 며칠씩 기다리지 말고 Capgo를 통해 수정 사항을 배포하세요. 네이티브 변경 사항은 정상 리뷰 절차를 그대로 따르는 반면, 사용자는 백그라운드에서 업데이트를 받습니다.

블로그 최신 글

Capgo는 정말 프로페셔널한 모바일 앱을 만드는 데 필요한 최고의 인사이트를 제공합니다.