fix: 수집 필터 완화 — 영문 RSS 살리기 + 코너 자동배정 + 클릭베이트 완화

- 영문 RSS(카테고리 지정됨)에 한국관련성 기본 10점 부여 (즉시폐기 방지)
- korean_relevance 키워드에 AI/GPT/Apple/Netflix 등 글로벌 키워드 추가
- 키워드 매칭을 case-insensitive로 변경
- RSS 카테고리를 corner로 직접 배정 (쉬운세상 대신 실제 라벨)
- 클릭베이트 필터에서 충격/대박/레전드/역대급 제거 (TV뉴스 과다 필터링)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
JOUNGWOOK KWON
2026-03-30 11:50:47 +09:00
parent 0783775cdd
commit af57c3500c
2 changed files with 14 additions and 6 deletions

View File

@@ -95,7 +95,7 @@ def calc_freshness_score(published_at: datetime | None, max_score: int = 20) ->
return int(max_score * ratio) return int(max_score * ratio)
def calc_korean_relevance(text: str, rules: dict) -> int: def calc_korean_relevance(text: str, rules: dict, rss_category: str = '') -> int:
"""한국 독자 관련성 점수""" """한국 독자 관련성 점수"""
max_score = rules['scoring']['korean_relevance']['max'] max_score = rules['scoring']['korean_relevance']['max']
keywords = rules['scoring']['korean_relevance']['keywords'] keywords = rules['scoring']['korean_relevance']['keywords']
@@ -107,11 +107,14 @@ def calc_korean_relevance(text: str, rules: dict) -> int:
base = 15 # 한국어 텍스트면 기본 15점 base = 15 # 한국어 텍스트면 기본 15점
elif korean_ratio >= 0.05: elif korean_ratio >= 0.05:
base = 8 base = 8
elif rss_category:
# RSS 카테고리가 지정된 영문 소스는 큐레이션된 것이므로 기본점수 부여
base = 10
else: else:
base = 0 base = 0
# 브랜드/지역 키워드 보너스 # 브랜드/지역 키워드 보너스
matched = sum(1 for kw in keywords if kw in text) matched = sum(1 for kw in keywords if kw.lower() in text.lower())
bonus = min(matched * 5, max_score - base) bonus = min(matched * 5, max_score - base)
return min(base + bonus, max_score) return min(base + bonus, max_score)
@@ -199,7 +202,11 @@ def apply_discard_rules(item: dict, rules: dict, published_titles: list[str]) ->
def assign_corner(item: dict, topic_type: str) -> str: def assign_corner(item: dict, topic_type: str) -> str:
"""글감에 코너 배정""" """글감에 코너 배정 — RSS 카테고리가 있으면 우선 사용"""
rss_cat = item.get('_rss_category', '')
if rss_cat:
return rss_cat
title = item.get('topic', '').lower() title = item.get('topic', '').lower()
source = item.get('source', 'rss').lower() source = item.get('source', 'rss').lower()
@@ -227,7 +234,7 @@ def calculate_quality_score(item: dict, rules: dict) -> int:
except Exception: except Exception:
pass pass
kr_score = calc_korean_relevance(text, rules) kr_score = calc_korean_relevance(text, rules, rss_category=item.get('_rss_category', ''))
fresh_score = calc_freshness_score(pub_at) fresh_score = calc_freshness_score(pub_at)
# search_demand: pytrends 연동 후 실제값 사용 (RSS 기본값 12) # search_demand: pytrends 연동 후 실제값 사용 (RSS 기본값 12)
search_score = item.get('search_demand_score', 12) search_score = item.get('search_demand_score', 12)
@@ -389,6 +396,7 @@ def collect_rss_feeds(sources_cfg: dict) -> list[dict]:
'search_demand_score': 8, 'search_demand_score': 8,
'topic_type': 'trending', 'topic_type': 'trending',
'_trust_override': trust, '_trust_override': trust,
'_rss_category': feed_cfg.get('category', ''),
}) })
except Exception as e: except Exception as e:
logger.warning(f"RSS 수집 실패 ({url}): {e}") logger.warning(f"RSS 수집 실패 ({url}): {e}")

View File

@@ -4,7 +4,7 @@
"korean_relevance": { "korean_relevance": {
"max": 30, "max": 30,
"description": "한국 독자 관련성", "description": "한국 독자 관련성",
"keywords": ["한국", "국내", "한글", "카카오", "네이버", "쿠팡", "삼성", "LG", "현대", "기아", "배달", "토스", "당근", "야놀자"] "keywords": ["한국", "국내", "한글", "카카오", "네이버", "쿠팡", "삼성", "LG", "현대", "기아", "배달", "토스", "당근", "야놀자", "AI", "GPT", "ChatGPT", "Claude", "Gemini", "Apple", "Google", "iPhone", "갤럭시", "Netflix", "넷플릭스", "YouTube"]
}, },
"freshness": { "freshness": {
"max": 20, "max": 20,
@@ -63,7 +63,7 @@
{ {
"id": "clickbait", "id": "clickbait",
"description": "클릭베이트성 주제", "description": "클릭베이트성 주제",
"patterns": ["충격", "경악", "난리", "ㅋㅋ", "ㅠㅠ", "대박", "레전드", "역대급"] "patterns": ["경악", "난리", "ㅋㅋ", "ㅠㅠ"]
} }
], ],
"evergreen_keywords": [ "evergreen_keywords": [