언어 모델

웹 기능: LanguageModel

Prompt API를 사용하면 개발자가 Gemini Nano를 사용하여 브라우저에서 직접 자연어 처리 작업을 실행할 수 있습니다. 이러한 내장 AI 접근 방식은 사용자 개인 정보 보호를 보장하고 서버 비용을 절감하며 오프라인 기능을 지원합니다.

1. 시작하기 및 하드웨어 요구사항

Prompt API는 현재 Windows, macOS, Linux, Chromebook Plus용 Chrome 버전 148 (데스크톱)에서 사용할 수 있습니다.

하드웨어 기본 요건

  • 저장용량: 22GB의 여유 공간 (초기 프로필 및 모델용)
  • 메모리/CPU: 16GB RAM 및 CPU 코어 4개 이상
  • GPU: 4GB VRAM 이상 (오디오 입력에 필요)
  • 네트워크: 초기 모델 다운로드에만 필요합니다.

API 설치

다운로드를 트리거하기 전에 모델 가용성을 확인합니다.

const availability = await LanguageModel.availability();

// Do not call create() when unavailable — the model cannot run on this device.
if (availability !== 'unavailable') {
    const session = await LanguageModel.create({
        monitor(m) {
            // Inform the user while the model downloads so the UI doesn't appear frozen.
            m.addEventListener('downloadprogress', (e) => {
                console.log(`Downloaded ${e.loaded * 100}%`);
            });
        },
    });
}

2. 핵심 프롬프팅 기능

이 섹션의 세션 예시에서는 편의상 session.destroy()를 생략합니다. 세션이 더 이상 필요하지 않으면 항상 session.destroy()를 호출하여 기기 메모리를 확보합니다 (섹션 5 참고).

기본 및 스트리밍 출력

짧은 응답에는 prompt()를 사용합니다. 더 긴 콘텐츠의 경우 promptStreaming()를 사용하여 더 반응성이 뛰어난 UI를 제공합니다.

필수: 모델 출력을 innerHTML에 할당하지 마세요. 모델 출력은 신뢰할 수 없으며 삽입된 마크업이 포함될 수 있습니다. 항상 textContent 또는 새니타이저를 사용합니다.

const session = await LanguageModel.create();

// prompt() accumulates the full response before resolving — use for short, one-shot output.
const result = await session.prompt('Write a haiku about coding.');
// textContent, not innerHTML — model output is untrusted and must not be parsed as markup.
outputEl.textContent = result;

// promptStreaming() yields independent chunks that must be concatenated;
// use for longer content so each chunk can be rendered progressively.
const stream = session.promptStreaming('Write a long story about a robot.');
let completeResult = '';
for await (const chunk of stream) {
    completeResult += chunk;
    outputEl.append(chunk);
}
console.log('Full story:', completeResult);

멀티모달 입력

Prompt API는 텍스트, 오디오, 시각적 입력 (이미지, 캔버스, 동영상 프레임)을 지원합니다.

const session = await LanguageModel.create({
    // Declaring expected input types lets the browser optimize model loading.
    expectedInputs: [{ type: 'text' }, { type: 'image' }],
    expectedOutputs: [{ type: 'text' }],
});

const response = await session.prompt([
    {
        role: 'user',
        content: [
            { type: 'text', value: 'What is in this image?' },
            { type: 'image', value: document.querySelector('canvas') },
        ],
    },
]);

3. 고급 세션 관리

세션을 사용하면 모델이 여러 상호작용에서 컨텍스트를 유지할 수 있습니다.

컨텍스트 및 할당량

각 세션에는 최대 토큰 한도가 있습니다. session.contextUsage 및 session.contextWindow를 통해 사용량을 모니터링할 수 있습니다. 창이 오버플로되면 가장 오래된 메시지 (시스템 프롬프트 제외)가 삭제됩니다.

세션 클론

클론은 다시 초기화하지 않고도 동일한 초기 컨텍스트('시스템' 성격 등)를 공유하는 병렬 대화를 시작하는 데 효율적입니다.

const mainSession = await LanguageModel.create({
    initialPrompts: [{ role: 'system', content: 'You speak like a pirate.' }],
});

const branchA = await mainSession.clone();
const branchB = await mainSession.clone();
// Destroy the base after cloning — the clones own their own context from here.
mainSession.destroy();

이전 세션 복원

기본 '복원' 기능은 개발 중이지만 이전 기록을 initialPrompts에 입력하여 세션을 다시 만들 수 있습니다.

참고: localStorage는 암호화되지 않으며 영구적입니다. 저장된 대화 기록에는 사용자 개인 식별 정보(PII)가 포함될 수 있습니다. 채팅 기록을 유지하기 전에 개인 정보 보호에 미치는 영향을 고려하세요.

