ginipick commited on
Commit
01adeab
·
verified ·
1 Parent(s): 9a08b0c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +168 -65
app.py CHANGED
@@ -3,7 +3,7 @@
3
  from flask import Flask, render_template_string, jsonify, request
4
  import requests
5
  import json
6
- from datetime import datetime
7
  from typing import List, Dict, Optional
8
  import os
9
  import sys
@@ -698,12 +698,12 @@ HTML_TEMPLATE = """
698
 
699
  <!-- 푸터 -->
700
  <div class="footer">
701
- <p>🤖 AI 뉴스 LLM 분석 시스템 v3.2</p>
702
  <p style="margin-top: 10px; font-size: 0.9em;">
703
- 💾 SQLite DB 영구 저장 | 🌐 AI Times 실시간 크롤링 | 🤗 Hugging Face Trending API | 🧠 Powered by Fireworks AI (Qwen3-235B)
704
  </p>
705
  <p style="margin-top: 10px; font-size: 0.85em; color: #999;">
706
- 데이터 출처: AI Times (실시간 크롤링), Hugging Face | 실시간 분석: Fireworks AI
707
  </p>
708
  </div>
709
  </div>
@@ -1081,27 +1081,27 @@ class LLMAnalyzer:
1081
  {
1082
  "role": "system",
1083
  "content": """당신은 중고등학생도 이해할 수 있게 AI 뉴스를 쉽게 설명하는 전문가입니다.
1084
- 한국어로 답변하며, 다음 형식의 JSON으로만 응답하세요:
1085
 
1086
- {
1087
- "summary": "뉴스 내용을 8-10문장으로 자세하고 구체적으로 설명 (수치, 사실, 배경 포함)",
1088
- "significance": "이 뉴스가 왜 중요한지 2-3문장으로 설명",
1089
- "impact_level": "high 또는 medium 또는 low",
1090
- "impact_text": "높음 또는 중간 또는 낮음",
1091
- "impact_description": "어떤 영향이 있을지 2-3문장으로 설명",
1092
- "action": "중고등학생이 할 수 있는 것을 2-3문장으로 제안"
1093
- }
1094
 
1095
- 반드시 위 형식의 JSON만 출력하세요."""
1096
  },
1097
  {
1098
  "role": "user",
1099
  "content": f"""다음 AI 뉴스를 중고등학생이 이해할 수 있도록 분석해주세요:
1100
 
1101
- 제목: {title}
1102
 
1103
- 각 항목을 구체적이고 자세하게 작성하되, 중고등학생 수준에 맞춰 쉽게 설명해주세요.
1104
- 특히 summary는 8-10문장으로 충분히 상세하게 작성하세요."""
1105
  }
1106
  ]
1107
 
@@ -1134,13 +1134,13 @@ class LLMAnalyzer:
1134
  analysis_templates = {
1135
  "챗GPT": {
1136
  "summary": """마이크로소프트(MS)는 챗GPT의 폭발적인 사용량 증가로 인해 데이터센터 용량이 부족한 심각한 상황에 직면했습니다.
1137
- 현재 미국 내 여러 핵심 지역에서 물리적 공간과 서버 용량이 모두 한계에 도달한 상태입니다.
1138
- 특히 버지니아와 텍사스 등 주요 클라우드 허브 지역에서는 2026년 상반기까지 신규 Azure 클라우드 구독이 제한될 것으로 예상됩니다.
1139
- 이는 생성형 AI 서비스의 급격한 성장 속도가 기업들의 인프라 준비 능력을 크게 초과하고 있음을 보여니다.
1140
- MS는 데이터센터 확장을 위해 막대한 투자를 하고 있지만, 실제 인프라 구축에는 최소 2-3년이 소요됩니다.
1141
- 이러한 공급 부족 현상은 AI 서비스 가격 상승과 접근성 제한으로 이어질 수 있으며,
1142
- 경쟁사들도 유사한 문제에 직면할 가능성이 높습니다.
1143
- 전문가들은 이 상황이 AI 산업의 성장 속도를 일시적으로 늦출 수 있다고 분석하고 있습니다.""",
1144
  "significance": "이 뉴스는 AI 기술의 대중화 속도가 기업들의 예상을 훨씬 뛰어넘고 있음을 보여줍니다. MS 같은 글로벌 IT 기업도 AI 수요를 따라잡기 위해 고군분투하고 있으며, 이는 AI가 단순한 유행이 아닌 산업 전반을 변화시키는 핵심 기술임을 증명합니다.",
1145
  "impact_level": "high",
1146
  "impact_text": "높음",
@@ -1149,12 +1149,12 @@ class LLMAnalyzer:
1149
  },
1150
  "GPU": {
1151
  "summary": """미국 정부가 아랍에미리트(UAE)에 최첨단 AI 칩(GPU) 수출을 공식적으로 승인했습니다.
