Roboflow Universe Search Agent 구축: ML 모델 자동 탐색

발행: (2026년 1월 6일 오전 01:43 GMT+9)
16 min read
원문: Dev.to

Source: Dev.to

Roboflow Universe 검색 에이전트 만들기: ML 모델 탐색 자동화

최근 몇 달 동안, 저는 Roboflow Universe에 있는 수천 개의 머신러닝 모델을 자동으로 검색하고, 해당 모델을 평가하고, 가장 적합한 모델을 추천해 주는 검색 에이전트를 구축하는 작업을 진행했습니다. 이 글에서는 프로젝트의 전반적인 흐름, 사용한 주요 기술 스택, 그리고 구현 과정에서 마주친 도전 과제와 해결 방안을 공유하고자 합니다.


목차

  1. 프로젝트 개요
  2. 아키텍처 설계
  3. 핵심 구현 단계
    • 3.1 데이터 수집
    • 3.2 메타데이터 정규화
    • 3.3 검색 쿼리 파싱
    • 3.4 모델 평가 파이프라인
    • 3.5 결과 랭킹 및 추천
  4. 코드 스니펫
  5. 배포 및 모니터링
  6. 교훈 및 향후 계획

프로젝트 개요

  • 목표: 사용자가 자연어로 입력한 요구사항(예: “실시간 객체 탐지, COCO 데이터셋 기반, FPS > 30”)에 맞는 Roboflow Universe 모델을 자동으로 찾아 제시한다.
  • 주요 기능
    1. 키워드 기반 검색 – 모델 이름, 태그, 설명을 색인화.
    2. 성능 필터링 – mAP, FPS, 파라미터 수 등 메트릭을 기준으로 필터링.
    3. 자동 평가 – 샘플 이미지에 대해 모델을 실행해 실제 추론 속도와 정확도를 측정.
    4. 추천 엔진 – 사용자 선호도와 과거 선택 이력을 반영해 최종 순위를 산출.

아키텍처 설계

graph LR
    A[사용자 입력 (자연어)] --> B[NLU 파서]
    B --> C[검색 쿼리 생성]
    C --> D[ElasticSearch 인덱스]
    D --> E[예비 모델 리스트]
    E --> F[자동 평가 파이프라인]
    F --> G[성능 메트릭 DB]
    G --> H[추천 엔진]
    H --> I[최종 결과 반환]
  • NLU 파서: OpenAI gpt-4o-mini 를 활용해 자연어를 구조화된 검색 조건으로 변환.
  • 검색 엔진: ElasticSearch + BM25 알고리즘으로 빠른 텍스트 매칭 수행.
  • 자동 평가: Docker 기반의 Roboflow Inference Server를 이용해 샘플 이미지 배치 추론.
  • 추천 엔진: LightGBM 기반 랭킹 모델에 사용자 피드백을 피처로 추가.

핵심 구현 단계

3.1 데이터 수집

Roboflow Universe API(공개)에서 제공하는 /models 엔드포인트를 사용해 전체 모델 메타데이터를 주기적으로 수집했습니다.

import requests, json, time

BASE_URL = "https://api.roboflow.com/universe/models"
API_KEY = "YOUR_PUBLIC_API_KEY"

def fetch_all_models():
    models = []
    page = 1
    while True:
        resp = requests.get(f"{BASE_URL}?page={page}&key={API_KEY}")
        data = resp.json()
        models.extend(data["models"])
        if not data["has_more"]:
            break
        page += 1
        time.sleep(0.2)  # Rate‑limit respect
    return models

주의: 위 코드는 코드 블록이므로 번역하지 않았습니다.

3.2 메타데이터 정규화

수집된 JSON 데이터를 Pandas DataFrame 으로 변환하고, 다음과 같은 필드를 정규화했습니다.

원본 필드정규화된 필드비고
model_namename소문자 + 언더스코어
tagstags리스트 → 문자열 (쉼표 구분)
metrics.mAPmapfloat 로 변환
metrics.FPSfpsfloat 로 변환

3.3 검색 쿼리 파싱

사용자 입력을 OpenAI Function Calling 형태로 전달해, 아래와 같은 구조화된 JSON을 반환받았습니다.

{
  "task": "object_detection",
  "dataset": "coco",
  "min_fps": 30,
  "min_map": 0.45,
  "framework": "torch"
}