// || '[]' ensures JSON.parse never receives null when the key doesn't exist yet.
const history = JSON.parse(localStorage.getItem('chat_history') || '[]');
const session = await LanguageModel.create({
    initialPrompts: history, // Array of {role, content} objects
});

4. JSON 스키마를 사용한 구조화된 출력

모델이 '잡담' (예:'물론입니다.JSON은 다음과 같습니다.')을 추가하지 못하도록 하려면 responseConstraint 필드를 통해 JSON 스키마를 사용하세요. 이렇게 하면 출력이 즉시 파싱할 수 있는 유효한 JSON이 됩니다.

예시: 감정 분류

// Pass the schema as a plain object — do not JSON.stringify() it first.
const schema = {
    type: 'object',
    properties: {
        rating: { type: 'number', minimum: 1, maximum: 5 },
        is_positive: { type: 'boolean' },
    },
    required: ['rating', 'is_positive'],
};

const result = await session.prompt(
    "Rate the following feedback: 'The food was great!'",
    { responseConstraint: schema },
);

const data = JSON.parse(result);
console.log(data.rating); // 5

제약 조건 및 프리픽스

prefix: true를 사용하여 어시스턴트의 대답을 미리 채워 모델을 추가로 안내할 수 있습니다.

const character = await session.prompt([
    { role: 'user', content: 'Create a character sheet' },
    { role: 'assistant', content: '```json\n', prefix: true },
]);

5. 권장사항 및 안전

  • 리소스 정리: 대화가 끝나면 항상 session.destroy()를 호출하여 메모리를 확보합니다.
  • 출력 안전: 모델 출력을 신뢰할 수 없습니다. 악의적인 모델 출력으로 인한 XSS 삽입을 방지하려면 항상 innerHTML가 아닌 textContent에 결과를 작성합니다.
  • 제한된 HTML을 허용해야 하는 경우 네이티브 Sanitizer API 또는 DOMPurify와 같은 새니타이저를 사용합니다.
  • 작업 중단: AbortController를 사용하여 사용자가 장기 실행 생성을 중지할 수 있도록 합니다. signal를 LanguageModel.create()가 아닌 prompt() 또는 promptStreaming()에 전달합니다.
  • 보안: 권한 정책을 사용하여 iframe의 액세스를 제어합니다(<iframe src="..." allow="language-model"></iframe>).
  • 설계: People + AI 가이드북을 검토하여 책임감 있는 AI 구현을 보장합니다.

구조화된 출력과 강력한 세션 관리를 결합하면 개발자는 사용자의 기기에서 완전히 실행되는 복잡한 스테이트풀(Stateful) AI 애플리케이션을 빌드할 수 있습니다.

권장사항 및 주의사항

권장사항 및 금지사항의 전체 목록은 https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt를 참고하세요. 요점은 다음과 같습니다.

적절한 시간에 모델 준비

적용 대상: 모든 API(예: Summarizer, Translator, Writer)

권장사항: 사용자가 AI 기능을 사용하려는 의도를 명확히 표시하는 즉시 세션을 초기화합니다. 예를 들어 사용자가 관련 AI 도구 표시 영역으로 이동하거나, AI 작업공간 위로 마우스를 가져가거나, 기능 주변의 UI와 상호작용할 때 세션을 초기화합니다. 세션을 미리 준비하면 사용자가 작업을 설정하는 동안 모델이 백그라운드에서 메모리에 로드되므로 콜드 스타트 지연 시간을 방지할 수 있습니다. 예를 들어 기능이 반복 사용을 위해 설계된 경우 현재 결과를 렌더링하기 시작하는 즉시 다음으로 가능성이 높은 AI 작업을 시작하여 한 단계 앞서 나가세요.

금지사항: 필요한 경우가 아니라면 사용자가 '생성'을 클릭하여 세션을 초기화할 때까지 기다리지 마세요. 이로 인해 모델이 먼저 메모리에 로드되고 실행 파이프라인을 준비해야 하므로 콜드 스타트 지연이 발생합니다.

생성 중에 초기 프롬프트 설정

적용 대상: Prompt API

권장사항: 세션 초기화 중에 시스템 요청 사항을 제공하여 첫 번째 프롬프트의 속도를 개선합니다.

금지사항: 빈 세션으로 시작하고 첫 번째 prompt() 호출의 일부로 시스템 안내를 전송합니다. 이렇게 하면 모델이 마지막 순간에 해당 명령어를 처리해야 하므로 지연 시간이 늘어납니다.

반복 작업에 세션 클론

적용 대상: Prompt API

Prompt API의 경우 각 세션은 이전의 모든 상호작용을 고려하여 대화의 컨텍스트를 추적합니다. 클론은 초기 프롬프트와 클론 시점까지의 모든 상호작용 기록을 포함하여 상위 세션의 모든 항목을 상속하므로 필요한 항목만 상속하도록 사용을 구성하세요.

