Touchwood: 야외에서만 피드가 열리는 이유
요약
Touchwood는 사용자의 과도한 스크롤링(doomscrolling) 습관을 개선하기 위해 개발된 브라우저 확장 프로그램입니다. 이 앱은 특정 사이트 접속 시, 사용자에게 주변의 실제 장소를 찾아가 미션을 수행하도록 강제합니다. 미션 완료 후 오픈 웨이트 비전 모델이 사진과 위치를 검증하면 일회용 코드를 받아 잠긴 피드를 열 수 있습니다.
핵심 포인트
- 야외 활동을 유도하는 '둠스크롤' 방지 브라우저 확장 프로그램입니다.
- OpenStreetMap 기반으로 실제 장소 미션을 부여하고, 사용자의 이동을 강제합니다.
- 오픈 웨이트 비전 모델이 현장 사진과 위치를 검증하여 코드를 발급합니다.
- 단순한 타이머가 아닌, 외부 활동을 통해 보상을 얻는 구조입니다.
이 글은 Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass에 제출하는 내용입니다.
제가 만든 것
Touchwood는 야외에서만 열리는 '둠스크롤(doomscroll)' 잠금장치입니다.
이 브라우저 확장 프로그램은 제가 몇 시간을 잃어버리곤 하는 사이트들을 차단합니다. 해당 사이트에 접속하면 죄책감을 주는 타이머 대신, 저에게 하나의 임무(quest)가 주어집니다. 저는 휴대폰으로 Touchwood를 열고, 이 앱은 OpenStreetMap에서 근처의 실제 장소를 하나 골라줍니다:
💧 Mallard Lake는 남쪽으로 330m 거리에 있습니다. 그곳까지 걸어가서 물을 사진 찍으세요.
저는 휴대폰을 주머니에 넣고 걷습니다. 도착하면 진동과 소리가 울립니다. 사진을 찍으면, 휴대폰에서 구동되는 오픈 웨이트 비전 모델이 두 가지를 확인합니다: 제가 실제로 야외에 있는지, 그리고 그것이 정말 물인지? 둘 다 통과하면, 저는 일회용 6자리 코드를 받습니다. 이 코드를 차단된 페이지에 입력하고, 제 피드가 30분 동안 열립니다. 그러고 나면 다시 잠깁니다.
화면은 그저 잠금장치일 뿐입니다. 중요한 모든 것은 외부에서 일어납니다.
| 오늘 | 임무 완료 | 현장 기록 |
|---|---|---|
![]() | ![]() | ![]() |
이것은 습관적으로 생각하기 전에 엄지손가락이 피드를 열어버리는 사람, 즉 저 같은 사람을 위한 것입니다. 몇 가지 요소들이 이것을 단순한 장난감 이상의 것으로 만듭니다:
- 실제 장소 기반의 미션, 단순한 '산책하기'가 아닙니다. 미션은 주변에 실제로 지도화된 것들(나무, 호수, 공원, 벤치, 전망대, 공공 예술 작품)에서 발생합니다. 각 미션은 도보 시간과 방향을 보여줍니다.
- 주머니 속 내비게이션 기능: 휴대폰과 함께 돌아가는 나침반 화살표, 진행률 링(progress ring), 그리고 도착 시 진동 알림이 있어 이동 중에 화면만 응시하고 있지 않게 합니다.
- 현장 일지(Field journal): 완료된 모든 미션은 사진, 장소, 시간 정보와 함께 휴대폰에만 저장됩니다.
- 연속 기록(Streaks), 걸은 거리(km), 야외 체류 시간(분), 그리고 퀘스트 유형별 수집 가능 스탬프 12개.
- 실제 하늘을 반영하는 홈 화면: 배경 풍경이 시간대와 계절에 따라 변하며, "남은 일광 시간 2시간 10분 · 일몰 6:44 PM"과 같은 정보가 기기에서 계산되어 표시됩니다.
- 잠긴 페이지는 카운트를 유지합니다: "오늘 #7 시도해 보세요." 이 숫자가 저에게 어떤 타이머보다 더 큰 의미를 주었습니다.

