TrendShift 딥다이브 · 2026-07-06 · Daily #3

ai-goofish-monitor 딥다이브
— "AI가 대신 중고장터를 잠복 감시한다": 스크래핑 × 멀티모달 LLM × 실시간 관제

ai-goofish-monitor는 중국 최대 중고거래 플랫폼 闲鱼(셴위 / 영문명 goofish)를 Playwright로 24시간 감시하다가, 새 매물이 뜰 때마다 이미지를 볼 줄 아는 LLM이 "내 구매 기준"으로 점수를 매겨 합격한 매물만 즉시 알림으로 쏴 주는 자기호스팅 관제 시스템이다. 단순 크롤러가 아니라, Playwright 스크래핑 + 비전 LLM 심사 + APScheduler 예약 + Vue 3 관리 대시보드를 한 몸에 담은 FastAPI 백엔드 · Vue 프런트 풀스택 애플리케이션이다. "봇을 막는 마켓플레이스"와 "긁으려는 클라이언트"의 공방, 그리고 "LLM에게 판단을 위임하는 파이프라인 설계"를 동시에 배울 수 있는 실전 표본. (저장소: Usagi-org/ai-goofish-monitor · Python + Vue 3 · MIT · v2.0.0 · ★13.2k · archived · TrendShift 오늘 Daily 3위, 모멘텀 156)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 시스템 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

ai-goofish-monitor는 闲鱼(셴위, 알리바바가 운영하는 중국 최대 개인 간 중고거래 앱)에서 특정 키워드의 새 매물을 실시간·예약으로 감시하고, 각 매물을 비전 LLM(이미지 판독이 되는 대형언어모델) 이 사용자가 설정한 구매 기준으로 자동 심사해, "살 만하다"고 판단한 매물만 휴대폰 알림으로 보내주는 프로그램이다. 모든 조작은 웹 관리 UI(대시보드)에서 이뤄진다.

한 줄 개념
AI 심사형 매물 모니터 (AI-gated marketplace monitor)
사람이 하루 종일 중고장터를 새로고침하며 "이거 괜찮나?"를 판단하는 노동을, 스크래핑(수집) + LLM(판단) + 알림(통보) 세 단계 파이프라인으로 자동화한 것. 闲鱼의 영문 브랜드명이 Goofish라서 프로젝트 이름이 goofish-monitor다.
비유로 이해하기

"눈 밝은 중고 감정사를 24시간 장터 입구에 세워둔 것"

중고장터에서 좋은 물건을 잡으려면 남보다 빨라야 한다. 하지만 사람은 잠도 자야 하고, 매물 사진과 판매자 이력을 일일이 뜯어볼 시간도 없다. 이 도구는 장터 입구(검색 결과)에 잠복한 감정사다. 새 물건이 들어오는 즉시 사진을 살펴보고, 판매자의 거래 이력·신용도까지 조회한 뒤, "이건 급매 진품, 즉시 연락하세요" 같은 판정을 문자로 보내준다.

핵심은 그 감정사가 사람이 아니라 멀티모달 LLM이라는 점, 그리고 장터가 "자동화 봇 출입금지" 팻말(안티봇)을 붙여둬서, 감정사가 손님인 척 위장(실제 브라우저 지문 복제)하고 들어가야 한다는 점이다.

코드 내부 버전은 2.0.0(FastAPI 앱 타이틀 기준)이며, AI 심사 페르소나의 코드네임은 EagleEye-V6.4다. 라이선스는 관대한 MIT(원저작권자 dingyufei615, 현재 Usagi-org 조직 호스팅). 별 13,200개·포크 1,900개로 인기가 검증됐지만, 현재 GitHub에서 저장소가 archived(보관·읽기전용) 상태라는 점은 유의해야 한다(추가 업데이트·보안 패치가 멈춤).

먼저 짚고 갈 것 — 법적/윤리적 주의
"엔지니어링을 배우는 것"과 "함부로 긁는 것"은 다르다