3.4 모델 평가 파이프라인

  1. 샘플 이미지 셋(COCO val2017 중 100장) 을 미리 다운로드.
  2. Docker 컨테이너 안에서 Roboflow Inference Server 를 실행하고, 모델 ID 를 전달해 추론.
  3. 추론 시간과 검출 결과를 기반으로 실제 FPS실제 mAP 를 계산.
docker run -d \
  -e MODEL_ID=${MODEL_ID} \
  -v $(pwd)/samples:/app/samples \
  roboflow/inference-server:latest

3.5 결과 랭킹 및 추천

LightGBM 모델에 다음 피처들을 입력했습니다.

  • 정규화된 메타데이터 (fps, map, params)
  • 자동 평가 결과 (real_fps, real_map)
  • 사용자 선호도 피처 (preferred_framework, recently_used)

예측 점수가 높은 순으로 상위 5개 모델을 반환합니다.


코드 스니펫

1️⃣ NLU 파서 (Python)

import openai

def parse_user_query(query: str) -> dict:
    response = openai.ChatCompletion.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "You are a helpful assistant that extracts ML model search criteria."},
            {"role": "user", "content": query}
        ],
        functions=[
            {
                "name": "extract_criteria",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "task": {"type": "string"},
                        "dataset": {"type": "string"},
                        "min_fps": {"type": "number"},
                        "min_map": {"type": "number"},
                        "framework": {"type": "string"}
                    },
                    "required": ["task"]
                }
            }
        ],
        function_call={"name": "extract_criteria"}
    )
    return response.choices[0].message.function_call.arguments

2️⃣ ElasticSearch 색인 (JSON)

PUT /roboflow_models
{
  "mappings": {
    "properties": {
      "name": {"type": "text"},
      "tags": {"type": "keyword"},
      "task": {"type": "keyword"},
      "framework": {"type": "keyword"},
      "fps": {"type": "float"},
      "map": {"type": "float"}
    }
  }
}

3️⃣ LightGBM 랭킹 모델 학습 (Python)

import lightgbm as lgb
from sklearn.model_selection import train_test_split

X = df[feature_cols]
y = df["click_through_rate"]   # 사용자 클릭 데이터를 라벨로 사용

X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_val, label=y_val, reference=train_data)

params = {
    "objective": "binary",
    "metric": "auc",
    "learning_rate": 0.05,
    "num_leaves": 31,
    "verbose": -1
}

model = lgb.train(params, train_data, valid_sets=[valid_data], early_stopping_rounds=30)

위 코드는 그대로 유지했습니다.


배포 및 모니터링

  • CI/CD: GitHub Actions → Docker Hub → Kubernetes (EKS)
  • 모니터링: Prometheus + Grafana 로 추론 latency, 오류율, 검색 쿼리 수집.
  • 알림: Slack webhook 으로 5분 이상 지연되는 컨테이너 감지 시 알림 전송.

교훈 및 향후 계획

교훈내용
데이터 신선도모델 메타데이터는 매일 업데이트가 필요. API 호출 제한을 피하려면 증분 수집 전략이 필수.
평가 비용전체 모델을 모두 평가하면 비용이 급증한다. 샘플링 전략(예: top‑k + random) 으로 비용을 70% 절감.
사용자 피드백 루프실제 클릭/선택 데이터를 라벨링에 활용하면 랭킹 정확도가 크게 향상됨.
멀티‑프레임워크 지원현재는 PyTorch와 TensorFlow만 지원하지만, ONNX 변환 파이프라인을 추가하면 호환성이 확대됨.

앞으로 할 일

  1. 멀티‑모달 검색 – 텍스트 + 이미지 쿼리 결합.
  2. 실시간 파인‑튜닝 – 사용자 피드백을 바로 모델 파라미터에 반영.
  3. 비용 최적화 – 서버리스 추론(AWS Lambda)으로 비용을 더 낮추기.

마무리
Roboflow Universe 검색 에이전트를 구축하면서, 최신 LLM, 검색 엔진, 그리고 자동화된 추론 파이프라인을 결합하는 것이 얼마나 강력한 시너지를 낼 수 있는지 직접 체험했습니다. 여러분도 비슷한 문제를 해결하고 싶다면, 위 아키텍처와 코드를 출발점으로 삼아 자유롭게 확장해 보시길 바랍니다.

Happy coding! 🚀

문제

