DOCS/journey/troubleshooting/250901_claude_skill_news_duplicate_issue.md
Claude-51124 22557e7132 docs: 오래된 트러블슈팅 아카이브 및 구조 정리
- 7-8월 초기 구축 문서 12개를 _archive/troubleshooting/2025_07-08_initial_setup/로 이동
- book/300_architecture/390_human_in_the_loop_intent_learning.md를 journey/research/intent_classification/로 이동 (개발 여정 문서)
- 빈 폴더 제거 (journey/assets/*)
2025-11-17 14:06:05 +09:00

5.3 KiB

News Skill 동작 시퀀스 및 문제 분석

작성일: 2025-09-01
작성자: Claude
상태: 🔍 분석 완료

1. News Skill 개요

시스템 정보

  • 서비스명: robeing-skill-news
  • 포트: 8505
  • 컨테이너: skill_news-skill-news
  • 데이터 저장: ChromaDB (/app/data/chroma)

현재 설정

NEWS_KEYWORDS=keyword1,keyword2  # 더미값
NEWS_SEARCH_DAYS=7
MAX_NEWS_ITEMS=20
NEWS_SERVICE_PORT=8505

2. 뉴스 수집 시퀀스

2.1 API 호출 흐름

sequenceDiagram
    participant User
    participant API as /api/news/search
    participant Collector as GoogleNewsCollector
    participant Manager as NewsDataManager
    participant ChromaDB
    participant GoogleNews

    User->>API: POST {"keywords": ["AI"], "max_items": 5}
    API->>Collector: search_news(keywords, max_items)
    
    loop 각 키워드별
        Collector->>GoogleNews: Playwright 브라우저 자동화
        GoogleNews-->>Collector: HTML 파싱 결과
        Collector->>Collector: NewsArticle 객체 생성
    end
    
    Collector->>Manager: save_articles(articles)
    
    loop 각 기사별
        Manager->>ChromaDB: check_duplicate(article)
        alt 중복 아님
            Manager->>ChromaDB: collection.add(article)
            Manager-->>API: saved_count++
        else 중복
            Manager-->>API: skip
        end
    end
    
    API-->>User: {"success": true, "count": N, "articles": [...]}

2.2 Latest API 문제점

sequenceDiagram
    participant User
    participant API as /api/news/latest
    participant Manager as NewsDataManager
    participant ChromaDB

    User->>API: GET /api/news/latest?limit=5
    API->>Manager: get_articles_by_status("collected", 5)
    Manager->>ChromaDB: collection.get(where={"status": "collected"})
    ChromaDB-->>Manager: 기존 저장된 뉴스
    Manager-->>API: 오래된 뉴스 반환
    API-->>User: 8월 12일 뉴스 (20일 전)

3. 발견된 문제점

3.1 뉴스 중복 메커니즘

  1. 정상 동작하는 중복 방지

    • URL과 제목 기반 중복 체크 (news_data_manager.py:71-86)
    • 한 번 저장된 뉴스는 재저장 안 됨
  2. 문제: 새로운 뉴스 없음

    • Google News가 같은 결과 반복 제공
    • 일반적 키워드일수록 ("AI", "기술") 변화 없음

3.2 Latest API 구조적 문제

# news_endpoints.py:104-131
@router.get("/latest")
async def get_latest_news():
    # 새로운 수집 없이 DB 조회만!
    articles = news_manager.get_articles_by_status("collected", limit)
    return articles  # 오래된 뉴스 반환

3.3 환경변수 미설정

  • NEWS_KEYWORDS=keyword1,keyword2 (의미 없는 더미값)
  • happybell80이 실제 키워드 설정 안 함
  • 사용자별 맞춤 키워드 없음

4. 키워드 처리 과정

4.1 키워드 로드 (google_news_collector.py:26-30)

def __post_init__(self):
    if self.search_terms is None:
        keywords = os.getenv('NEWS_KEYWORDS', 'keyword1,keyword2')
        self.search_terms = [kw.strip() for kw in keywords.split(',')]

4.2 검색 URL 생성 (google_news_collector.py:99-100)

encoded_term = search_term.replace('"', '%22').replace(' ', '%20')
url = f"{self.base_url}?q={encoded_term}%20when%3A{self.config.days_back}d&hl=ko&gl=KR"

5. 데이터 저장 구조

5.1 ChromaDB 현황

  • 총 67개 뉴스 저장
  • 가장 오래된: 2025-08-12
  • 가장 최근: 2025-09-01
  • 중복 0개 (URL, 제목 모두 고유)

5.2 시간대별 분포

  • 08-12: 10개 (AI 관련)
  • 08-23: 5개 (AI 관련)
  • 08-24: 1개
  • 08-26: 5개 (삼성전자)
  • 08-27: 12개 (드라마, IT)
  • 08-28: 3개
  • 08-29: 5개
  • 08-30: 6개
  • 08-31: 2개
  • 09-01: 18개 (최신 기술, 오늘 날짜)

6. 테스트 결과

6.1 중복 테스트

# 첫 검색
POST /api/news/search {"keywords": ["최신 기술 뉴스"]}
→ 5개 수집 성공

# 재검색 (동일 키워드)
POST /api/news/search {"keywords": ["최신 기술 뉴스"]}  
→ 0개 (중복 체크로 차단)

6.2 날짜별 테스트

# 오늘 날짜 검색
POST /api/news/search {"keywords": ["2025년 9월 1일 뉴스"]}
→ 3개 수집 성공

# 재검색
POST /api/news/search {"keywords": ["2025년 9월 1일 뉴스"]}
→ 0개 (이미 저장됨)

7. 개선 제안

7.1 긴급

  1. 환경변수 설정

    NEWS_KEYWORDS=AI,로봇,자율주행,반도체,스타트업
    
  2. Latest API 개선

    • 새로운 뉴스 수집 후 반환
    • 시간 기반 필터링 추가

7.2 중요

  1. 오래된 뉴스 삭제

    • 7일 이상 된 뉴스 자동 삭제
    • 또는 시간별 우선순위 부여
  2. 사용자별 키워드

    • user_id별 선호 키워드 저장
    • 맞춤형 뉴스 제공

7.3 선택

  1. 다양한 뉴스 소스

    • Google News 외 추가 소스
    • RSS 피드 통합
  2. 캐싱 전략

    • Redis 도입 검토
    • TTL 기반 캐시 관리

8. 결론

핵심 문제:

  1. /latest는 새 수집 없이 오래된 DB 조회만 수행
  2. 환경변수가 더미값 (keyword1,keyword2)
  3. 시간 기반 필터링/삭제 로직 없음

중복은 정상 작동하나, 새로운 뉴스를 가져오지 못하는 것이 근본 원인.


이 문서는 rb8001과 skill_news 통합 과정에서 발견된 문제를 분석한 것입니다.