Files
inspiration-collector/scripts/summarize_policy.py

122 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Use DeepSeek to summarize policy news into categorized Chinese briefs."""
import json, os, requests, re
from datetime import datetime, timezone, timedelta
API_KEY = "sk-bbca4a0380d549389f0d27cdea0b5228"
API_URL = "https://api.deepseek.com/v1/chat/completions"
MODEL = "deepseek-v4-flash"
INPUT = "/var/www/nav/data/policy.json"
OUTPUT = "/var/www/nav/data/policy_summary.json"
tz = timezone(timedelta(hours=8))
def load_raw():
if not os.path.exists(INPUT):
return []
with open(INPUT) as f:
data = json.load(f)
return data.get("items", [])
def summarize(items):
news_text = ""
for i, item in enumerate(items[:100], 1):
title = item.get("title", "")
summary = item.get("summary", "")[:200].replace("<", "").replace(">", "")
source = item.get("source", "")
link = item.get("link", "")
news_text += f"{i}. [{source}] {title}\n {summary}\n url: {link}\n\n"
prompt = f"""你是一个政策分析助手。请从原始政策新闻中精选出**最重要的政策动态**,按优先级排序。
## 选稿标准
- 国务院/发改委/部委最新政策文件
- 习近平总书记重要讲话/活动
- 重大经济/产业政策数字经济、AI、能源、金融
- 重大改革举措
- 重要人事任免
## 输出
- 分类名:**政策速递**(只有一个分类)
- 每条:**15-30字完整标题**subtitle**300-500字政策解读摘要**summary
- 总计 **10-20 条**,按重要性排序
## 输出格式
每条输出到 items 数组包含rank, subtitle, title, source, link, summary
summary 用自然段落,关键信息用 **加粗**。
## 原始新闻
{news_text}
JSON格式: {{"categories": [{{"name":"政策速递","items":[{{"rank":1,"subtitle":"...","title":"...","source":"...","link":"...","summary":"..."}}]}}]}}"""
resp = requests.post(
API_URL,
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
json={
"model": MODEL,
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.3,
"max_tokens": 16000,
},
timeout=180,
)
if resp.status_code != 200:
print(f"API error: {resp.status_code}")
return None
content = resp.json()["choices"][0]["message"]["content"].strip()
if content.startswith("```"):
lines = content.split("\n")
content = "\n".join(lines[1:-1]) if lines[-1].strip() == "```" else "\n".join(lines[1:])
try:
result = json.loads(content)
except:
import re as 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 500: {content[:500]}")
return None
return result
def run():
now = datetime.now(tz).strftime("%Y-%m-%d %H:%M")
items = load_raw()
if not items:
print("No policy data")
exit(0)
print(f"Loaded {len(items)} policy items. AI summarizing...")
data = summarize(items)
if not data:
print("Summarization failed")
exit(1)
result = {
"updated_at": now,
"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 {total} policy briefs -> {OUTPUT}")
for c in result["categories"]:
print(f" {c['name']}: {len(c['items'])} items")
if __name__ == "__main__":
run()