1152
- 이번 승인은 UAE 내에서 미국 기업이 직접 운영하는 데이터센터에만 한정되며, 특히 오픈AI 전용 5기가와트(GW) 규모의 대형 데이터센터 구축에 사용될 예정입니다.
1153
- GPU는 AI 모델 학습과 추론에 필수적인 하드웨어로, 수천 개의 연산을 동시에 처리할 수 있는 병렬 처리 능력이 핵심입니다.
1154
- 현재 GPU 시장은 엔비디아가 약 80% 이상을 장악하고 있으며, 특히 AI 전용 H100, H200 칩은 공급 부족 현상이 심각합니다.
1155
- 이번 결정으로 엔비디아의 시가총액이 5조 달러에 근접할 것으로 월스트리트는 전망하고 있습니다.
1156
- 한편, 이는 미국의 전략적 기술 수출 정책 변화를 보여주는 중요한 사례입니다.
1157
- 중국에 대해서는 엄격한 수출 통제를 유지하면서도, 중동의 주요 동맹국에는 선별적으로 허용하는 '기술 동맹' 전략을 구사하고 있습니다.""",
1158
  "significance": "이는 미국의 AI 기술 수출 정책 변화를 보여주는 중요한 신호입니다. 기술 패권 경쟁 속에서도 전략적 동맹국과의 협력을 통해 AI 생태계를 확장하려는 미국의 의도를 엿볼 수 있습니다.",
1159
  "impact_level": "medium",
1160
  "impact_text": "중간",
@@ -1163,12 +1163,12 @@ class LLMAnalyzer:
1163
  },
1164
  "소라": {
1165
  "summary": """오픈AI의 혁신적인 AI 동영상 생성 앱 '소라(Sora)'가 출시 단 5일 만에 100만 다운로드를 돌파하는 경이적인 기록을 세웠습니다.
1166
- 이는 전설적인 챗GPT보다도 빠른 성장 속도이며, 초대 전용(invite-only) 방식의 제한적 출시임을 고려하면 더욱 놀라운 성과입니다.
1167
- 소라는 사용자가 입력한 텍스트 프롬프트만으로 최대 1분 길이의 고품질 동영상을 자동으로 생성할 수 있는 생성형 AI 도구입니다.
1168
- 현재 미국과 캐나다에서 iOS 전으로 먼저 출시되었으며, 안드로이드 버전과 글로벌 확장이 계획되어 있습니다.
1169
- 소라는 기존의 이미지 생성 AI(미드저니, 스테이블 디퓨전 등)를 뛰어넘어, 시간의 흐름과 물리 법칙을 이해하는 수준으로 발전했습니다.
1170
- 예를 들어, 파도가 치는 장면을 생성할 때 물의 움직임, 빛의 반사, 소리까지 자연스럽게 표현할 수 있습니다.
1171
- 이는 영화, 광고, 교육 콘텐츠, 게임 등 모든 영상 산업에 혁명적 변화를 예고합니다.""",
1172
  "significance": "텍스트를 이미지로 변환하는 기술에서 더 나아가 동영상 생성까지 가능해진 것은 AI 기술의 진화를 보여줍니다. 콘텐츠 제작의 민주화가 가속화되고 있으며, 누구나 쉽게 고품질 영상을 만들 수 있는 시대가 열리고 있습니다.",
1173
  "impact_level": "high",
1174
  "impact_text": "높음",
@@ -1185,12 +1185,12 @@ class LLMAnalyzer:
1185
  # 기본 분석 (중고등학생 수준)
1186
  return {
1187
  "summary": f"""'{title}'는 최신 AI 기술 동향을 다루는 중요한 뉴스입니다.
