본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 06. 00:41

Electron 기반 AI 브라우저에 Design Harvester를 만든 이야기

요약

Electron 기반 AI 브라우저에서 웹 페이지의 디자인 구조를 추출하여 AI로 재구축하는 'Design Harvester' 기능 개발 사례를 소개합니다. 단순 복제가 아닌 디자인 언어 추출과 Gemini를 활용한 재구성을 통해 새로운 디자인 자산을 생성하는 프로세스를 다룹니다.

핵심 포인트

  • Electron WebView에서 JavaScript를 통해 HTML/CSS 데이터 추출
  • 단순 복제가 아닌 AI를 통한 디자인 재구축 설계 사상 적용
  • Gemini 모델을 활용하여 브랜드와 콘텐츠를 가공한 새로운 디자인 생성
  • AI 응답을 HTML/CSS 코드 블록 형식으로 고정하여 기계적 처리 최적화

서론

Electron으로 제작 중인 AI 브라우저에는 우측 사이드바에 AI 어시스턴트와 도구들을 배치하고 있습니다.

그중에서 Design Harvester라는 기능을 만들었습니다.

목적은 브라우저에서 보고 있는 웹 페이지로부터 디자인 구조를 추출하고, AI를 통해 별도의 디자인으로 재구축하여 저장 및 업로드로 연결하는 것입니다.

VibeUI의 「AI 에이전트용 디자인 API」와도 궁합이 좋아, 디자인 수집부터 API화까지의 입구가 됩니다.

하고 싶었던 것

원했던 것은 단순한 스크린샷 저장이 아닙니다.

다음과 같은 흐름입니다.

1. 브라우저에서 참고 페이지를 본다
2. 페이지 전체 또는 지정된 selector의 HTML을 가져온다
3. CSS 규칙도 가져온다
...

여기서 중요한 것은 「복사하는 것」이 아니라 「디자인 언어를 추출하여 별개의 것으로 재구축하는 것」입니다.

공개 가능한 디자인 자산으로 만들기 위해서는 이 경계를 강력하게 의식해야 합니다.

브라우저와 Design 기능을 분리

Electron 브라우저 측에서는 일반적인 브라우저 기능과 Design 기능을 동일한 화면에 배치하고 있습니다.

다만, 내부적으로는 모드를 나누었습니다.

Browser mode: 탭, 북마크, 페이지 조작
Script mode: 템플릿 실행, 외부 API 호출
Design mode: 추출, 재구축, 저장, 업로드

Design Harvester는 Design mode에 가두어 두었습니다.

브라우저에서 보고 있는 페이지를 대상으로 하지만, 조작의 의미는 다릅니다. 사용자가 「이 페이지를 디자인 소재로 처리한다」라고 명시적으로 선택했을 때만 동작합니다.

HTML과 CSS를 WebView에서 가져오기

Electron에서는 표시 중인 페이지가 webview 내에 있습니다.

Design Harvester에서는 active tab의 webview에 대해 JavaScript를 실행하여 HTML과 CSS를 취득합니다.

HTML은 selector가 지정되어 있으면 해당 요소, 없으면 body 전체를 대상으로 합니다.

selector 있음: document.querySelector(selector).outerHTML
selector 없음: document.body.innerHTML

CSS는 document.styleSheets에서 읽을 수 있는 범위의 CSS 규칙을 수집합니다.

크로스 오리진 (Cross-origin) stylesheet는 읽을 수 없는 경우가 있으므로, 그 부분은 예외를 무시하고 스킵합니다.

이 시점에서 완전한 재현을 목표로 하는 것이 아니라, AI에게 전달하기 위한 재료를 모은다는 식으로 타협했습니다.

AI에게는 복사가 아닌 재구축을 의뢰하기

취득한 HTML/CSS는 그대로 저장하기 위한 것이 아니라, Gemini에게 전달하여 재구축하기 위해 사용합니다.

프롬프트에서는 상당히 강하게 「원래 사이트를 복사하지 말 것」을 지정하고 있습니다.

원래의 브랜드명을 사용하지 말 것
제목이나 본문을 그대로 사용하지 말 것
가공의 회사나 서비스로 다시 만들 것
...

