From dba82ab5961031f78d010e862122d6d7c00078f6 Mon Sep 17 00:00:00 2001 From: Claude-51124 Date: Tue, 26 Aug 2025 22:07:58 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EB=89=B4=EC=8A=A4=20=EC=8A=A4=ED=82=AC?= =?UTF-8?q?=20=ED=82=A4=EC=9B=8C=EB=93=9C=20=EB=AC=B8=EC=A0=9C=20=EB=B6=84?= =?UTF-8?q?=EC=84=9D=20=EB=B0=8F=20DB=20=EA=B8=B0=EB=B0=98=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=20=EA=B4=80=EB=A6=AC=20=EB=B0=A9=EC=95=88=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 매일 같은 AI 뉴스 반복 문제 원인 분석 - 하드코딩된 키워드를 동적 시스템으로 개선 방안 제시 - DB 기반 환경변수 관리 방법 문서화 - 사용자별 맞춤 키워드 시스템 설계 --- .../250826_slack_id_column_standardization.md | 212 +++++++++++++++++- 1 file changed, 211 insertions(+), 1 deletion(-) diff --git a/troubleshooting/250826_slack_id_column_standardization.md b/troubleshooting/250826_slack_id_column_standardization.md index b1a7fd2..cee388b 100644 --- a/troubleshooting/250826_slack_id_column_standardization.md +++ b/troubleshooting/250826_slack_id_column_standardization.md @@ -168,4 +168,214 @@ WHERE slack_id IS NOT NULL AND slack_user_id IS NULL; --- -*작성 완료: 2025-08-26 21:30* \ No newline at end of file +## 10. 뉴스 스킬 키워드 문제 분석 + +### 10.1 발견된 문제 +**매일 같은 AI 뉴스만 반복되는 현상** + +#### 원인 분석 +1. **하드코딩된 키워드** + - 위치: `/home/admin/ivada_project/rb8001/app/skills/dm_skill.py:309` + - 코드: `["AI", "기술", "IT"]`로 고정 + - 문제: 매일 동일한 키워드로만 검색 + +2. **환경변수 미활용** + - 설정: `NEWS_KEYWORDS=keyword1,keyword2` + - 실제: 사용되지 않음 + +3. **중복 방지 로직의 부작용** + - 이미 수집된 뉴스는 건너뜀 + - 새 뉴스 없으면 최근 저장된 뉴스 5개 반복 표시 + - 결과: 매일 같은 뉴스 표시 + +### 10.2 개선 방안 + +#### 방안 1: 동적 키워드 시스템 +```python +# dm_skill.py 수정 예시 +import random +from datetime import datetime + +def get_daily_keywords(): + """날짜별로 다른 키워드 세트 반환""" + keyword_sets = [ + ["AI", "인공지능", "ChatGPT"], + ["반도체", "삼성", "SK하이닉스"], + ["전기차", "테슬라", "현대차"], + ["빅테크", "구글", "애플"], + ["스타트업", "유니콘", "투자"], + ["바이오", "제약", "헬스케어"], + ["핀테크", "블록체인", "가상자산"] + ] + # 요일별로 다른 키워드 세트 사용 + day_of_week = datetime.now().weekday() + return keyword_sets[day_of_week] + +# 사용 +keywords = get_daily_keywords() # ["AI", "기술", "IT"] 대신 +``` + +#### 방안 2: DB 기반 키워드 관리 +```sql +-- 키워드 설정 테이블 생성 +CREATE TABLE news_keywords ( + id SERIAL PRIMARY KEY, + user_id UUID REFERENCES users(id), + slack_user_id VARCHAR(100), + keywords TEXT[], -- PostgreSQL 배열 타입 + priority INTEGER DEFAULT 0, + active BOOLEAN DEFAULT true, + created_at TIMESTAMP DEFAULT NOW(), + updated_at TIMESTAMP DEFAULT NOW() +); + +-- 기본 키워드 설정 +INSERT INTO news_keywords (slack_user_id, keywords, priority) VALUES +('U091UNVE41M', ARRAY['AI', '스타트업', '투자'], 1), +('U0925SXQFDK', ARRAY['반도체', '삼성', 'IT'], 1), +('U092F7FQ55L', ARRAY['전기차', '배터리', '에너지'], 1); +``` + +#### 방안 3: 사용자별 맞춤 키워드 +```python +async def get_user_keywords(slack_user_id: str) -> List[str]: + """사용자별 맞춤 키워드 조회""" + try: + db = SessionLocal() + result = db.execute( + text("SELECT keywords FROM news_keywords WHERE slack_user_id = :sid"), + {"sid": slack_user_id} + ).fetchone() + + if result and result[0]: + return result[0] # PostgreSQL 배열 반환 + else: + # 기본값 또는 랜덤 키워드 + return get_daily_keywords() + finally: + db.close() +``` + +### 10.3 환경변수 DB 저장 방식 + +#### 설정 테이블 구조 +```sql +-- 시스템 설정 테이블 +CREATE TABLE system_config ( + id SERIAL PRIMARY KEY, + service_name VARCHAR(50) NOT NULL, + key VARCHAR(100) NOT NULL, + value TEXT, + description TEXT, + updated_at TIMESTAMP DEFAULT NOW(), + updated_by VARCHAR(100), + UNIQUE(service_name, key) +); + +-- 예시 데이터 +INSERT INTO system_config (service_name, key, value, description) VALUES +('news_skill', 'default_keywords', '["AI", "기술", "IT"]', '기본 뉴스 검색 키워드'), +('news_skill', 'max_items', '5', '최대 뉴스 개수'), +('news_skill', 'search_days', '7', '검색 기간 (일)'), +('rb8001', 'morning_briefing_time', '09:00', '모닝 브리핑 시간'); +``` + +#### Python에서 DB 설정 읽기 +```python +from typing import Optional, Any +import json + +class ConfigManager: + """DB 기반 설정 관리자""" + + def __init__(self, service_name: str): + self.service_name = service_name + self._cache = {} + + def get(self, key: str, default: Any = None) -> Any: + """설정값 조회""" + # 캐시 확인 + if key in self._cache: + return self._cache[key] + + try: + db = SessionLocal() + result = db.execute( + text(""" + SELECT value FROM system_config + WHERE service_name = :service AND key = :key + """), + {"service": self.service_name, "key": key} + ).fetchone() + + if result: + # JSON 파싱 시도 + try: + value = json.loads(result[0]) + except: + value = result[0] + + self._cache[key] = value + return value + + return default + + finally: + db.close() + + def set(self, key: str, value: Any, description: str = None): + """설정값 저장""" + try: + db = SessionLocal() + + # JSON 직렬화 가능한 경우 + if isinstance(value, (list, dict)): + value = json.dumps(value, ensure_ascii=False) + else: + value = str(value) + + db.execute( + text(""" + INSERT INTO system_config (service_name, key, value, description) + VALUES (:service, :key, :value, :desc) + ON CONFLICT (service_name, key) + DO UPDATE SET value = :value, updated_at = NOW() + """), + { + "service": self.service_name, + "key": key, + "value": value, + "desc": description + } + ) + db.commit() + + # 캐시 업데이트 + self._cache[key] = value + + finally: + db.close() + +# 사용 예시 +config = ConfigManager("news_skill") +keywords = config.get("default_keywords", ["AI", "IT"]) +max_items = config.get("max_items", 5) +``` + +### 10.4 구현 우선순위 + +1. **즉시 적용 가능**: 요일별 키워드 로테이션 +2. **중기 목표**: DB 기반 키워드 관리 +3. **장기 목표**: 사용자별 맞춤 키워드 + AI 추천 + +### 10.5 효과 + +- **다양성**: 매일 다른 뉴스 제공 +- **맞춤화**: 사용자별 관심사 반영 +- **유연성**: DB에서 키워드 실시간 변경 가능 +- **확장성**: 새로운 키워드 세트 쉽게 추가 + +--- + +*작성 완료: 2025-08-26 21:30* +*뉴스 스킬 분석 추가: 2025-08-26 21:45* \ No newline at end of file