823 lines
33 KiB
Markdown
823 lines
33 KiB
Markdown
# 新闻智能分析系统开发计划 v2.0
|
||
|
||
> 基于大模型的时政/军事/科技新闻聚类、评价与整合系统
|
||
>
|
||
> **迭代说明**:参考 AI Daily 项目实践,融合细粒度聚类与工程化部署经验
|
||
|
||
---
|
||
|
||
## 一、项目概述
|
||
|
||
### 1.1 项目目标
|
||
构建一个自动化新闻分析系统,实现:
|
||
- **细粒度聚类**:保留多角度报道,避免简单去重丢失热点
|
||
- **动态热点识别**:基于当日新闻分布统计特征自适应判定热点
|
||
- **双层整合**:摘要级速览(全量)+ 洞察级深度分析(Top 10)
|
||
- **混合处理**:实时热点感知 + 每日批量汇总生成早报
|
||
- **跨日关联**:追踪同一事件的多日发展脉络
|
||
|
||
### 1.2 核心约束
|
||
| 维度 | 约束 |
|
||
|------|------|
|
||
| 数据规模 | 200-500篇/日 |
|
||
| 数据源 | RSS Feed(公众号订阅源) |
|
||
| 输出格式 | Web页面 / Markdown / 即时推送 |
|
||
| 成本预算 | 混合模型调度,日成本约1.3-1.6元 |
|
||
| 处理时效 | 批处理15-20分钟完成 |
|
||
| 部署方式 | 支持systemd服务化部署 |
|
||
|
||
### 1.3 双循环架构(参考AI Daily优化)
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Fetch 循环(实时) │
|
||
│ 每30分钟运行一次 │
|
||
│ RSS抓取 → 转为Markdown → LLM评分 → 重要性判断 → 即时推送? │
|
||
│ ↓ ↓ │
|
||
│ 存入数据库(fetch-yyyy-mm-dd.json) 飞书/Discord│
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
↓
|
||
┌─────────────────────────────────────────────────────────────────┐
|
||
│ Push 循环(定时) │
|
||
│ 每日定时运行(如早8点) │
|
||
│ 读取碎片化信息 → 细粒度聚类 → 多角度关联 → 综合评分 │
|
||
│ → 摘要级整合(全量) → 洞察级整合(Top10) → 生成日报 → 推送 │
|
||
└─────────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 二、与AI Daily的对比分析
|
||
|
||
### 2.1 相似性
|
||
|
||
| 维度 | AI Daily | 本系统 | 相似度 |
|
||
|------|----------|--------|--------|
|
||
| **数据源** | RSS订阅源 | RSS订阅源(公众号) | ⭐⭐⭐⭐⭐ |
|
||
| **核心流程** | RSS→LLM评分→推送/汇总 | RSS→聚类→评分→整合→推送/汇总 | ⭐⭐⭐⭐ |
|
||
| **双循环架构** | Fetch循环+Push循环 | 实时检测+批处理 | ⭐⭐⭐⭐⭐ |
|
||
| **即时推送** | 飞书/Discord webhook | 飞书/企微/邮件 | ⭐⭐⭐⭐ |
|
||
| **定时汇总** | 每日定时推送 | 每日早报生成 | ⭐⭐⭐⭐⭐ |
|
||
| **成本预算** | 每天6毛钱 | 每天1.3-1.6元 | ⭐⭐⭐⭐ |
|
||
|
||
### 2.2 本系统的差异化优势
|
||
|
||
| 特性 | AI Daily | 本系统 | 价值 |
|
||
|------|----------|--------|------|
|
||
| **热点识别** | 单篇文章评分 | **双层筛选:硬约束+动态阈值融合** | 质量控制+热点发现协同 |
|
||
| **去重策略** | 简单去重 | 细粒度聚类+多角度保留 | 不丢失多角度报道 |
|
||
| **内容整合** | 单篇摘要 | 双层整合(摘要+洞察) | 深度分析Top热点 |
|
||
| **领域聚焦** | AI领域 | 时政/军事/科技 | 专业领域实体识别 |
|
||
| **角度分类** | 无 | 6种报道角度分类 | 支持多角度整合 |
|
||
| **跨日关联** | 无 | 事件时间线追踪+Sentinel标记 | 追踪事件发展脉络 |
|
||
|
||
### 2.3 AI Daily 参考资源
|
||
|
||
- 项目介绍(热点追踪系统):https://yeekal.com/ai/ai-daily-news-tracker/
|
||
- 项目介绍(进化实录):https://yeekal.com/ai/ai-daily-news-update/
|
||
- GitHub 代码库:https://github.com/YeeKal/ai-daily
|
||
|
||
### 2.4 从AI Daily借鉴的核心设计
|
||
|
||
1. **双循环架构**:Fetch循环(实时)+ Push循环(定时)
|
||
2. **systemd服务化**:使用systemd timer替代Python内部定时,提升稳定性
|
||
3. **文件存储规范**:fetch/notify/push三种文件类型,明确保留策略
|
||
4. **评分硬约束**:非目标领域上限、KOL转述上限,有效控制信息质量
|
||
5. **Prompt防退化**:禁止套话、要求从素材出发,避免LLM输出风格趋同
|
||
6. **双视角洞察**:metadata(事实压缩)+ 正文(趋势判断)解耦
|
||
7. **Sentinel分段标记**:单文件多板块精确管理,支持跨日关联
|
||
|
||
---
|
||
|
||
## 三、开发阶段规划
|
||
|
||
### 阶段一:基础架构搭建(Week 1-2)
|
||
**目标**:建立数据流和存储基础,确保稳定采集
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 1.1 | RSS采集模块 | 解析公众号RSS Feed,提取标题、正文、来源、发布时间 | 原始文章数据库 | - |
|
||
| 1.2 | 数据标准化 | 统一文章格式,清洗HTML标签,提取纯文本 | 标准化文章表 | 1.1 |
|
||
| 1.3 | 文件存储层 | JSON文件存储(fetch-yyyy-mm-dd.json) | 存储规范 | 1.2 |
|
||
| 1.4 | 数据库设计 | SQLite设计文章表、实体表、聚类表 | 数据库Schema | 1.2 |
|
||
| 1.5 | 基础监控 | 采集成功率、文章数量统计 | 监控面板 | 1.1 |
|
||
| 1.6 | 日志系统 | 有效日志记录,便于问题定位 | 日志模块 | 1.1 |
|
||
|
||
**数据字段规范**:
|
||
```json
|
||
{
|
||
"title": "内容标题",
|
||
"link": "原始链接",
|
||
"published": "发布时间",
|
||
"source": "来源(公众号名称)",
|
||
"content": "Markdown格式的正文内容",
|
||
"tags": "LLM识别的标签",
|
||
"score": "LLM评分(0-100)",
|
||
"summary": "LLM生成的中文摘要",
|
||
"fetched_at": "抓取时间",
|
||
"entities": ["提取的实体列表"],
|
||
"reporting_angle": "报道角度"
|
||
}
|
||
```
|
||
|
||
**验收标准**:
|
||
- [ ] 稳定采集50+ RSS源
|
||
- [ ] 数据入库成功率 > 95%
|
||
- [ ] 基础监控可查看当日采集概况
|
||
- [ ] 日志系统可定位问题
|
||
|
||
---
|
||
|
||
### 阶段二:Fetch循环与双层评分系统(Week 3-4)
|
||
**目标**:实现实时采集、双层评分(硬约束+动态阈值融合)、即时推送
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 2.1 | Fetch循环引擎 | 每30分钟循环一次,抓取RSS→Markdown→评分 | fetch引擎 | 1.6 |
|
||
| 2.2 | **第一层:单篇评分Prompt** | 单篇文章重要性评分(0-100),**含硬约束** | `prompts/article_score.txt` | 2.1 |
|
||
| 2.3 | **硬约束过滤器** | 非时政军事上限、KOL转述上限、时效衰减 | 硬约束模块 | 2.2 |
|
||
| 2.4 | 即时推送判断 | 单篇≥90分触发即时推送候选 | 推送判断模块 | 2.3 |
|
||
| 2.5 | 飞书Webhook推送 | 飞书群机器人推送 | 飞书推送适配器 | 2.4 |
|
||
| 2.6 | systemd服务化 | 使用systemd timer管理服务 | systemd配置 | 2.1 |
|
||
|
||
#### 双层评分架构设计
|
||
|
||
```
|
||
第一层:单篇文章评分(硬约束) 第二层:实体簇热度(动态阈值)
|
||
├── 输入:单篇RSS文章 ├── 输入:同一实体的多篇报道(已硬约束评分)
|
||
├── 处理:LLM评分 + 硬约束修正 ├── 处理:统计特征 + 动态阈值计算
|
||
└── 输出:0-100分(已约束) └── 输出:热点判定
|
||
├── ≤79:非目标领域,过滤 ├── 低于阈值:普通关注
|
||
├── 80-89:一般关注,进入聚类 └── 高于阈值:热点,优先整合
|
||
└── 90+:高优先级,即时推送候选
|
||
```
|
||
|
||
#### 第一层:评分硬约束设计
|
||
|
||
**Prompt核心约束**:
|
||
```markdown
|
||
## 评分规则(硬性约束)
|
||
|
||
1. **非时政/军事/科技主题上限 79 分**
|
||
- 如果内容不属于目标领域(如纯娱乐八卦、生活琐事),最高只能给 79 分
|
||
|
||
2. **KOL 转述上限 89 分**
|
||
- 如果只是 KOL/大V 对已有信息的转述/评论,而非原创信息,最高只能给 89 分
|
||
|
||
3. **时效性衰减**
|
||
- 发布超过24小时:分数×0.9
|
||
- 发布超过48小时:分数×0.8
|
||
|
||
4. **90+ 分必须同时满足**:
|
||
- 重大事件/突破性进展/政策发布
|
||
- 一手信息源(官方发布、权威媒体首发)
|
||
- 对目标领域有实质性影响
|
||
|
||
5. **标签禁止空泛**
|
||
- 禁止:["军事", "新闻", "热点"]
|
||
- 要求:["歼-35A", "舰载战斗机", "隐身性能", "海军航空兵"]
|
||
```
|
||
|
||
**代码实现**:
|
||
```python
|
||
def apply_score_constraints(entry: dict, raw_score: int) -> tuple[int, list[str]]:
|
||
"""
|
||
应用评分硬约束
|
||
返回:修正后的分数,应用的约束标签列表
|
||
"""
|
||
constraints_applied = []
|
||
|
||
# 约束1:非目标领域上限79
|
||
if not is_target_domain(entry['content']):
|
||
raw_score = min(raw_score, 79)
|
||
constraints_applied.append("非目标领域")
|
||
|
||
# 约束2:KOL转述上限89
|
||
if is_kol_repost(entry):
|
||
raw_score = min(raw_score, 89)
|
||
constraints_applied.append("KOL转述")
|
||
|
||
# 约束3:时效性衰减
|
||
hours_old = get_hours_since_published(entry)
|
||
if hours_old > 24:
|
||
decay_factor = 0.9 ** (hours_old // 24)
|
||
raw_score = int(raw_score * decay_factor)
|
||
constraints_applied.append(f"时效衰减({hours_old}h)")
|
||
|
||
return raw_score, constraints_applied
|
||
```
|
||
|
||
**第一层输出分级**:
|
||
| 分数段 | 处理策略 | 说明 |
|
||
|--------|---------|------|
|
||
| ≤79 | 过滤,不入库 | 非目标领域内容 |
|
||
| 80-89 | 入库,进入聚类 | 一般关注,参与动态阈值计算 |
|
||
| 90+ | 入库,即时推送候选 | 高优先级,同时触发即时推送判断 |
|
||
|
||
**验收标准**:
|
||
- [ ] Fetch循环每30分钟稳定运行
|
||
- [ ] 硬约束生效(非目标领域≤79,KOL转述≤89,时效衰减)
|
||
- [ ] 90+文章触发即时推送候选
|
||
- [ ] systemd服务可一键启动/停止
|
||
|
||
---
|
||
|
||
### 阶段三:实体提取与细粒度聚类(Week 5-6)
|
||
**目标**:实现细粒度聚类,区分同一实体的不同报道角度
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 3.1 | 实体提取Prompt | 设计并优化实体提取提示词 | `prompts/extract_entities.txt` | 2.6 |
|
||
| 3.2 | 角度分类Prompt | 设计报道角度分类提示词 | `prompts/classify_angle.txt` | 2.6 |
|
||
| 3.3 | 批量实体提取 | 实现50篇/批并发调用,小模型处理 | 实体提取服务 | 3.1 |
|
||
| 3.4 | 角度分类服务 | 批量角度分类,与实体提取并行 | 角度分类服务 | 3.2 |
|
||
| 3.5 | 实体归一化 | 大模型消歧,合并别名 | 实体归一化服务 | 3.3 |
|
||
| 3.6 | 聚类算法 | 基于实体+角度的细粒度聚类 | 聚类引擎 | 3.4, 3.5 |
|
||
| 3.7 | 记忆系统 | 避免同一信息反复推送 | 去重模块 | 3.6 |
|
||
|
||
**验收标准**:
|
||
- [ ] 实体提取准确率 > 85%
|
||
- [ ] 角度分类准确率 > 80%
|
||
- [ ] 聚类后实体簇数量合理(200篇→30-50个簇)
|
||
- [ ] 同一信息不重复推送
|
||
|
||
---
|
||
|
||
### 阶段四:热度评价与动态阈值(Week 7-8)
|
||
**目标**:实现第二层筛选——基于硬约束后分数的动态热点识别
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 4.1 | **实体簇热度计算** | 融合硬约束分数的多维度热度计算 | 热度指标服务 | 3.6 |
|
||
| 4.2 | **第二层:动态阈值算法** | 基于硬约束后分数分布的自适应阈值 | 阈值计算模块 | 4.1 |
|
||
| 4.3 | 热点识别引擎 | 硬约束过滤 + 动态阈值筛选的双层判定 | 热点识别服务 | 4.2 |
|
||
| 4.4 | 热点精评Prompt | 大模型深度评分(Top 30热点簇) | `prompts/precise_heat.txt` | 4.3 |
|
||
|
||
#### 第二层:动态阈值设计(融合硬约束分数)
|
||
|
||
**实体簇热度计算**:
|
||
```python
|
||
class Cluster:
|
||
def __init__(self, entity_name: str):
|
||
self.entity_name = entity_name
|
||
self.articles = [] # 已硬约束评分的文章列表
|
||
self.hot_score = 0 # 综合热度分
|
||
|
||
def calculate_hot_score(self) -> int:
|
||
"""
|
||
计算实体簇热度,融合硬约束后的单篇分数
|
||
"""
|
||
if not self.articles:
|
||
return 0
|
||
|
||
# 基础分数:最高分文章的分数(已硬约束)
|
||
max_score = max(a['score'] for a in self.articles)
|
||
|
||
# 传播热度:报道数量 × log(来源多样性)
|
||
report_count = len(self.articles)
|
||
source_diversity = len(set(a['source'] for a in self.articles))
|
||
propagation_heat = report_count * math.log(source_diversity + 1)
|
||
|
||
# 角度覆盖度:不同报道角度数 / 6
|
||
angles = set(a.get('reporting_angle', 'unknown') for a in self.articles)
|
||
angle_coverage = len(angles) / 6
|
||
|
||
# 高优先级文章加成(90+文章额外加权)
|
||
high_priority_count = sum(1 for a in self.articles if a['score'] >= 90)
|
||
priority_bonus = high_priority_count * 5 # 每篇90+加5分
|
||
|
||
# 综合计算
|
||
self.hot_score = min(100, int(
|
||
max_score * 0.4 + # 单篇最高分权重40%
|
||
min(propagation_heat * 3, 30) + # 传播热度权重30%
|
||
angle_coverage * 20 + # 角度覆盖权重20%
|
||
priority_bonus # 高优先级加成10%
|
||
))
|
||
|
||
return self.hot_score
|
||
```
|
||
|
||
**动态阈值算法(融合版)**:
|
||
```python
|
||
def calculate_hotspot_threshold(clusters: list[Cluster], date: str) -> float:
|
||
"""
|
||
基于硬约束后分数分布计算动态阈值
|
||
同时考虑统计特征和高优先级文章数量
|
||
"""
|
||
# 获取当日所有簇的热度分数(已融合硬约束)
|
||
scores = [c.hot_score for c in clusters]
|
||
|
||
if len(scores) < 5:
|
||
return 75 # 数据不足时使用保底阈值
|
||
|
||
# 统计特征
|
||
mean_score = mean(scores)
|
||
std_score = std(scores)
|
||
median_score = median(scores)
|
||
|
||
# 方法1:统计阈值(均值+1.5倍标准差)
|
||
threshold_stat = mean_score + 1.5 * std_score
|
||
|
||
# 方法2:保底阈值(至少3条或前10%)
|
||
min_count = max(3, len(scores) * 0.1)
|
||
sorted_scores = sorted(scores, reverse=True)
|
||
threshold_adaptive = sorted_scores[min_count - 1]
|
||
|
||
# 方法3:硬约束保底(考虑90+高优先级文章数量)
|
||
high_priority_count = sum(
|
||
1 for c in clusters
|
||
if any(a['score'] >= 90 for a in c.articles)
|
||
)
|
||
if high_priority_count >= 3:
|
||
# 如果有3个以上簇包含90+文章,降低阈值确保热点被识别
|
||
threshold_backup = median_score
|
||
else:
|
||
threshold_backup = mean_score + 0.5 * std_score
|
||
|
||
# 取三者中较低值,确保热点不被遗漏
|
||
final_threshold = min(threshold_stat, threshold_adaptive, threshold_backup)
|
||
|
||
# 记录阈值计算日志
|
||
logger.info(f"动态阈值计算: 统计={threshold_stat:.1f}, "
|
||
f"保底={threshold_adaptive:.1f}, 硬约束保底={threshold_backup:.1f}, "
|
||
f"最终={final_threshold:.1f}")
|
||
|
||
return final_threshold
|
||
```
|
||
|
||
**双层热点判定流程**:
|
||
```python
|
||
def identify_hotspots(clusters: list[Cluster], date: str) -> tuple[list[Cluster], list[Cluster]]:
|
||
"""
|
||
双层热点识别:硬约束过滤 + 动态阈值筛选
|
||
"""
|
||
# 第一层:硬约束过滤(单篇层面已处理,此处检查)
|
||
valid_clusters = []
|
||
for c in clusters:
|
||
# 过滤掉所有文章都≤79的簇(非目标领域)
|
||
if all(a['score'] <= 79 for a in c.articles):
|
||
continue
|
||
valid_clusters.append(c)
|
||
|
||
# 计算各簇热度(融合硬约束分数)
|
||
for c in valid_clusters:
|
||
c.calculate_hot_score()
|
||
|
||
# 第二层:计算动态阈值
|
||
threshold = calculate_hotspot_threshold(valid_clusters, date)
|
||
|
||
# 阈值筛选 + 额外条件
|
||
hotspots = []
|
||
normal = []
|
||
for c in valid_clusters:
|
||
if c.hot_score >= threshold:
|
||
# 额外检查:是否有90+文章 或 超过阈值10分以上
|
||
has_high_priority = any(a['score'] >= 90 for a in c.articles)
|
||
significantly_above = c.hot_score >= threshold + 10
|
||
|
||
if has_high_priority or significantly_above:
|
||
hotspots.append(c)
|
||
else:
|
||
normal.append(c)
|
||
else:
|
||
normal.append(c)
|
||
|
||
# 排序:先按热度,再按最高单篇分数
|
||
hotspots.sort(key=lambda x: (x.hot_score, x.max_article_score), reverse=True)
|
||
|
||
return hotspots, normal
|
||
```
|
||
|
||
**融合设计优势**:
|
||
| 层级 | 作用 | 输入 | 输出 |
|
||
|------|------|------|------|
|
||
| 第一层(硬约束) | 质量控制 | 单篇文章 | 过滤非目标领域,标记高优先级 |
|
||
| 第二层(动态阈值) | 热点发现 | 实体簇(多篇聚合) | 识别突发热点,自适应当日分布 |
|
||
|
||
**验收标准**:
|
||
- [ ] 实体簇热度计算正确(融合硬约束分数)
|
||
- [ ] 动态阈值自适应当日分布
|
||
- [ ] 双层筛选协同工作(硬约束过滤→动态阈值筛选)
|
||
- [ ] 热点识别召回率 > 90%,误报率 < 20%
|
||
|
||
---
|
||
|
||
### 阶段五:Push循环与双层整合(Week 9-10)
|
||
**目标**:实现定时汇总、双层整合(双视角设计)、日报生成
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 5.1 | Push循环引擎 | 每日定时运行,读取碎片化信息→整合→推送 | push引擎 | 4.4 |
|
||
| 5.2 | 摘要级整合Prompt | 多源报道合并为50-80字精炼摘要 | `prompts/summary_integrate.txt` | 5.1 |
|
||
| 5.3 | 洞察级整合Prompt | Top 10生成结构化深度分析(**双视角设计**) | `prompts/insight_integrate.txt` | 5.1 |
|
||
| 5.4 | **Prompt防退化模块** | 禁止套话、要求从素材出发 | 防退化检查器 | 5.2, 5.3 |
|
||
| 5.5 | 摘要整合服务 | 小模型批量处理全量簇 | 摘要整合服务 | 5.2, 5.4 |
|
||
| 5.6 | 洞察整合服务 | 大模型逐个处理Top 10(**双视角输出**) | 洞察整合服务 | 5.3, 5.4 |
|
||
| 5.7 | 时间线提取 | 从多源报道中提取事件时间线 | 时间线提取模块 | 5.5 |
|
||
| 5.8 | 多角度整合 | 同一事件不同角度报道的整合 | 多角度整合模块 | 5.6 |
|
||
|
||
#### 双视角洞察设计(借鉴AI Daily)
|
||
|
||
**设计理念**:metadata(新闻编辑视角,事实压缩)+ 正文(情报分析师视角,趋势判断)解耦
|
||
|
||
**Prompt设计**:
|
||
```markdown
|
||
## Part 1: Metadata(新闻编辑视角)
|
||
|
||
请生成以下结构化信息:
|
||
- title: 10字以内的标题(事实陈述,无修饰)
|
||
- lead: 20字以内的导语(核心事实)
|
||
- highlights: 3-5个关键要点(bullet points,纯事实)
|
||
|
||
约束:只陈述事实,不做趋势判断,不用形容词。
|
||
|
||
## Part 2: 洞察正文(情报分析师视角)
|
||
|
||
基于多源报道,识别:
|
||
1. 事件脉络:关键时间节点和进展
|
||
2. 多角度分析:技术维度、战略维度、舆论维度
|
||
3. 影响与展望:短期影响、中长期趋势、值得关注信号
|
||
|
||
约束:
|
||
- 禁止空泛评论(如"意义重大""影响深远")
|
||
- 每个观点必须有素材支撑
|
||
- 使用具体名称(装备型号/政策名称/组织名称),不用"某些""部分"等模糊指代
|
||
```
|
||
|
||
**输出示例**:
|
||
```markdown
|
||
---
|
||
title: "歼-35A列装部队"
|
||
lead: "空军官方确认歼-35A已列装首批作战部队"
|
||
highlights:
|
||
- 首次公开确认进入实战化部署阶段
|
||
- 隐身性能对标F-35C,可能在舰载领域形成优势
|
||
- 多国媒体关注其对西太平洋军事平衡的影响
|
||
---
|
||
|
||
## 事件脉络
|
||
- 2024-11:珠海航展首次公开亮相
|
||
- 2025-03:完成舰载适配测试
|
||
- 2025-05:空军确认列装首批作战部队【新进展】
|
||
|
||
## 多角度分析
|
||
- **技术维度**:隐身涂层、航电系统、舰载适配均有突破
|
||
- **战略维度**:提升海军航空兵远海作战能力
|
||
- **舆论维度**:外媒关注中美舰载机代差缩小
|
||
|
||
## 影响与展望
|
||
短期:提升海军航母编队作战能力
|
||
中期:可能在西太平洋形成局部优势
|
||
值得关注:后续舰载版测试进展、出口动向
|
||
```
|
||
|
||
#### Prompt防退化设计(借鉴AI Daily)
|
||
|
||
**禁止套话列表**:
|
||
```python
|
||
FORBIDDEN_PHRASES = [
|
||
"意义重大", "影响深远", "引发关注", "备受瞩目",
|
||
"深水区", "拐点", "白热化", "新纪元", "里程碑",
|
||
"不容忽视", "值得注意", "值得关注", # 除非后接具体内容
|
||
"某些", "部分", "一些", "相关", # 模糊指代
|
||
]
|
||
|
||
def check_degeneration(content: str) -> list[str]:
|
||
"""检查内容是否包含禁止套话"""
|
||
violations = []
|
||
for phrase in FORBIDDEN_PHRASES:
|
||
if phrase in content:
|
||
violations.append(phrase)
|
||
return violations
|
||
```
|
||
|
||
**Prompt中的防退化指令**:
|
||
```markdown
|
||
## 输出约束(防退化)
|
||
|
||
1. 禁止使用以下套话:
|
||
- "意义重大""影响深远""引发关注""备受瞩目"
|
||
- "深水区""拐点""白热化""新纪元""里程碑"
|
||
|
||
2. 每个观点必须有素材支撑:
|
||
- 错误:该装备性能先进
|
||
- 正确:该装备隐身系数0.01,优于F-35的0.02
|
||
|
||
3. 使用具体名称,禁止模糊指代:
|
||
- 错误:某些国家表示关注
|
||
- 正确:日本防卫省发布关注声明
|
||
|
||
4. 从素材出发,每次措辞应不同,避免模板化输出
|
||
```
|
||
|
||
**验收标准**:
|
||
- [ ] 摘要信息完整度 > 90%
|
||
- [ ] 洞察分析覆盖双视角(metadata + 正文)
|
||
- [ ] 无禁止套话出现
|
||
- [ ] 整合内容无明显事实错误
|
||
|
||
---
|
||
|
||
### 阶段六:日报生成与跨日关联(Week 11-12)
|
||
**目标**:生成结构化日报(含Sentinel标记),实现跨日关联
|
||
|
||
| 序号 | 任务 | 描述 | 输出 | 依赖 |
|
||
|------|------|------|------|------|
|
||
| 6.1 | 日报模板设计 | Markdown模板,包含热点、速览、数据概览 | `templates/daily_report.md` | 5.8 |
|
||
| 6.2 | **Sentinel分段标记** | 单文件多板块精确管理 | `src/utils/sentinel.py` | 6.1 |
|
||
| 6.3 | **跨日关联模块** | 从历史日报提取上下文,追踪事件脉络 | `src/processors/cross_day.py` | 6.2 |
|
||
| 6.4 | 排序算法 | 综合热度、时效、重要性的排序逻辑 | 排序模块 | 4.4 |
|
||
| 6.5 | 日报渲染服务 | 按模板组装数据,生成Markdown(含Sentinel) | 日报渲染服务 | 6.1, 6.2, 6.4 |
|
||
| 6.6 | Web归档站点 | 部署在线阅览站点 | Web站点 | 6.5 |
|
||
| 6.7 | 数据保留策略 | fetch保留2天,notify保留2天,push保留5天 | 清理策略 | 6.6 |
|
||
|
||
#### 简化版Sentinel分段标记设计
|
||
|
||
**标记格式**:
|
||
```markdown
|
||
---
|
||
title: "每日情报早报"
|
||
date: "2026-05-24"
|
||
stats:
|
||
total_entities: 87
|
||
hotspot_count: 10
|
||
---
|
||
|
||
<!-- SECTION:summary BEGIN -->
|
||
## 📋 全量新闻速览
|
||
|
||
| # | 实体 | 摘要 | 来源数 | 热度 |
|
||
|---|------|------|--------|------|
|
||
| 1 | 歼-35A | 空军确认列装\|隐身性能对标F-35C | 8 | ★★★★★ |
|
||
<!-- SECTION:summary END -->
|
||
|
||
<!-- SECTION:insights BEGIN -->
|
||
## 🔥 热点深度洞察
|
||
|
||
### 1. 歼-35A列装进展 [持续跟踪]
|
||
> 速览:空军官方确认歼-35A已列装首批作战部队 [8源报道]
|
||
|
||
**事件脉络**
|
||
- 5月20日:首次公开亮相
|
||
- 5月24日:【新进展】确认列装部队
|
||
...
|
||
<!-- SECTION:insights END -->
|
||
```
|
||
|
||
**核心代码**:
|
||
```python
|
||
import re
|
||
from datetime import datetime, timedelta
|
||
|
||
def extract_section(content: str, section_name: str) -> str:
|
||
"""从日报内容中提取指定section"""
|
||
pattern = rf'<!-- SECTION:{re.escape(section_name)} BEGIN -->(.*?)<!-- SECTION:{re.escape(section_name)} END -->'
|
||
match = re.search(pattern, content, re.DOTALL | re.IGNORECASE)
|
||
return match.group(1).strip() if match else ""
|
||
|
||
def get_historical_context(entity_name: str, days: int = 7) -> dict:
|
||
"""获取某实体近N天的历史报道上下文"""
|
||
context = {
|
||
"first_seen": None,
|
||
"previous_summaries": [],
|
||
"previous_insights": [],
|
||
"mention_count": 0
|
||
}
|
||
|
||
for i in range(days):
|
||
date = (datetime.now() - timedelta(days=i)).strftime("%Y-%m-%d")
|
||
file_path = f"data/reports/daily-{date}.md"
|
||
|
||
try:
|
||
with open(file_path, 'r', encoding='utf-8') as f:
|
||
content = f.read()
|
||
|
||
if entity_name in content:
|
||
context["mention_count"] += 1
|
||
if context["first_seen"] is None:
|
||
context["first_seen"] = date
|
||
|
||
# 提取该实体在摘要中的记录
|
||
summary_section = extract_section(content, "summary")
|
||
for line in summary_section.split('\n'):
|
||
if entity_name in line and line.strip().startswith('|'):
|
||
context["previous_summaries"].append({
|
||
"date": date,
|
||
"content": line.strip()
|
||
})
|
||
|
||
# 提取该实体在洞察中的记录
|
||
insights_section = extract_section(content, "insights")
|
||
if entity_name in insights_section:
|
||
insight_blocks = re.split(r'### \d+\.', insights_section)
|
||
for block in insight_blocks:
|
||
if entity_name in block:
|
||
context["previous_insights"].append({
|
||
"date": date,
|
||
"content": block.strip()[:500]
|
||
})
|
||
break
|
||
except FileNotFoundError:
|
||
continue
|
||
|
||
return context
|
||
|
||
def generate_cross_day_marker(entity_name: str) -> str:
|
||
"""生成跨日标记"""
|
||
history = get_historical_context(entity_name, days=7)
|
||
|
||
if history["mention_count"] == 0:
|
||
return "首次报道"
|
||
elif history["mention_count"] == 1:
|
||
return "持续跟踪"
|
||
else:
|
||
return f"持续跟踪({history['mention_count']}次)"
|
||
```
|
||
|
||
**跨日关联应用**:
|
||
```python
|
||
# 在生成洞察时,添加跨日时间线
|
||
history = get_historical_context("歼-35A", days=7)
|
||
|
||
# 输出:
|
||
# {
|
||
# "first_seen": "2026-05-20",
|
||
# "mention_count": 3,
|
||
# "previous_summaries": [
|
||
# {"date": "2026-05-20", "content": "| 1 | 歼-35A | 首次公开亮相... |"},
|
||
# {"date": "2026-05-22", "content": "| 3 | 歼-35A | 专家分析隐身性能... |"}
|
||
# ]
|
||
# }
|
||
|
||
# 在洞察中展示时间线
|
||
timeline = f"""
|
||
**事件脉络**
|
||
- 5月20日:首次公开亮相(珠海航展)
|
||
- 5月22日:专家分析隐身性能,推测可能上舰
|
||
- 5月24日:【新进展】空军官方确认列装首批作战部队
|
||
"""
|
||
```
|
||
|
||
**验收标准**:
|
||
- [ ] 日报生成时间 < 20分钟
|
||
- [ ] Sentinel标记正确,可精确提取summary/insights
|
||
- [ ] 跨日关联可追踪实体历史报道
|
||
- [ ] Web站点可正常访问
|
||
|
||
---
|
||
|
||
### 阶段七:优化与迭代(Week 13-14)
|
||
**目标**:持续优化,功能扩展
|
||
|
||
| 序号 | 任务 | 描述 | 优先级 |
|
||
|------|------|------|--------|
|
||
| 7.1 | Prompt优化 | 基于实际效果迭代优化提示词 | 高 |
|
||
| 7.2 | 反馈闭环 | 收集用户反馈,标注数据,优化模型 | 高 |
|
||
| 7.3 | 趋势分析 | 7日热点趋势图,周期性报告 | 中 |
|
||
| 7.4 | 个性化推荐 | 基于用户阅读历史的个性化排序 | 低 |
|
||
|
||
---
|
||
|
||
## 四、技术栈建议
|
||
|
||
### 4.1 核心组件
|
||
| 组件 | 推荐方案 | 说明 |
|
||
|------|----------|------|
|
||
| 数据采集 | Python + feedparser | RSS解析 |
|
||
| 数据存储 | SQLite + JSON文件 | 数据库+文件双存储 |
|
||
| LLM调用 | OpenAI SDK / 国产模型SDK | 统一接口封装 |
|
||
| 任务调度 | systemd timer | 系统级服务管理 |
|
||
| Web展示 | Hugo / Flask | 静态/动态站点 |
|
||
| 日志 | Python logging + systemd journal | 集中日志管理 |
|
||
|
||
### 4.2 模型选择
|
||
| 任务类型 | 推荐模型 | 预估成本 |
|
||
|----------|----------|----------|
|
||
| 实体提取 | DeepSeek-V3 / Qwen-Plus | ~0.001元/次 |
|
||
| 角度分类 | DeepSeek-V3 / Qwen-Plus | ~0.001元/次 |
|
||
| 单篇评分 | DeepSeek-V3 / Qwen-Plus | ~0.001元/次 |
|
||
| 摘要整合 | DeepSeek-V3 / Qwen-Plus | ~0.002元/次 |
|
||
| 实体消歧 | GPT-4o / Claude-3.5-Sonnet | ~0.01元/次 |
|
||
| 热点精评 | GPT-4o / Claude-3.5-Sonnet | ~0.02元/次 |
|
||
| 洞察整合 | GPT-4o / Claude-3.5-Sonnet | ~0.1元/次 |
|
||
|
||
**日成本估算**:
|
||
- 200-500篇/日 × 0.001元(小模型)= 0.2-0.5元
|
||
- 100个簇 × 0.001元(小模型)= 0.1元
|
||
- 10个洞察 × 0.1元(大模型)= 1元
|
||
- **总计:约1.3-1.6元/日**
|
||
|
||
---
|
||
|
||
## 五、项目结构
|
||
|
||
```
|
||
news-intelligence-system/
|
||
├── config/
|
||
│ ├── rss_sources.json # RSS源配置
|
||
│ ├── models.yaml # 模型配置
|
||
│ └── systemd/ # systemd服务配置
|
||
├── src/
|
||
│ ├── collectors/ # 数据采集
|
||
│ │ └── rss_collector.py
|
||
│ ├── processors/ # 处理管道
|
||
│ │ ├── entity_extractor.py
|
||
│ │ ├── angle_classifier.py
|
||
│ │ ├── cluster_engine.py
|
||
│ │ ├── heat_calculator.py
|
||
│ │ └── cross_day.py # 跨日关联(新增)
|
||
│ ├── integrators/ # 内容整合
|
||
│ │ ├── summary_integrator.py
|
||
│ │ └── insight_integrator.py
|
||
│ ├── generators/ # 报告生成
|
||
│ │ ├── daily_report_generator.py
|
||
│ │ └── web_renderer.py
|
||
│ ├── push/ # 推送平台
|
||
│ │ ├── base.py
|
||
│ │ ├── feishu.py
|
||
│ │ └── discord.py
|
||
│ └── utils/ # 工具函数
|
||
│ ├── sentinel.py # Sentinel分段标记(新增)
|
||
│ └── prompt_checker.py # Prompt防退化检查(新增)
|
||
├── prompts/ # 提示词文件
|
||
│ ├── article_score.txt # 单篇评分(含硬约束)
|
||
│ ├── extract_entities.txt
|
||
│ ├── classify_angle.txt
|
||
│ ├── quick_heat.txt
|
||
│ ├── precise_heat.txt
|
||
│ ├── summary_integrate.txt
|
||
│ └── insight_integrate.txt # 双视角洞察
|
||
├── templates/
|
||
│ └── daily_report.md # 含Sentinel标记
|
||
├── data/
|
||
│ ├── fetch/ # fetch-yyyy-mm-dd.json
|
||
│ ├── notify/ # notify-yyyy-mm-dd.json
|
||
│ └── reports/ # daily-yyyy-mm-dd.md
|
||
├── web/ # Web归档站点
|
||
├── tests/
|
||
├── scripts/
|
||
│ ├── fetch_loop.py
|
||
│ ├── push_loop.py
|
||
│ └── setup_systemd.sh
|
||
├── requirements.txt
|
||
└── README.md
|
||
```
|
||
|
||
---
|
||
|
||
## 六、关键风险与应对
|
||
|
||
| 风险 | 影响 | 应对措施 |
|
||
|------|------|----------|
|
||
| RSS源失效 | 数据缺失 | 多源备份,监控告警 |
|
||
| LLM API限流 | 处理延迟 | 批量处理,重试机制,降级策略 |
|
||
| 实体识别错误 | 聚类偏差 | 人工标注反馈,Prompt迭代 |
|
||
| 热点漏识别 | 信息缺失 | 动态阈值保底机制,人工复核 |
|
||
| 成本超支 | 预算超支 | Token监控,模型降级,配额控制 |
|
||
| 进程崩溃 | 服务中断 | systemd自动重启 |
|
||
| LLM输出退化 | 质量下降 | **Prompt防退化检查** |
|
||
|
||
---
|
||
|
||
## 七、里程碑与交付物
|
||
|
||
| 里程碑 | 时间 | 交付物 |
|
||
|--------|------|--------|
|
||
| M1 | Week 2 | 稳定运行的数据采集系统 |
|
||
| M2 | Week 4 | Fetch循环上线,**评分硬约束生效** |
|
||
| M3 | Week 6 | 细粒度聚类引擎,实体提取准确率>85% |
|
||
| M4 | Week 8 | 动态热点识别系统,召回率>90% |
|
||
| M5 | Week 10 | Push循环上线,**双视角洞察+Prompt防退化** |
|
||
| M6 | Week 12 | **Sentinel跨日关联上线**,Web归档站点 |
|
||
| M7 | Week 14 | 持续优化迭代 |
|
||
|
||
---
|
||
|
||
## 八、借鉴AI Daily的核心设计总结
|
||
|
||
### 8.1 架构层面
|
||
1. **双循环架构**:Fetch循环(实时)+ Push循环(定时)
|
||
2. **systemd服务化**:替代Python内部定时,提升稳定性
|
||
3. **文件存储规范**:fetch/notify/reports三种文件类型,明确保留策略
|
||
|
||
### 8.2 LLM应用层面
|
||
1. **评分硬约束**:非目标领域≤79、KOL转述≤89,有效控制信息质量
|
||
2. **Prompt防退化**:禁止套话、要求从素材出发,避免LLM输出风格趋同
|
||
3. **双视角洞察**:metadata(事实压缩)+ 正文(趋势判断)解耦
|
||
|
||
### 8.3 数据管理层面
|
||
1. **Sentinel分段标记**:单文件多板块精确管理,支持跨日关联
|
||
2. **跨日关联**:从历史日报提取上下文,追踪事件发展脉络
|
||
3. **数据保留策略**:自动清理过期文件
|
||
|
||
### 8.4 工程层面
|
||
1. **日志集中管理**:systemd journal便于问题定位
|
||
2. **多平台推送**:飞书、Discord webhook支持
|
||
3. **成本可控**:每天约1.3-1.6元
|
||
|
||
---
|
||
|
||
*文档版本:v2.1*
|
||
*最后更新:2026-05-28*
|
||
*状态:已融合AI Daily四大核心设计(Sentinel、硬约束、防退化、双视角)*
|