- 新增 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)
14 KiB
project_plan.md
A股 Deep Research 私有投研平台项目计划
版本:v1.0
最后更新:2026-06-16
一、项目目标
构建一个面向 A 股投资研究的私有化 Deep Research 平台,实现:
- 自动抓取国内财经新闻网站;
- 支持 JavaScript 动态渲染网站;
- 自动提取中文新闻正文;
- 自动去重;
- 利用大模型抽取投资事件;
- 自动生成向量知识;
- 构建长期财经知识库;
- 支持语义检索;
- 支持 Cherry Studio、Claude Code、MCP 调用;
- 自动生成 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:新闻抓取模块
目标:
建立稳定可靠的新闻抓取能力。
任务:
- 安装 Crawl4AI;
- 验证浏览器环境;
- 实现 crawler 模块;
- 从 YAML 读取网站配置;
- 支持异步并发抓取;
- 支持导出原始 HTML;
- 支持导出 Markdown;
- 本地保存抓取结果。
交付物:
crawler/ configs/sources.yaml tests/test_crawler.py
验收标准:
- 至少支持 5 个财经网站;
- 抓取成功率 ≥ 90%;
- 抓取失败自动重试。
六、Milestone 2:正文提取模块
目标:
提取高质量中文新闻正文。
任务:
- 集成 GNE;
- 实现 extractor 模块;
- 自动去除广告;
- 自动去除相关推荐;
- 自动去除评论区;
- 提取:
- 标题
- 正文
- 发布时间
- 作者
- 来源
统一输出格式:
{ "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 5:Embedding 向量化
目标:
构建语义检索能力。
任务:
支持:
本地模型:
- BGE-M3;
远程API:
- Qwen Embedding;
- 百炼 Embedding。
输出:
List[float]
交付物:
embedding/
验收标准:
向量生成稳定可用。
十、Milestone 6:Qdrant 向量知识库
目标:
建立长期财经知识库。
任务:
- Docker 部署 Qdrant;
- 创建 Collection;
- 定义 Payload;
- 写入向量;
- 支持检索;
- 支持过滤。
交付物:
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 8:MCP 服务
目标:
支持 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 必须严格遵守:
- 每次只完成一个 Milestone;
- 完成后停止并等待人工验收;
- 每个阶段更新 README;
- 未经允许不得重构已验收模块;
- 必须保持向后兼容;
- 需求冲突时主动提问;
- 优先保证稳定性和可维护性;
- 不得追求炫技式实现;
- 所有关键设计必须记录到 docs/;
- 每次提交前必须确认代码可运行。
项目完成标准:
用户能够通过 Cherry Studio 提出类似:
“请分析宁德时代最近30天的利好利空变化,并给出主要投资逻辑演化过程。”
系统自动检索知识库、分析新闻事件,并生成完整研究报告。
十八、Milestone 10:日报结构化入库(前后端分离数据层)
状态:✅ 已实施(2026-08-03,等待人工验收) 范围:本项目只负责「日报内容生成 + 结构化存入 MySQL」,不实现 API 与前端(由用户另行实现)。
背景与决策
| 决策点 | 结论 |
|---|---|
| DB | 192.168.1.10:13306(pi 上 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(日报主表)
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 事件统一入此表)
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-A:DB 连接层与建表
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: 日报结构化入库
待确认项(不阻塞开发,部署前需用户决策)
- 生产连接:pi5(192.168.1.160)无法直连
192.168.1.10:13306(隧道只绑 loopback)。可选:a) pi 的 autossh 改为绑定 0.0.0.0(需改 pi 系统配置)b) pi5 自建隧道 c) 其他 - intl 日报生成方:项目代码中无 intl 生成逻辑(doorcome 上另有来源)。历史解析照做;未来 intl 新日报如需入库,由生成方按同一表结构写入
- 个股日报(002714.SZ_0724.html 等 research 根目录文件):本期不处理,如需请另行提出
—— project_plan.md 结束 ——