이 도구는 마켓플레이스의 비공개 내부 API를 가로채고, 로그인 쿠키를 복제하며, 안티봇 탐지를 능동적으로 회피한다. 이는 闲鱼/타오바오 이용약관 위반일 가능성이 크고, 과도한 요청은 계정 정지·서버 부하를 부른다. 저장소 자체도 DISCLAIMER.md에서 "학습·연구 목적, robots.txt·약관 준수, 불법 사용 금지"를 명시한다. 이 문서는 비동기 스크래핑 · 안티봇 공방 · LLM 파이프라인 · 풀스택 아키텍처를 학습하기 위한 자료이며, 특정 플랫폼을 무단 수집하라는 뜻이 아니다.

2왜 주목받는가

트렌딩 이유와, 흔한 "크롤러 스크립트"와의 결정적 차이.

① LLM을 "필터"가 아니라 "판단자"로 쓴다

대부분의 매물 알리미는 키워드·가격 범위 같은 단순 규칙으로 거른다. 이 프로젝트는 한 발 더 나아가, 매물 사진 + 상세정보 + 판매자 이력을 통째로 비전 LLM에게 주고 "사람처럼 판단"하게 한다. 예컨대 "겉보기 개인 판매자지만 실제로는 되팔이(업자)인지"를 판매자의 구매·판매·평가 이력에서 행동 서사를 재구성해 가려낸다. 프롬프트에는 "PERSONA-FIRST 원칙", "이미지 우선 원칙", "한 방에 탈락시키는 deal-breaker 규칙" 같은 실전 프롬프트 엔지니어링이 담겨 있다.

비교

보통 알리미 = "삼성 냉장고 30만원 이하"라고 필터를 걸어두면 조건만 맞으면 다 알림이 온다(사기·업자·하자 매물 포함). 이 프로젝트 = "냉장고 사진의 성에·녹, 판매자가 최근 5개를 팔았는지, 신용등급은 어떤지"까지 감정사가 눈으로 보고 걸러, 진짜 살 만한 것만 통과시킨다.

② "안티봇 vs 스크래퍼" 공방을 실물로 보여준다

闲鱼는 자동화를 막으려고 여러 방어선을 친다. 이 프로젝트는 그걸 계층적으로 돌파한다.

즉, "서버가 막으면 어떻게 우회하나"의 여러 계층을 한 코드베이스에서 관찰할 수 있다.

③ 스크립트가 아니라 "제대로 설계된 풀스택 앱"

루트의 spider_v2.py 한 파일이 전부가 아니다. 112개 Python + 79개 Vue + 46개 TypeScript 파일api → services → domain → infrastructure 4계층(DDD풍)으로 나뉘고, WebSocket 실시간 로그, APScheduler 크론 예약, 6종 알림 채널, SQLite 저장, Docker 멀티스테이지 빌드, 40여 개 테스트(실트래픽 스모크 포함)까지 갖췄다. "크롤러 하나"를 어떻게 운영 가능한 제품으로 키우는지 보여주는 표본이다.

배움 관점 핵심
"이 레포에서 무엇을 얻는가"

대상이 闲鱼라는 점은 부차적이다. 진짜 가치는 비동기 스크래핑 · 멀티모달 LLM 통합(및 호환성 레이어) · 프로세스 격리 · 계층형 백엔드 · Vue 3 SPA · 실시간 관제(WebSocket) · 안티봇 대응실전 규모의 코드로 통째로 볼 수 있다는 것.

3기술 스택 전체 지도

무엇으로 만들어졌나 — 계층별로. (requirements.txt·package.json에서 실제 확인)

백엔드 — 웹/비동기 코어

기술역할왜 이걸 썼나
Python 3.10+백엔드 언어스크래핑·AI 생태계가 가장 풍부(Docker는 3.11-slim)
FastAPI + uvicorn웹 API + SPA 서빙async 네이티브, 하나의 src/app.py가 API와 Vue 빌드물을 함께 제공
Playwright (async)스크래핑 엔진실제 Chromium을 몰아 안티봇 우회·API 가로채기
openai SDK (AsyncOpenAI)LLM 호출OpenAI 호환 엔드포인트면 무엇이든(모델스코프/제미니/딥시크…) 붙음
APScheduler (AsyncIOScheduler)예약 실행크론식으로 감시 작업을 주기 실행
pydantic / pydantic-settings설정·도메인 모델타입 안전한 env 설정과 Task 엔티티 검증
SQLite (stdlib)주 저장소tasks·result_items·price_snapshots를 파일 DB로(무설치)

