Files
intl_news/docs/pipeline.md
T
simon 3b44f64f66 refactor: 清理历史 AI Agent 文档残留 + 重构 docs/ + Pipeline 健壮性修复
- docs: 删除 CLAUDE.md / continuation.md / english-news-plan.md 及旧版 intlnews_usage.*,
        统一迁移到 docs/{README,architecture,quickstart,usage,pipeline,configuration,deployment,development,faq}.md
- README: 精简为仓库入口,指向 docs/
- configs/sources.yaml: 更新注释指向新文档
- .env.example: 修正 DashScope Embedding 端点说明

Pipeline 修复:
- dedup/llm/embedding/vectorstore/reporter: 过滤 M2 no_content / 空正文,避免污染下游与 Qdrant
- dedup/pipeline: 改为先写唯一文件再写指纹,避免崩溃导致文章永久丢失
- crawler/orchestrator: sources_crawled 改为“尝试数”,成功数 = crawled - failed
- crawler/storage: write_index_jsonl 从文章路径推断日期,修复跨天/测试路径问题
- scheduler/pipeline: STEP_TIMEOUTS 实际生效(SIGALRM)
- scheduler/reporter: emb_count 排除 index.json;日报跳过无原文事件
- vectorstore/pipeline: payload 增加 source_ids;--recreate --all 时空日期也重建 collection
- app/cli: extract/dedup/translate/embed/index/pipeline 支持 --date;embed/index 支持 --all;crawl 全源失败返回非零
- scripts: domestic_full/crawl_8g/crawl_2g/pipeline 安全加载 .env;M1 全失败不标记且最终退出码=1
2026-08-22 20:47:53 +08:00

163 lines
5.7 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`,日报可展示多来源。
```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`(需重新入库全部向量)。