Initial commit
This commit is contained in:
@@ -0,0 +1,712 @@
|
||||
# A 股 Deep Research 私有投研平台 — 用户手册
|
||||
|
||||
版本:v1.0 | 最后更新:2026-06-17
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [项目概述](#1-项目概述)
|
||||
2. [环境准备](#2-环境准备)
|
||||
3. [全链路一键运行](#3-全链路一键运行)
|
||||
4. [分模块使用](#4-分模块使用)
|
||||
- [M1 新闻抓取](#m1-新闻抓取)
|
||||
- [M2 正文提取](#m2-正文提取)
|
||||
- [M3 三层去重](#m3-三层去重)
|
||||
- [M4 投资事件抽取](#m4-投资事件抽取)
|
||||
- [M5 向量化](#m5-向量化)
|
||||
- [M6 Qdrant 入库与检索](#m6-qdrant-入库与检索)
|
||||
5. [定时任务部署](#5-定时任务部署)
|
||||
6. [MCP 服务与 AI Agent](#6-mcp-服务与-ai-agent)
|
||||
7. [投研分析模板](#7-投研分析模板)
|
||||
8. [附录](#8-附录)
|
||||
|
||||
---
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
**A 股 Deep Research** 是一个私有化投研平台,自动完成财经新闻抓取 → 正文提取 → 事件抽取 → 向量化 → 语义检索的完整链路,最终通过 MCP 协议接入 Cherry Studio / Claude Code 等 AI 客户端,实现"用自然语言提问,获得结构化研究报告"。
|
||||
|
||||
**核心数据流**:
|
||||
|
||||
```
|
||||
财经网站 → 抓取(HTML+Markdown) → 正文提取 → 去重
|
||||
→ LLM 抽取(股票/公司/行业/情绪/事件类型)
|
||||
→ Embedding 向量化(1024维)
|
||||
→ Qdrant 知识库(语义检索,2ms 级)
|
||||
→ MCP 服务 → AI Agent 深度研究
|
||||
```
|
||||
|
||||
**技术栈**:Python 3.11 / Crawl4AI / GNE / DeepSeek / DashScope / Qdrant / APScheduler / MCP
|
||||
|
||||
**部署位置**:树莓派 5(ARM64),`/home/pi/news/`
|
||||
|
||||
---
|
||||
|
||||
## 2. 环境准备
|
||||
|
||||
### 2.1 前置条件
|
||||
|
||||
- Python 3.11
|
||||
- uv(包管理器):`brew install uv`(macOS) 或 `curl -LsSf https://astral.sh/uv/install.sh | sh`(Linux)
|
||||
- Playwright 浏览器(仅 M1 抓取需要):`uv run python -m playwright install chromium`
|
||||
|
||||
### 2.2 获取代码
|
||||
|
||||
```bash
|
||||
git clone <repo> /home/pi/news
|
||||
cd /home/pi/news
|
||||
```
|
||||
|
||||
### 2.3 安装依赖
|
||||
|
||||
```bash
|
||||
uv sync
|
||||
```
|
||||
|
||||
### 2.4 配置环境变量
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# 编辑 .env,填写:
|
||||
# DEEPSEEK_API_KEY=sk-xxx (M4 LLM 调用)
|
||||
# DASHSCOPE_API_KEY=sk-xxx (M5/M8 嵌入调用)
|
||||
```
|
||||
|
||||
### 2.5 验证安装
|
||||
|
||||
```bash
|
||||
uv run pytest -m "not integration" # 应显示 186 passed
|
||||
```
|
||||
|
||||
### 2.6 统一 CLI `a-share`
|
||||
|
||||
所有操作通过 `a-share` 命令完成,替代之前的 8 个脚本入口:
|
||||
|
||||
```bash
|
||||
# 模块操作
|
||||
uv run a-share crawl # M1 抓取全部源
|
||||
uv run a-share crawl --source cls # 单源
|
||||
uv run a-share extract --date 20260616 # M2 提取
|
||||
uv run a-share dedup --date 20260616 # M3 去重
|
||||
uv run a-share events --date 20260616 # M4 LLM 抽取
|
||||
uv run a-share events --provider qwen # 切换 LLM
|
||||
uv run a-share embed --date 20260616 # M5 向量化
|
||||
uv run a-share ingest --date 20260616 # M6 入库
|
||||
|
||||
# 全链路
|
||||
uv run a-share pipeline --once # 立即执行一次全链路
|
||||
|
||||
# 检索(直接查 Qdrant,无需写代码或配 Cherry Studio)
|
||||
uv run a-share search "宁德时代固态电池"
|
||||
uv run a-share search "政策" --source cls --sentiment positive
|
||||
uv run a-share search "风险" --stock 001212 --min-importance 3
|
||||
|
||||
# 状态总览
|
||||
uv run a-share status
|
||||
```
|
||||
|
||||
子命令速查:
|
||||
|
||||
| 命令 | 功能 | 常用参数 |
|
||||
| --- | --- | --- |
|
||||
| `a-share crawl` | M1 抓取 | `--source cls` |
|
||||
| `a-share extract` | M2 提取 | `--date 20260616` |
|
||||
| `a-share dedup` | M3 去重 | `--date 20260616 --reset` |
|
||||
| `a-share events` | M4 LLM 抽取 | `--provider qwen --limit 5` |
|
||||
| `a-share embed` | M5 向量化 | `--model text-embedding-v3` |
|
||||
| `a-share ingest` | M6 入库 | `--date 20260616 --recreate` |
|
||||
| `a-share pipeline` | 全链路 | `--once --report` |
|
||||
| `a-share discover` | 站点分析 | `--name 中文名 --add --extra URL` |
|
||||
| `a-share add-entry` | 追加入口 | `source_id url1 url2 ...` |
|
||||
| `a-share report` | 生成日报 | `--date 20260616 --no-upload` |
|
||||
| `a-share search` | 检索知识库 | `--source --stock --sentiment` |
|
||||
| `a-share status` | 数据总览 | 无参数 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 全链路一键运行
|
||||
|
||||
**一条命令跑通 M1→M6**:
|
||||
|
||||
```bash
|
||||
uv run a-share pipeline --once
|
||||
```
|
||||
|
||||
(等效于旧版 `uv run python -m scripts.run_scheduler --once`,`a-share` 命令更短更好记)
|
||||
|
||||
```bash
|
||||
uv run python -m scripts.run_scheduler --once
|
||||
```
|
||||
|
||||
全链路耗时约 4-5 分钟(100 篇文章):
|
||||
|
||||
| 步骤 | 耗时 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| crawler | ~3 分钟 | 含浏览器渲染,最耗时 |
|
||||
| extractor | ~24 秒 | GNE 正文提取 |
|
||||
| dedup | ~2 秒 | 三层去重 |
|
||||
| llm | ~45 秒 | DeepSeek 事件抽取 |
|
||||
| embedding | ~10 秒 | DashScope 向量化 |
|
||||
| qdrant | ~4 秒 | 写入知识库 |
|
||||
|
||||
产物路径:
|
||||
- `data/raw/` — 原始 HTML + Markdown(M1)
|
||||
- `data/processed/` — 提取后的 Article(M2)
|
||||
- `data/deduped/` — 去重后唯一文章(M3)
|
||||
- `data/events/` — 结构化投资事件(M4)
|
||||
- `data/embeddings/` — 1024 维向量(M5)
|
||||
- `data/qdrant_storage/` — Qdrant 知识库(M6)
|
||||
|
||||
只执行部分步骤:
|
||||
|
||||
```bash
|
||||
uv run python -m scripts.run_scheduler --once --steps crawler,llm,qdrant
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 分模块使用
|
||||
|
||||
### M1 新闻抓取
|
||||
|
||||
从 5 个 A 股财经源抓取文章。
|
||||
|
||||
```bash
|
||||
# 抓取全部启用源
|
||||
uv run python -m scripts.run_crawler
|
||||
|
||||
# 抓取单个源
|
||||
uv run python -m scripts.run_crawler --source cls
|
||||
|
||||
# 试跑不写文件
|
||||
uv run python -m scripts.run_crawler --no-save
|
||||
```
|
||||
|
||||
配置文件:`configs/sources.yaml`
|
||||
|
||||
当前支持的源:
|
||||
|
||||
| ID | 名称 | JS 渲染 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| cls | 财联社 | 是 | 深度频道 |
|
||||
| eastmoney | 东方财富 | 是 | 首页 |
|
||||
| sina | 新浪财经 | 否 | 静态页面,速度快 |
|
||||
| stcn | 证券时报 | 是 | 要闻列表 |
|
||||
| yicai | 第一财经 | 是 | 新闻频道 |
|
||||
|
||||
**新增新闻源**:一条命令完成分析+配置:
|
||||
|
||||
```bash
|
||||
# 自动分析 + 自动写入 sources.yaml(推荐)
|
||||
uv run a-share discover https://wallstreetcn.com/news/global --name 华尔街见闻 --add
|
||||
|
||||
# 仅预览,不写入
|
||||
uv run a-share discover https://example.com/news/
|
||||
```
|
||||
|
||||
`discover` 自动完成 7 步:
|
||||
|
||||
1. Crawl4AI 抓取首页(自动判断 JS 渲染)
|
||||
2. 提取所有站内 `<a href>` 链接
|
||||
3. 过滤导航/功能页(about/download/member 等)
|
||||
4. 按 URL 路径模式聚类
|
||||
5. 数字 ID 模式优先排序(文章特征)
|
||||
6. 自动生成正则
|
||||
7. 输出 yaml 配置 + `--add` 自动追加到 `sources.yaml`
|
||||
|
||||
`--add` 写入时自动:空行分隔、序号递增、`# ---- N. 名称 ----` 注释头。
|
||||
|
||||
**验证新源**:
|
||||
|
||||
```bash
|
||||
uv run a-share crawl --source wallstreetcn
|
||||
```
|
||||
|
||||
**同一网站多个入口**:使用 `--extra` 添加额外频道,共用同一个正则:
|
||||
|
||||
```bash
|
||||
uv run a-share discover https://wallstreetcn.com/news/global \
|
||||
--extra https://wallstreetcn.com/news/china \
|
||||
--extra https://wallstreetcn.com/news/tech \
|
||||
--name 华尔街见闻 --add
|
||||
```
|
||||
|
||||
生成的 yaml 自动包含 `extra_homepages` 字段。抓取时依次访问所有入口,自动去重。
|
||||
|
||||
**为已有源追加额外入口**(无需重新 discover):
|
||||
|
||||
```bash
|
||||
uv run a-share add-entry wallstreetcn https://xxx.com/news/新频道
|
||||
```
|
||||
|
||||
自动去重:已存在的 URL 跳过。
|
||||
|
||||
### M2 正文提取
|
||||
|
||||
从 M1 抓取的 HTML 中提取标准化 Article(title/content/时间/作者)。
|
||||
|
||||
```bash
|
||||
# 处理今日所有源
|
||||
uv run python -m scripts.run_extractor
|
||||
|
||||
# 指定日期
|
||||
uv run python -m scripts.run_extractor --date 20260616
|
||||
|
||||
# 单源
|
||||
uv run python -m scripts.run_extractor --source sina --date 20260616
|
||||
```
|
||||
|
||||
输入:`data/raw/{source}/{YYYYMMDD}/*.html`
|
||||
输出:`data/processed/{source}/{YYYYMMDD}/{url_hash}.json`
|
||||
|
||||
输出格式(Article):
|
||||
|
||||
```json
|
||||
{
|
||||
"source_id": "sina",
|
||||
"url": "https://finance.sina.com.cn/...",
|
||||
"url_hash": "abc123...",
|
||||
"title": "宁德时代发布新一代麒麟电池",
|
||||
"content": "财联社6月15日电...",
|
||||
"publish_time": "2026-06-15T14:30:00",
|
||||
"author": "记者 张三",
|
||||
"word_count": 1234
|
||||
}
|
||||
```
|
||||
|
||||
### M3 三层去重
|
||||
|
||||
对 M2 输出做 URL Hash → 内容 Hash → SimHash 三层去重,指纹持久化到 SQLite。
|
||||
|
||||
```bash
|
||||
# 处理今日
|
||||
uv run python -m scripts.run_dedup
|
||||
|
||||
# 指定日期
|
||||
uv run python -m scripts.run_dedup --date 20260616
|
||||
|
||||
# 重建指纹库
|
||||
uv run python -m scripts.run_dedup --reset
|
||||
|
||||
# 调 SimHash 阈值(默认 3)
|
||||
uv run python -m scripts.run_dedup --simhash-threshold 5
|
||||
```
|
||||
|
||||
输入:`data/processed/{source}/{YYYYMMDD}/*.json`
|
||||
输出:
|
||||
- `data/deduped/{YYYYMMDD}/uniques/{url_hash}.json` — 唯一文章
|
||||
- `data/deduped/{YYYYMMDD}/duplicates.jsonl` — 重复记录
|
||||
- `data/dedup/fingerprints.sqlite3` — 指纹库(跨日累积)
|
||||
|
||||
### M4 投资事件抽取
|
||||
|
||||
调用 DeepSeek/Qwen 从去重文章中抽取结构化投资事件。
|
||||
|
||||
```bash
|
||||
# DeepSeek(默认)
|
||||
uv run python -m scripts.run_event_extraction --date 20260616
|
||||
|
||||
# Qwen(百炼)
|
||||
uv run python -m scripts.run_event_extraction --provider qwen --model qwen-plus
|
||||
|
||||
# 联调小批量
|
||||
uv run python -m scripts.run_event_extraction --limit 5
|
||||
|
||||
# 调整并发(默认 3)
|
||||
uv run python -m scripts.run_event_extraction --concurrency 5
|
||||
```
|
||||
|
||||
输入:`data/deduped/{YYYYMMDD}/uniques/*.json`
|
||||
输出:`data/events/{YYYYMMDD}/{url_hash}.json`
|
||||
|
||||
输出格式(ExtractedEvent):
|
||||
|
||||
```json
|
||||
{
|
||||
"source_id": "cls",
|
||||
"url": "https://...",
|
||||
"title": "宁德时代签订100GWh供货协议",
|
||||
"event": {
|
||||
"stock_codes": ["300750.SZ"],
|
||||
"company_names": ["宁德时代"],
|
||||
"industries": ["动力电池"],
|
||||
"sentiment": "positive",
|
||||
"importance": 5,
|
||||
"event_type": "重大合同",
|
||||
"summary": "宁德时代签5年100GWh协议,金额超1500亿"
|
||||
},
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-chat"
|
||||
}
|
||||
```
|
||||
|
||||
23 种事件类型:`业绩预告/业绩快报/财报披露/合作签约/投资并购/重大合同/产品发布/技术突破/监管处罚/诉讼仲裁/股东减持/股东增持/回购/分红/高管变动/资产重组/停牌复牌/ST警示/退市风险/宏观政策/行业政策/国际局势/其他`
|
||||
|
||||
### M5 向量化
|
||||
|
||||
将 M4 事件文本用 DashScope `text-embedding-v3`(1024 维)或本地 BGE-M3 向量化。
|
||||
|
||||
```bash
|
||||
# DashScope(默认)
|
||||
uv run python -m scripts.run_embedding --date 20260616
|
||||
|
||||
# 强制覆盖模型
|
||||
uv run python -m scripts.run_embedding --provider dashscope --model text-embedding-v3
|
||||
|
||||
# 本地 BGE-M3(需先 uv sync --extra local-embedding)
|
||||
uv run python -m scripts.run_embedding --provider local-bge
|
||||
```
|
||||
|
||||
输入:`data/events/{YYYYMMDD}/*.json`
|
||||
输出:`data/embeddings/{YYYYMMDD}/{url_hash}.json`(含 1024 维向量)
|
||||
|
||||
### cninfo 公告抓取
|
||||
|
||||
cninfo(巨潮资讯网)是独立的 A 股公告抓取管道,与新闻抓取分开调度(每天 08:00)。
|
||||
|
||||
**全链路(一条命令, watchlist 模式)**:
|
||||
|
||||
```bash
|
||||
uv run a-share pipeline --cninfo-once
|
||||
```
|
||||
|
||||
包含 9 步: 公告抓取(关注公司) → 调研筛选 → 互动问答 → 正文提取 → PDF 富化 → 去重 → LLM 抽取 → 向量化 → Qdrant 入库。
|
||||
|
||||
**单独操作**:
|
||||
|
||||
```bash
|
||||
uv run a-share cninfo --watchlist # 仅公告(关注公司)
|
||||
uv run a-share cninfo --research # 仅调研(关注公司)
|
||||
uv run a-share cninfo --irm # 仅互动问答(关注公司)
|
||||
uv run a-share cninfo --enrich-pdf # PDF→Markdown
|
||||
|
||||
**分步操作**:
|
||||
|
||||
```bash
|
||||
# 抓取公告
|
||||
uv run a-share cninfo --days 1
|
||||
uv run a-share cninfo --start 2026-06-17 --end 2026-06-19 --max-pages 50
|
||||
|
||||
# PDF 正文 (MarkItDown → Markdown)
|
||||
uv run a-share cninfo --enrich-pdf --pdf-limit 50
|
||||
```
|
||||
|
||||
### 个股日报(关注列表)
|
||||
|
||||
为 watchlist 中每家公司生成综合日报:
|
||||
|
||||
```bash
|
||||
uv run a-share stock-report
|
||||
```
|
||||
|
||||
报告内容: AI 要点分析 / 近 7 日公告 / 相关新闻 / 互动问答。
|
||||
上传路径: `echart/research/{YYYYMMDD}/{代码}_{名称}_个股日报_{日期}.html`
|
||||
|
||||
### 公告关注列表
|
||||
|
||||
只关注特定公司公告,日报中高亮显示:
|
||||
|
||||
```bash
|
||||
# 管理关注列表
|
||||
uv run a-share watchlist add 300750 宁德时代 --note "动力电池龙头"
|
||||
uv run a-share watchlist add 000001 平安银行
|
||||
uv run a-share watchlist list # 查看关注列表
|
||||
uv run a-share watchlist remove 000001 # 移除
|
||||
|
||||
# 只抓关注公司公告
|
||||
uv run a-share cninfo --watchlist
|
||||
|
||||
# 日报效果: 关注公司事件置顶 + ⭐ 标记
|
||||
```
|
||||
|
||||
关注列表存储在 `configs/watchlist.yaml`。
|
||||
|
||||
**`.env` 配置**:
|
||||
|
||||
| 变量 | 默认 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `CNINFO_ENABLED` | `true` | 是否启用 |
|
||||
| `CNINFO_DAYS_BACK` | `1` | 每次抓最近 N 天 |
|
||||
| `CNINFO_MAX_PAGES` | `20` | 最大页数(×30=600 条/次) |
|
||||
| `CNINFO_API_BASE` | `http://www.cninfo.com.cn/new` | API 地址 |
|
||||
| `CNINFO_PDF_BASE` | `http://static.cninfo.com.cn` | PDF 地址 |
|
||||
|
||||
**`.env` 注意**: 值后面不能跟 `#` 注释。`python-dotenv` 会错误地把 `#` 后内容当成值。注释必须独占一行。
|
||||
|
||||
### M6 Qdrant 入库与检索
|
||||
|
||||
将 M5 向量 + M4 事件标签写入 Qdrant 本地知识库。
|
||||
|
||||
**入库**:
|
||||
|
||||
```bash
|
||||
# 默认本地文件模式(无需 Docker)
|
||||
uv run python -m scripts.run_qdrant_ingest --date 20260616
|
||||
|
||||
# 重建 collection
|
||||
uv run python -m scripts.run_qdrant_ingest --recreate
|
||||
```
|
||||
|
||||
**Python 检索**:
|
||||
|
||||
```python
|
||||
from vectorstore import VectorStore, SearchFilter, make_qdrant_client
|
||||
|
||||
c = make_qdrant_client()
|
||||
store = VectorStore(c)
|
||||
|
||||
# 基础语义检索
|
||||
hits = store.query(query_vector=probe["vector"], top_k=10)
|
||||
for h in hits:
|
||||
print(h.short_summary())
|
||||
|
||||
# 结构化过滤
|
||||
hits = store.query(
|
||||
query_vector=probe["vector"],
|
||||
top_k=10,
|
||||
filter=SearchFilter(
|
||||
source_id="cls", # 按源
|
||||
importance_min=3, # 影响程度 >= 3
|
||||
sentiment="positive", # 利好
|
||||
stock_codes=["300750"], # 按股票代码
|
||||
industries=["动力电池"], # 按行业
|
||||
publish_date_from="2026-06-01", # 时间范围
|
||||
),
|
||||
)
|
||||
|
||||
store.close()
|
||||
```
|
||||
|
||||
Qdrant 部署说明见[附录 A](#a-qdrant-部署模式)。
|
||||
|
||||
---
|
||||
|
||||
## 5. 定时任务部署
|
||||
|
||||
将 M1→M6 全链路注册为系统服务,每天 7:00 / 12:00 / 18:00 / 22:00 自动执行。
|
||||
|
||||
### 安装(一次性)
|
||||
|
||||
```bash
|
||||
sudo cp scripts/a-share-research.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable a-share-research
|
||||
```
|
||||
|
||||
### 日常操作
|
||||
|
||||
```bash
|
||||
sudo systemctl start a-share-research # 启动
|
||||
sudo systemctl stop a-share-research # 停止
|
||||
sudo systemctl restart a-share-research # 重启
|
||||
sudo systemctl status a-share-research # 查看状态(含 PID)
|
||||
|
||||
# 查看日志
|
||||
journalctl -u a-share-research -f # 实时系统日志
|
||||
tail -f logs/scheduler.log # 文件日志
|
||||
```
|
||||
|
||||
修改执行时间和配置:
|
||||
|
||||
```bash
|
||||
# 编辑 .env 中的 SCHEDULE_TIMES
|
||||
nano /home/pi/news/.env
|
||||
# 格式: HH:MM,HH:MM,... (24 小时制,逗号分隔)
|
||||
# 例: SCHEDULE_TIMES=08:00,14:00,20:00
|
||||
|
||||
# 重启服务使新配置生效
|
||||
sudo systemctl restart a-share-research
|
||||
|
||||
# 验证新配置
|
||||
grep "已注册定时任务" /home/pi/news/logs/scheduler.log | tail -4
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. MCP 服务与 AI Agent
|
||||
|
||||
### 6.1 连接 Cherry Studio
|
||||
|
||||
1. 打开 Cherry Studio → 设置 → MCP 服务器 → 添加
|
||||
2. 填入:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"a-share-research": {
|
||||
"command": "uv",
|
||||
"args": ["run", "python", "-m", "scripts.run_mcp_server"],
|
||||
"cwd": "/home/pi/news"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. 点击启用。Cherry Studio 会自动启动 MCP 服务进程(stdio 模式)。
|
||||
|
||||
### 6.2 连接 Claude Code
|
||||
|
||||
编辑项目根目录 `.mcp.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"a-share-research": {
|
||||
"command": "uv",
|
||||
"args": ["run", "python", "-m", "scripts.run_mcp_server"],
|
||||
"cwd": "/home/pi/news"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 5 个 MCP 工具
|
||||
|
||||
| 工具 | 使用示例 |
|
||||
| --- | --- |
|
||||
| `search_news` | `search_news("宁德时代固态电池进展")` |
|
||||
| `search_company_news` | `search_company_news("价格调整", company="贵州茅台")` |
|
||||
| `search_industry_news` | `search_industry_news("最新政策", industry="半导体")` |
|
||||
| `search_stock_events` | `search_stock_events("重大事件", stock_code="300750")` |
|
||||
| `search_sentiment_trend` | `search_sentiment_trend("AI算力", sentiment="all")` |
|
||||
|
||||
### 6.4 调试(HTTP SSE 模式)
|
||||
|
||||
```bash
|
||||
uv run python -m scripts.run_mcp_server --sse 8765
|
||||
# 浏览器访问 http://<host>:8765/sse
|
||||
```
|
||||
|
||||
### 6.5 工作原理
|
||||
|
||||
```
|
||||
用户输入自然语言查询
|
||||
→ DashScope 嵌入(1024 维)
|
||||
→ Qdrant 余弦相似度检索(2.3ms)
|
||||
→ 按过滤条件筛选(公司/行业/代码/情绪)
|
||||
→ Markdown 格式化返回
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 投研分析模板
|
||||
|
||||
在 Cherry Studio 中粘贴 `docs/agent_prompt.md` 的内容作为 System Prompt,然后可以使用以下提问模式:
|
||||
|
||||
### 公司深度分析
|
||||
|
||||
> 分析宁德时代(300750)近 30 天的利好利空变化,并给出主要投资逻辑演化过程。
|
||||
|
||||
### 行业分析
|
||||
|
||||
> 分析动力电池行业最近的政策动向和竞争格局变化。
|
||||
|
||||
### 风险排查
|
||||
|
||||
> 帮我梳理中旗新材(001212)近期面临的主要风险点。
|
||||
|
||||
### 事件追踪
|
||||
|
||||
> 过去一周 A 股市场有哪些重大监管处罚事件?
|
||||
|
||||
### 情绪趋势
|
||||
|
||||
> 近一个月 AI 算力概念的情绪变化趋势如何?
|
||||
|
||||
---
|
||||
|
||||
## 8. 附录
|
||||
|
||||
### A. Qdrant 部署模式
|
||||
|
||||
本项目支持两种 Qdrant 运行模式:
|
||||
|
||||
| | 本地文件模式(默认) | Docker Server 模式 |
|
||||
| --- | --- | --- |
|
||||
| 类比 | SQLite | PostgreSQL |
|
||||
| 进程 | 无独立进程 | 容器 `a_share_qdrant` |
|
||||
| 端口 | 不监听 | 6333/6334 |
|
||||
| 并发 | 单进程 | 多客户端 |
|
||||
| 数据位置 | `data/qdrant_storage/` | Docker volume |
|
||||
| 适用场景 | 树莓派/单机 | x86 生产/Cherry Studio 远程 |
|
||||
| ARM64 兼容 | ✅ | ❌(jemalloc 16K 页崩溃) |
|
||||
|
||||
### B. 环境变量完整列表
|
||||
|
||||
| 变量 | 默认值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `LLM_PROVIDER` | `deepseek` | M4 LLM 提供商 |
|
||||
| `DEEPSEEK_API_KEY` | - | DeepSeek API Key |
|
||||
| `DASHSCOPE_API_KEY` | - | 百炼 API Key(M5/M8) |
|
||||
| `EMBEDDING_PROVIDER` | `dashscope` | M5 嵌入提供商 |
|
||||
| `SCHEDULE_TIMES` | `07:00,12:00,18:00,22:00` | M7 定时时间 |
|
||||
| `QDRANT_COLLECTION` | `a_share_news` | M6 Collection 名 |
|
||||
| `LOG_LEVEL` | `INFO` | 日志级别 |
|
||||
|
||||
### C. 日志文件
|
||||
|
||||
| 文件 | 对应模块 |
|
||||
| --- | --- |
|
||||
| `logs/crawler.log` | M1 抓取 |
|
||||
| `logs/extractor.log` | M2 提取 |
|
||||
| `logs/dedup.log` | M3 去重 |
|
||||
| `logs/llm.log` | M4 LLM |
|
||||
| `logs/embedding.log` | M5 向量化 |
|
||||
| `logs/qdrant.log` | M6 入库 |
|
||||
| `logs/scheduler.log` | M7 调度 |
|
||||
| `logs/mcp_server.log` | M8 MCP |
|
||||
|
||||
日志自动轮转(10MB/文件,保留 5 份)。
|
||||
|
||||
### D. 项目目录结构
|
||||
|
||||
```
|
||||
news/
|
||||
├── crawler/ M1 新闻抓取
|
||||
├── extractor/ M2 正文提取
|
||||
├── dedup/ M3 三层去重
|
||||
├── llm/ M4 事件抽取
|
||||
├── embedding/ M5 向量化
|
||||
├── vectorstore/ M6 Qdrant 客户端
|
||||
├── scheduler/ M7 定时任务
|
||||
├── mcp_server/ M8 MCP 服务
|
||||
├── configs/ 配置文件(sources.yaml)
|
||||
├── prompts/ LLM Prompt 模板
|
||||
├── docs/ 文档与 Agent Prompt
|
||||
├── scripts/ 运行脚本(每个模块一个入口)
|
||||
├── tests/ pytest 测试
|
||||
├── data/ 数据产物(各层按日期组织)
|
||||
├── logs/ 运行日志
|
||||
├── pyproject.toml 依赖定义
|
||||
└── .env.example 环境变量模板
|
||||
```
|
||||
|
||||
### E. 常见问题
|
||||
|
||||
**Q:M1 某源抓取 0 篇文章?**
|
||||
|
||||
编辑 `configs/sources.yaml`,检查该源的 `article_url_pattern` 正则是否匹配真实链接格式。可先用 `uv run python -m scripts.run_crawler --source <id>` 单源调试。
|
||||
|
||||
**Q:M2 提取的正文不是新闻内容(而是"郑重声明"等模板文本)?**
|
||||
|
||||
这是已知的 M2.2 模板兜底问题,提取器已内置关键词黑名单自动过滤。若遇到新模板,可在 `extractor/parser.py` 的 `_BOILERPLATE_PATTERNS` 追加。
|
||||
|
||||
**Q:M4 调用 LLM 报错?**
|
||||
|
||||
检查 `.env` 中 `DEEPSEEK_API_KEY` 是否填写。可用 `--provider qwen` 切换到百炼测试。
|
||||
|
||||
**Q:Qdrant 搜索不到结果?**
|
||||
|
||||
检查是否已入库:`uv run python -c "from vectorstore import VectorStore, make_qdrant_client; c=make_qdrant_client(); s=VectorStore(c); print(s.count()); s.close()"`。若 count=0,运行 `uv run python -m scripts.run_qdrant_ingest --date <date>` 入库。
|
||||
|
||||
**Q:如何从零重建整个知识库?**
|
||||
|
||||
```bash
|
||||
rm -rf data/raw data/processed data/dedup data/deduped data/events data/embeddings data/qdrant_storage
|
||||
uv run python -m scripts.run_scheduler --once
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
—— 用户手册结束 ——
|
||||
Reference in New Issue
Block a user