그 밖에 requests(이미지 다운로드를 executor로), httpx[socks]+python-socks(프록시), aiofiles, Pillow, pyzbar+qrcode(QR 로그인 처리), jinja2를 쓴다. 테스트는 pytest·pytest-asyncio·coverage.

프런트엔드 — 관리 대시보드 (web-ui/)

기술역할메모
Vue 3 (^3.5)SPA 프레임워크Composition API 기반, 79개 .vue 파일
TypeScript + Vite 7타입·빌드vue-tsc로 타입체크 후 번들
vue-router / vue-i18n라우팅·다국어HTML5 history 모드, zh-CN + en-US 로케일
Tailwind CSS 3 + reka-ui스타일·컴포넌트Radix-Vue 후속인 reka-ui + shadcn-vue풍 컴포넌트
@vueuse/core / lucide유틸·아이콘WebSocket 실시간 갱신(services/websocket.ts)

화면은 Dashboard·Tasks·Results·Accounts·Settings·Logs·Login 뷰로 구성된다. Vite 개발 서버는 /api·/auth·/ws를 백엔드(:8000)로 프록시한다.

인프라 / 부가 요소

기술역할메모
Docker (멀티스테이지)배포node:22 빌드→python:3.11-slim, Chromium 프리베이크
Chrome Extension (MV3)로그인 상태 추출chrome.cookies로 HttpOnly 쿠키까지 캡처
ntfy·Bark·Gotify·WeCom·Telegram·Webhook알림 팬아웃추천 매물에 대해 asyncio.gather로 동시 발송
desktop_launcher.py데스크톱 래퍼webview로 감싼 로컬 실행 모드

4아키텍처 심화 분석

감시 작업 하나가 처음부터 끝까지 어떻게 흐르는가.

2계층 프로세스 모델 — 웹서버와 작업이 분리돼 있다

이 설계의 첫 번째 핵심은 "웹서버 프로세스"와 "감시 작업 프로세스"가 완전히 분리돼 있다는 것이다. 웹서버(python -m src.app)는 API를 제공하고 예약을 관리할 뿐, 실제 스크래핑은 작업마다 별도 OS 서브프로세스(spider_v2.py --task-name)로 띄운다. 한 작업이 캡차에 막히거나 죽어도 서버·다른 작업은 멀쩡하다.

