# 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 5：Embedding 向量化

目标：

构建语义检索能力。

任务：

支持：

本地模型：

* BGE-M3；

远程API：

* Qwen Embedding；
* 百炼 Embedding。

输出：

List[float]

交付物：

embedding/

验收标准：

向量生成稳定可用。

---

# 十、Milestone 6：Qdrant 向量知识库

目标：

建立长期财经知识库。

任务：

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 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 必须严格遵守：

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: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（日报主表）

```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-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: 日报结构化入库`

## 待确认项（不阻塞开发，部署前需用户决策）

1. **生产连接**：pi5（192.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 结束 ——

