Files
news/project_plan.md
simon 366e60e8a9 feat: 日报结构化入库(M10 前后端分离数据层)
- 新增 report_db 包: MySQL 连接/建表/幂等写入 (news_report/news_event, myquant 库)
- 新增 report_import 包: 历史 178 份日报 HTML 解析入库, 表头驱动列映射
- reporter.py 完全切换: generate_report 结构化入库, 不再生成/上传 HTML
- CLI: 新增 report-import 子命令
- 依赖: uv add pymysql; 配置: NEWS_DB_* / REPORT_HISTORY_DIR
- 文档: docs/report_db_design.md(实现逻辑), docs/db_schema.md(表结构供 API/前端)
- 测试: 24 个单测通过 (parser/builder/models/importer)
2026-08-03 21:32:07 +08:00

701 lines
14 KiB
Markdown
Raw Permalink 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.
# project_plan.md
# A股 Deep Research 私有投研平台项目计划
版本:v1.0
最后更新:2026-06-16
---
# 一、项目目标
构建一个面向 A 股投资研究的私有化 Deep Research 平台,实现:
1. 自动抓取国内财经新闻网站;
2. 支持 JavaScript 动态渲染网站;
3. 自动提取中文新闻正文;
4. 自动去重;
5. 利用大模型抽取投资事件;
6. 自动生成向量知识;
7. 构建长期财经知识库;
8. 支持语义检索;
9. 支持 Cherry Studio、Claude Code、MCP 调用;
10. 自动生成 A 股投研分析报告。
本项目定位:
> 「A 股研究辅助平台」,而非自动交易系统。
---
# 二、总体技术架构
Crawl4AI
(网页抓取)
GNE
(中文正文提取)
标准化处理
新闻去重
LLM 投资事件抽取
Embedding 向量化
Qdrant 向量知识库
MCP 服务
Cherry Studio / Claude Code Agent
A 股深度研究分析
---
# 三、开发原则
Claude Code 在整个开发过程中必须遵守以下原则。
## 3.1 分阶段开发原则
严禁一次性生成整个项目。
必须按照 Milestone(里程碑)逐步开发。
每个阶段必须:
* 独立运行;
* 独立测试;
* 独立验收。
验收通过后再进入下一阶段。
---
## 3.2 生产级代码原则
所有生成代码必须满足:
* 使用 Python 类型注解;
* 必须记录日志;
* 必须具备异常处理;
* 必须支持重试机制;
* 不允许硬编码配置;
* 配置必须可修改;
* 必要时编写测试代码。
禁止为了简洁而牺牲可维护性。
---
## 3.3 配置驱动原则
网站抓取规则不得写死。
所有新闻源配置必须来自 YAML 文件。
示例:
sources.yaml
* id: sina
enabled: true
homepage: https://finance.sina.com.cn
article_selector: article
title_selector: h1
---
## 3.4 中文优先原则
本系统主要服务于中文财经研究。
优先支持:
* 财联社
* 东方财富
* 新浪财经
* 证券时报
* 中国证券网
* 界面新闻
* 第一财经
* 雪球
后续支持:
* 微博财经
* 微信公众号
* B站财经UP主
* 知乎专栏
---
## 3.5 可持续演进原则
后续新增网站时:
不得修改已有核心逻辑。
新增网站应仅通过:
* 修改配置;
* 新增适配器;
完成扩展。
---
# 四、推荐项目结构
a_share_research/
├─ app/
├─ crawler/ # 抓取模块
├─ extractor/ # 正文提取
├─ dedup/ # 去重模块
├─ llm/ # 大模型抽取
├─ embedding/ # 向量生成
├─ vectorstore/ # Qdrant
├─ scheduler/ # 定时任务
├─ mcp/ # MCP服务
├─ api/ # 对外接口
├─ configs/ # 配置文件
├─ prompts/ # Prompt模板
├─ tests/ # 测试
├─ scripts/ # 工具脚本
├─ logs/
├─ docs/
├─ main.py
├─ pyproject.toml
├─ docker-compose.yml
├─ README.md
├─ CLAUDE.md
├─ continuation.md
└─ project_plan.md
---
# 五、Milestone 1:新闻抓取模块
目标:
建立稳定可靠的新闻抓取能力。
任务:
1. 安装 Crawl4AI
2. 验证浏览器环境;
3. 实现 crawler 模块;
4. 从 YAML 读取网站配置;
5. 支持异步并发抓取;
6. 支持导出原始 HTML
7. 支持导出 Markdown
8. 本地保存抓取结果。
交付物:
crawler/
configs/sources.yaml
tests/test_crawler.py
验收标准:
* 至少支持 5 个财经网站;
* 抓取成功率 ≥ 90%
* 抓取失败自动重试。
---
# 六、Milestone 2:正文提取模块
目标:
提取高质量中文新闻正文。
任务:
1. 集成 GNE
2. 实现 extractor 模块;
3. 自动去除广告;
4. 自动去除相关推荐;
5. 自动去除评论区;
6. 提取:
* 标题
* 正文
* 发布时间
* 作者
* 来源
统一输出格式:
{
"title":"",
"content":"",
"publish_time":"",
"author":"",
"source":""
}
交付物:
extractor/
tests/test_extractor.py
验收标准:
主流财经网站正文提取效果达到人工可接受水平。
---
# 七、Milestone 3:新闻去重
目标:
避免重复新闻污染知识库。
任务:
实现三层去重:
第一层:
URL Hash 去重;
第二层:
正文 Hash 去重;
第三层:
模糊匹配去重。
交付物:
dedup/
tests/test_dedup.py
验收标准:
重复新闻比例 ≤ 5%。
---
# 八、Milestone 4:投资事件抽取
目标:
将新闻转换为结构化投资信息。
任务:
调用 DeepSeek 或 Qwen API。
抽取:
* 股票代码;
* 公司名称;
* 所属行业;
* 利好/利空;
* 影响程度;
* 事件类型。
输出 JSON。
示例:
{
"stock_codes":["300750"],
"company_names":["宁德时代"],
"industries":["锂电池"],
"sentiment":"positive",
"importance":5,
"event_type":"合作签约"
}
交付物:
llm/
prompts/
验收标准:
JSON 输出成功率 ≥ 95%。
---
# 九、Milestone 5Embedding 向量化
目标:
构建语义检索能力。
任务:
支持:
本地模型:
* BGE-M3
远程API
* Qwen Embedding
* 百炼 Embedding。
输出:
List[float]
交付物:
embedding/
验收标准:
向量生成稳定可用。
---
# 十、Milestone 6Qdrant 向量知识库
目标:
建立长期财经知识库。
任务:
1. Docker 部署 Qdrant
2. 创建 Collection
3. 定义 Payload
4. 写入向量;
5. 支持检索;
6. 支持过滤。
交付物:
docker-compose.yml
vectorstore/
验收标准:
Top-K 检索正确。
---
# 十一、Qdrant Payload 规范
{
"id":"",
"title":"",
"content":"",
"publish_time":"",
"source":"",
"url":"",
```
"stock_codes":[],
"company_names":[],
"industries":[],
"sentiment":"",
"importance":0,
"event_type":""
```
}
---
# 十二、Milestone 7:定时任务
目标:
实现无人值守更新。
任务:
集成 APScheduler。
执行时间:
07:00
12:00
18:00
22:00
执行流程:
抓取
正文提取
新闻去重
LLM 抽取
Embedding
Qdrant 入库
交付物:
scheduler/
验收标准:
能够长期稳定运行。
---
# 十三、Milestone 8MCP 服务
目标:
支持 Agent 调用知识库。
任务:
实现 MCP 工具:
search_news
search_company_news
search_industry_news
search_stock_events
search_sentiment_trend
验收标准:
Cherry Studio 能够成功调用。
交付物:
mcp/
---
# 十四、Milestone 9:投研 Agent
目标:
生成 A 股深度研究报告。
任务:
设计 Prompt。
支持:
* 公司分析;
* 行业分析;
* 利好利空梳理;
* 新闻时间线追踪;
* 情绪变化分析;
* 风险识别;
* 投资逻辑总结。
输出:
结构化研究报告。
交付物:
docs/agent_prompt.md
验收标准:
研究报告具备实际参考价值。
---
# 十五、运行与运维要求
所有服务必须支持 Docker 部署。
要求:
* 使用 .env 管理敏感配置;
* API Key 禁止提交至 Git
* 日志自动轮转;
* 支持增量更新;
* 支持断点恢复;
* 提供健康检查接口。
---
# 十六、非目标(Non-Goals
本项目不负责:
* 自动下单交易;
* 股票价格预测;
* 提供投资建议;
* 保证投资收益;
* 替代人工决策。
本项目定位为:
> A 股研究辅助与知识管理平台。
---
# 十七、Claude Code 执行规则
Claude Code 必须严格遵守:
1. 每次只完成一个 Milestone
2. 完成后停止并等待人工验收;
3. 每个阶段更新 README
4. 未经允许不得重构已验收模块;
5. 必须保持向后兼容;
6. 需求冲突时主动提问;
7. 优先保证稳定性和可维护性;
8. 不得追求炫技式实现;
9. 所有关键设计必须记录到 docs/;
10. 每次提交前必须确认代码可运行。
项目完成标准:
> 用户能够通过 Cherry Studio 提出类似:
“请分析宁德时代最近30天的利好利空变化,并给出主要投资逻辑演化过程。”
系统自动检索知识库、分析新闻事件,并生成完整研究报告。
---
# 十八、Milestone 10:日报结构化入库(前后端分离数据层)
> 状态:✅ 已实施(2026-08-03,等待人工验收)
> 范围:本项目只负责「日报内容生成 + 结构化存入 MySQL」,**不实现 API 与前端**(由用户另行实现)。
## 背景与决策
| 决策点 | 结论 |
| --- | --- |
| DB | 192.168.1.10:13306pi 上 autossh 隧道 → doorcome.cn:3306 MariaDB 10.11.18),业务库 `myquant`,表前缀 `news_` |
| API / 前端 | 用户另行实现,本项目只保证数据完整、表结构文档清晰 |
| 日报生成 | 完全切换:只存 DB + 前端渲染,不再生成 HTML 静态文件 |
| 历史数据 | doorcome `/var/www/html/echart/research/{YYYYMMDD}/` 下 178 份 `*_news_daily_*.html`finance×50 + intl×128,日期 20260608~20260803),解析入库 |
## 表结构设计
### news_report(日报主表)
```sql
CREATE TABLE IF NOT EXISTS news_report (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
report_date DATE NOT NULL COMMENT '日报日期',
report_type VARCHAR(16) NOT NULL COMMENT 'finance=A股日报 / intl=国际财经日报',
file_name VARCHAR(160) NOT NULL DEFAULT '' COMMENT '源文件名(历史解析);新生成可为空',
generated_at DATETIME NOT NULL COMMENT '生成时间',
ai_summary TEXT NULL COMMENT 'AI 摘要全文',
stats JSON NULL COMMENT '数据总览统计快照(管道/情绪/重要度/事件类型/来源分布)',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_report_file (report_date, report_type, file_name),
KEY idx_report_date (report_date)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='每日日报主表';
```
### news_event(日报事件明细,新闻联播/财经新闻/公告调研/intl 事件统一入此表)
```sql
CREATE TABLE IF NOT EXISTS news_event (
id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
report_id BIGINT UNSIGNED NOT NULL COMMENT 'FK → news_report.id',
section VARCHAR(16) NOT NULL COMMENT '板块: xwlb=新闻联播 / news=财经新闻 / cninfo=公告调研 / intl=国际重要事件',
rank INT NOT NULL DEFAULT 0 COMMENT '板块内序号',
importance INT NULL COMMENT '重要度 1-5',
event_type VARCHAR(64) NULL COMMENT '事件类型',
title VARCHAR(512) NOT NULL COMMENT '标题',
summary TEXT NULL COMMENT '摘要/正文',
sentiment VARCHAR(8) NULL COMMENT 'positive/negative/neutral',
source VARCHAR(64) NULL COMMENT '来源',
url VARCHAR(512) NULL COMMENT '原文链接',
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
KEY idx_report_section (report_id, section)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='日报事件明细';
```
设计说明:
- 数据总览统计(M1→M6 管道、各源数据、情绪/重要度/事件类型/来源分布)以 JSON 快照存 `news_report.stats`,前端自行解析。
- 幂等:导入/生成按 `(report_date, report_type, file_name)` 唯一键,重复执行跳过或覆盖,不产生重复行。
- 历史同一天多次生成(intl 一日 3 次)保留多行,前端取最新。
## 阶段划分(每阶段验收后进入下一阶段)
### M10-ADB 连接层与建表
- `uv add pymysql`(纯 Python 驱动,无编译依赖)
- 新包 `report_db/``db.py`(连接、事务、建表)、`schema.py`DDL
- `.env` 新增 `NEWS_DB_HOST / NEWS_DB_PORT / NEWS_DB_USER / NEWS_DB_PASSWORD / NEWS_DB_NAME`(默认 myquant),`.env.example` 同步
- 验收:连接成功、`news_report` / `news_event` 建表成功;`tests/test_report_db.py` 通过(测试用 sqlite3 内存模拟同构 SQL,真实 MySQL 走 integration 标记)
### M10-B:历史日报解析入库
- 一次性将 doorcome 178 份 HTML 拉到 `data/reports_history/`
- 新包 `report_import/``parser.py`finance/intl 两类 HTML → 结构化 dict,容错缺板块)、`importer.py`(幂等入库)
- CLI 子命令:`a-share report-import [--date YYYYMMDD] [--type finance|intl]`(默认全量)
- 验收:178 份全部入库,`SELECT COUNT(*)` 与文件数一致;抽查 finance/intl 各 2 份字段正确;重复执行不产生重复行
### M10-C:日报生成改造(完全切换)
- `scheduler/reporter.py``generate_report()` 改为「收集结构化数据 → 写入 news_report/news_event」,移除 `_render_html` / `_upload` 调用(函数可保留但不再触发)
- `scheduler/pipeline.py` 调用签名保持兼容(仍调 `generate_report(day_str)`
- 验收:`uv run a-share report --date YYYYMMDD` 后 DB 出现当日记录且无 HTML 文件产出;AI 摘要、事件行、stats JSON 完整
### M10-D:文档与收尾
- `docs/db_schema.md`:完整表结构 + 字段说明 + 示例数据(供用户实现 API/前端)
- 更新 README、continuation.md;提交信息 `feat: 日报结构化入库`
## 待确认项(不阻塞开发,部署前需用户决策)
1. **生产连接**pi5192.168.1.160)无法直连 `192.168.1.10:13306`(隧道只绑 loopback)。可选:a) pi 的 autossh 改为绑定 0.0.0.0(需改 pi 系统配置)b) pi5 自建隧道 c) 其他
2. **intl 日报生成方**:项目代码中无 intl 生成逻辑(doorcome 上另有来源)。历史解析照做;未来 intl 新日报如需入库,由生成方按同一表结构写入
3. **个股日报**002714.SZ_0724.html 等 research 根目录文件):本期不处理,如需请另行提出
—— project_plan.md 结束 ——