Update app.py
Browse files
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.
|
| 702 |
<p style="margin-top: 10px; font-size: 0.9em;">
|
| 703 |
-
๐พ SQLite DB ์๊ตฌ ์ ์ฅ | ๐ AI Times ์ค์๊ฐ
|
| 704 |
</p>
|
| 705 |
<p style="margin-top: 10px; font-size: 0.85em; color: #999;">
|
| 706 |
-
๋ฐ์ดํฐ ์ถ์ฒ: AI Times
|
| 707 |
</p>
|
| 708 |
</div>
|
| 709 |
</div>
|
|
@@ -1081,27 +1081,27 @@ class LLMAnalyzer:
|
|
| 1081 |
{
|
| 1082 |
"role": "system",
|
| 1083 |
"content": """๋น์ ์ ์ค๊ณ ๋ฑํ์๋ ์ดํดํ ์ ์๊ฒ AI ๋ด์ค๋ฅผ ์ฝ๊ฒ ์ค๋ช
ํ๋ ์ ๋ฌธ๊ฐ์
๋๋ค.
|
| 1084 |
-
|
| 1085 |
|
| 1086 |
-
|
| 1087 |
-
|
| 1088 |
-
|
| 1089 |
-
|
| 1090 |
-
|
| 1091 |
-
|
| 1092 |
-
|
| 1093 |
-
|
| 1094 |
|
| 1095 |
-
|
| 1096 |
},
|
| 1097 |
{
|
| 1098 |
"role": "user",
|
| 1099 |
"content": f"""๋ค์ AI ๋ด์ค๋ฅผ ์ค๊ณ ๋ฑํ์์ด ์ดํดํ ์ ์๋๋ก ๋ถ์ํด์ฃผ์ธ์:
|
| 1100 |
|
| 1101 |
-
|
| 1102 |
|
| 1103 |
-
|
| 1104 |
-
|
| 1105 |
}
|
| 1106 |
]
|
| 1107 |
|
|
@@ -1134,13 +1134,13 @@ class LLMAnalyzer:
|
|
| 1134 |
analysis_templates = {
|
| 1135 |
"์ฑGPT": {
|
| 1136 |
"summary": """๋ง์ดํฌ๋ก์ํํธ(MS)๋ ์ฑGPT์ ํญ๋ฐ์ ์ธ ์ฌ์ฉ๋ ์ฆ๊ฐ๋ก ์ธํด ๋ฐ์ดํฐ์ผํฐ ์ฉ๋์ด ๋ถ์กฑํ ์ฌ๊ฐํ ์ํฉ์ ์ง๋ฉดํ์ต๋๋ค.
|
| 1137 |
-
|
| 1138 |
-
|
| 1139 |
-
|
| 1140 |
-
|
| 1141 |
-
|
| 1142 |
-
|
| 1143 |
-
|
| 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 |
-
|
| 1153 |
-
|
| 1154 |
-
|
| 1155 |
-
|
| 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 |
-
|
| 1167 |
-
|
| 1168 |
-
|
| 1169 |
-
|
| 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 |
-
|
| 1190 |
-
|
| 1191 |
-
|
| 1192 |
-
|
| 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-
|
|
|
|
| 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}๊ฐ
|
| 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)}๊ฐ ์ค๋ณต ์ ๊ฑฐ๋
|
| 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.
|
| 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.
|
| 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.
|
| 1832 |
โ โ
|
| 1833 |
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
| 1834 |
|
| 1835 |
โจ ์ฃผ์ ๊ธฐ๋ฅ:
|
| 1836 |
โข ๐พ SQLite DB ์๊ตฌ ์คํ ๋ฆฌ์ง
|
| 1837 |
-
โข ๐ AI Times ์ค์๊ฐ ๋ด์ค ํฌ๋กค๋ง (
|
| 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 ๋ถ์
|