지도에는 앉을 곳이 없다고 했지만, Gemma에게 물어봤습니다
요약
본 글은 무릎 통증이 있는 사람을 위해 '앉을 곳'을 중심으로 산책 경로를 계획하는 앱 'Bench to Bench'를 소개합니다. 이 앱은 기존 지도 데이터(OpenStreetMap)가 놓치는 사소한 휴식 공간까지 AI 모델 Gemma의 능력을 활용하여 찾아내어, 실제 사용자 경험에 맞는 안전하고 지속 가능한 산책 코스를 제공함을 보여줍니다.
핵심 포인트
- 앉을 곳 150m 이내, 평탄한 경로를 계획하는 앱입니다.
- OpenStreetMap만으로는 부족했던 휴식 공간을 Gemma가 보완합니다.
- AI 기반의 위치 인식 및 사용자 맞춤형 안내 기능을 구현했습니다.
이것은 Hacktoberfest Open-Source AI Challenge: Touch Grass에 제출하는 작품입니다.
제가 만든 것 (What I Built)
저의 아버지는 무릎 통증이 있으십니다. 산책을 좋아하시지만, 무릎이 버티지 못할 때 앉을 곳이 확실하지 않으면 외출을 삼가하십니다. 그래서 모든 산책에서 던져지는 질문은 "얼마나 멀리"가 아니라 "어디서 쉴 수 있는가"입니다.
Bench to Bench는 사용자가 있는 어디든 짧은 산책 경로를 계획합니다. 이 경로는 앉을 곳이 항상 150m 이내에 있으며, 계단이나 자갈길, 혹은 돌길이 없는 곳이어야 합니다. 위치를 입력하고 원하는 길이를 선택한 다음 '시작'을 누릅니다. 그러면 화면이 검게 변하고 휴대폰은 주머니 속으로 들어가며 다음과 같이 말합니다: "70미터 거리에 앉을 곳이 있습니다." "30미터 앞에서 왼쪽으로 도세요." "절반 지점입니다. 돌아가는 길도 마찬가지로 완만합니다."
화면은 약 10초 동안 켜져 있고, 나머지 산책은 외부에서 이루어집니다.
저는 이 앱을 두 곳에서 테스트했고, 그 차이가 바로 이야기의 핵심이었습니다:
- 독일 마인츠-노이슈타트(Mainz-Neustadt). OpenStreetMap에는 이곳에 431개의 벤치가 있습니다. 이 앱은 지도에서 곧바로 590m, 987m, 그리고 1,294m 길이의 루프를 계획하며, 좌석 없이 가장 긴 구간도 149m에 불과합니다.
- 인도의 콜카타-하즈라(Kalighat-Hazra). OpenStreetMap에는 앉을 곳이 전혀 없습니다. 지도만으로는 앱이 "안전한 산책은 불가능합니다."라고 말합니다. 하지만 콜카타를 걸어본 사람이라면 누구나 그것이 틀렸다는 것을 압니다. 사방에 찻집의 벤치, 가게 계단, 높은 플랫폼, 낮은 벽들이 있습니다. 단지 어떤 지도에도 기록되어 있지 않을 뿐입니다.
그 간극을 Gemma가 채웁니다.
데모 (Demo)
앱: https://koushik890.github.io/bench-to-bench/web/ (위치 권한을 허용하고, 아무 곳에 가지 않고 안내 음성을 듣기 위해 "Practice walk"를 누르세요).
코드 (Code)
GitHub logo Koushik890 / bench-to-bench
앉을 곳이 가까이에 있는 산책 경로 계획기. Hacktoberfest 2026 Week 1.
Bench to Bench
무릎 통증이 있는 사람을 위한 산책 계획기입니다. 앉을 곳이 150m를 넘지 않는 짧은 순환 경로를 짜주며, 계단이나 울퉁불퉁한 지형도 없습니다. 걸으면서 휴대폰은 주머니에 넣어두고 다음과 같이 말합니다: "벤치까지 80미터입니다."
DEV의 Hacktoberfest 2026 Week 1 'Touch Grass' 챌린지를 위해 제작되었습니다.
같은 앱, 두 도시
- 마인츠-노이슈타트 (Mainz-Neustadt) (55118): OpenStreetMap은 이미 이곳에 431개의 벤치를 알고 있으므로, 경로가 지도에서 바로 나옵니다.
- 콜카타, 칼리가트-하즈라 (Kolkata, Kalighat-Hazra): OpenStreetMap은 앉을 곳이 0군데밖에 모릅니다. Gemma는 Mapillary의 거리 사진들을 보고 찾아냅니다: 차 노점 벤치, 높은 단상, 건물 앞 계단.
Gemma는 오직 사진만을 설명합니다. 단순한 코드가 모든 경로 결정을 내립니다. 모든 Gemma 답변은 고정된 형식에 따라 확인됩니다. 만약 형식을 따르지 않으면, 해당 사진은 건너뛰고 실패로 간주되며, 추측하지 않습니다.
작동 방식
OpenStreetMap 거리 ──> 도보 그래프 (no
…
제작 과정
Gemma가 보고, 단순 코드가 결정합니다. 이 규칙이 모든 것을 만들었습니다.
- 거리(Streets). Overpass API의 OpenStreetMap 데이터가 도보 그래프로 변환됩니다. 코드는 계단, 자갈길, 돌길, 사유지 경로, 그리고 경사도 6% 이상의 구간을 제거합니다. 마인츠(Mainz)에서는 이 과정으로 계단 1.4km와 거친 지면 3.4km가 제외되었습니다.
- 사진(Photos). 저는 Mapillary에서 칼리가트-하즈라(Kalighat-Hazra) 지역의 거리 사진 165장을 가져왔습니다.
- Gemma 4 E4B는 RTX 5060 노트북의 Ollama를 통해 로컬로 구동되며, 각 사진을 보고 고정된 JSON 형식으로 답변합니다: 앉을 곳이 있는지, 어떤 종류인지(계단, 부서진 보도, 그늘 등), 그리고 이유에 대한 문장 하나가 포함됩니다. 코드는 모든 답변을 확인하며, 형식이 일치하지 않으면 해당 사진은 실패로 간주되어 지도에 아무것도 추가되지 않습니다.
- 경로(Routes). 시드된 검색(seeded search)은 좌석에서 좌석으로 이동하며, 모든 구간이 150m 이하인 루프만 허용합니다. Gemma는 이 단계를 결코 알지 못합니다.
- 산책(The walk). 정적 웹 페이지입니다. 사용자의 주변 900m 내의 거리와 벤치를 다운로드하고, 동일한 규칙으로 브라우저에서 산책 경로를 계획합니다. GPS가 사용자 위치를 경로에 맞추고 Chrome의 내장 음성 기능이 안내 문구를 읽어줍니다.
콜카타(Kolkata)에서의 결과: Gemma는 165장의 사진 중 앉을 곳 7곳을 발견했습니다 (대부분 상점 앞 낮은 난간이나 플랫폼, 그리고 한 상점 밖에 있는 의자였습니다). 이를 바탕으로 앱은 사용자가 좌석에서 69m를 넘지 않는 254m 루프를 계획합니다. 지도만으로는 아무것도 계획할 수 없었습니다.
이것은 짧은 산책이며, 제가 솔직하게 이유를 밝히고 싶습니다. 해당 지역의 최근 사진 157장은 한 사람에 의해 몇몇 거리를 따라 약 40개 지점에서 찍힌 것입니다. 저는 주변 여덟 개 지역을 확인했지만, 최근 사진이 있는 곳은 없었습니다. Gemma는 누군가 사진을 찍은 곳에서만 좌석을 찾을 수 있습니다. 따라서 600m나 1km의 산책은 불가능했습니다.
Gemma는 이 정도인가요? 직접 확인해봤습니다
저는 Gemma의 답변을 보기 전에 마인츠 거리 사진 40장을 제가 직접 라벨링했고, 그 후 비교했습니다.
| 질문 | 항상 '아니오'라고 답함 | Gemma 4 E4B | Gemma 4 E2B |
|---|---|---|---|
| 앉을 곳 | 92% | 95% | 95% |
| ... | |||
| 실제 좌석 3개 찾기 | 발견함 | 오답 좌석 | |
| --- | --- | --- | --- |
| Gemma 4 E4B | 2 | 1 | |
| ... | |||
| 무엇을 얻었는가: |
- 좌석에 대해서는 Gemma가 같은 사진에서 map보다 우수했습니다. 15m 떨어진 지도상의 벤치는 종종 카메라 뒤에 있습니다. Gemma는 자신이 볼 수 있는 것만 이름을 언급합니다.
- 계단과 그늘에 대해서는 항상 "아니요"라고 답하는 규칙에게 Gemma가 패배했습니다. E4B는 계단이 없는 사진 16장과 그늘이 없는 사진 26장에 각각 "계단(steps)"과 "그늘(shade)"이라고 말했습니다. 따라서 경로 계획기는 좌석 답변만 사용합니다. 이것이 바로 모델이 읽고 코드가 결정하는 이유입니다.
- 40장의 사진 중 단지 3장만이 좌석을 포함하고 있었기 때문에, 이 수치들은 매우 적은 예시에 기반합니다. 저는 콜카타가 아닌 마인츠(Mainz)를 라벨링했으므로, 콜카타의 좌석은 아직 수동으로 확인되지 않았습니다.
- 속도: E4B는 사진당 약 0.9초, E2B는 0.6초로, 총 165장의 사진을 3분 이내에 처리했습니다.
문제점 (What broke)
- 모델 서버가 두 번 충돌했습니다 (E4B를 처음 로드할 때,
0xc0000409). 모델이 사용 가능한 GPU 메모리의 절반만 들어갔기 때문에 첫 번째 사진은 77초가 걸렸습니다. 그 이후로는 약 1초였습니다. 현재 스크립트는 실패한 사진을 재시도합니다. - 앱이 너무 많이 말했습니다. 콜카타에서는 좌석 간 거리가 약 20m이어서, 첫 번째 연습 산책에서 저는 254m를 이동하며 23개의 문장을 말했습니다. 이제는 다음 좌석만 안내하고 최대 40m마다 "여기에(here)"라고 말합니다: 총 12개 문장.
- 검은색 도보 화면이 지도 아래에 위치했습니다. 지도 라이브러리의 레이어들이 더 높은 z-index를 가지고 있었습니다. 테스트 비디오에서 프레임을 추출하는 방식으로만 이를 발견할 수 있었습니다.
- ElevenLabs 사용이 차단되었습니다. 무료 계정이 첫 요청에서 "비정상적인 활동(unusual activity)"으로 플래그가 지정되어, 음성은 휴대폰 자체의 것입니다. 오프라인에서도 작동하며, 어쨌든 이것이 더 적합했습니다.
- 아무도 아직 경로를 걸어보지 않았습니다. 저는 시뮬레이션된 산책을 통해 모든 것을 집에서 구축하고 테스트했습니다. 꾸며내는 것보다는 그렇게 말하는 편이 낫다고 생각합니다.
여기서 OpenAI가 중요한 이유
- 어떤 사람의 아버지가 걷는 장소의 거리 사진은 노트북에서 떠나지 않습니다. Gemma를 Ollama를 통해 제 GPU에서 실행합니다.
- 사진당 비용이 들지 않기 때문에, 동네의 모든 사진을 읽어도 괜찮습니다.
- 모델을 교체하는 것은 한 단어였고, 이로 인해 E2B 대 E4B 테스트가 저렴했습니다. 더 큰 모델이 더 많은 좌석을 찾고 작은 모델은 적게 상상한다는 것을 보여주었습니다.
- 저는 어디서 실패하는지 볼 수 있었고, 그것을 믿기보다는 그 주변에 규칙을 만들 수 있었습니다.
수상 부문 (Prize Categories)
- Gemma: Gemma 4 E4B(비교를 위해 E2B도 사용)는 Ollama로 로컬에서 실행되며, 콜카타에서 앱이 어디에 앉을지 알 수 있는 유일한 방법입니다.
지도 데이터 © OpenStreetMap contributors (ODbL). Mapillary의 거리 사진 (CC BY-SA 4.0). Claude Code의 도움으로 구축됨.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기