1188
- 인공지능 분야는 매일 새로운 발전을 이루고 있으며, 이러한 기술 변화는 우리의 일상생활, 교육, 그리고 미래 직업 세계에 직접적인 영향을 미칠 것으로 예상됩니다.
1189
- 최근 AI 기술은 단순히 데이터를 처리하는 수준을 넘어, 창의적인 콘텐츠를 생성하고 복잡한 문제를 해결하는 단계로 진화하고 있습니다.
1190
- 특히 대규모 언어 모델(LLM)과 생성형 AI의 발전은 산업 전반에 걸쳐 혁신을 가져오고 있습니다.
1191
- 이러한 기술 변화는 새로운 일자리를 창출하는 동시에, 기존 직업의 성격을 변화시키고 있어 우리 모두가 주목해야 할 트렌드입니다.
1192
- 전문가들은 향후 5-10년 내에 AI가 거의 모든 산업 분야에 통합될 것으로 전망하고 있습니다.
1193
- 따라서 관련 기술의 원리를 이해하고, 사회적 파급효과를 함께 고민하는 것이 미래 세대에게 매우 중요한 역량이 될 것입니다.""",
1194
  "significance": "AI 기술의 발전은 단순한 기술 혁신을 넘어 사회, 경제, 윤리적 측면에서 다양한 논의를 불러일으키고 있습니다. 이러한 변화를 이해하고 대비하는 것이 미래 세대에게 중요한 역량입니다.",
1195
  "impact_level": "medium",
1196
  "impact_text": "중간",
@@ -1352,7 +1352,8 @@ class AdvancedAIAnalyzer:
1352
  ]
1353
 
1354
  all_news = []
1355
- today = datetime.now().strftime('%m-%d') # 예: '10-10'
 
1356
 
1357
  for url_idx, url in enumerate(urls, 1):
1358
  try:
@@ -1412,8 +1413,8 @@ class AdvancedAIAnalyzer:
1412
  if not date_text:
1413
  date_text = today
1414
 
1415
- # 오늘 날짜만 필터링
1416
- if today not in date_text:
1417
  continue
1418
 
1419
  news_item = {
@@ -1432,7 +1433,7 @@ class AdvancedAIAnalyzer:
1432
  except Exception as e:
1433
  continue
1434
 
1435
- print(f" → {articles_found}개 오늘자 기사 수집\n")
1436
  time.sleep(1) # 서버 부하 방지
1437
 
1438
  except Exception as e:
@@ -1447,7 +1448,7 @@ class AdvancedAIAnalyzer:
1447
  unique_news.append(news)
1448
  seen_urls.add(news['url'])
1449
 
1450
- print(f"✅ 총 {len(unique_news)}개 중복 제거된 오늘자 뉴스\n")
1451
 
1452
  # 최소 3개는 보장 (없으면 샘플 추가)
1453
  if len(unique_news) < 3:
@@ -1481,6 +1482,104 @@ class AdvancedAIAnalyzer:
1481
 
1482
  return unique_news[:20] # 최대 20개
1483
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1484
  def fetch_huggingface_models(self, limit: int = 30) -> List[Dict]:
1485
  """허깅페이스 트렌딩 모델 30개 수집 (실제 API)"""
1486
  print(f"🤗 허깅페이스 트렌딩 모델 {limit}개 수집 중...")
@@ -1532,7 +1631,7 @@ class AdvancedAIAnalyzer:
1532
  print(f" ⚠️ 모델 {idx} 처리 오류: {e}")
1533
  continue
1534
 
1535
- print(f"✅ {len(models_list)}개 트렌딩 모델 수집 완료")
1536
 
1537
  # DB에 저장
1538
  if models_list:
@@ -1542,7 +1641,7 @@ class AdvancedAIAnalyzer:
1542
 
1543
  except Exception as e:
1544
  print(f"❌ 모델 수집 오류: {e}")
1545
- print("💾 DB에서 이전 데이터 로드 시도...")
1546
  return load_models_from_db()
1547
 
1548
  def fetch_huggingface_spaces(self, limit: int = 30) -> List[Dict]:
@@ -1602,7 +1701,7 @@ class AdvancedAIAnalyzer:
1602
  print(f" ⚠️ 스페이스 {idx} 처리 오류: {e}")
1603
  continue
1604
 
1605
- print(f"✅ {len(spaces_list)}개 트렌딩 스페이스 수집 완료")
1606
 
1607
  # DB에 저장
1608
  if spaces_list:
@@ -1612,15 +1711,15 @@ class AdvancedAIAnalyzer:
1612
 
1613
  except Exception as e:
1614
  print(f"❌ 스페이스 수집 오류: {e}")
1615
- print("💾 DB에서 이전 데이터 로드 시도...")
1616
  return load_spaces_from_db()
1617
 
1618
  def analyze_all_news(self) -> List[Dict]:
1619
  """모든 뉴스에 LLM 분석 추가"""
1620
- print("📰 뉴스 LLM 분석 시작...")
1621
 
1622
- # 실제 웹사이트에서 뉴스 수집
1623
- news = self.fetch_aitimes_news()
1624
 
1625
  if not news:
1626
  print("⚠️ 수집된 뉴스가 없습니다.")
@@ -1638,8 +1737,11 @@ class AdvancedAIAnalyzer:
1638
 
1639
  article['analysis'] = analysis
1640
  analyzed_news.append(article)
 
 
 
1641
 
1642
- print(f"✅ {len(analyzed_news)}개 뉴스 분석 완료")
1643
 
1644
  # DB에 저장
1645
  if analyzed_news:
@@ -1658,12 +1760,12 @@ class AdvancedAIAnalyzer:
1658
  print("="*60 + "\n")
1659
 
1660
  if force_refresh:
1661
- print("🔄 강제 새로고침 모드: 모든 데이터 새로 수집")
1662
  analyzed_news = self.analyze_all_news()
1663
  analyzed_models = self.fetch_huggingface_models(30)
1664
  analyzed_spaces = self.fetch_huggingface_spaces(30)
1665
  else:
1666
- print("💾 DB 우선 로드 모드")
1667
 
1668
  # DB에서 먼저 로드
1669
  analyzed_news = load_news_from_db()
@@ -1671,21 +1773,21 @@ class AdvancedAIAnalyzer:
1671
  print("📰 DB에 뉴스 없음 → 새로 수집")
1672
  analyzed_news = self.analyze_all_news()
1673
  else:
1674
- print(f"✅ DB에서 {len(analyzed_news)}개 뉴스 로드")
1675
 
1676
  analyzed_models = load_models_from_db()
1677
  if not analyzed_models:
1678
  print("🤗 DB에 모델 없음 → 새로 수집")
1679
  analyzed_models = self.fetch_huggingface_models(30)
1680
  else:
1681
- print(f"✅ DB에서 {len(analyzed_models)}개 모델 로드")
1682
 
1683
  analyzed_spaces = load_spaces_from_db()
1684
  if not analyzed_spaces:
1685
  print("🚀 DB에 스페이스 없음 → 새로 수집")
1686
  analyzed_spaces = self.fetch_huggingface_spaces(30)
1687
  else:
1688
- print(f"✅ DB에서 {len(analyzed_spaces)}개 스페이스 로드")
1689
 
1690
  # 통계
1691
  stats = {
@@ -1698,7 +1800,7 @@ class AdvancedAIAnalyzer:
1698
  print(f"\n✅ 전체 분석 완료: {stats['llm_analyses']}개 항목")
1699
  print(f" 📰 뉴스: {stats['total_news']}개")
1700
  print(f" 🤗 모델: {stats['hf_models']}개")
1701
- print(f" 🚀 스페이스: {stats['hf_spaces']}개")
1702
 
1703
  return {
1704
  'analyzed_news': analyzed_news,
@@ -1799,7 +1901,7 @@ def health():
1799
  return jsonify({
1800
  "status": "healthy",
1801
  "service": "AI News LLM Analyzer",
1802
- "version": "3.2.0",
1803
  "database": {
1804
  "connected": True,
1805
  "news_count": news_count,
@@ -1828,14 +1930,15 @@ if __name__ == '__main__':
1828
  print(f"""
