diff --git a/scripts/summarize_news.py b/scripts/summarize_news.py index 0543b77..943ca25 100644 --- a/scripts/summarize_news.py +++ b/scripts/summarize_news.py @@ -1,4 +1,4 @@ -"""Use DeepSeek to summarize top news into 500-word Chinese briefs.""" +"""Use DeepSeek to summarize top news into categorized Chinese briefs (5 per category).""" import json, os, requests from datetime import datetime, timezone, timedelta @@ -20,38 +20,50 @@ def load_raw_news(): def summarize(items): - """Send raw news to DeepSeek and get summarized articles.""" - # Build a condensed input for the AI (titles + summaries) news_text = "" - for i, item in enumerate(items[:20], 1): + for i, item in enumerate(items[:30], 1): title = item.get("title", "") summary = item.get("summary", "")[:150].replace("<", "").replace(">", "") - news_text += f"{i}. [{item['source']}] {title}\n {summary}\n\n" + source = item.get("source", "") + news_text += f"{i}. [{source}] {title}\n {summary}\n\n" - prompt = f"""你是一个新闻整理助手。以下是来自BBC世界新闻、BBC中文、Hacker News的最新资讯。 + prompt = f"""你是一个新闻整理助手。以下是来自BBC世界新闻、BBC中文、新浪新闻、涌报、Hacker News的最新资讯。 -请从以上内容中精选出最重要的10条新闻,每条用中文写成一段300-500字的精炼摘要。 -要求: -1. 选择真正重要、有信息量的新闻(优先世界大事、科技突破、财经动向) -2. 每条摘要独立、完整,包含核心事实和背景 -3. 语言简洁有力,适合快速阅读 -4. 按重要性排序 -5. 每条附上来源标签 +请从以上内容中精选出最重要的新闻,按以下分类组织(每个分类最多5条): -输出格式为JSON数组: -[ - {{ - "rank": 1, - "title": "精炼标题(20字以内)", - "source": "BBC World", - "summary": "300-500字中文摘要..." - }}, - ... -] +分类要求: +- 国际要闻:全球政治、外交、军事 +- 科技前沿:AI、软件、硬件、互联网 +- 财经动向:市场、经济、商业 +- 中国热点:中国相关新闻 +- 社会生活:健康、环境、文化、民生 -只输出JSON,不要其他内容。 +每条新闻格式: +## 小标题(10字以内概括核心) -今日要闻原始数据: +正文(200-300字中文精炼摘要,包含核心事实和背景) + +输出格式为JSON: +{{ + "categories": [ + {{ + "name": "国际要闻", + "items": [ + {{"rank": 1, "subtitle": "小标题", "title": "原标题", "source": "BBC World", "summary": "正文..."}}, + ... + ] + }}, + ... + ] +}} + +注意: +- 每个分类最多5条 +- 小标题要精炼抓人 +- 摘要要有信息量,不要空话 +- 只输出JSON,不要其他内容 + +原始新闻: {news_text}""" resp = requests.post( @@ -60,35 +72,39 @@ def summarize(items): json={ "model": MODEL, "messages": [{"role": "user", "content": prompt}], - "temperature": 0.5, - "max_tokens": 6000, + "temperature": 0.4, + "max_tokens": 8000, }, - timeout=120, + timeout=180, ) if resp.status_code != 200: print(f"API error: {resp.status_code} {resp.text[:200]}") return None - result = resp.json() - content = result["choices"][0]["message"]["content"] - - # Parse JSON from response + content = resp.json()["choices"][0]["message"]["content"] content = content.strip() if content.startswith("```"): - content = content.split("\n", 1)[1] - content = content.rsplit("\n", 1)[0] - if content.endswith("```"): - content = content[:-3] - content = content.strip() + lines = content.split("\n") + content = "\n".join(lines[1:-1]) if lines[-1].strip() == "```" else "\n".join(lines[1:]) try: - articles = json.loads(content) + result = json.loads(content) except: - print(f"JSON parse failed, content: {content[:300]}") - return None + # Try to fix common JSON issues + content = content.strip() + # Remove trailing commas before closing brackets + import re + content = re.sub(r',\s*}', '}', content) + content = re.sub(r',\s*]', ']', content) + try: + result = json.loads(content) + except: + print(f"JSON parse failed, len={len(content)}") + print(f"First 800 chars: {content[:800]}") + return None - return articles + return result if __name__ == "__main__": @@ -98,21 +114,23 @@ if __name__ == "__main__": print("No news data") exit(0) - print(f"Loaded {len(items)} raw news items. Summarizing...") - articles = summarize(items) + print(f"Loaded {len(items)} raw news items. AI summarizing by category...") + data = summarize(items) - if not articles: + if not data: print("Summarization failed") exit(1) result = { "updated_at": now, - "total": len(articles), - "articles": articles, + "categories": data.get("categories", []), } + total = sum(len(c["items"]) for c in result["categories"]) os.makedirs(os.path.dirname(OUTPUT), exist_ok=True) with open(OUTPUT, "w", encoding="utf-8") as f: json.dump(result, f, ensure_ascii=False, indent=2) - print(f"Written {len(articles)} summarized articles to {OUTPUT}") + print(f"Written {total} articles across {len(result['categories'])} categories") + for c in result["categories"]: + print(f" {c['name']}: {len(c['items'])} items")