# A 股 Deep Research 用户手册 v1.1

## 1. 项目概述

A 股 Deep Research 是私有化投研平台,自动完成财经新闻抓取 → 正文提取 → 事件抽取 → 向量化 → 语义检索,通过 MCP 协议接入 Cherry Studio / Claude Code,实现「自然语言提问 → 结构化研究报告」。

技术栈: Python 3.11 · Crawl4AI · GNE · DeepSeek/Qwen · DashScope · Qdrant · APScheduler · MCP

部署: 树莓派 5 (ARM64) `/home/pi/news/`

## 2. 快速开始

### 2.1 安装

    cd /home/pi/news
    uv sync
    cp .env.example .env
    # 编辑 .env, 填入 DEEPSEEK_API_KEY 和 DASHSCOPE_API_KEY
    uv run python -m playwright install chromium   # 仅 M1 抓取需要

### 2.2 验证

    uv run pytest -m "not integration"   # 应显示 186 passed

## 3. 统一 CLI 速查

所有操作通过 `a-share` 命令完成。

命令 | 功能 | 常用参数
--- | --- | ---
`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 Qdrant 入库 | `--date 20260616 --recreate`
`a-share pipeline` | 全链路 (M1→M6) | `--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 --top`
`a-share status` | 数据总览 | 无参数

## 4. 全链路一键运行

    uv run a-share pipeline --once           # 一次跑通 M1→M6
    uv run a-share pipeline --once --report  # 末尾自动生成日报并上传

耗时约 4-5 分钟 (100 篇): crawler ~3min / extractor ~24s / dedup ~2s / llm ~45s / embedding ~10s / qdrant ~4s

只执行部分步骤: `uv run a-share pipeline --once --steps crawler,llm`

产物路径: `data/raw/` (M1) → `data/processed/` (M2) → `data/deduped/` (M3) → `data/events/` (M4) → `data/embeddings/` (M5) → `data/qdrant_storage/` (M6)

## 5. 新闻源管理

### 5.1 查看已有源

配置文件: `configs/sources.yaml`。内置财联社 / 东方财富 / 新浪财经 / 证券时报 / 第一财经。

### 5.2 新增站点 (一条命令)

    # 自动分析 + 写入 sources.yaml
    uv run a-share discover https://example.com/news/ --name 中文名 --add

    # 仅预览
    uv run a-share discover https://example.com/news/

自动完成: JS 抓取 → 链接提取 → 导航过滤 → 模式聚类 → 正则生成 → yaml 输出。写入时自动空行分隔、序号递增、`# ---- N. 名称 ----` 注释头。

### 5.3 同站多频道

    # 一次性分析多入口
    uv run a-share discover https://example.com/news/global \
      --extra https://example.com/news/china \
      --extra https://example.com/news/tech \
      --name 中文名 --add

生成的 yaml 自动包含 `extra_homepages` 字段,抓取时依次访问所有入口,自动去重。

### 5.4 为已有源追加入口

    uv run a-share add-entry wallstreetcn https://xxx.com/news/新频道

自动去重 — 已存在的 URL 跳过。

### 5.5 验证

    uv run a-share crawl --source wallstreetcn

## 6. cninfo 公告抓取

cninfo(巨潮资讯网)是独立的 A 股公告抓取管道,与新闻抓取分开调度(每天 08:00)。

    uv run a-share pipeline --cninfo-once           # watchlist 全链路 (公告+调研+IRM)
    uv run a-share cninfo --watchlist               # 仅公告(关注公司)
    uv run a-share cninfo --research                # 仅调研
    uv run a-share cninfo --irm                     # 仅互动问答
    uv run a-share stock-report                     # 个股日报

全链路 9 步: 公告→调研→IRM→提取→PDF→去重→LLM→向量→Qdrant。

#### 公告关注列表

    uv run a-share watchlist add 300750 宁德时代 --note "动力电池龙头"
    uv run a-share watchlist list
    uv run a-share watchlist remove 000001
    uv run a-share cninfo --watchlist                        # 只抓关注公司

关注公司公告在日报中置顶并 ⭐ 高亮。配置: `configs/watchlist.yaml`。

配置: `CNINFO_ENABLED` `CNINFO_DAYS_BACK` `CNINFO_MAX_PAGES` `CNINFO_API_BASE` `CNINFO_PDF_BASE`

⚠ .env 注意: 值后面不能跟 `#` 注释。python-dotenv 会把 `#` 后内容当成值。注释必须独占一行。

## 7. 知识库检索

### 6.1 终端直接检索

    uv run a-share search "宁德时代固态电池" --top 5
    uv run a-share search "政策" --source cls --sentiment positive
    uv run a-share search "风险" --stock 001212 --min-importance 3

