transformersjs 를 활용해 Manifest V3(MV3) 크롬 확장 프로그램에 로컬 AI 기능을 통합하는 방법을 다룬다. HuggingFace가 Gemma 4 기반 브라우저 어시스턴트 확장을 개발하면서 정리한 아키텍처 패턴이다.
누가 활용하면 좋은가
크롬 확장 프로그램에 로컬 AI 기능(텍스트 생성, 페이지 분석, 검색 등)을 추가하고 싶은 프론트엔드 개발자. 서버 없이 완전한 온디바이스 추론을 원하는 경우에 적합하다.
참고 구현체
- 확장 프로그램: Chrome Web Store — Transformers.js Gemma 4 Browser Assistant
- 소스 코드: github.com/nico-martin/gemma4-browser-extension
1. MV3 아키텍처 개요
MV3 환경에서는 세 가지 런타임이 분리되어 동작한다.
1.1 세 가지 엔트리포인트
| 파일 | 역할 |
|---|---|
background.js (service worker) | 모델 호스팅, 에이전트 생명주기, 도구 실행 |
sidebar.html (사이드 패널) | 채팅 UI, 스트리밍 업데이트 표시 |
content.js (컨텐츠 스크립트) | DOM 추출, 하이라이팅 등 페이지 브릿지 |
1.2 설계 원칙
무거운 오케스트레이션은 백그라운드에, UI/페이지 로직은 얇게 유지한다.
- 백그라운드: 모델 초기화, 추론 실행, 도구 결과 처리, 대화 기록 보관
- 사이드 패널: 채팅 입출력 렌더링, 이벤트 발송
- 컨텐츠 스크립트: DOM 추출 및 하이라이트 액션
이 분리 덕분에 모델이 중복으로 로드되지 않고, 여러 탭에서 동일한 모델 인스턴스를 공유한다.
1.3 메시지 계약
모든 런타임 간 통신은 타입 열거형(enum)으로 정의한다.
사이드 패널 → 백그라운드:
CHECK_MODELS,INITIALIZE_MODELSAGENT_GENERATE_TEXT,AGENT_GET_MESSAGES,AGENT_CLEAREXTRACT_FEATURES
백그라운드 → 사이드 패널:
DOWNLOAD_PROGRESS,MESSAGES_UPDATE
백그라운드 → 컨텐츠:
EXTRACT_PAGE_DATA,HIGHLIGHT_ELEMENTS,CLEAR_HIGHLIGHTS
전형적인 요청 흐름:
- 사이드 패널이
AGENT_GENERATE_TEXT전송 - 백그라운드가
Agent.chatMessages에 추가하고 추론 실행 - 백그라운드가
MESSAGES_UPDATE방출 - 사이드 패널이 갱신된 메시지 목록으로 재렌더링
2. Transformers.js 통합
2.1 모델 구성
이 확장은 두 가지 모델을 사용한다.
// src/shared/constants.ts
// 텍스트 생성 (Gemma 4 2B)
const LLM_MODEL = "onnx-community/gemma-4-E2B-it-ONNX"; // q4f16, text-generation
// 임베딩 (MiniLM)
const EMBEDDING_MODEL = "onnx-community/all-MiniLM-L6-v2-ONNX"; // fp32, feature-extractionGemma 4는 추론·도구 결정을 담당하고, MiniLM은 ask_website·find_history 기능의 의미론적 유사도 검색에 사용된다.
2.2 추론 위치
모든 추론은 백그라운드 서비스 워커에서 실행된다.
import { pipeline } from "@huggingface/transformers";
// 텍스트 생성
const generator = await pipeline("text-generation", LLM_MODEL, {
dtype: "q4f16",
device: "webgpu",
});
// 임베딩
const extractor = await pipeline("feature-extraction", EMBEDDING_MODEL, {
dtype: "fp32",
});MV3 주의사항: 서비스 워커는 일시 중단·재시작될 수 있으므로, 모델 상태는 재초기화 가능하도록 설계해야 한다.
2.3 모델 캐시 관리
CHECK_MODELS → 캐시 상태 확인 및 남은 다운로드 용량 계산
INITIALIZE_MODELS → 모델 다운로드·초기화 후 DOWNLOAD_PROGRESS 방출크롬 확장 프로그램에서 모델은 확장 오리진(chrome-extension://<id>)에 캐시되어 탭 간 공유된다.
3. 도구 호출 루프
3.1 도구 정의
const output = await generator(messages, {
max_new_tokens: 128,
do_sample: false,
tools: [
{
type: "function",
function: {
name: "getWeather",
description: "특정 위치의 날씨를 가져온다",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "날씨를 확인할 위치",
},
},
required: ["location"],
},
},
},
],
});모델이 도구 호출을 결정하면 특수 토큰 블록이 출력된다. webMcp 레이어가 이를 파싱해 결정론적 도구 실행으로 변환한다.
4. 권한 설계
// manifest.json
{
"permissions": ["sidePanel", "storage", "scripting", "tabs"],
"host_permissions": ["http://*/*", "https://*/*"]
}sidePanel: 사이드 패널 UI 제어storage: 설정 영속화tabs+scripting: 탭 인식 도구 및 페이지 액션host_permissions: 임의 웹사이트 컨텐츠 추출
원칙: 필요한 권한만 요청하고, 추론이 로컬에서 실행됨을 사용자에게 명확히 알린다.
참고 자료
- How to Use Transformers.js in a Chrome Extension — HuggingFace Blog (2026-04-23)
- github.com/nico-martin/gemma4-browser-extension — GitHub 공식 저장소