2번의 주말 만에 AI 사이드 패널을 출시한 경험
요약
두 번의 주말 동안 Chrome 확장 프로그램을 통해 AI 사이드 패널 MVP를 구축하고 출시한 개발 경험담입니다. Chrome API 활용, CSP 보안 정책 해결, 그리고 멀티 모델 연동 과정을 다룹니다.
핵심 포인트
- Chrome Side Panel API를 활용한 UX 개선
- CSP 정책으로 인한 fetch 제한 및 서비스 워커 해결법
- OpenAI, Claude, Gemini 등 멀티 모델 연동 구현
- 빠른 출시(Shipping Speed)를 위한 MVP 중심 개발
지난 두 달 동안 저에게 가장 중요했던 주제인 출시 속도(shipping speed)에 대해 이야기해 보려 합니다.
설정 (The setup)
저는 Chrome 확장 프로그램에 대한 아이디어가 있었습니다. 텍스트를 하이라이트(highlight)하고, 이를 ChatGPT로 보낸 뒤, 사이드 패널(side panel)에서 답변을 확인하는 것이었습니다. 저는 이 기능의 일부를 수행하는 세 가지 서로 다른 도구를 사용해 보았지만, 그중 어느 것도 제가 원하는 방식으로 작동하지 않았습니다.
저에게 두 번의 주말을 주었습니다. 첫 번째 주 토요일과 일요일에는 MVP(Minimum Viable Product, 최소 기능 제품)를 구축하고, 두 번째 주 토요일과 일요일에는 다듬기(polish) 작업을 합니다. 그리고 월요일에 Chrome Web Store에 제출하는 것이 계획이었습니다.
첫 번째 주말 (Weekend 1)
토요일 오전 9시에 시작했습니다. 점심때쯤에는 선택된 텍스트가 미리 채워진 상태로 ChatGPT를 여는 팝업 창(popup window)을 만들었습니다. 그것은 잘못된 UX(User Experience, 사용자 경험)였습니다. 화면에 두 가지 요소가 나타나고 원래 페이지가 밀려나면서 워크플로우(workflow)가 깨졌기 때문입니다.
점심을 먹고 돌아와서 대신 사이드 패널을 만들기로 결정했습니다. Chrome 사이드 패널 API(side panel API)가 존재합니다. 문서는 4문단 정도로 짧게 작성되어 있으며, 대부분의 내용은 색상과 크기에 관한 것이었습니다. 페이지 탐색(navigation) 중에도 패널이 유지되도록 만드는 방법을 알아내기 위해 예시 확장 프로그램의 소스 코드를 읽어야 했습니다.
일요일 저녁까지 저는 다음과 같은 기능을 구현했습니다: 텍스트 선택, 버튼 클릭, 그리고 사이드 패널에서 ChatGPT 스타일의 답변 확인. 답변은 하나의 가짜 응답으로 하드코딩(hardcoded)되어 있었습니다. 선택된 텍스트는 chrome.storage.session을 통해 전달되었습니다. 아직 실제 모델(model)에 연결된 것은 아무것도 없었습니다.
첫 번째 주말 총 소요 시간: 약 14시간. 여기에는 버려버린 팝업 창 방식에 낭비한 2시간이 포함되어 있습니다.
두 번째 주말 (Weekend 2)
토요일은 OpenAI API에 직접 연결하는 작업이었습니다. 백엔드(backend)는 없습니다. 사용자의 API 키는 Chrome 로컬 스토리지(local storage)에 저장됩니다. 선택된 텍스트는 제가 작성한 시스템 프롬프트(system prompt)와 함께 OpenAI로 전송됩니다. 답변은 사이드 패널로 스트리밍(streaming)됩니다.
그날 저는 제가 몰랐던 CSP(Content Security Policy, 콘텐츠 보안 정책) 문제 때문에 Chrome 확장 프로그램의 사이드 패널에서 fetch를 사용할 수 없다는 사실을 배웠습니다. 이 문제로 3시간을 허비했습니다. 해결 방법은 fetch 호출을 백그라운드 서비스 워커(background service worker)에 넣고, chrome.runtime.sendMessage를 통해 응답을 사이드 패널로 다시 스트리밍하는 것이었습니다.
토요일 밤이 되었을 때, OpenAI를 통한 엔드 투 엔드 (end-to-end) 작동이 완료되었습니다.
일요일은 멀티 모델 (multi-model) 작업의 날이었습니다. Claude를 추가하고, Gemini를 추가하고, DeepSeek를 추가했습니다. 모델마다 서로 다른 베이스 URL (base URL), 서로 다른 요청 형태 (request shape), 그리고 스트리밍 응답 (streaming response)을 파싱하는 서로 다른 방식이 필요했습니다. OpenAI 호환 API (OpenRouter를 통한 Claude, OpenRouter를 통한 Gemini, DeepSeek 직접 연결) 덕분에 이전보다 수월하긴 했지만, 각 모델을 테스트하는 데 여전히 6시간씩 소요되었습니다.
일요일 밤이 되었을 때 저는 4개의 모델을 작동시켰습니다. 이를 패키징하여 Chrome 웹 스토어 (Chrome Web Store)에 업로드했습니다.
주말 총 소요 시간은 약 16시간이었습니다. CSP 디버깅이 토요일 시간의 상당 부분을 잡아먹었습니다.
제출 이후
Chrome 웹 스토어 심사에는 3일이 걸렸습니다. 수요일에 승인되었습니다. 저는 Reddit, X, 그리고 Indie Hackers에 이 소식을 게시했습니다.
첫 48시간 동안 약 9명의 사용자를 확보했습니다. 이는 제가 기대했던 것보다 훨씬 적은 수치였습니다. 이후 5주 동안 6명을 더 확보했습니다. 따라서 총 5주가 지난 시점에 15명의 사용자를 얻었습니다.
배운 점
1. 출시 (Shipping)는 생각보다 빠릅니다. 사이드 패널 API (side panel API)가 작고 대부분의 작업이 이전에 해봤던 배관 작업 (plumbing)이었기 때문에, 두 번의 주말은 현실적인 목표였습니다.
2. CSP는 시간을 낭비하게 만듭니다. 외부 API와 통신하는 사이드 패널이 있는 Chrome 확장 프로그램을 만든다면, 서비스 워커 (service worker)와 sendMessage 간의 상호작용을 위해 4시간 정도의 예산을 잡으세요. 이에 대한 좋은 문서가 없습니다.
3. OpenAI 호환 API 생태계가 진정한 승리 요인입니다. 제가 지원하는 4개 모델 중 3개가 OpenAI 요청 형태 (request shape)를 통해 접근 가능했습니다. 덕분에 통합 작업 시간을 절반으로 줄일 수 있었습니다.
4. 5주 동안 15명의 사용자는 충분하지 않습니다. 머리로는 알고 있었습니다. 하지만 이제는 밤 11시에 대시보드 앞에 앉아 사용자 수를 새로고침하며 몸소 깨닫게 되었습니다. 배포 (Distribution)가 게임의 전부입니다. 만드는 것은 쉬운 부분입니다.
5. 저를 가장 느리게 만든 것은 개발이 아니었습니다. 사이드 패널 UX가 올바른 선택인지 스스로를 설득하는 과정이었습니다. 팝업 창 (popup window) 대신 처음부터 그 부분부터 시작했어야 했습니다.
다르게 했을 점
제출하기 전에 리스팅 페이지 (listing page)에 더 많은 시간을 투자했을 것입니다. 초기 48시간 동안의 트래픽은 대부분 제가 Reddit 게시물을 클릭하고 Chrome 웹 스토어 (Chrome Web Store) 페이지에 접속했다가 바로 이탈한 사람들로부터 발생했습니다. 설명 (description)의 첫 문장이 이 확장 프로그램이 무엇을 하는지에 대해 충분히 명확하지 않았습니다.
그것은 해결 가능한 문제입니다. 어려운 부분은 이미 끝났습니다.
만약 여러분이 Chrome 확장 프로그램 (Chrome extension)을 개발 중이고 사이드 패널 (side panel)이 어떻게 연결되어 있는지 확인하고 싶다면, 소스 코드는 GitHub에 있습니다. 관련 파일은 sidepanel.js이며 서비스 워커 (service worker)는 background.js입니다. 주석이 달려 있습니다.
여러분의 지난 2주간의 주말 프로젝트는 어떤 모습이었나요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기