### 6.2 Python 检索 (带过滤)

    from vectorstore import VectorStore, SearchFilter, make_qdrant_client
    c = make_qdrant_client()
    s = VectorStore(c)
    hits = s.query(vector=probe["vector"], top_k=10,
        filter=SearchFilter(source_id="cls", importance_min=3, sentiment="positive"))
    for h in hits: print(h.short_summary())
    s.close()

支持 8 种过滤: source_id / stock_codes / company_names / industries / sentiment / importance_min / event_types / date_range。

### 6.3 日报

    uv run a-share report                     # 生成今日日报并上传
    uv run a-share report --date 20260616     # 指定日期
    uv run a-share report --no-upload         # 仅生成不上传

HTML 日报含: AI 摘要 (LLM 生成 400-500 字要点) + 数据总览 + 情绪分布 + 事件类型 + 高重要度事件列表。

## 8. 定时任务部署

### 7.1 安装 systemd 服务 (一次性)

    sudo cp scripts/a-share-research.service /etc/systemd/system/
    sudo systemctl daemon-reload
    sudo systemctl enable a-share-research

### 7.2 日常操作

启动 | `sudo systemctl start a-share-research`
停止 | `sudo systemctl stop a-share-research`
状态 | `sudo systemctl status a-share-research`
实时日志 | `journalctl -u a-share-research -f`

默认执行时间: 每天 07:00 / 12:00 / 18:00 / 22:00。7:00 的日报自动覆盖过去 24 小时新闻。

#### 修改定时配置

    # 1. 编辑 .env 中的 SCHEDULE_TIMES
    nano /home/pi/news/.env
    # 格式: HH:MM,HH:MM,... (24 小时制, 逗号分隔)
    # 例: SCHEDULE_TIMES=08:00,14:00,20:00

    # 2. 重启服务
    sudo systemctl restart a-share-research

    # 3. 验证
    grep "已注册定时任务" /home/pi/news/logs/scheduler.log | tail -4

## 8. MCP 服务与 AI Agent

### 8.1 连接 Cherry Studio

设置 → MCP 服务器 → 添加:

    {"mcpServers":{"a-share-research":{"command":"uv","args":["run","python","-m","scripts.run_mcp_server"],"cwd":"/home/pi/news"}}}

### 8.2 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")`

## 9. 投研分析模板

在 Cherry Studio 中粘贴 `docs/agent_prompt.md` 作为 System Prompt:

公司分析: 分析宁德时代 (300750) 近 30 天的利好利空变化
行业分析: 分析动力电池行业最近的政策动向和竞争格局
风险排查: 梳理中旗新材 (001212) 近期面临的主要风险
事件追踪: 过去一周 A 股有哪些重大监管处罚事件?
情绪趋势: 近一个月 AI 算力概念的情绪变化趋势如何?

## 10. 附录

### A. Qdrant 部署模式

| 本地文件模式 (默认) | Docker Server 模式
--- | --- | ---
类比 | SQLite | PostgreSQL
进程 | 无独立进程 | 容器 a_share_qdrant
ARM64 | ✅ | ❌ jemalloc 16K 页崩溃
适用 | 树莓派 / 单机 | x86 生产 / 远程

### B. 环境变量

`LLM_PROVIDER` | `deepseek` | M4 LLM
`DEEPSEEK_API_KEY` | — | DeepSeek Key
`DASHSCOPE_API_KEY` | — | 百炼 Key (M5/M8)
`EMBEDDING_PROVIDER` | `dashscope` | M5 嵌入
`SCHEDULE_TIMES` | `07:00,12:00,18:00,22:00` | M7 定时

### C. 日志文件

`logs/crawler.log` · `logs/extractor.log` · `logs/dedup.log` · `logs/llm.log` · `logs/embedding.log` · `logs/qdrant.log` · `logs/scheduler.log` · `logs/mcp_server.log` (自动轮转 10MB×5)

### D. 常见问题

#### Q: 某源抓取 0 篇?

A: 编辑 `configs/sources.yaml`,检查 `article_url_pattern` 正则。或重新 `discover` 分析。

#### Q: LLM 报错?

A: 检查 `.env` 中 `DEEPSEEK_API_KEY`。可切换 `--provider qwen` 测试。

#### Q: Qdrant 搜索无结果?

A: `uv run a-share status` 检查数据量。若 Qdrant 为 0,执行 `uv run a-share ingest --date <date> --recreate`。

#### Q: 从零重建知识库?

    rm -rf data/raw data/processed data/dedup data/deduped data/events data/embeddings data/qdrant_storage
    uv run a-share pipeline --once