내가 로컬 및 클라우드 AI를 조합하는 Chrome Extension을 만든 방법
Source: Dev.to
Chrome가 조용히 거대한 기능을 출시했습니다: 디바이스 내에서 완전하게 실행되는 내장 AI (Gemini Nano). 별도의 설치 없이 브라우저 안에 바로 존재하고 네트워크 호출도 없습니다.
실제 제품에서 얼마나 활용할 수 있는지 확인하고 싶어 DocuMentor AI라는 Chrome 확장 프로그램을 만들었습니다. 이 확장은 개발자들이 기술 콘텐츠를 학습하도록 돕습니다: 스마트 요약, “읽어볼까?” 신호, 그리고 선별된 학습 자료 제공.
실제 서비스에서는 이 확장이 두 가지 환경에서 동작합니다:
- Chrome의 로컬 Gemini Nano (프라이버시 우선, 디바이스에 종속)
- 클라우드 AI 백엔드 (더 빠르고, 더 강력)
두 환경 중 적절한 경로를 자동으로 선택합니다. 이 글은 그 하이브리드 아키텍처가 어떻게 동작하는지의 짧은 버전입니다.
문제: 두 가지 매우 다른 AI
대부분의 클라우드 LLM은 하나의 일반적인 채팅 엔드포인트만 제공하고, 모든 것을 프롬프트 엔지니어링과 도구로 해결하도록 요구합니다.
Chrome의 내장 AI는 다릅니다. 전문화된 API를 제공합니다:
// Chrome AI APIs
Summarizer // TL;DR 및 핵심 포인트용
Writer // 콘텐츠 생성용
LanguageModel // 일반 프롬프트 및 채팅용
이 모든 것을 하나의 generate() 함수 뒤에 숨기면, 로컬이든 클라우드든 한쪽은 항상 어색하게 느껴집니다.
그래서 “모델”이 아니라 기능을 기준으로 추상화했습니다.
1단계: 기능 중심 인터페이스 설계
확장 프로그램 내부에는 시스템이 무엇을 할 수 있는가 를 설명하는 작은 인터페이스가 있습니다. 어떤 제공자가 어떻게 동작하는가 가 아니라요:
summarize(text, options)executePrompt(messages, options)write(content, options)isAvailable() / initialize()
제공자
- **
GeminiNanoProvider**는 Chrome의Summarizer,LanguageModel,WriterAPI를 감싸줍니다. - **
DocumentorAIProvider**는 단일 클라우드 LLM과 프롬프트 엔지니어링을 사용해 동일한 기능을 흉내내는 백엔드와 통신합니다.
제공자 선택은 간단합니다:
- 로그인한 사용자 → 클라우드 제공자 (속도 + 강력한 추론)
- 로그인하지 않은 사용자 → 로컬 제공자 (프라이버시 + 오프라인 유사)
세션 중에 전환되지 않습니다. 인증 상태가 제공자를 결정하므로 확장 로직이 예측 가능해집니다.
2단계: 로컬 AI와 클라우드 AI에 대한 서로 다른 전략
두 제공자가 동일한 인터페이스를 구현하면 새로운 문제가 등장합니다: 능력 및 신뢰성.
클라우드 모델은 도구와 함께 단일 호출로 다단계 워크플로를 처리할 수 있습니다.
Chrome의 로컬 Gemini Nano는 특히 CPU 전용 머신에서 이를 신뢰성 있게 수행하지 못합니다:
- 여러 단계에 걸쳐 컨텍스트를 유지하기 어려움
- 도구 호출이 불안정함
- 구조화된 JSON 출력이 일관되지 않음
그래서 두 가지 오케스트레이션 전략을 사용하게 되었습니다.
로컬 AI: 순차적, 앱 주도형 오케스트레이션
YouTube 동영상 추천 같은 기능은 Chrome 전용 경로에서 다음과 같이 진행됩니다:
- Gemini Nano에 검색 쿼리 생성 요청
- 코드에서 YouTube API를 직접 호출
- Gemini Nano에 다시 결과를 순위 매기고 재작성 요청
- JSON을 방어적으로 파싱·수정하고, 필요하면 재시도
모델은 작고 집중된 추론 작업만 수행하고, 나머지 로직은 확장 프로그램이 담당합니다.
클라우드 AI: 하나의 도구‑보강 호출
클라우드 제공자에서는 동일한 기능을 하나의 프롬프트와 도구 호출로 처리합니다:
“이 페이지를 분석하고
search_youtube를 호출해 관련성을 점수 매긴 뒤, 상위 3개의 동영상을 JSON 형태로 반환해 주세요.”
클라우드 모델이 플래너 + 실행자 역할을 합니다. 확장 프로그램은 한 번만 호출하고 결과를 렌더링합니다.
동일한 UX, 두 가지 내부 전략
- 로컬 = 순차적 분해
- 클라우드 = 단일 도구‑보강 호출
3단계: 디바이스 제한 사항 존중하기
브라우저 안에서 AI를 실행하면 클라우드가 보통 숨겨주는 제약을 직접 고려해야 합니다:
- 토큰 할당량:
measureInputUsage()와inputQuota를 사용해 입력이 맞는지 확인하고, 맞지 않으면 잘라냅니다. - 콘텐츠 추출: Mozilla Readability 같은 도구로 노이즈(네비게이션, 광고, 푸터)를 제거하고, 콘텐츠 길이를 (~15 K 문자) 제한한 뒤 AI에 전달합니다.
- 순차 vs 병렬: 여러 Chrome AI 호출을 병렬로 실행하면 느려지고 더 불안정해지는 경우가 많았습니다.
UX 개선: 먼저 빠른 TL;DR을 보내고, 무거운 결과는 이후에 스트리밍하도록 합니다.
4단계: 사용자가 인지하지 못하도록 하는 폴백
확장 프로그램은 간단하고 조용한 폴백 체인을 사용합니다:
- 클라우드 AI 시도 (빠른 경로)
- 실패하거나 할당량 초과 시 로컬 AI로 폴백
- 그래도 실패하면 오류 표시
UI는 “제공자를 전환합니다”라는 메시지를 전혀 보여주지 않습니다. 그냥 이렇게 느껴집니다:
- 대부분의 경우 → 빠른 응답 (클라우드)
- 가끔 → 느리지만 여전히 동작 (로컬)
여러분의 Chrome AI 프로젝트를 위한 교훈
- 모델이 아니라 기능을 중심으로 설계하세요.
- 클라우드 모델은 복잡하고 도구가 많이 필요한 워크플로를 한 번에 처리하도록 두세요.
- 확장 프로그램은 로컬 AI에서는 프롬프트를 작게 유지하고 오케스트레이션을 담당하게 하세요.
- 디바이스 제약(토큰, 콘텐츠 크기, 병렬성)을 첫 번째 설계 입력으로 다루세요.
- 폴백을 구축해 사용자는 성능 저하는 겪지만 오류는 보지 않게 하세요.
이것이 로컬과 클라우드 AI를 조용히 조합해 사용자에게 복잡성을 숨긴 Chrome 확장 프로그램을 만든 핵심 요약입니다.