1829
  ╔═══════════════════════════════════════��════════════════════╗
1830
  ║ ║
1831
- ║ 🤖 AI 뉴스 & 허깅페이스 LLM 분석 웹앱 v3.2
1832
  ║ ║
1833
  ╚════════════════════════════════════════════════════════════╝
1834
 
1835
  ✨ 주요 기능:
1836
  • 💾 SQLite DB 영구 스토리지
1837
- • 🌐 AI Times 실시간 뉴스 크롤링 (2개 섹션)
1838
- 📰 뉴스 중고등학생 수준 분석
 
1839
  • 🤗 허깅페이스 트렌딩 모델 TOP 30 (모델 카드 분석)
1840
  • 🚀 허깅페이스 트렌딩 스페이스 TOP 30 (app.py 분석)
1841
  • 🧠 Fireworks AI (Qwen3-235B) 실시간 LLM 분석
 
3
  from flask import Flask, render_template_string, jsonify, request
4
  import requests
5
  import json
6
+ from datetime import datetime, timedelta
7
  from typing import List, Dict, Optional
8
  import os
9
  import sys
 
698
 
699
  <!-- 푸터 -->
700
  <div class="footer">
701
+ <p>🤖 AI 뉴스 LLM 분석 시스템 v3.3</p>
702
  <p style="margin-top: 10px; font-size: 0.9em;">
703
+ 💾 SQLite DB 영구 저장 | 🌐 AI Times + Hacker News 실시간 수집 | 🤗 Hugging Face Trending API | 🧠 Powered by Fireworks AI (Qwen3-235B)
704
  </p>
705
  <p style="margin-top: 10px; font-size: 0.85em; color: #999;">
706
+ 데이터 출처: AI Times, Hacker News, Hugging Face | 실시간 분석: Fireworks AI
707
  </p>
708
  </div>
709
  </div>
 
1081
  {
1082
  "role": "system",
1083
  "content": """당신은 중고등학생도 이해할 수 있게 AI 뉴스를 쉽게 설명하는 전문가입니다.
1084
+ 한국어로 답변하며, 다음 형식의 JSON으로만 응답하세요:
1085
 
1086
+ {
1087
+ "summary": "뉴스 내용을 8-10문장으로 자세하고 구체적으로 설명 (수치, 사실, 배경 포함)",
1088
+ "significance": "이 뉴스가 왜 중요한지 2-3문장으로 설명",
1089
+ "impact_level": "high 또는 medium 또는 low",
1090
+ "impact_text": "높음 또는 중간 또는 낮음",
1091
+ "impact_description": "어떤 영향이 있을지 2-3문장으로 설명",
1092
+ "action": "중고등학생이 할 수 있는 것을 2-3문장으로 제안"
1093
+ }
1094
 
1095
+ 반드시 위 형식의 JSON만 출력하세요."""
1096
  },