권장사항:

  • 기본 세션 만들기: 관련 없는 작업을 효율적으로 처리하려면 시스템 안내만 포함하고 이전 대화 컨텍스트는 포함하지 않는 기본 세션을 만듭니다.
  • 기준 클론: 새 작업의 기본 세션에서 clone()를 사용하여 시스템 요청 사항을 다시 파싱하는 오버헤드를 줄입니다. 이를 통해 병렬 대화를 만들거나 작업을 기준선으로 재설정할 수 있습니다.

금지사항:

  • 관련 없는 작업에 동일한 세션을 재사용하지 말고, 불필요한 상호작용 기록이 이미 포함된 세션을 클론하지 마세요. 두 패턴 모두 관련 없는 이전 컨텍스트가 현재 작업을 방해할 수 있습니다.
  • 동일한 시스템 안내로 create()를 반복적으로 호출하지 마세요. 대신 클론 패턴을 사용하여 성능을 최적화하세요.

사용하지 않는 세션 폐기

적용 대상: 모든 API

권장사항: 더 이상 필요하지 않은 세션에서 destroy()를 명시적으로 호출하여 기능이 더 이상 사용되지 않을 때 메모리를 확보합니다. 클론 패턴을 사용하는 경우 기본 세션을 유지하고 더 이상 필요하지 않은 클론을 삭제합니다.

금지사항: 여러 개의 대규모 세션을 활성 상태로 유지합니다. 각 세션은 메모리를 소비하므로 불필요한 리소스 사용이 발생하고 문제가 될 수 있습니다. 세션은 가비지 컬렉터에 의해 자연스럽게 정리되지만 destroy()를 호출하면 메모리가 더 빠르게 확보됩니다.

스트리밍 응답을 안전하고 효율적으로 렌더링하기

적용 대상: 스트리밍을 지원하는 모든 API (Prompt, Summarizer, Writer, Rewriter, Translator)

권장사항: 모든 LLM 출력을 신뢰할 수 없는 콘텐츠로 취급합니다. 악성 코드가 업데이트 전반에 걸쳐 분할될 수 있으므로 청크뿐만 아니라 결합된 전체 출력을 정제합니다. 렌더링하기 전에 지원되는 경우 Sanitizer API를 사용합니다. 성능 저하를 방지하려면 streaming-markdown과 같은 스트리밍 마크다운 파서를 사용하세요.

하지 말아야 할 일: 모든 청크 업데이트에서 innerHTML를 직접 설정합니다. 이 방법은 특히 문법 강조 표시와 같은 복잡한 형식 지정의 경우 속도가 느리고 삽입에 취약합니다.

속도에 맞게 입력 최적화

적용 대상: 모든 API

권장사항: 꼭 필요한 정보만 모델에 전달합니다. 당면한 작업과 관련이 없는 모든 항목을 삭제합니다. 대규모 데이터 세트의 경우 간단한 개요와 관련 항목을 소량 제공합니다.

금지사항: 처리되지 않은 원시 텍스트, 불필요한 메타데이터, HTML 태그 또는 필터링되지 않은 대규모 목록을 API에 전송하지 마세요. 지연 시간은 입력 크기에 따라 크게 증가하므로 많은 기기에서 AI 기능이 손상된 것처럼 보일 수 있습니다.

예측 가능한 결과를 위해 구조화된 출력 사용

적용 대상: Prompt API

권장사항: 모델이 특정 형식으로 데이터를 반환해야 하는 경우 responseConstraint 필드를 제공하여 JSON 스키마를 제공하는 구조화된 출력을 사용합니다. 이렇게 하면 출력을 예측할 수 있으며 복잡한 후처리나 수동 파싱이 필요하지 않습니다.

금지사항: 자연어 요청 사항('JSON만 출력' 등)에만 의존하지 마세요. 모델에 파서를 중단하는 대화형 필러가 포함될 수 있습니다.

길이 제약 조건에서 생성 분리

적용 대상: Prompt API는 구조화된 출력 스키마를 지원하는 유일한 API입니다.

권장사항: 모델이 자연스럽게 대답을 생성하도록 한 다음 클라이언트 측 로직을 사용하여 UI에 맞게 텍스트를 자릅니다.

금지사항: 구조화된 출력 스키마를 사용하여 maxLength: 125와 같은 엄격한 글자 수 제한을 적용하지 마세요. 모델의 대답이 설정한 한도보다 길면 모델이 의미를 압축하기 위해 외국어나 이모티콘과 같은 고밀도 토큰으로 전환하여 무의미한 출력이 생성될 수 있습니다.

사용자에게 알리기

적용 대상: 모든 API