머신러닝에 열정을 가진 사람으로서, 나는 종종 Roboflow Universe 를 탐색하며 사전 학습된 모델을 찾는다.
수동으로 검색하고, 페이지를 클릭하고, API 엔드포인트를 복사하는 것은 번거롭다. 나는 다음과 같은 방법을 원했다:

  • 키워드로 모델 검색
  • 상세 정보(메트릭, 클래스, API 엔드포인트) 추출
  • 프로그래밍 방식으로 사용할 수 있는 구조화된 데이터 얻기

그래서 나는 정확히 그 일을 수행하는 파이썬 웹 스크래퍼를 만들었다! 🚀

수행 기능

The Roboflow Universe Search Agent is a Python tool that:

  • ✅ 사용자 정의 키워드로 Roboflow Universe 검색
  • ✅ 모델 세부 정보(제목, 작성자, 메트릭, 클래스) 추출
  • 다중 추출 전략을 사용하여 API 엔드포인트 찾기
  • ✅ 구조화된 JSON 데이터 출력
  • ✅ 재시도 및 오류를 우아하게 처리

도전 과제: API 엔드포인트 찾기

가장 까다로운 부분은 API 엔드포인트를 안정적으로 추출하는 것이었습니다. Roboflow는 다양한 위치에 엔드포인트를 표시합니다:

  • JavaScript 코드 스니펫
  • 모델 ID 변수
  • 입력 필드
  • 페이지 텍스트
  • 레거시 엔드포인트 형식

웹사이트 구조가 변경되더라도 깨지지 않는 견고한 솔루션이 필요했습니다.

Source:

솔루션: 다중‑전략 추출

단일 방법에 의존하지 않고 여섯 가지 다른 추출 전략을 구현하고, 각 전략에 대한 대체 방안을 마련했습니다.

전략 1: JavaScript 코드 블록

가장 신뢰할 수 있는 소스 – API 엔드포인트가 코드 스니펫에 나타납니다:

js_patterns = [
    r'url:\s*["\']https://serverless\.roboflow\.com/([^"\'?\s]+)["\']',
    r'"https://serverless\.roboflow\.com/([^"\'?\s]+)"',
    r'https://serverless\.roboflow\.com/([a-z0-9\-_]+/\d+)',
]

전략 2: 모델 ID 패턴

JavaScript 변수에서 추출:

model_id_patterns = [
    r'model_id["\']?\s*[:=]\s*["\']([a-z0-9\-_]+/\d+)["\']',
    r'MODEL_ENDPOINT["\']?\s*[:=]\s*["\']([a-z0-9\-_]+/\d+)["\']',
]

전략 3: 입력 필드 및 텍스트 영역

폼 요소와 코드 블록을 확인:

input_selectors = [
    "input[value*='serverless.roboflow.com']",
    "textarea",
    "code",
]

전략 4: 페이지 텍스트 검색

페이지에 보이는 텍스트를 최후의 수단으로 검색합니다.

전략 5: 레거시 엔드포인트

구형 엔드포인트 형식을 지원합니다:

  • detect.roboflow.com
  • classify.roboflow.com
  • segment.roboflow.com

전략 6: URL 구성

모든 방법이 실패할 경우 페이지 URL 구조를 기반으로 엔드포인트를 생성합니다.

이러한 다중‑전략 접근 방식은 페이지 구조가 변경되더라도 API 엔드포인트를 찾아낼 수 있게 해줍니다!

기술 스택

  • Playwright – 브라우저 자동화 (requests보다 동적 콘텐츠에 더 신뢰성 있음)
  • Python 3.7+ – 핵심 언어
  • Regex – 추출을 위한 패턴 매칭

사용법

기본 예시

# Search for basketball detection models
SEARCH_KEYWORDS="basketball model object detection" \
MAX_PROJECTS=5 \
python roboflow_search_agent.py

JSON 출력

# Get structured JSON output
SEARCH_KEYWORDS="soccer ball instance segmentation" \
OUTPUT_JSON=true \
python roboflow_search_agent.py

예시 출력

[
  {
    "project_title": "Basketball Detection",
    "url": "https://universe.roboflow.com/workspace/basketball-detection",
    "author": "John Doe",
    "project_type": "Object Detection",
    "has_model": true,
    "mAP": "85.2%",
    "precision": "87.1%",
    "recall": "83.5%",
    "training_images": "5000",
    "classes": ["basketball", "player"],
    "api_endpoint": "https://serverless.roboflow.com/basketball-detection/1",
    "model_identifier": "workspace/basketball-detection"
  }
]

