docs: 多源入库与生产迁移说明

- README: 多源记录补充 M4/日报/DB(news_event.sources)透传说明
- continuation.md: 记录多源入库、阶段/AI 显性输出、AI 摘要崩溃修复与生产迁移
This commit is contained in:
2026-08-12 12:56:10 +08:00
parent 794ce6c853
commit 8bbf5104a7
2 changed files with 25 additions and 26 deletions
+23 -25
View File
@@ -1,6 +1,6 @@
# continuation.md
> `checkpoint` @ 2026-08-12 10:30
> `checkpoint` @ 2026-08-12 13:00
---
@@ -13,41 +13,39 @@
| 日报 | **M10 完成并已部署 pi5: 结构化入库 MySQL;日报按当天日期生成(新闻 30h 回溯 / xwlb 取前一日 / 公告调研近 15 日)** |
| DB 连接 | pi 上 systemd 服务 `a-share-db-tunnel` 常驻(0.0.0.0:13306 → doorcome.cn:3306);**pi5 直连 192.168.1.10:13306** |
| 调度器 | APScheduler,systemd `a-share-research.service`(pi5);每天 07:00 首次任务生成日报(12/18/22 点不生成) |
| LLM | 场景化配置 `configs/llm_models.yaml`(4 场景: event_extraction/daily_report/stock_report/embedding);YAML 优先、`.env` 兜底;模型必须显式配置,无内置兜底 |
| 去重 | 多源记录:指纹库 `source_ids` 列 + uniques JSON `sources` 字段 + `data/deduped/{day}/sources.json` |
| 增量/断点 | M2/M4/M5 产物存在即跳过(`--force` 全量);`pipeline --once --resume` 断点续跑(状态 `data/pipeline/state.json`) |
| LLM | 场景化配置 `configs/llm_models.yaml`(4 场景);YAML 优先、`.env` 兜底 |
| 去重 | 多源记录:指纹库 `source_ids` 列 + uniques `sources` 字段 + `sources.json`;**M4 事件 / 日报 / DB `news_event.sources` 全链路透传** |
| 增量/断点 | M2/M4/M5 产物存在即跳过(`--force` 全量);`pipeline --once --resume` 断点续跑 |
| 服务器 | `pi@192.168.1.160`(生产)/ `pi@192.168.1.10`(DB 隧道宿主) |
| 抓取方式 | js_render=false → httpx 直连;js_render=true → Playwright |
---
## 本次完成 (2026-08-12) — 增量处理与 pipeline 断点续跑
## 本次完成 (2026-08-12 13:00) — 日报事件多新闻源入库 + 阶段/AI 显性输出 + 摘要崩溃修复
**目标:** ① 全链路中断后可从断点恢复;② 各子任务排除已处理文件,避免全量重跑与重复 API 计费。
**1. 多新闻源贯通至 DB(方案 A:新增 sources 列):**
- `llm/models.py`:`ExtractedEvent` 增加 `sources`(validator 保主源居首、去重;旧产物兜底 `[source_id]`)
- `llm/extractor.py`:`extract_event(_async)` 增加 `sources` 参数透传
- `scripts/run_event_extraction.py`:读取 deduped uniques 的 `sources` 字段传入抽取(`_load_sources`)
- `scheduler/reporter.py`:`_load_events_from_dir` 读取 `sources`(兜底 `[source_id]`)→ `EventRow.sources`
- `report_db`:`news_event` 建表加 `sources TEXT` 列;`init_schema` 幂等迁移(ALTER,Duplicate column 捕获);`save_report` INSERT 写 JSON
- 生产 pi5:`init_schema` 已执行,`news_event.sources` 列就绪(text, NULL);旧数据为 NULL,下次全链路 M4 后新事件带多源
**1. 各步骤增量处理(产物存在即跳过,`--force` 全量):**
- M2 `run_extractor.py`:输出目录已有 `{url_hash}.json` 即跳过提取,仅回补 index 行;`--force` 重建;成功率统计含跳过项(修复全跳过时误报 rc=1)
- M4 `run_event_extraction.py`:`data/events/{day}/{url_hash}.json` 已存在即跳过(**不重复调用 LLM API**);`--force` 全量;failed.jsonl 只保留本次失败、index 累积追加
- M5 `run_embedding.py`:`data/embeddings/{day}/{url_hash}.json` 已存在即跳过(**不重复调用 embed API**);`--force` 全量
- M1(seen_urls 增量)/ M3(指纹库判重)/ M6(upsert 幂等)为既有能力,README 汇总成表
**2. pipeline 阶段与 AI 显性输出(scheduler/pipeline.py):**
- 每步前打印 `阶段 i/n: 中文名 [步骤] 日期` 分隔标题
- llm/report/embedding 步骤打印 `🤖 AI 大模型: provider=..., model=...`(按场景配置解析,缺 key 也可展示)
**2. pipeline 断点续跑(scheduler/pipeline.py + run_scheduler.py):**
- 新增 `data/pipeline/state.json`(按日期隔离,记录每步骤 ok/failed + 退出码 + 耗时),原子写
- `run_pipeline(resume=True)` 跳过连续成功前缀,从首个失败/未执行步骤继续执行到结尾
- `pipeline --once --resume`(默认全量不变;`--resume` 与 `--steps` 互斥报错);定时守护模式不受影响
**3. 修复日报 AI 摘要崩溃('str' object has no attribute 'model'):**
- `_llm_summarize` 内 3 处 `_llm_call(client, model, ...)` 改为传 `config`(上轮改签名遗漏)
- 新增回归测试(单块/多分块全链路)
**验证(Mac 本地,20260616 数据 100 篇):**
- pytest **225 passed**(新增 tests/test_incremental.py 10 个:M2/M4/M5 跳过、状态记录、resume 续跑、resume 全完成 noop、--resume+--steps 互斥);crawler 3 个基线失败仍与本次无关
- ruff 零新增(9 个基线错误不变)
- 端到端:M2 增量重跑 140 条跳过 126 条,2.5s 完成、rc=0(修复前误报失败);state.json 正确记录 extractor ok
**效果评估(100 篇规模中断重跑场景):**
- M4 减少约 100 次 LLM API 调用、M5 减少约 100 次 embedding API 调用 → 中断恢复不再重复计费,耗时从分钟级降至秒级
- M2 重跑从全量 GNE 提取(分钟级)降至约 2.5s
- 断点恢复操作:中断后直接重跑同一条 `pipeline --once --resume` 命令即可
**验证(pi5 生产):**
- 本地 pytest **231 passed**(新增 ExtractedEvent.sources×2、EventRow.sources×2、_load_events_from_dir×1);ruff 基线 9 零新增
- pi5:`init_schema` 迁移成功(news_event 新增 sources 列);日报生成入库正常(report_id=225, events=60)
- 部署前已修复并在生产实测 AI 摘要恢复
**待办:**
- 同步 pi5(代码 + 文档),重启 `a-share-research`;首次同步后 pi5 的 `data/pipeline/state.json` 不存在 → resume 按全量处理,行为安全
- 下次全链路运行后抽查 `news_event.sources` 多源值(当前生产 events 为旧产物,sources=NULL)
- git 提交(本次改动尚未提交)
---