┌──────────────────────── 웹서버 프로세스 (src/app.py) ────────────────────────┐ │ FastAPI (uvicorn) │ │ ├─ /api/tasks /results /accounts /settings /prompts /logs /dashboard │ │ ├─ /ws ──(WebSocket)── 실시간 로그·작업상태 브로드캐스트 │ │ ├─ APScheduler(AsyncIOScheduler) ── 크론 시각에 작업 spawn │ │ └─ lifespan 시작 시: SQLite 부트스트랩 → is_running 초기화 → 크론 로드 │ └───────────────┬──────────────────────────────────────────────────────────────┘ │ asyncio.create_subprocess_exec("python -u spider_v2.py --task-name ...") │ (POSIX: os.setsid 로 프로세스그룹 격리, 로그는 logs/<task>.log 로 스트리밍) ▼ ┌──────────────────── 감시 작업 프로세스 (spider_v2.py) ────────────────────────┐ │ scrape_xianyu() (src/scraper.py, ~1290줄) │ │ │ │ ① 계정/프록시 선택 RotationPool → state/*.json 쿠키 + (선택)프록시, TTL 블랙리스트 │ │ ② FailureGuard 게이트 연속 실패 N회 초과 시 24h 일시정지(죽은 쿠키 방어) │ │ ③ Playwright 기동 안티봇 플래그 + 모바일 컨텍스트 + webdriver 위장 스크립트 │ │ ④ 워밍업 → 검색 goofish.com 홈 방문 후 /search?q=키워드 │ │ ⑤ API 응답 가로채기 page.on("response") 로 mtop JSON(검색·상세·판매자) 수집 │ │ ⑥ 신규 매물 판별 link_unique_key 로 기존 처리분과 dedup │ │ ⑦ Dispatcher 로 위임 ──────────────────────────────┐ │ └─────────────────────────────────────────────────────┼──────────────────────────┘ ▼ ┌──── ItemAnalysisDispatcher (Semaphore=2) ────┐ │ 판매자 이력 조회(캐시) → 이미지 다운로드 │ │ → AI 심사 or 키워드 규칙 → SQLite 저장 │ │ → is_recommended 이면 알림 팬아웃 │ └───────────────────────────────────────────────┘
핵심 설계 ①
API 인터셉션 스크래핑 (DOM을 긁지 않는다)
보통 크롤러는 HTML 요소를 CSS 선택자로 긁는데, 사이트 디자인이 바뀌면 와르르 깨진다. 이 프로젝트는 대신 闲鱼 앱이 내부적으로 호출하는 mtop JSON API 응답(...idlemtopsearch.pc.search 등)을 page.on("response")도청한다. 필터(신규·개인판매·지역·가격)는 실제 UI 버튼을 클릭해 걸고, 갱신된 API 응답을 기다린다. 화면이 아니라 데이터를 잡으므로 훨씬 견고하다.
핵심 설계 ②
경계 동시성 디스패처 (Bounded-Concurrency Dispatcher)
ItemAnalysisDispatcherasyncio.Semaphore(기본 2, AI_ANALYSIS_CONCURRENCY)로 동시에 처리할 매물 수를 제한한다. 빠른 "수집 루프"와 느린 "AI 심사·판매자조회·이미지다운로드"를 분리(decouple)해, 수집이 심사를 기다리며 막히지 않게 한다. 전형적인 생산자-소비자 + 백프레셔 패턴.
핵심 설계 ③
LLM 호환성 레이어 (ai_request_compat.py)
OpenAI 호환이라 해도 게이트웨이마다 지원 파라미터가 제각각이다. 이 레이어는 Chat Completions API와 Responses API를 자동 협상하고, 에러 메시지를 보고 response_format(구조화 출력)·temperature·enable_thinking 같은 미지원 파라미터를 스스로 끄고 재시도한다. 여러 모델 제공사를 한 코드로 감당하는 방어적 설계.

AI 심사 파이프라인 — 프롬프트가 2층으로 조립된다

AI 심사는 이 프로젝트의 백미다. 프롬프트는 고정된 "출력 형식 계약"과, 작업별 "구매 기준"이 런타임에 합쳐지는 2층 구조다.

# prompts/base_prompt.txt — 모든 작업이 공유하는 출력 형식 계약
너는 EagleEye-V6.4. 반드시 아래 JSON 스키마로만 답하라:
{
  "prompt_version": ...,
  "is_recommended": true|false,      # 이 불리언 하나로 알림 여부가 갈린다
  "reason": "...",
  "risk_tags": ["...", ...],
  "criteria_analysis": {             # 기준별 세부 판정
    "model_chip": ..., "battery_health": ...,
    "condition": ..., "seller_type": { "analysis_details": ... },
    "shipping": ..., "seller_credit": ...
  }
}
{{CRITERIA_SECTION}}                  # ← 여기에 작업별 기준이 주입됨

런타임에 spider_v2.pybase_prompt.replace("{{CRITERIA_SECTION}}", 기준텍스트)로 합친다. 기준 파일(예: prompts/macbook_criteria.txt)에는 "겉보기 개인/실제 업자 구분", "한 방 탈락 규칙", "이미지 우선", 사후 확인이 필요한 항목은 NEEDS_MANUAL_CHECK로 보류 같은 실전 프롬프트 규칙이 들어있다.

요청 조립(ai_message_builder.py)은 매물 JSON(판매자·가격 참조 포함)을 시스템 프롬프트와 합치고, 매물 이미지들을 data:image/jpeg;base64,… image_url 파트로 붙인 멀티모달 메시지를 만든다. temperature=0.1(재시도 시 0.05), 최대 4회 재시도, 필수 필드 누락 시 재요청하는 검증기(validate_ai_response_format)까지 붙는다.

특히 영리한 부분
자연어로 감시 작업을 만든다 (메타-프롬프트)

사용자가 "이런 조건의 물건 찾아줘"라고 평범한 문장으로 적으면, prompt_utils.py의 메타-프롬프트("너는 세계적 프롬프트 엔지니어…")가 그 문장 + 참조 기준파일을 LLM에 넘겨 새 카테고리용 기준 파일을 자동 생성한다. 이 작업은 백그라운드 잡(POST /api/tasks/generate → 202 + job id, 프런트가 진행률 폴링)으로 돈다. LLM으로 "LLM 프롬프트를 짓는" 재귀적 자동화.

운영 견고성 — RotationPool · FailureGuard · 리스크컨트롤

중국 마켓플레이스의 강한 안티봇과 쿠키 만료에 대응하는 장치가 촘촘하다. RotationPool은 여러 계정/프록시를 TTL 블랙리스트와 함께 돌려쓰고, FailureGuard는 연속 실패(TASK_FAILURE_THRESHOLD 기본 3회)가 나면 작업을 TASK_FAILURE_PAUSE_SECONDS(기본 86400초=24시간) 정지시킨 뒤 쿠키 갱신 시 자동 복구한다. 캡차 오버레이(baxia-dialog)나 FAIL_SYS_USER_VALIDATE 응답을 만나면 RiskControlError를 던지고 무모한 재시도 없이 즉시 중단한다.

5디렉토리 구조 해부

어디에 무엇이 있나 — 계층형(DDD풍) 백엔드 + Vue SPA.

ai-goofish-monitor/ ├── src/ # 백엔드 (Python, 계층형) │ ├── app.py # FastAPI 진입점 (lifespan: DB부트스트랩·크론로드) │ ├── api/routes/ # tasks·results·accounts·settings·prompts·logs·websocket │ ├── services/ # 비즈니스 로직 │ │ ├── scheduler_service.py # APScheduler 크론 → 작업 spawn │ │ ├── item_analysis_dispatcher.py # 경계 동시성 심사 큐(Semaphore) │ │ ├── notification_service.py # 6채널 알림 팬아웃 │ │ ├── task_generation_service.py # 자연어→기준파일 생성 잡 │ │ └── ai_request_compat.py # Chat/Responses API 자동 협상 │ ├── domain/models/task.py # pydantic Task 엔티티 │ ├── infrastructure/ │ │ ├── persistence/ # SQLite 부트스트랩·연결·리포지토리 │ │ ├── config/settings.py # pydantic-settings 환경설정 │ │ └── external/ # ai_client + notification_clients/ │ ├── scraper.py # ★ Playwright 스크래핑 엔진(~1290줄) │ ├── ai_handler.py # LLM 심사 + 이미지다운로드 + 알림 │ ├── rotation.py # 계정/프록시 로테이션 풀 │ ├── failure_guard.py # 연속 실패 게이트 │ └── keyword_rule_engine.py # 비-LLM 키워드 매칭 모드 ├── spider_v2.py # ★ 작업 단위 CLI 러너 (서브프로세스로 실행됨) ├── prompts/ # base_prompt.txt + *_criteria.txt (심사 기준) ├── web-ui/ # 프런트엔드 (Vue 3 + TS + Vite) │ └── src/ (views/ components/ services/websocket.ts i18n/messages/) ├── chrome-extension/ # MV3: 闲鱼 로그인 상태 추출기 ├── state/ # acc_*.json (로그인 쿠키·브라우저 지문) ├── data/app.sqlite3 # 주 저장소 ├── Dockerfile / docker-compose.yaml / start.sh └── AGENTS.md / DISCLAIMER.md / README.md

진입점을 읽는 순서를 권한다: ① src/app.py(서버가 뜰 때 무슨 일이 일어나나) → ② spider_v2.py(작업 하나가 어떻게 실행되나) → ③ src/scraper.pyscrape_xianyu()(수집 루프) → ④ item_analysis_dispatcher.py + ai_handler.py(심사) → ⑤ ai_request_compat.py(LLM 호환) 순.

6학습 포인트 (기술별)

이 코드를 뜯어 무엇을 내 것으로 만들 수 있나.

① 비동기 스크래핑 & 프로세스 격리

asyncio.create_subprocess_exec로 작업을 독립 프로세스로 띄우고, os.setsid로 프로세스 그룹을 분리해 SIGTERM으로 통째 정리하는 패턴. 크래시 격리·개별 취소가 필요한 워커 시스템의 정석이다. page.on("response")네트워크 응답을 도청하는 스크래핑 기법도 여기서 배운다.

② 멀티모달 LLM 파이프라인 설계

이미지+텍스트를 하나의 메시지로 조립하고, 구조화 JSON 출력을 강제·검증·재시도하는 전 과정. 특히 ai_request_compat.py의 "에러 메시지를 보고 미지원 파라미터를 스스로 끄는" 방식은 여러 LLM 제공사를 지원해야 하는 실무에서 그대로 쓸 수 있다.

③ 계층형 백엔드(DDD풍) + 의존성 주입

api → services → domain → infrastructure 분리, 리포지토리 패턴(SqliteTaskRepository), src/api/dependencies.py의 DI. "크롤러 스크립트"를 "유지보수 가능한 서비스"로 승격시키는 구조를 실물로 관찰할 수 있다.

④ 실시간 관제 UI (FastAPI + WebSocket + Vue 3)

백엔드가 작업 상태를 /ws로 브로드캐스트하고 Vue 프런트가 실시간 갱신하는 전형. 단일 FastAPI 서버가 API와 SPA 정적파일을 함께 서빙하고, catch-all 라우트로 SPA 히스토리 모드를 받치는 배포 구성도 배울 만하다.

실습 아이디어

스크래핑 대상을 합법적인 공개 API(예: 공공데이터포털, GitHub API, RSS 피드)로 바꿔, "수집 → LLM 심사 → 알림" 3단 파이프라인만 그대로 이식해보라. 안티봇 부분을 걷어내면 이 프로젝트의 아키텍처만 깔끔히 재사용할 수 있다.

7시스템 요구사항

돌리려면 무엇이 필요한가.

항목요구사항
실행 방식Docker 권장 (docker compose up -d) — 이미지 ghcr.io/usagi-org/ai-goofish:latest
포트웹 UI :8000
런타임Python 3.10+ / Node 22(프런트 빌드 시). Docker 이미지에 Chromium 프리베이크
필수 envOPENAI_API_KEY · OPENAI_BASE_URL · OPENAI_MODEL_NAME (모델은 비전 지원 필수)
기본 모델.env.example 기준 ModelScope의 XiaomiMiMo/MiMo-V2-Flash (교체 가능)
로그인크롬 확장으로 闲鱼 로그인 상태를 추출해 state/acc_1.json에 저장
웹 인증WEB_USERNAME/WEB_PASSWORD (기본 admin/admin123반드시 변경)
저장 볼륨./data ./state ./prompts ./logs ./images 등 마운트(compose에 정의)
보안 주의
기본 계정 admin/admin123은 평문 검증이다

웹 UI를 외부에 노출할 거라면 기본 자격증명을 즉시 바꾸고, 가능하면 리버스 프록시·VPN 뒤에 둬라. state/*.json에는 내 로그인 쿠키가 통째로 들어있으니 이 파일 유출은 곧 계정 탈취와 같다.

8직접 해볼 수 있는 실습 과제

난이도별로. (합법·안전한 범위 내에서 아키텍처를 익히는 데 초점)

LEVEL 1 · 입문 — 반나절

알림 채널 하나 붙여보기

src/infrastructure/external/notification_clients/의 기존 클라이언트(예: ntfy)를 본떠, Discord Webhook 클라이언트를 추가하고 factory에 등록하라. "추천 매물이 뜨면 내 디스코드로 온다"까지 완성하면 알림 팬아웃 구조가 손에 잡힌다.

LEVEL 2 · 초급 — 하루

구조화 출력 검증기 강화

validate_ai_response_format가격 범위·필드 타입 검증을 추가하고, 실패 시 재시도 프롬프트에 "무엇이 틀렸는지"를 되먹여(feedback) 정확도를 높여보라. LLM 구조화 출력의 실전 견고화 기법을 익힌다.

LEVEL 3 · 중급 — 2~3일

대상을 합법 공개 API로 교체

스크래핑 계층(scraper.py)을 공공데이터/RSS/GitHub API 수집기로 갈아끼우고, 하위의 Dispatcher·AI 심사·알림·SQLite 저장은 그대로 재사용하라. "수집원만 바꿔도 나머지 파이프라인이 재사용되는" 계층 분리의 위력을 체감한다.

LEVEL 4 · 고급 — 1주+

심사 결과 대시보드 확장

price_snapshots 테이블을 활용해 키워드별 시세 추이 차트를 Vue 프런트에 추가하고, WebSocket으로 실시간 갱신되게 하라. 백엔드 집계 API + 프런트 차트 + 실시간 스트림을 한 번에 다루는 풀스택 과제.

LEVEL 5 · 심화 — 연구

LLM 호환성 레이어 이식

ai_request_compat.py를 독립 라이브러리로 떼어내, 임의의 OpenAI 호환 게이트웨이(vLLM, Ollama, LiteLLM 등)에 대해 파라미터 자동 협상이 되는지 테스트 매트릭스를 짜라. 여러 추론 백엔드를 감당하는 방어적 클라이언트 설계를 깊이 파고든다.

9관련 기술 심화 학습 로드맵

이 레포를 축으로 4주 커리큘럼.

주차주제배울 것 · 실습
1주차비동기 파이썬 & Playwrightasyncio 이벤트 루프·세마포어, Playwright async로 페이지 몰기·응답 가로채기. scrape_xianyu() 정독
2주차멀티모달 LLM 통합이미지 base64 메시지 조립, 구조화 JSON 강제·검증·재시도, 호환성 레이어(Chat vs Responses). ai_handler.py+ai_request_compat.py
3주차FastAPI 계층형 백엔드DDD풍 레이어링·DI·리포지토리, APScheduler 예약, WebSocket 실시간, SQLite 스키마·마이그레이션
4주차Vue 3 관제 UI & 배포Vue 3 + Vite + Tailwind SPA, WebSocket 클라이언트, Docker 멀티스테이지로 프런트+백 한 이미지에 담기

10핵심 키워드 사전

문서에 나온 용어를 한 번에.

용어
闲鱼 / Goofish알리바바가 운영하는 중국 최대 개인 간 중고거래 플랫폼. 이 도구의 감시 대상
API 인터셉션DOM을 긁는 대신, 페이지가 호출하는 내부 JSON API 응답을 page.on("response")로 가로채 데이터를 얻는 견고한 스크래핑 기법
mtop타오바오/闲鱼가 쓰는 모바일 게이트웨이 API 프로토콜. 검색·상세·판매자 정보가 여기로 흐른다
멀티모달 LLM텍스트뿐 아니라 이미지도 입력으로 받는 대형언어모델. 매물 사진을 "보고" 판단
구조화 출력LLM이 자유 문장 대신 정해진 JSON 스키마로만 답하게 강제하는 것. is_recommended 같은 필드로 후속 로직이 분기
경계 동시성Semaphore로 동시 처리량을 제한해, 느린 단계가 시스템을 폭주시키지 않게 하는 백프레셔 패턴
프로세스 격리작업마다 별도 OS 프로세스로 실행해, 하나가 죽어도 전체가 안 죽게 하는 설계
안티봇 / 리스크컨트롤자동화 요청을 탐지·차단하는 서버 방어(캡차·서명·지문). 이 도구는 실제 브라우저 지문 복제로 우회
RotationPool / FailureGuard계정·프록시를 TTL 블랙리스트와 함께 돌려쓰고, 연속 실패 시 작업을 일시정지해 밴을 피하는 운영 장치
APScheduler파이썬 크론 스케줄러. "매 N분마다 감시" 같은 주기 실행을 담당
MV3 (Manifest V3)크롬 확장 최신 규격. 여기선 로그인 쿠키·브라우저 환경을 추출하는 데 사용

11참고 링크

더 파고들 곳.