Files
intl_news/docs/pipeline.md
T
simon 9e4f5b4c75 fix: 去重合并多来源后同步到 events/Qdrant/MySQL,新增 sync-sources 回填命令
- dedup/pipeline: 合并 source_ids 后自动同步已生成的 events JSON 和 Qdrant payload
- 新增 sync_sources_from_deduped / uv run en-news sync-sources,用于历史数据回填
- sync-sources 会扫描 deduped 多来源唯一篇,更新 events、Qdrant、MySQL news_event.sources
- docs: 补充 sync-sources 使用说明
2026-08-23 10:55:23 +08:00

167 lines
5.8 KiB
Markdown
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.
# 流水线详解
本文档描述 M1→M9 每一步的输入、输出、配置与增量机制。
## M1 新闻抓取
- 模块:`crawler/`
- 输入:`configs/sources.yaml` 中的新闻源配置
- 输出:`data/raw/{source_id}/{YYYYMMDD}/`
- `index.jsonl`:本次/当日抓取索引,包含 `url_hash`、标题、URL、摘要、时间
- `{url_hash}.html` / `{url_hash}.md`:原始网页或 Markdown
- 策略:
1. 有 `rss_url` 的源先走 RSS/Atom/Google News RSS;
2. RSS 失败或返回空时,根据 `anti_bot_mode` 走 stealth/headful Web;
3. 单源串行,`index.jsonl` 按 `url_hash` 追加去重。
- 常用命令:
- `bash scripts/domestic_crawl_8g.sh [source_id]`
- `uv run en-news crawl --source cnbc`
## M2 正文提取
- 模块:`extractor/`
- 输入:`data/raw/{source_id}/{date}/index.jsonl`
- 输出:`data/processed/{source_id}/{date}/{url_hash}.json`
- `ProcessedArticle` 包含标题、正文 `content`、词数、提取器名、发布时间等。
- 提取器:`trafilatura`,失败时回退 Markdown。
- 增量:已存在同名 `{url_hash}.json` 则跳过。
```bash
uv run en-news extract
# 或只处理一个源
uv run en-news extract --source cnbc
```
## M3 三层去重
- 模块:`dedup/`
- 输入:`data/processed/**/{date}/*.json`
- 输出:
- `data/deduped/{date}/uniques/{url_hash}.json`(唯一篇)
- `data/dedup/fingerprints.sqlite3`(指纹库)
- `data/deduped/{date}/index.json`(去重统计)
- 逻辑:
1. URL 完全一致 → 重复
2. 正文 hash 一致 → 重复
3. SimHash 汉明距离 ≤ 阈值 → 模糊重复
- 跨源合并:重复篇的来源 ID 会追加到保留唯一篇的 `source_ids`,日报可展示多来源。
- 合并后会同步更新已生成的 `events` 与 Qdrant payload;历史数据可执行:
```bash
uv run en-news sync-sources
```
```bash
uv run en-news dedup
```
## M4 翻译 + 投资事件抽取
- 模块:`llm/`
- 输入:`data/deduped/{date}/uniques/*.json`
- 输出:`data/events/{date}/{url_hash}.json`
- `EnTranslatedArticle`:英文原字段 + `title_zh` / `content_zh` / `events` / `source_ids`
- 事件结构:`event_type` / `stock_codes` / `sentiment` / `importance` / `summary_zh`
- LLM:默认 DeepSeek `deepseek-v4-flash`,场景 `translation`
- 并发:默认 3 线程,来自 `system.yaml llm.concurrency`
- 增量:`events/{date}/{url_hash}.json` 存在则跳过。
```bash
uv run en-news translate
```
## M5 向量生成
- 模块:`embedding/`
- 输入:`data/events/{date}/*.json`
- 输出:`data/embeddings/{date}/{url_hash}.json`
- 包含 `url_hash`、`source_id`、`vector` 等
- `data/embeddings/{date}/index.json` 记录该批统计
- 向量:DashScope `text-embedding-v3`,默认 1024 维、batch_size=10
- 增量:已存在向量文件则跳过。
```bash
uv run en-news embed
```
## M6 Qdrant 入库与检索
- 模块:`vectorstore/`
- 输入:`data/embeddings/{date}/` 与 `data/events/{date}/`
- 输出:Qdrant collection `en_finance_news`
- collection 大小:1024 维,余弦距离
- point ID:`url_hash` 通过 UUIDv5 转换,确定性幂等
- payload:标题、双语标题、事件、来源、时间、正文预览等
- 支持模式:
- 本地文件模式(默认):`data/qdrant_storage`
- 远程 HTTP 模式:`.env` 中配置非本地的 `QDRANT_URL`
- 命令:
```bash
# 入库
uv run en-news index
# 重建 collection(会清空)
uv run en-news index --recreate
# 重建并全量回灌所有历史向量
uv run en-news index --recreate --all
# 指定日期入库
uv run en-news index --date 20260801
# 检索
uv run en-news search "苹果 财报"
```
## M7 全链路管道编排
- 模块:`scheduler/pipeline.py`
- 串行执行:`extract → dedup → translate → embed → index → report`
- 每步失败不阻断后续,最终返回各步骤成功/失败统计。
- CLI:`uv run en-news pipeline` / `--skip-report`
- Shell:`bash scripts/pipeline.sh [--resume]`
## M8 MCP 服务
- 模块:`mcp_server/server.py`
- 启动:`uv run en-news mcp-server`
- 工具:
- `search_news`:语义搜索
- `search_by_stock`:按美股代码搜索
- `search_by_sentiment`:按情绪过滤搜索
- `get_today_events`:当日重要事件
- `get_stats`:系统统计
- 用途:供 Claude Code / Cherry Studio 等 MCP 客户端做深度研究。
## M9 日报结构化入库
- 模块:`scheduler/reporter.py` + `report_db/`
- 时间窗口:最近 25 小时
- 输出:MySQL `myquant` 库
- `news_report`:`report_type='intl'`、`report_date`、`generated_at`、`ai_summary`、`stats`
- `news_event`:`section='intl'`、Top 事件明细
- 幂等:`(report_date, report_type='intl', file_name='')` 唯一键覆盖
- 命令:`uv run en-news report`
## 数据目录速查
```text
data/
├── raw/{source_id}/{YYYYMMDD}/ M1 原始
├── processed/{source_id}/{YYYYMMDD}/ M2 正文
├── dedup/fingerprints.sqlite3 M3 指纹库
├── deduped/{YYYYMMDD}/uniques/ M3 去重后唯一篇
├── events/{YYYYMMDD}/ M4 翻译+事件
├── embeddings/{YYYYMMDD}/ M5 向量
├── qdrant_storage/ M6 本地 Qdrant
├── run_state/ 步骤级 --resume 状态
└── reports/ 历史 HTML 日报(M9 已不再产出)
```
## 失败恢复建议
1. 如果某个 Python 步骤失败,直接重跑同一命令即可,已完成的文件会自动跳过。
2. 如果 Shell 脚本中断,使用 `bash scripts/domestic_full.sh --resume` 或 `bash scripts/pipeline.sh --resume`。
3. 日报失败通常与 MySQL 连接/凭据有关,可先单独执行 `uv run en-news report` 查看日志。
4. 若 Qdrant 本地文件损坏,可考虑备份后删除 `data/qdrant_storage` 并重新 `uv run en-news index`(需重新入库全部向量)。