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
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
# 流水线详解
|
||||
|
||||
本文档描述 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`(需重新入库全部向量)。
|
||||
Reference in New Issue
Block a user