권장사항: 작업의 복잡성과 예상 소요 시간에 따라 애니메이션, 시각적 단서, 진행률 표시기를 사용하여 사용자에게 정보를 제공합니다. 최적의 접근 방식은 사용 사례와 API 출력의 예상 길이에 따라 달라집니다. 다음은 몇 가지 아이디어 예시입니다.

  • 긴 콘텐츠 스트리밍: 요약 또는 채팅의 경우 스트리밍은 기본적으로 토큰별 타자기 효과를 만듭니다. 이렇게 하면 자연스럽게 느껴지고 즉각적인 피드백을 제공할 수 있습니다.
  • 짧은 작업 (또는 긴 비동기 작업)을 위한 비스트리밍: 대체 텍스트와 같은 짧은 출력의 경우 비스트리밍을 사용하면 더 세련된 UI를 만들 수 있습니다. 또한 현재 AI 태스크가 렌더링되는 동안 다음 AI 태스크를 추측적으로 준비할 시간을 제공합니다. 이 접근 방식은 더 긴 비동기 작업이나 백그라운드 작업에도 작동합니다. 사용자가 여정을 계속하기 위해 출력이 차단되지 않는다면 출력을 즉시 생성할 필요가 없습니다. UI에서 프로세스가 진행 중임을 알립니다.
  • 업데이트를 위한 시각적 전환: 텍스트를 번역하거나 다시 작성할 때 애니메이션(예: 단어 변형)을 사용합니다.

권장하지 않음: 시각적 단서 없이 UI를 업데이트합니다.

시간과 작업에 대한 사용자의 멘탈 모델에 맞추기

적용 대상: 모든 API

권장사항: 대답이 거의 즉시 표시되는 경우 1~2초의 인위적인 지연을 고려합니다. 역설적으로, 사용자는 작업의 난이도에 부합하는 생성 프로세스를 인식할 때 결과를 더 신뢰할 수 있습니다. 애니메이션을 사용하여 AI 처리가 발생했음을 알립니다.

금지사항: 즉각적인 UI 교체로 사용자를 놀라게 합니다.

사용자가 AI 수정사항을 빠르게 탐색하고 실행취소할 수 있도록 허용

적용 대상: 모든 API

권장사항: 사용자가 다양한 결과를 자신 있게 탐색할 수 있도록 UI에 스테퍼 또는 탐색 기록을 제공하고 AI 수정을 빠르게 실행취소할 수 있도록 합니다. 이렇게 하면 다양한 버전을 계속 사용할 수 있습니다.

금지사항: 사용자의 이전 초안 또는 사용자가 마음에 들어 했을 수 있는 AI 결과를 되돌리거나, 되돌리거나, 버전을 비교할 수 있는 방법 없이 덮어쓰지 마세요.

사용자 제어 및 재정의 지원

적용 대상: 모든 API

권장사항: 사용자가 생성된 모든 콘텐츠의 최종 편집자가 되도록 합니다. 사용자가 최종 출력에 대한 완전한 소유권을 유지할 수 있도록 직관적인 재정의를 제공합니다. API가 잘못된 결과를 생성할 수 있습니다.

금지사항: AI 생성 결과를 유일한 옵션으로 강제합니다.

반복되는 할 일의 결과 캐시

적용 대상: 모든 API

권장사항: 반복되는 입력 또는 쿼리에 대해 로컬 결과 캐시를 구현합니다 (예: sessionStorage 또는 IndexedDB 사용). 공백을 자르고 소문자로 변환하여 입력을 정규화하여 캐시 적중을 늘립니다. 이미지와 같은 대량 입력의 경우 캐시 키로 사용할 해시를 생성합니다. 캐시에 보수적인 TTL (수명)을 설정합니다 (또는 백그라운드에서 업데이트하는 동안 캐시된 결과를 제공). 결과가 만족스럽지 않으면 사용자가 새로운 추론을 트리거할 수 있도록 합니다.

금지사항: 사용자가 검색 결과 사이를 앞뒤로 이동하는 경우와 같이 변동성이 바람직하지 않은 반복 검색어나 동일한 데이터 입력에 대해 동일한 추론을 다시 실행하지 마세요. 이를 통해 응답성과 로컬 컴퓨팅의 효율적인 사용이 최적화됩니다.

6. 대체 전략

사용하기 전에 LanguageModel 객체를 전역 범위에서 사용할 수 있는지 확인합니다.

if ('LanguageModel' in self) {
  // The Prompt API is supported.
} else {
  // Execute fallback strategy
}

Prompt API가 지원되지 않거나 사용 가능 여부 확인에서 '사용할 수 없음'을 반환하는 경우 다음과 같이 단계적으로 대체해야 합니다.

  • 원격 API 대체: 감지 요청을 서버 엔드포인트 또는 Cloud API (예: Vertex AI Gemini API)로 리디렉션합니다.
  • 로컬 API 대체: 감지 요청을 로컬 엔드포인트로 리디렉션합니다(예: Transformers.js 사용).