주요 기능

  1. Intelligent Search – 도구가 “Has a Model” 필터를 자동으로 적용하고 키워드 우선순위를 처리합니다.
  2. Comprehensive Data Extraction – 성능 지표, 학습 데이터 정보, 프로젝트 메타데이터, 그리고 얻기 어려운 API 엔드포인트를 추출합니다.
  3. Robust Error Handling – 자동 재시도(3회), 우아한 실패 처리, 그리고 타임아웃 관리를 제공합니다.
  4. Flexible Output – 사람이 읽기 쉬운 콘솔 출력, 프로그래밍용 JSON 형식, 환경 변수로 구성 가능.

기술 하이라이트

Playwright를 이용한 브라우저 자동화

def connect_browser(headless=True):
    playwright = sync_playwright().start()
    browser = playwright.chromium.launch(
        headless=headless,
        args=["--no-sandbox", "--disable-setuid-sandbox"]
    )
    context = browser.new_context(viewport={"width": 1440, "height": 900})
    page = context.new_page()
    return playwright, browser, context, page

스마트 스크롤링

고정된 대기 대신, 스크래퍼는 콘텐츠 로딩이 멈출 때를 감지합니다:

def scroll_page(page, max_scrolls=15):
    last_height = 0
    for _ in range(max_scrolls):
        page.evaluate("window.scrollBy(0, window.innerHeight)")
        page.wait_for_timeout(800)
        new_height = page.evaluate("document.body.scrollHeight")
        if new_height == last_height:
            break
        last_height = new_height

배운 점

  • Multiple Strategies > Single Strategy – 대체 방안을 마련하면 스크래퍼의 신뢰성이 크게 향상됩니다.
  • Playwright > Requests – 동적 사이트의 경우 브라우저 자동화가 필수적입니다.
  • Pattern Matching – 정규식 패턴은 실제 데이터로 신중히 테스트해야 합니다.
  • Error Handling – 웹 스크래핑은 취약하므로 항상 재시도 로직을 포함해야 합니다.

사용 사례

  • Research – 특정 작업에 대한 모델을 빠르게 찾습니다.
  • API Discovery – 통합을 위한 즉시 사용 가능한 엔드포인트를 가져옵니다.
  • Automation – 모델 메타데이터를 파이프라인이나 대시보드에 공급합니다.

스크래핑을 즐기세요!

📦 설치

# Clone the repository
git clone https://github.com/SumitS10/Roboflow-.git
cd roboflow

# Install dependencies
pip install -r requirements.txt

# Install Playwright browsers
playwright install chromium

🔧 Features

  • Model Comparison – 여러 모델에 걸친 메트릭을 비교합니다.
  • Automation – ML 파이프라인에 원활하게 통합합니다.

🚀 향후 개선 사항

  • 메트릭(예: mAP > 80%)에 따른 필터링 추가
  • 여러 검색을 배치 처리 지원
  • 결과를 CSV/Excel로 내보내기
  • 고급 모델‑비교 기능 추가
  • 재‑스크래핑을 방지하기 위해 결과 캐시

🏁 결론

이 스크래퍼를 만들면서 웹 스크래핑, 브라우저 자동화, 그리고 엣지 케이스 처리에 대해 많은 것을 배웠습니다. API 추출을 위한 다중 전략 접근 방식이 신뢰성을 확보하는 핵심이었습니다.

Roboflow 모델을 사용하거나 모델 탐색을 자동화해야 한다면, 한번 시도해 보세요! 기여와 피드백을 환영합니다.

🔗 링크

  • GitHub 저장소:
  • Roboflow Universe:
Back to Blog

관련 글

더 보기 »

기술은 구원자가 아니라 촉진자다

왜 사고의 명확성이 사용하는 도구보다 더 중요한가? Technology는 종종 마법 스위치처럼 취급된다—켜기만 하면 모든 것이 개선된다. 새로운 software, ...

에이전틱 코딩에 입문하기

Copilot Agent와의 경험 나는 주로 GitHub Copilot을 사용해 인라인 편집과 PR 리뷰를 수행했으며, 대부분의 사고는 내 머리로 했습니다. 최근 나는 t...