데모(Demo)
휴대폰에서 사용해 보세요: https://touchwood-7q5r.onrender.com/
휴대폰 브라우저에서 열고, 위치 및 카메라 접근을 허용한 후 **퀘스트 찾기(Find me a quest)**를 누르세요. 홈 화면에 추가하여 설치할 수 있습니다. 첫 사진 확인 후에는 비전 모델(vision model)이 캐시되어 신호가 없어도 작동합니다.
이 앱은 자체적으로 작동합니다: 퀘스트, 기기 내 사진 확인 기능, 일지, 연속 기록 및 스탬프까지 모두 가능합니다. 브라우저 확장 프로그램은 잠금 기능을 추가하며, 완료된 퀘스트에서 얻는 6자리 코드가 이를 해제합니다. 책상에서 사용해 보고 싶으신가요? 설정(Settings)에서 **데모 모드(Demo mode)**를 켜서 도보 거리 확인 과정을 건너뛸 수 있습니다.
코드(Code)
GitHub logo lillygrace-l / touchwood
🌿 Touchwood
밖으로 나가지 않으면 피드가 잠겨 있습니다.
▶ 사용해 보기: https://touchwood-7q5r.onrender.com/ (휴대폰에서 열기)
브라우저 차단 및 현실 탐험 경험 제공 앱, Touchwood
브라우저 확장 프로그램이 사용자의 과도한 스크롤링(doomscrolling) 사이트를 차단합니다. 다시 접속하려면 휴대폰에서 Touchwood를 엽니다. 이 앱은 사용자 근처의 실제 장소("Elk Glen Lake is 430 m southeast, go photograph the water")에서 임무(quest)를 하나 선택하고, 사용자를 그곳으로 안내합니다. 휴대폰에 탑재된 오픈 웨이트 비전 모델이 사진을 확인하면, 1회용 6자리 코드를 받게 되며 이 코드로 30분 동안 사이트가 잠금 해제됩니다.
화면은 단지 잠금장치일 뿐입니다. 전체 경험은 외부에서 일어납니다.
포함된 기능
휴대폰 (PWA)
- 지도 기반 실제 임무: OpenStreetMap에서 가져온 근처 나무, 호수, 공원, 벤치, 전망대, 공공 예술 작품 등이며, 도보 시간과 방향이 제공됩니다.
- 주머니 속 내비게이션: 휴대폰에 나침반 기능이 있는 경우 회전하는 나침반 화살표, 진행률 링(progress ring), OSM 도보 길 안내, 그리고 특정 상황에서 울리는 진동 및 벨소리 등
Repo: https://github.com/lillygrace-l/touchwood
전체 앱은 순수 HTML, CSS 및 JavaScript로 구성되어 있습니다. 설치 가능한 PWA이며, 번들러나 백엔드 없이 약 100 KB의 앱 코드를 가집니다. 확장 프로그램은 Chrome Manifest V3 확장 프로그램입니다.
제작 과정
노트북 (Chrome 확장 프로그램) 휴대폰 (PWA)
declarativeNetRequest가 피드 차단 GPS → OpenStreetMap (Overpass) → 근처 시설물
"Go touch grass" 페이지 → 임무: 나무 / 물 / 공원 / 벤치 / 예술품 / 전망대
...
1. transformers.js를 통한 CLIP ViT-B/32: 심판 역할. 오픈 가중치(open-weight) 모델인 CLIP을 transformers.js를 통해 브라우저에서 실행합니다 (약 155 MB, 한 번 다운로드 후 캐시됨). 제로샷 분류(Zero-shot classification)란 제가 아무것도 학습시키지 않았다는 의미입니다. 분류기의 "지식"은 단지 영어 레이블 목록일 뿐이며, 이는 Is this even a valid card? Zero-shot image classification model in a lambda container에서 설명된 것과 같은 속임수입니다. 제 모델은 Lambda가 아닌 휴대폰에서 실행됩니다.
모든 사진에 대해 두 가지 검사를 수행합니다:
- 야외인가? (Outdoors?): "outdoors / nature / a street" 대 "indoors / a room / a screen". 저는 샘플 사진을 이용해 이 부분을 조정했습니다: 야외 사진은 0.56–0.86점을 기록했고 실내 사진은 0.20–0.29점을 기록했으므로, 기준점(cutoff)은 0.5입니다. 또한 모니터 위의 나무 사진도 거부합니다.
- 목표물인가? (Is it the target?): 이 부분에서 제가 처음으로 실수를 했습니다.
제 첫 번째 버전은 모든 동의어 점수를 합산했습니다: water + a river + a pond + a lake + a fountain. 시뮬레이션 카메라를 이용한 종단 간(end-to-end) 테스트 중, 모래 위의 해변 수건과 책 사진이 물 관련 질문에서 41%의 확률로 통과했습니다. 사진 속에는 물이 아무것도 없었습니다. 열세 개의 레이블 중 다섯 개가 물에 관한 것이었기 때문에, 모델이 무언가를 보기 전에 목표물 자체가 약 38%의 확률을 수집합니다. 제 기준점은 35%였습니다.
수정된 부분은 softmax 함수가 로짓(logit) 차이를 유지한다는 사실을 이용한 것입니다. 따라서 $\ln(p_a / p_b) = \text{logit}_a - \text{logit}_b$ 입니다:
// Best target label must rank top-3 AND beat the median decoy by ~2.7×.
const logit = Object.fromEntries(target.map((r) => [r.label, Math.log(r.score)]));
const best = Math.max(...quest.labels.map((l) => logit[l]));
...
18개의 오답(decoys)("모래", "포장된 길", "동물", "책" 등)을 사용하자, 샘플 사진 7장 모두가 올바르게 분류되었습니다. 수건 이미지는 _"물을 찾지 못했습니다. 책처럼 보였습니다."_라는 메시지와 함께 실패합니다. 꽃 위의 나비와 잔디 위의 개는 통과합니다. 사진 7장은 적은 세트이므로, 제가 외부에서 테스트를 진행함에 따라 이 임계값(thresholds)들은 계속 변동할 것입니다. 이것들이 제 코드 내의 단순한 숫자이기 때문에, 저는 이 값들을 조정할 수 있습니다.
앱도 작동하는 것을 보여줍니다. 모든 결과 아래에는 "온디바이스 모델이 본 것(What the on-device model saw)" 목록에 실제 점수들이 나열됩니다. 여기서 "동물"은 CLIP의 최고 추측이지만, 잔디는 여전히 2위를 차지하며 마진을 쉽게 확보합니다:
2. Overpass API를 통한 OpenStreetMap: 퀘스트 제공자. 단 하나의 Overpass 쿼리만으로 선택한 반경 내의 나무, 물, 공원, 숲, 벤치, 놀이터, 전망대 및 공공 예술 작품을 가져올 수 있습니다. 퀘스트는 최소 120m 거리에 설정되어 있어 실제로 걸어 다닐 수 있으며, 마지막 지도는 캐시(cached)되므로 신호가 없어도 작동합니다. 주변에 매핑된 것이 없거나 오프라인 상태라면, 하늘, 나뭇잎, 꽃, 잔디와 같은 "어디서든" 퀘스트를 받게 됩니다.
3. WebLLM을 통한 선택적 로컬 LLM: 이야기꾼. WebGPU를 이용해 브라우저에서 실행되는 오픈 웨이트 모델(Gemma 2 2B, Qwen2.5 0.5B 또는 Llama 3.2 1B이며 설정에서 교체 가능)이 각 퀘스트를 친구가 외부로 부추기듯 읽히도록 다시 작성합니다. LLM은 결코 중요한 것을 결정하지 않습니다. 퀘스트 유형, CLIP 레이블 및 지오펜스(geofences)는 결정론적(deterministic)입니다. 모델은 제가 이미 가지고 있는 사실들(장소 이름, 거리, 방향, 계절)만을 받아 단어를 작성할 뿐입니다. 크기가 작거나 교체된 모델이 텍스트를 더 나쁘게 만들 수는 있지만, 존재하지 않는 장소로 당신을 안내할 수는 없습니다.
4. 서버가 전혀 없음. 휴대폰과 확장 프로그램은 링크 또는 16자리 코드를 입력하여 비밀을 한 번 공유합니다. 잠금 해제 코드는 해당 비밀과 5분 시간 창의 HMAC-SHA256이며, TOTP와 같은 아이디어로 양쪽에서 오프라인으로 확인됩니다. 각 퀘스트는 정확히 하나의 코드를 제공하며, 확장 프로그램은 재사용을 거부하고 잘못된 추측에 대해 속도 제한을 적용합니다.
Open Innovation이 중요한 이유?
이 앱의 핵심이 제가 사는 곳과 걸어 다니는 장소의 일일 지오태그 사진이기 때문입니다. Touchwood는 폐쇄적인 비전 API로는 출시하지 않을 것입니다.
| Touchwood (개방형, 온디바이스) | 폐쇄적 API에서의 동일한 아이디어 | |
|---|---|---|
| 사용자의 사진 | 휴대폰을 벗어나지 않음 | 다른 사람의 서버에 있는 이웃의 일일 사진 기록 |
| ... | ||
| 마지막 줄에서 개방형이 가장 어려운 부분을 이겼습니다. 해변 수건 버그는 제가 전체 확률 분포를 볼 수 있고 로짓(logits)으로 되돌아갈 수 있었기 때문에만 수정할 수 있었습니다. 폐쇄적인 |
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기


