🌿 WildScout: 주변을 둘러보게 만드는 이유를 주는 AI 동반자
요약
WildScout은 사용자가 주변의 자연물을 발견했을 때 호기심을 충족시키고 탐험을 장려하는 AI 동반자 앱입니다. 이미지 기반 식별, 시각적 단서 제공, 그리고 안전한 관찰 임무(Observation missions)를 통해 단순한 정보 전달을 넘어 지속적인 흥미를 유발합니다. Flutter와 FastAPI로 구축되었으며, OpenRouter를 통해 Qwen3.5-9B 모델을 활용하여 멀티모달 분석을 수행합니다.
핵심 포인트
- AI 동반자 앱 WildScout은 자연물 발견 시 호기심 충족에 초점.
- 이미지 기반 식별과 함께 안전한 관찰 임무를 제공하는 것이 특징.
- Flutter(프론트엔드)와 FastAPI(백엔드)로 구성된 아키텍처를 사용함.
- OpenRouter를 통해 Qwen3.5-9B 오픈 웨이트 모델을 활용하여 멀티모달 분석을 구현함.
이 글은 Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass에 대한 제출물입니다.
제가 만든 것
야외에 있을 때 발생하는 특정한 종류의 호기심이 있습니다.
산책로 옆에서 자라는 꽃을 발견합니다. 이상한 무늬를 가진 나뭇잎을 발견합니다. 무엇인지 식별할 수 없는 것을 보고, 그것이 무엇일지 궁금해하지만, 어디서부터 시작해야 할지 몰라 계속 걷게 됩니다.
저는 바로 그 순간을 위한 무언가를 만들고 싶었습니다.
그래서 WildScout — 안전하게 자연을 탐험하는 AI 동반자를 만들었습니다.
이 아이디어는 현장 안내서(field guide)를 대체하거나 산책을 또 다른 긴 화면 세션으로 만드는 것이 아닙니다. 단지 그러한 작은 호기심의 순간들을 더 쉽게 탐험할 수 있도록 하는 것입니다.
WildScout은 다음과 같은 기능을 합니다:
- 이미지 기반 탐색: 자연물 사진을 업로드하고 가능한 식별 정보를 받습니다.
- 시각적 단서: 모델이 이미지 속 무엇인지 설명하는 데 사용하는 특징들을 볼 수 있습니다.
- 자연 맥락 (Nature Context): 짧고 친근한 설명이나 무언가를 더 자세히 관찰하도록 초대하는 내용을 얻을 수 있습니다.
- WildSafe: 문서화된 위험 경고를 유지하고 지원되지 않는 위험 주장을 피하는, 안전에 민감한 응답 처리 기능을 제공합니다.
- 관찰 임무 (Observation missions): 접근하거나 다루기 위험할 수 있는 무언가를 하도록 요구하지 않으면서 추가적인 탐험을 장려하는, 작고 주제에 맞는 활동을 받습니다.
임무(mission)는 아이디어의 중요한 부분입니다. 저는 이 앱이 이름과 읽고 잊어버리는 단락으로 끝나기를 원하지 않습니다. 다시 주변을 둘러보게 만드는 이유를 주고 싶습니다.
WildScout은 호기심 많은 초보자, 학생, 그리고 평범한 산책을 조금 더 흥미롭게 만들고 싶은 사람들을 위해 설계되었습니다.
사전에 언급할 한 가지 제한 사항이 있습니다. AI 식별은 틀릴 수 있으며, WildSafe는 유기체가 안전하다고 보장할 수 없습니다. 낯선 식물이나 동물은 오직 AI가 생성한 답변만을 근거로 먹거나 다루어서는 안 됩니다.
데모
해당 녹화 영상은 실제 앱 사용 경험을 보여줍니다. 다운로드 가능한 APK와 호스팅된 백엔드는 설정의 별개 부분이며, 실시간 AI 분석을 위해서는 인터넷 접속과 유효한 모델 자격 증명(credentials)이 구성된 백엔드가 필요합니다.
Android 앱: WildScout v0.1.0 릴리스
코드
GitHub 저장소: https://github.com/Pranitha06sri/wildscout
WildScout은 모바일 앱에 Flutter를, 백엔드에 FastAPI를 사용합니다. 이 저장소에는 애플리케이션, 백엔드 구현, 샘플 응답 및 자동화된 테스트가 포함되어 있습니다.
구축 과정
아키텍처
이 애플리케이션은 두 가지 주요 부분으로 구성됩니다:
- Flutter는 Android 사용자 인터페이스와 이미지 제출 흐름을 처리합니다.
- Python과 FastAPI는 이미지 유효성 검사, 모델 요청, 구조화된 응답 및 안전 관련 확인을 처리합니다.
멀티모달 분석을 위해 WildScout은 OpenRouter를 통해 접근하는 오픈 웨이트 모델인 Qwen3.5-9B를 사용합니다.
백엔드는 다음과 같은 7개 필드의 응답을 반환합니다:
identification(식별)confidence(신뢰도)visual_clues(시각적 단서)nature_context(자연 환경 맥락)safety_level(안전 수준)safety_note(안전 참고 사항)mission(임무/목표)
이 필드들을 분리함으로써, 모바일 앱은 하나의 큰 생성 텍스트 블록을 해석해야 하는 대신 예측 가능한 응답 계약(response contract)을 얻게 됩니다.
로컬 추론에서 벗어난 이유
가장 유용했던 교훈 중 하나는 멀티모달 모델을 로컬로 실행해 보려고 시도하면서 얻었습니다.
제 노트북에서 진행한 초기 로컬 추론(local inference) 실험은 매우 느렸습니다. 모델 자체는 올바르게 작동할 수 있었지만, 이미지를 처리하는 데 걸리는 시간이 제가 원했던 모바일 워크플로우에는 비현실적일 정도로 길었습니다.
이 차이점은 중요합니다: 모델을 실행시키는 것과 유용한 속도로 응답하게 만드는 것은 별개의 문제입니다.
현재 구현을 위해 라이브 추론 경로를 OpenRouter를 통해 Qwen3.5-9B로 옮겼습니다. 이 덕분에 모델이 제 노트북에서 직접 실행될 필요 없이 모바일 앱을 호스팅된 모델 추론에 연결하는 것이 실용적이 되었습니다.
트레이드오프는 명확합니다. 이 구성은 인터넷 접속을 요구하며 완전히 오프라인 AI 애플리케이션은 아닙니다.
자연 동반자를 덜 일반적으로 만들기
AI 자연 앱의 첫 번째 버전은 친근한 단락이 붙은 이미지 분류기가 되기 쉽습니다.
저는 그보다 더 나은 것을 원했고, 특히 Nature Context와 관찰 임무에 있어서 그랬습니다.
최신 백엔드 변경 사항은 보존된 시각적 세부 정보에 근거하거나, 이용 가능한 일반 지식을 검토하거나, 유용한 관찰 요청을 담은 두세 개의 대화형 문장을 생성하는 것을 목표로 합니다.
검토된 생태학적 지식은 현재 정원 페튜니아와 꿀벌을 다룹니다. 다른 주제들은 지원되지 않는 생태학적 주장 대신 관찰 기반의 맥락을 받습니다. 시각적 단서는 여전히 모델의 정확도에 의존하므로, 시스템이 모든 세부 정보가 정확하다고 보장할 수는 없습니다.
임무 역시 주제, 눈에 보이는 특징, 위험 요소에 따라 다릅니다. 이들은 사용자가 위험한 상호작용을 장려하기보다는 기존의 안전한 위치에 머물도록 설계되었습니다.
WildSafe: 모델이 최종 권위는 아니다
모델은 유효한 JSON을 반환하더라도 자연 세계에 대해서는 틀릴 수 있습니다.
그렇기 때문에 WildScout은 잘 구성된 응답을 사실적 정확성의 증거로 취급하지 않습니다.
WildSafe는 안전 관련 출력에 결정론적 검사를 적용합니다. 문서화된 위험 경고는 유지되고, 알려지지 않은 위험에는 실질적인 예방 조치가 제공되며, 지원되지 않는 위험 주장은 폐기됩니다.
이것은 보장(guarantee)이 아니라 위험 감소 계층입니다. 모든 모델 오류를 제거하거나 전문가 지식을 대체할 수는 없습니다.
응답 형식뿐만 아니라 행동을 테스트하기
저는 백엔드가 예상되는 7개 필드를 반환하는지 여부보다 더 많은 것을 테스트하고 싶었습니다.
최근 보고된 자동화 테스트 결과에는 다음이 포함됩니다:
- 39 context, grounding, and WildSafe 케이스.
- 12 식물 보존(botanical-preservation) 케이스.
- 240 안전하지 않은 언어(unsafe-language) 케이스.
- 기존 목업 API 검사(mocked API checks).
- 24 통과한 Flutter 테스트.
- 보고된 문제 없이 진행된 Flutter 분석.
- 성공적인 Python 컴파일 및 차이점 검사(diff checks).
The 테스트는 꽃, 잎, 야생 동물, 지원되는 위험 요소, 그리고 불분명한 이미지를 포함한 선택적 엣지 케이스를 다룹니다.
이러한 결과는 특정 동작들이 테스트되었음을 보여주는 증거일 뿐입니다. 모든 실제 세계의 식별(identification)이 정확하다는 것을 입증하지는 않습니다.
최신 코드 변경 사항은 자동화된 검증을 통과했지만, 새로운 동작이 휴대폰에서 엔드투엔드로 검증되었다고 주장하기 위해서는 여전히 신선한 라이브 OpenRouter 테스트와 APK 재빌드가 필요합니다.
왜 오픈 이노베이션(Open Innovation)이 중요할까요?
WildScout에게 있어 오픈 이노베이션이란 모델을 실험하고 그 주변 시스템을 구축할 수 있는 여유 공간을 갖는 것을 의미합니다.
오픈 가중치(open-weight) 모델을 사용함으로써, 프로젝트를 독점적인 모델 생태계에 완전히 의존하지 않으면서 멀티모달 AI로 작업할 기회를 얻었습니다. OpenRouter 덕분에 제가 모바일 경험, 백엔드, 테스트 및 안전 로직에 집중하는 동안 호스팅된 API를 통해 Qwen에 접근하는 것이 실용적이었습니다.
모델은 시스템의 일부일 뿐입니다.
주변 구현(surrounding implementation)이 이미지가 어떻게 검증되는지, 불확실성이 어떻게 제시되는지, 출력이 어떻게 구조화되는지, 그리고 생성된 답변이 안전하지 않은 행동을 장려할 수 있을 때 무슨 일이 발생하는지를 결정합니다.
오픈 가중치 모델은 또한 하드웨어 및 성능 요구 사항이 변경됨에 따라 대안을 평가할 여지(room to evaluate alternatives)를 남겨줍니다. 실제 하드웨어와 예산 제약 내에서 작업하는 학생 개발자에게는 이러한 유연성이 중요합니다.
오픈 가중치 자체가 애플리케이션을 자동으로 오프라인, 비공개 또는 정확하게 만들지는 않습니다. 그러한 속성들은 실제 구현에 달려 있습니다.
저에게 중요한 것은 모델 자체를 완성된 제품으로 취급하기보다는, 실험하고 실패한 접근 방식으로부터 배우며 모델 주변에 유용한 무언가를 구축할 수 있다는 점입니다.
WildScout은 이러한 유연성을 활용하여 사람들이 자연 세계의 더 많은 것을 알아차리도록 장려하려는 저의 시도입니다.
나의 에이전트 세션
WildScout 구축: Flutter, FastAPI, Qwen3.5-9B, 그리고 WildSafe
당신
우리는 WildScout을 처음부터 시작합니다. 아직 GitHub 저장소는 없습니다.
목표:
초기 WildScout 프로젝트와 GitHub 저장소를 생성한 다음, 로컬 AI 백엔드를 구축하는 것입니다.
프로젝트:
WildScout
태그라인: "안전하게 자연을 탐험하기 위한 오프라인 AI 동반자."
핵심 흐름:
스카우트(Scout) → 식별(Identify) → WildSafe → 학습(Learn) → 풀밭 밟기(Touch Grass)
스택:
- Python
- FastAPI
- Ollama
- qwen3-vl:2b
- 로컬/오프라인 AI
- Flutter 프론트엔드는 나중에 추가될 예정입니다.
GitHub 설정:
- 현재 작업 공간을 먼저 검사합니다.
- WildScout을 위한 깨끗한 Git 저장소가 없다면 생성합니다.
- GitHub 인증/접근이 가능하다면
wildscout이라는 이름의 공개 GitHub 저장소를 만듭니다. - 로컬 저장소를 GitHub 원격에 연결합니다.
- 적절한 .gitignore 파일을 추가합니다.
- 비밀 정보, .env 파일, 모델 파일, 데이터셋 또는 생성된 아티팩트는 커밋하지 마십시오.
- 관련 없는 파일을 덮어쓰거나 삭제하지 마십시오.
- 초기 커밋을 만들고 GitHub에 푸시합니다.
- GitHub 인증이나 저장소 생성이 불가능하다면, 푸시하기 전에 중단하고 제가 무엇을 해야 할지 명확하게 알려주세요.
백엔드:
경량 FastAPI 서비스를 생성합니다.
POST /analyze
- 이미지를 받습니다.
- 이미지와 프롬프트를 Ollama로 전송합니다.
- qwen3-vl:2b를 사용합니다.
- 검증된 JSON을 반환합니다.
JSON:
{
"identification": "...",
"confidence": "low|moderate|high",
"visual_clues": ["..."],
"nature_context": "...",
"safety_level": "unknown|low|caution|high",
"safety_note": "...",
"mission": "..."
}
안전성 (SAFETY):
- 모델의 안전 출력은 신뢰할 수 없는 것으로 간주합니다.
- 알지 못하는 식물/균류/동물이 먹거나, 만지거나, 접근해도 안전하다고 절대 주장하지 마십시오.
- 보수적인 표현을 사용하십시오.
- 불확실한 식별은 조심스러움을 유지해야 합니다.
임무 (MISSION):
사용자가 휴대폰을 내려놓도록 장려하는 짧고 안전한 야외 관찰 과제를 하나 생성합니다.
파일 (FILES):
- 백엔드 코드
- requirements.txt
- .gitignore
- 필요한 경우에만 .env.example
- README.md
- 간단한 로컬 테스트 스크립트
하지 말 것 (DO NOT):
- 플러터(Flutter)를 아직 빌드하지 마십시오.
- 데이터베이스/인증(auth)/GPS/지도 기능을 추가하지 마십시오.
- 클라우드 AI를 사용하지 마십시오.
- 모델을 훈련하거나 미세 조정(fine-tune)하지 마십시오.
- 불필요한 종속성(dependencies)을 추가하지 마십시오.
- Ollama 모델을 GitHub에 업로드하지 마십시오.
테스트 (TEST):
로컬에 설치된 qwen3-vl:2b를 사용하여 백엔드가 작동하는지 확인합니다.
최종 응답만:
- GitHub 저장소 URL
- 생성된 파일
- 작동하는 것
- 테스트 결과
- 장애물(blocker)
더 보기
에이전트 (Agent)
제가 작업 공간과 로컬 GitHub/Ollama 접근을 검사한 다음, 커밋하고 푸시하기 전에 백엔드를 빌드하고 테스트하겠습니다.
에이전트 (Agent)
작업 공간에는 work와 outputs 폴더만 포함되어 있습니다. 또한 Ollama 통합 및 유효성 검사 방식을 확인하면서 DevRelay 커뮤니티 리서치 기술을 적용하고 있습니다.
에이전트 (Agent)
▸ exec text(await tools.apply_patch("*** Begin Patch\n*** Add File: outputs/wildscou...
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기