이를 통해 단순한 클론이 아니라 「학습한 디자인 언어를 사용한 별개의 디자인」을 만드는 방향으로 유도하고 있습니다.

물론 법무적으로 완벽하다는 뜻은 아닙니다. 다만, 적어도 설계 사상으로서 복사가 아닌 재구성에 무게를 두어야 합니다.

출력은 HTML/CSS 2개 블록으로 고정하기

AI의 출력을 자유롭게 두면 다루기 어려워집니다.

그래서 응답 형식을 고정했습니다.

1. html code block
2. css code block

Electron 측에서는 이 두 개의 코드 블록을 정규 표현식으로 추출합니다.

...
...

추출할 수 없으면 에러로 처리합니다.
AI의 응답은 편리하지만, 앱 측에서는 반드시 기계적으로 다룰 수 있는 형태로 가두어 둘 필요가 있습니다.

저장 시에는 1폴더 1디자인으로 하기

재구축한 디자인은 로컬 폴더에 저장합니다.

Desktop/vibeui-designs/generated/<category>_<title>_<timestamp>/
index.html
style.css
...

index.html에는 최소한의 HTML 래퍼(wrapper)를 붙이고, style.css를 불러오는 형태로 만듭니다.

source.txt에는 참조 URL, 카테고리, 생성 일시를 남깁니다.

이것은 나중에 다시 확인할 때 매우 중요합니다.

AI로 생성한 디자인은 수가 많아지기 때문에, "어디에서 영감을 얻었는지", "어떤 카테고리였는지"를 파일 단위로 남겨두면 정리하기가 쉬워집니다.

GAS 큐(Queue)로 일괄 처리하기

단발적인 추출만으로는 디자인 수집의 효율을 높일 수 없습니다.

그래서 Google Apps Script (GAS)와 스프레드시트를 큐 (Queue)로 사용할 수 있도록 만들었습니다.

행 데이터에는 URL, 카테고리, selector 등을 포함합니다.

{
"url": "https://example.com",
"category": "part",
...

Electron 측은 GAS로부터 대기 중인 (pending) 행을 가져와 순서대로 처리합니다.

GAS에서 대상 URL 목록을 가져옴
각 URL을 webview로 열기
selector로부터 HTML/CSS 추출
...

이런 방식으로 구성하면 사람이 한 페이지씩 직접 여는 작업을 줄일 수 있습니다.

VibeUI로의 업로드 동선

Design Harvester에서는 zip 파일을 지정하여 업로드하는 동선도 마련해 두었습니다.

업로드 대상 URL은 UI 입력 또는 환경 변수 (Environment Variable)를 통해 전달합니다.

DESIGN_UPLOAD_URL
PRODUCTION_UPLOAD_URL

전송 시에는 category와 zip 파일을 multipart/form-data 형식으로 보냅니다.

VibeUI 측에서 이를 받으면, 생성된 디자인을 검색 API용 데이터로 만들 수 있습니다.

즉, 다음과 같은 흐름이 연결됩니다.

참조 사이트를 본다
디자인 언어를 추출한다
AI로 다른 디자인으로 재구축한다
...

구현하며 알게 된 점

Design Harvester에서 중요했던 것은 기술적인 추출보다 경계 설계 (Boundary Design)였습니다.

어디까지를 참고할 것인가
무엇을 복사 금지할 것인가
AI 출력을 어떻게 기계적으로 다룰 것인가
...

AI로 HTML/CSS를 만드는 것 자체는 쉬워지고 있습니다.

하지만 프로덕트의 자산으로 다루려면, 생성 전후의 로그, 저장 형식, 출처, 카테고리, 업로드 동선까지 결정해야 합니다.

요약

Electron 기반 AI 브라우저에 Design Harvester를 넣음으로써, 열람, 추출, 재구축, 저장, 업로드를 하나의 흐름으로 만들 수 있었습니다.

WebView에서 HTML/CSS를 가져옴
AI에 디자인 언어로 전달함
복사가 아닌 다른 디자인으로 재구축함
...

VibeUI와 같은 디자인 검색 API를 키워나가기 위해서는 디자인을 수집하는 입구가 필요합니다.

Design Harvester는 그 입구를 Electron 브라우저 측에 만드는 시도였습니다.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0