1097
  {
1098
  "role": "user",
1099
  "content": f"""다음 AI 뉴스를 중고등학생이 이해할 수 있도록 분석해주세요:
1100
 
1101
+ 제목: {title}
1102
 
1103
+ 각 항목을 구체적이고 자세하게 작성하되, 중고등학생 수준에 맞춰 쉽게 설명해주세요.
1104
+ 특히 summary는 8-10문장으로 충분히 상세하게 작성하세요."""
1105
  }
1106
  ]
1107
 
 
1134
  analysis_templates = {
1135
  "챗GPT": {
1136
  "summary": """마이크로소프트(MS)는 챗GPT의 폭발적인 사용량 증가로 인해 데이터센터 용량이 부족한 심각한 상황에 직면했습니다.
1137
+ 현재 미국 내 여러 핵심 지역에서 물리적 공간과 서버 용량이 모두 한계에 도달한 상태입니다.
1138
+ 특히 버지니아와 텍사스 등 주요 클라우드 허브 지역에서는 2026년 상반기까지 신규 Azure 클라우드 구독이 제한될 것으로 예상됩니다.
1139
+ 이는 생성형 AI 서비스의 급격한 성장 속도가 기업들의 인프라 준비 능력을 크게 초과하고 있음을 보여��니다.
1140
+ MS는 데이터센터 확장을 위해 막대한 투자를 하고 있지만, 실제 인프라 구축에는 최소 2-3년이 소요됩니다.
1141
+ 이러한 공급 부족 현상은 AI 서비스 가격 상승과 접근성 제한으로 이어질 수 있으며,
1142
+ 경쟁사들도 유사한 문제에 직면할 가능성이 높습니다.
1143
+ 전문가들은 이 상황이 AI 산업의 성장 속도를 일시적으로 늦출 수 있다고 분석하고 있습니다.""",
1144
  "significance": "이 뉴스는 AI 기술의 대중화 속도가 기업들의 예상을 훨씬 뛰어넘고 있음을 보여줍니다. MS 같은 글로벌 IT 기업도 AI 수요를 따라잡기 위해 고군분투하고 있으며, 이는 AI가 단순한 유행이 아닌 산업 전반을 변화시키는 핵심 기술임을 증명합니다.",
1145
  "impact_level": "high",
1146
  "impact_text": "높음",
 
1149
  },
1150
  "GPU": {
1151
  "summary": """미국 정부가 아랍에미리트(UAE)에 최첨단 AI 칩(GPU) 수출을 공식적으로 승인했습니다.
1152
+ 이번 승인은 UAE 내에서 미국 기업이 직접 운영하는 데이터센터에만 한정되며, 특히 오픈AI 전용 5기가와트(GW) 규모의 대형 데이터센터 구축에 사용될 예정입니다.
1153
+ GPU는 AI 모델 학습과 추론에 필수적인 하드웨어로, 수천 개의 연산을 동시에 처리할 수 있는 병렬 처리 능력이 핵심입니다.
1154
+ 현재 GPU 시장은 엔비디아가 약 80% 이상을 장악하고 있으며, 특히 AI 전용 H100, H200 칩은 공급 부족 현상이 심각합니다.
1155
+ 이번 결정으로 엔비디아의 시가총액이 5조 달러에 근접할 것으로 월스트리트는 전망하고 있습니다.
1156
+ 한편, 이는 미국의 전략적 기술 수출 정책 변화를 보여주는 중요한 사례입니다.
1157
+ 중국에 대해서는 엄격한 수출 통제를 유지하면서도, 중동의 주요 동맹국에는 선별적으로 허용하는 '기술 동맹' 전략을 구사하고 있습니다.""",
1158
  "significance": "이는 미국의 AI 기술 수출 정책 변화를 보여주는 중요한 신호입니다. 기술 패권 경쟁 속에서도 전략적 동맹국과의 협력을 통해 AI 생태계를 확장하려는 미국의 의도를 엿볼 수 있습니다.",
1159
  "impact_level": "medium",
1160
  "impact_text": "중간",
 
1163
  },
1164
  "소라": {
1165
  "summary": """오픈AI의 혁신적인 AI 동영상 생성 앱 '소라(Sora)'가 출시 단 5일 만에 100만 다운로드를 돌파하는 경이적인 기록을 세웠습니다.
1166
+ 이는 전설적인 챗GPT보다도 빠른 성장 속도이며, 초대 전용(invite-only) 방식의 제한적 출시임을 고려하면 더욱 놀라운 성과입니다.
1167
+ 소라는 사용자가 입력한 텍스트 프롬프트만으로 최대 1분 길이의 고품질 동영상을 자동으로 생성할 수 있는 생성형 AI 도구입니다.
1168
+ 현재 미국과 캐나다에서 iOS 전���으로 먼저 출시되었으며, 안드로이드 버전과 글로벌 확장이 계획되어 있습니다.
1169
+ 소라는 기존의 이미지 생성 AI(미드저니, 스테이블 디퓨전 등)를 뛰어넘어, 시간의 흐름과 물리 법칙을 이해하는 수준으로 발전했습니다.
1170
+ 예를 들어, 파도가 치는 장면을 생성할 때 물의 움직임, 빛의 반사, 소리까지 자연스럽게 표현할 수 있습니다.
1171
+ 이는 영화, 광고, 교육 콘텐츠, 게임 등 모든 영상 산업에 혁명적 변화를 예고합니다.""",
1172
  "significance": "텍스트를 이미지로 변환하는 기술에서 더 나아가 동영상 생성까지 가능해진 것은 AI 기술의 진화를 보여줍니다. 콘텐츠 제작의 민주화가 가속화되고 있으며, 누구나 쉽게 고품질 영상을 만들 수 있는 시대가 열리고 있습니다.",
1173
  "impact_level": "high",
1174
  "impact_text": "높음",
 
1185
  # 기본 분석 (중고등학생 수준)
1186
  return {
1187
  "summary": f"""'{title}'는 최신 AI 기술 동향을 다루는 중요한 뉴스입니다.
1188
+ 인공지능 분야는 매일 새로운 발전을 이루고 있으며, 이러한 기술 변화는 우리의 일상생활, 교육, 그리고 미래 직업 세계에 직접적인 영향을 미칠 것으로 예상됩니다.
1189
+ 최근 AI 기술은 단순히 데이터를 처리하는 수준을 넘어, 창의적인 콘텐츠를 생성하고 복잡한 문제를 해결하는 단계로 진화하고 있습니다.
1190
+ 특히 대규모 언어 모델(LLM)과 생성형 AI의 발전은 산업 전반에 걸쳐 혁신을 가져오고 있습니다.
1191
+ 이러한 기술 변화는 새로운 일자리를 창출하는 동시에, 기존 직업의 성격을 변화시키고 있어 우리 모두가 주목해야 할 트렌드입니다.
1192
+ 전문가들은 향후 5-10년 내에 AI가 거의 모든 산업 분야에 통합될 것으로 전망하고 있습니다.
1193
+ 따라서 관련 기술의 원리를 이해하고, 사회적 파급효과를 함께 고민하는 것이 미래 세대에게 매우 중요한 역량이 될 것입니다.""",
1194
  "significance": "AI 기술의 발전은 단순한 기술 혁신을 넘어 사회, 경제, 윤리적 측면에서 다양한 논의를 불러일으키고 있습니다. 이러한 변화를 이해하고 대비하는 것이 미래 세대에게 중요한 역량입니다.",
1195
  "impact_level": "medium",
1196
  "impact_text": "중간",
 
1352
  ]
1353
 
1354
  all_news = []
1355
+ today = datetime.now().strftime('%m-%d') # 예: '10-11'
1356
+ yesterday = (datetime.now() - timedelta(days=1)).strftime('%m-%d') # 예: '10-10'
1357
 
1358
  for url_idx, url in enumerate(urls, 1):
1359
  try:
 
1413
  if not date_text:
1414
  date_text = today
1415
 
1416
+ # 오늘 또는 어제 날짜만 필터링 (시간대 차이 고려)
1417
+ if today not in date_text and yesterday not in date_text:
1418
  continue
1419
 
1420
  news_item = {
 
1433
  except Exception as e:
1434
  continue
1435
 
1436
+ print(f" → {articles_found}개 최근 기사 수집\n")
1437
  time.sleep(1) # 서버 부하 방지
1438
 
1439
  except Exception as e:
 
1448
  unique_news.append(news)
1449
  seen_urls.add(news['url'])
1450
 
1451
+ print(f"✅ 총 {len(unique_news)}개 중복 제거된 최근 뉴스\n")
1452
 
1453
  # 최소 3개는 보장 (없으면 샘플 추가)
1454
  if len(unique_news) < 3:
 
1482
 
1483
  return unique_news[:20] # 최대 20개
1484
 
1485
+ def fetch_hackernews(self, limit: int = 15) -> List[Dict]:
1486
+ """Hacker News Top Stories 수집 (미국 시간 기준 24시간 이내)"""
1487
+ print(f"🔥 Hacker News Top {limit}개 스토리 수집 중...")
1488
+
1489
+ news_list = []
1490
+
1491
+ try:
1492
+ # 1. Top Stories ID 목록 가져오기
1493
+ topstories_url = "https://hacker-news.firebaseio.com/v0/topstories.json"
1494
+ response = requests.get(topstories_url, timeout=10)
1495
+ response.raise_for_status()
1496
+
1497
+ story_ids = response.json()[:limit * 3] # 여유있게 가져오기
1498
+ print(f" 📊 {len(story_ids)}개 스토리 ID 받음")
1499
+
1500
+ # 현재 시간 (UTC 기준)
1501
+ current_time = datetime.utcnow()
1502
+ cutoff_time = current_time - timedelta(hours=36) # 36시간 전까지 (미국 시간 고려)
1503
+
1504
+ # 2. 각 스토리 상세 정보 가져오기
1505
+ for idx, story_id in enumerate(story_ids, 1):
1506
+ try:
1507
+ if len(news_list) >= limit:
1508
+ break
1509
+
1510
+ item_url = f"https://hacker-news.firebaseio.com/v0/item/{story_id}.json"
1511
+ item_response = requests.get(item_url, timeout=5)
1512
+ item_response.raise_for_status()
1513
+
1514
+ story = item_response.json()
1515
+
1516
+ # story 타입만 (job, poll 등 제외)
1517
+ if story.get('type') != 'story':
1518
+ continue
1519
+
1520
+ # URL이 없는 경우 스킵 (Ask HN 등)
1521
+ if not story.get('url'):
1522
+ continue
1523
+
1524
+ # 시간 확인 (36시간 이내만)
1525
+ timestamp = story.get('time', 0)
1526
+ story_time = datetime.utcfromtimestamp(timestamp)
1527
+
1528
+ if story_time < cutoff_time:
1529
+ continue
1530
+
1531
+ # 시간 변환 (Unix timestamp -> 날짜)
1532
+ date_str = story_time.strftime('%m-%d %H:%M')
1533
+
1534
+ news_item = {
1535
+ 'title': story.get('title', 'No Title'),
1536
+ 'url': story.get('url', ''),
1537
+ 'date': date_str,
1538
+ 'source': 'Hacker News',
1539
+ 'category': 'Tech',
1540
+ 'score': story.get('score', 0),
1541
+ 'author': story.get('by', 'Unknown'),
1542
+ 'comments': story.get('descendants', 0)
1543
+ }
1544
+
1545
+ news_list.append(news_item)
1546
+
1547
+ print(f" ✓ [{len(news_list)}/{limit}] {news_item['title'][:60]}... (점수: {news_item['score']})")
1548
+
1549
+ # API rate limit 방지
1550
+ time.sleep(0.2)
1551
+
1552
+ except Exception as e:
1553
+ print(f" ⚠️ 스토리 {story_id} 처리 오류: {e}")
1554
+ continue
1555
+
1556
+ print(f"✅ {len(news_list)}개 Hacker News 스토리 수집 완료\n")
1557
+ return news_list
1558
+
1559
+ except Exception as e:
1560
+ print(f"❌ Hacker News 수집 오류: {e}\n")
1561
+ return []
1562
+
1563
+ def fetch_all_news_sources(self) -> List[Dict]:
1564
+ """모든 뉴스 소스에서 수집"""
1565
+ print("🌐 여러 소스에서 뉴스 수집 중...\n")
1566
+
1567
+ all_news = []
1568
+
1569
+ # 1. AI Times 뉴스
1570
+ aitimes_news = self.fetch_aitimes_news()
1571
+ all_news.extend(aitimes_news)
1572
+
1573
+ # 2. Hacker News
1574
+ hackernews = self.fetch_hackernews(limit=15)
1575
+ all_news.extend(hackernews)
1576
+
1577
+ print(f"\n📰 총 {len(all_news)}개 뉴스 수집 완료")
1578
+ print(f" - AI Times: {len(aitimes_news)}개")
1579
+ print(f" - Hacker News: {len(hackernews)}개\n")
1580
+
1581
+ return all_news
1582
+
1583
  def fetch_huggingface_models(self, limit: int = 30) -> List[Dict]:
1584
  """허깅페이스 트렌딩 모델 30개 수집 (실제 API)"""
1585
  print(f"🤗 허깅페이스 트렌딩 모델 {limit}개 수집 중...")
 
1631
  print(f" ⚠️ 모델 {idx} 처리 오류: {e}")
1632
  continue
1633
 
1634
+ print(f"✅ {len(models_list)}개 트렌딩 모델 수집 완료\n")
1635
 
1636
  # DB에 저장
1637
  if models_list:
 
1641
 
1642
  except Exception as e:
1643
  print(f"❌ 모델 수집 오류: {e}")
1644
+ print("💾 DB에서 이전 데이터 로드 시도...\n")
1645
  return load_models_from_db()
1646
 
1647
  def fetch_huggingface_spaces(self, limit: int = 30) -> List[Dict]:
 
1701
  print(f" ⚠️ 스페이스 {idx} 처리 오류: {e}")
1702
  continue
1703
 
1704
+ print(f"✅ {len(spaces_list)}개 트렌딩 스페이스 수집 완료\n")
1705
 
1706
  # DB에 저장
1707
  if spaces_list:
 
1711
 
1712
  except Exception as e:
1713
  print(f"❌ 스페이스 수집 오류: {e}")
1714
+ print("💾 DB에서 이전 데이터 로드 시도...\n")
1715
  return load_spaces_from_db()
1716
 
1717
  def analyze_all_news(self) -> List[Dict]:
1718
  """모든 뉴스에 LLM 분석 추가"""
1719
+ print("📰 뉴스 LLM 분석 시작...\n")
1720
 
1721
+ # 여러 소스에서 뉴스 수집
1722
+ news = self.fetch_all_news_sources()
1723
 
1724
  if not news:
1725
  print("⚠️ 수집된 뉴스가 없습니다.")
 
1737
 
1738
  article['analysis'] = analysis
1739
  analyzed_news.append(article)
1740
+
1741
+ # API rate limit 방지
1742
+ time.sleep(0.3)
1743
 
1744
+ print(f"\n✅ {len(analyzed_news)}개 뉴스 분석 완료\n")
1745
 
1746
  # DB에 저장
1747
  if analyzed_news:
 
1760
  print("="*60 + "\n")
1761
 
1762
  if force_refresh:
1763
+ print("🔄 강제 새로고침 모드: 모든 데이터 새로 수집\n")
1764
  analyzed_news = self.analyze_all_news()
1765
  analyzed_models = self.fetch_huggingface_models(30)
1766
  analyzed_spaces = self.fetch_huggingface_spaces(30)
1767
  else:
1768
+ print("💾 DB 우선 로드 모드\n")
1769
 
1770
  # DB에서 먼저 로드
1771
  analyzed_news = load_news_from_db()
 
1773
  print("📰 DB에 뉴스 없음 → 새로 수집")
1774
  analyzed_news = self.analyze_all_news()
1775
  else:
1776
+ print(f"✅ DB에서 {len(analyzed_news)}개 뉴스 로드\n")
1777
 
1778
  analyzed_models = load_models_from_db()
1779
  if not analyzed_models:
1780
  print("🤗 DB에 모델 없음 → 새로 수집")
1781
  analyzed_models = self.fetch_huggingface_models(30)
1782
  else:
1783
+ print(f"✅ DB에서 {len(analyzed_models)}개 모델 로드\n")
1784
 
1785
  analyzed_spaces = load_spaces_from_db()
1786
  if not analyzed_spaces:
1787
  print("🚀 DB에 스페이스 없음 → 새로 수집")
1788
  analyzed_spaces = self.fetch_huggingface_spaces(30)
1789
  else:
1790
+ print(f"✅ DB에서 {len(analyzed_spaces)}개 스페이스 로드\n")
1791
 
1792
  # 통계
1793
  stats = {
 
1800
  print(f"\n✅ 전체 분석 완료: {stats['llm_analyses']}개 항목")
1801
  print(f" 📰 뉴스: {stats['total_news']}개")
1802
  print(f" 🤗 모델: {stats['hf_models']}개")
1803
+ print(f" 🚀 스페이스: {stats['hf_spaces']}개\n")
1804
 
1805
  return {
1806
  'analyzed_news': analyzed_news,
 
1901
  return jsonify({
1902
  "status": "healthy",
1903
  "service": "AI News LLM Analyzer",
1904
+ "version": "3.3.0",
1905
  "database": {
1906
  "connected": True,
1907
  "news_count": news_count,
 
1930
  print(f"""
1931
  ╔═══════════════════════════════════════��════════════════════╗
1932
  ║ ║
1933
+ ║ 🤖 AI 뉴스 & 허깅페이스 LLM 분석 웹앱 v3.3
1934
  ║ ║
1935
  ╚════════════════════════════════════════════════════════════╝
1936
 
1937
  ✨ 주요 기능:
1938
  • 💾 SQLite DB 영구 스토리지
1939
+ • 🌐 AI Times 실시간 뉴스 크롤링 (오늘+어제)
1940
+ 🔥 Hacker News Top Stories (36시간 이내)
1941
+ • 📰 뉴스 중고등학생 수준 LLM 분석
1942
  • 🤗 허깅페이스 트렌딩 모델 TOP 30 (모델 카드 분석)
1943
  • 🚀 허깅페이스 트렌딩 스페이스 TOP 30 (app.py 분석)
1944
  • 🧠 Fireworks AI (Qwen3-235B) 실시간 LLM 분석