eyescity.kr /works/ hanlab
live service NLP · Clustering Reverse Engineering React Native FastAPI 2025 — 2026

HanLab
동훈햄 분석기

한동훈 관련 뉴스를 실시간 분석하는 AI 플랫폼 'HanLab 동훈햄 분석기' 개발기. TF-IDF에서 SBERT+OpenAI 하이브리드 임베딩으로 이어지는 알고리즘 진화 과정. 비공개 API 리버스 엔지니어링으로 구현한 댓글 델타 트래킹 시스템 등 풀스택 구현 과정을 공개합니다.

Period 2025.12 — 2026.04
Role Solo Full-Stack
Infrastructure AWS EC2 · Nginx · systemd
동훈햄 분석기 실시간 뉴스 클러스터링 및 여론 트래킹 대시보드 화면
Results
수천
Monthly Active Users
#1
네이버 키워드 검색 순위
300+
일일 기사 수집량
50+
실시간 수집 언론사
20min
댓글 스캔 주기
Android
Google Play 출시 (2026.04)
Algorithm Evolution

클러스터링 알고리즘 진화 과정

v1
TF-IDF + KMeans
단어 빈도 기반 벡터화.
k=5 클러스터 수 고정.
단순 키워드 매칭은 작동. 사전에 지정해야 해서 이슈 수에 대응 미흡. 빈 클러스터 및 노이즈 기사 강제 배정 문제.
의미 다른 기사 혼재.
클러스터 수 고정 문제
v2
SBERT 단독
+ HDBSCAN
ko-sbert-sts 모델.
밀도 기반 클러스터링.
클러스터 수 자동 결정. 반대 의미 기사 분리됨.
제목 짧은 압축 특성상 SBERT 단독으로 문맥 손실.
문맥 손실 문제
v3
OpenAI Embeddings
단독
text-embedding-ada-002.
1536차원 고밀도 벡터.
제목만으로도 문맥 파악 가능. 한국 정치 뉴스 도메인 특화 미흡.
비용 발생. 실시간 병목.
비용·레이턴시 문제
v4
SBERT + OpenAI
하이브리드
+ PCA + HDBSCAN
현재 프로덕션 적용 중.
SBERT 한국어 도메인 특화 + OpenAI 범용 문맥 결합. PCA 차원 압축 후 HDBSCAN. 제목×2 가중 최적화.
이슈 수 자동 결정. 인물 태깅으로 동일 이름 혼재 방지.
프로덕션 적용 중
# v4 핵심 파이프라인 — embedding_cluster.py
# 입력: 제목 가중치 2배 + 본문 앞 3문장
text = f"{title} {title} {' '.join(body_sentences[:3])}"

# 이중 임베딩
sbert_vec  = sbert_model.encode(texts)              # 768d, 한국어 특화
openai_vec = get_openai_embeddings(texts)          # 1536d, 범용 문맥

# concatenate + PCA 압축
combined = np.concatenate([sbert_vec, openai_vec], axis=1)  # 2304d
reduced  = PCA(n_components=128).fit_transform(combined)      # 128d

# 밀도 기반 클러스터링 — 클러스터 수 자동 결정
labels = hdbscan.HDBSCAN(
    min_cluster_size=3, min_samples=2
).fit_predict(normalize(reduced))
Reverse Engineering

댓글 급상승 감지 시스템
— 비공개 API 델타 트래킹

STEP 01
비공개 API 역추적
브라우저 DevTools Network 탭으로 실제 댓글 수를 반환하는 내부 엔드포인트 역추적.

comment.news.naver.com/comment/listCount 파라미터 구조 분석 및 요청 재현.Spoofing headers.
STEP 02
델타 트래킹 설계
절대 댓글 수보다 증가량(Δ)이 화제성 지표로 유효함. 스캔 주기마다 증가분만 추출하는 스냅샷 델타 구조 설계.

급상승 / 최다댓글 이중 랭킹 운영.
STEP 03
20분 주기 파이프라인
cron으로 comment_radar.py 20분마다 실행. 수집 대상 기사를SQLite WAL에서 동적 조회하여 호출 최소화. 직렬화 → Streamlit 폴링.
STEP 04
FCM 연동
임계값 초과 시 Firebase FCM으로 앱 푸시 알림 발송. embedding_cluster.py와 교차 분석으로 이슈 클러스터와 댓글 화제성 동시 추적.
# comment_radar.py — 델타 트래킹 핵심 로직
def fetch_naver_comment_count(article_id: str) -> int:
    # 비공개 엔드포인트 — DevTools 역추적
    url = f"https://comment.news.naver.com/comment/listCount?ticket=news&objectId={article_id}"
    res = requests.get(url, headers=SPOOFED_HEADERS, timeout=5)
    return res.json()["result"]["count"]["total"]

def compute_delta(articles: list) -> list:
    prev = load_snapshot()   # 직전 스캔 스냅샷
    current = {}
    for a in articles:
        count = fetch_naver_comment_count(a["id"])
        current[a["id"]] = {
            "count": count,
            "delta": count - prev.get(a["id"], count)   # 20분간 증가량
        }
    save_snapshot(current)
    return sorted(current.values(), key=lambda x: x["delta"], reverse=True)
Architecture
Source
네이버 뉴스 API
유튜브 API
댓글 비공개 API
→
Pipeline
ingest.py
embedding_cluster.py
comment_radar.py
→
Storage
SQLite WAL
JSON Cache
Supabase
→
API Layer
FastAPI
Nginx
Firebase FCM
→
Client
Streamlit Web
React Native App
Google Play
Tech Stack
Python 3.12
Core Language
백엔드, AI 파이프라인, 크롤링
SBERT
Korean NLP
ko-sbert-sts 한국어 특화 임베딩 768d
OpenAI Embeddings
Semantic Understanding
범용 문맥 이해 1536d, SBERT와 하이브리드
PCA + HDBSCAN
Clustering Pipeline
차원 압축 후 밀도 기반 자동 클러스터링
FastAPI
REST API
앱 전용 엔드포인트, Pydantic 검증
Streamlit
Web Frontend
커스텀 CSS + components.html 하이브리드
React Native / Expo
Mobile
expo-router, EAS Build, FCM
Supabase
Auth + Community
Google OAuth, 게시판, 댓글, 투표
SQLite WAL
Database
크롤러-API 동시성 제어
Firebase FCM
Push Notification
댓글 임계값 초과 시 앱 푸시 자동 발송
Nginx
Reverse Proxy
프록시, SSL 종단
AWS EC2
Infrastructure
t2.medium, systemd 서비스, cron 파이프라인
비슷한 시스템이
필요하신가요?
직접 설계하고 구현합니다.

뉴스 모니터링, AI 분석 파이프라인, 비공개 API 연동, 모바일 앱 개발. 실서비스 운영 경험을 바탕으로 처음부터 끝까지 구현합니다.

문의하기 → 서비스 보기 ↗