Files
intl_news/docs/intlnews_usage.md
T
2026-07-18 16:13:52 +08:00

673 lines
18 KiB
Markdown
Raw 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.
# 国际财经 Deep Research 平台 — 使用手册
> 版本:v1.0
> 最后更新:2026-06-21
> 项目路径:国内 `/home/pi/intlnews` / 海外 `/opt/intlgrab`
---
## 目录
1. [项目概述](#1-项目概述)
2. [部署拓扑](#2-部署拓扑)
3. [环境配置](#3-环境配置)
4. [CLI 命令参考](#4-cli-命令参考)
5. [M1 — 新闻抓取](#5-m1--新闻抓取)
6. [M2 — 正文提取](#6-m2--正文提取)
7. [M3 — 三层去重](#7-m3--三层去重)
8. [M4 — 翻译 + 事件抽取](#8-m4--翻译--事件抽取)
9. [M5 — 向量生成](#9-m5--向量生成)
10. [M6 — Qdrant 入库与检索](#10-m6--qdrant-入库与检索)
11. [M7 — 全链路管道 + 日报](#11-m7--全链路管道--日报)
12. [M8 — MCP 服务](#12-m8--mcp-服务)
13. [数据目录结构](#13-数据目录结构)
14. [定时任务](#14-定时任务)
15. [常见问题](#15-常见问题)
---
## 1. 项目概述
本项目构建面向**国际英文财经新闻**的私有化 Deep Research 平台。
核心能力:
- 英文财经新闻抓取(Crawl4AI,12 个源)
- 正文提取(trafilatura
- 全文英译中(DeepSeek LLM
- 投资事件抽取(美股代码识别 + 情绪判断 + 重要度评分)
- 双语向量知识库(Qdrant,1024 维)
- 语义检索(中文自然语言)
- MCP 服务(Claude Code / Cherry Studio Agent 深度研究)
- 每日 AI 摘要日报(HTML
**本项目不是**:交易系统 / 股票预测系统 / 投资顾问系统。
---
## 2. 部署拓扑
```
┌──────────────────────────────────────────────────┐
│ Overseas Server (海外) │
│ M1 Crawl4AI 抓取 → data/raw/ │
│ 每天 4 次打包 → rsync 推送 │
│ SSH: <海外服务器> │
│ 路径: /opt/intlgrab │
└────────────────────┬─────────────────────────────┘
│ rsync
┌──────────────────────────────────────────────────┐
│ Domestic Server (国内) │
│ M2 正文提取 → M3 去重 → M4 翻译+事件 │
│ → M5 向量生成 → M6 Qdrant 入库 │
│ → M7 调度 + 日报 → M8 MCP 服务 │
│ SSH: <国内服务器> │
│ 路径: /home/pi/intlnews │
└──────────────────────────────────────────────────┘
```
---
## 3. 环境配置
### 3.1 依赖安装
```bash
cd /home/pi/intlnews
uv sync
```
### 3.2 配置文件
| 文件 | 用途 | 示例 |
|------|------|------|
| `.env` | API Key / URL(不入 Git | `DEEPSEEK_API_KEY=sk-xxx` |
| `configs/system.yaml` | 功能参数(模型、阈值、超时) | `llm.provider: deepseek` |
| `configs/sources.yaml` | 新闻源定义 | 12 个英文财经源 |
### 3.3 必需环境变量(`.env`
```bash
# DeepSeekM4 翻译+事件抽取)
DEEPSEEK_API_KEY=sk-your-key
DEEPSEEK_BASE_URL=https://api.deepseek.com
# Qwen(备选 LLM
QWEN_API_KEY=sk-your-key
QWEN_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
# DashScopeM5 向量生成)
DASHSCOPE_API_KEY=sk-your-key
# Qdrant(留空使用本地文件模式)
QDRANT_URL=http://localhost:6333
QDRANT_API_KEY=
```
### 3.4 关键配置项(`configs/system.yaml`
```yaml
crawler:
max_memory_mb: 1800 # 串行抓取内存上限
dedup:
hamming_distance_threshold: 3 # SimHash 汉明距离阈值
simhash_window_days: 30 # 时间窗口
llm:
provider: "deepseek"
deepseek_model: "deepseek-v4-flash"
concurrency: 3 # LLM 并发数
embedding:
provider: "dashscope"
dashscope_model: "text-embedding-v3"
dimension: 1024
qdrant:
collection: "en_finance_news"
schedule:
day_cutoff_hour: 6 # 新闻日切分点(06:00
```
---
## 4. CLI 命令参考
所有命令通过 `uv run en-news` 执行:
| 命令 | Milestone | 功能 |
|------|-----------|------|
| `crawl` | M1 | 抓取英文财经新闻 |
| `extract` | M2 | 正文提取 |
| `dedup` | M3 | 三层去重 |
| `translate` | M4 | 翻译 + 事件抽取 |
| `embed` | M5 | 向量生成 |
| `index` | M6 | Qdrant 入库 |
| `search <query>` | M6 | 语义检索 |
| `pipeline` | M7 | 一键全链路 M2→M6 |
| `report` | M7 | 日报生成 |
| `mcp-server` | M8 | 启动 MCP 服务 |
常用选项:
```bash
# 指定源
uv run en-news crawl --source forexlive
uv run en-news extract --source forexlive
# 指定 top_k
uv run en-news search "美联储利率决议" --top-k 5
# 重建 Qdrant collection
uv run en-news index --recreate
# 全链路跳过日报
uv run en-news pipeline --skip-report
```
---
## 5. M1 — 新闻抓取
### 5.1 手动抓取
```bash
# 抓取所有启用的源
uv run en-news crawl
# 只抓取指定源
uv run en-news crawl -s forexlive
```
### 5.2 新闻源列表
| 源 ID | 名称 | 类型 |
|-------|------|------|
| reuters | Reuters | 综合财经 |
| cnbc | CNBC | 市场新闻 |
| marketwatch | MarketWatch | 市场数据 |
| ft | Financial Times | 财经深度 |
| yahoo_finance | Yahoo Finance | 综合 |
| investing | Investing.com | 全球市场 |
| seekingalpha | Seeking Alpha | 投资分析 |
| barrons | Barrons | 市场评论 |
| wsj | WSJ | 综合财经 |
| economist | The Economist | 经济分析 |
| forexlive | ForexLive | 外汇新闻 |
| zerohedge | ZeroHedge | 另类财经 |
### 5.3 反爬策略
部分新闻源设有反爬保护(如 DataDome)。系统支持三种策略,按优先级自动选择:
| 优先级 | 策略 | 配置字段 | 说明 | 适用源 |
|--------|------|---------|------|--------|
| 1 | **RSS 抓取** | `rss_url` | 通过 RSS/Atom Feed 获取文章列表,完全绕过反爬 | MarketWatch ✅ |
| 2 | **Stealth 模式** | `anti_bot_mode: "stealth"` | 隐藏 webdriver 特征(`--disable-blink-features=AutomationControlled`) | Reuters(海外内存不足待验证) |
| 3 | **Headful 模式** | `anti_bot_mode: "headful"` | 非 headless 浏览器,最像真人 | 重度反爬源回退 |
配置示例(`configs/sources.yaml`):
```yaml
- id: "marketwatch"
rss_url: "https://feeds.marketwatch.com/marketwatch/topstories" # RSS 优先
anti_bot_mode: "headful" # RSS 失败时回退
- id: "reuters"
anti_bot_mode: "stealth" # 无 RSS,直接 stealth
```
**已验证**
| 源 | 方式 | 结果 |
|----|------|------|
| MarketWatch | RSS | ✅ 10/10 |
| WSJ | RSS | ✅ 20/20 |
| ForexLive | 标准 headless | ✅ 17/17 |
| ZeroHedge | 标准 + URL 过滤 | ✅ 15/15 |
| Barron's | RSS (Dow Jones) | ✅ 10/10 |
| Reuters | stealth | ⚠️ DataDome |
| SeekingAlpha | stealth | ⚠️ PerimeterX |
### 5.4 海外定时抓取
```cron
# crontab<海外服务器>)— 每天 4 次
# 时序: 抓取(60min) → 打包(5min) → 10min后国内拉取
0 6 * * * cd /opt/intlgrab && bash scripts/overseas_crawl.sh
5 7 * * * cd /opt/intlgrab && bash scripts/overseas_pack.sh
0 12 * * * cd /opt/intlgrab && bash scripts/overseas_crawl.sh
5 13 * * * cd /opt/intlgrab && bash scripts/overseas_pack.sh
0 18 * * * cd /opt/intlgrab && bash scripts/overseas_crawl.sh
5 19 * * * cd /opt/intlgrab && bash scripts/overseas_pack.sh
0 22 * * * cd /opt/intlgrab && bash scripts/overseas_crawl.sh
5 23 * * * cd /opt/intlgrab && bash scripts/overseas_pack.sh
```
### 5.4 增量抓取机制
抓取采用**两层增量**确保不重复下载和存储:
| 层级 | 位置 | 机制 |
|------|------|------|
| 抓取层 | `_extract_article_urls` | 读取当日 `index.jsonl` 中已抓取的 url_hash,跳过已存在的 URL,不重复下载 |
| 存储层 | `write_index_jsonl` | 追加写入前再次检查 url_hash,已存在则跳过 |
同一天内多次执行 `crawl`,只有新文章才会被下载和存储。
### 5.5 产物
```
data/raw/{source_id}/{YYYYMMDD}/
├── {url_hash}.html # 原始 HTML
├── {url_hash}.md # Crawl4AI Markdown
└── index.jsonl # 文章索引
```
---
## 6. M2 — 正文提取
### 6.1 执行
```bash
# 提取所有源
uv run en-news extract
# 提取指定源
uv run en-news extract -s forexlive
```
### 6.2 技术方案
- 优先使用 Crawl4AI 输出的 Markdown
- 回退 `trafilatura` 英文正文提取
- 最小正文字数阈值:50 词
### 6.3 产物
```
data/processed/{source_id}/{YYYYMMDD}/
├── {url_hash}.json # ProcessedArticle
└── index.jsonl # 处理索引
```
---
## 7. M3 — 三层去重
### 7.1 执行
```bash
uv run en-news dedup
```
### 7.2 去重逻辑
| 层级 | 方法 | 说明 |
|------|------|------|
| L1 | URL Hash | 完全相同 URL 直接命中 |
| L2 | 内容 Hash | 标准化后 SHA1[:16] 匹配(去标点/空白) |
| L3 | SimHash | 字符 3-gram,汉明距离 ≤ 3,30 天窗口 |
### 7.3 产物
```
data/deduped/{YYYYMMDD}/
├── uniques/{url_hash}.json # 唯一文章
└── index.json # 去重索引
data/dedup/fingerprints.sqlite3 # 指纹库
```
---
## 8. M4 — 翻译 + 事件抽取
### 8.1 执行
```bash
uv run en-news translate
```
### 8.2 技术方案
- **Provider**: DeepSeek v4-flash(默认)/ Qwen 备选
- **单次调用**:翻译 + 事件抽取合并,节省 token
- **并发**3 线程(`system.yaml``llm.concurrency`
- **重试**:3 次指数退避(1s → 2s → 4s)
### 8.3 输出格式
```json
{
"title": "Fed Holds Rates Steady as Markets Rally",
"title_zh": "美联储维持利率不变,市场上涨",
"content_en": "The Federal Reserve held...",
"content_zh": "美联储周三维持利率不变...",
"events": [
{
"event_type": "央行决议",
"stock_codes": [],
"sentiment": "neutral",
"importance": 5,
"summary_zh": "美联储维持利率不变,市场反弹"
}
]
}
```
### 8.4 14 种事件类型
`财报披露` `并购收购` `产品发布` `监管政策` `宏观经济`
`央行决议` `行业动态` `技术突破` `高管变动` `诉讼法律`
`市场异动` `地缘政治` `大宗商品` `外汇波动` `其他`
### 8.5 产物
```
data/events/{YYYYMMDD}/
├── {url_hash}.json # EnTranslatedArticle
└── index.json # 事件索引
```
---
## 9. M5 — 向量生成
### 9.1 执行
```bash
uv run en-news embed
```
### 9.2 技术方案
- **Provider**: DashScope `text-embedding-v3`
- **维度**: 1024
- **嵌入文本**: `标题: {title_zh}` + `事件: [{sentiment}] {event_type} 重要度{n} {summary_zh}` + `正文: {content_zh[:3000]}`
- **截断**: 4000 字符上限
### 9.3 产物
```
data/embeddings/{YYYYMMDD}/
├── {url_hash}.json # EmbeddingResult1024 维)
└── index.json # 向量索引
```
---
## 10. M6 — Qdrant 入库与检索
### 10.1 入库
```bash
# 增量入库
uv run en-news index
# 重建 collection(清空旧数据)
uv run en-news index --recreate
```
### 10.2 语义搜索
```bash
# 基本搜索
uv run en-news search "美联储利率决议"
# 指定返回条数
uv run en-news search "伊朗霍尔木兹海峡" --top-k 5
```
### 10.3 技术方案
- **模式**: 本地文件(`data/qdrant_storage/`),无需 Docker
- **Collection**: `en_finance_news`
- **距离**: Cosine
- **Payload**: title / title_zh / url / source_id / events / content_zh_preview
### 10.4 产物
```
data/qdrant_storage/ # Qdrant 本地文件存储
```
---
## 11. M7 — 全链路管道 + 日报
### 11.1 手动全链路运行(完整流程)
当需要手工执行完整的数据处理流程时,按顺序执行以下命令:
```bash
# 步骤 1(海外): 抓取英文财经新闻
ssh <海外服务器> "cd /opt/intlgrab && uv run en-news crawl"
# 步骤 2(海外): 打包 raw 数据
ssh <海外服务器> "cd /opt/intlgrab && bash scripts/overseas_pack.sh"
# 步骤 3(国内): 拉取海外数据
cd /home/pi/intlnews && bash scripts/domestic_sync.sh
# 步骤 4: 一键全链路 M2→M6 + 日报
cd /home/pi/intlnews && uv run en-news pipeline
```
也可以分步执行(适合调试):
```bash
# 分步模式
uv run en-news extract # M2: 正文提取
uv run en-news dedup # M3: 三层去重
uv run en-news translate # M4: 翻译 + 事件抽取
uv run en-news embed # M5: 向量生成
uv run en-news index # M6: Qdrant 入库
uv run en-news report # 日报生成
```
### 11.2 一键管道(自动)
```bash
# 全链路 M2→M6 + 日报
uv run en-news pipeline
# 跳过日报生成
uv run en-news pipeline --skip-report
# 只生成日报
uv run en-news report
```
### 11.2 管道步骤
```
M2 extract → M3 dedup → M4 translate → M5 embed → M6 index → 日报
```
每步失败记录日志但不阻断后续步骤(降级继续)。
### 11.3 HTML 日报
日报包含五个板块:
1. 🤖 **AI 摘要** — LLM 根据当日 important≥4 事件生成要点总结
2. 🔥 **重要事件** — 高重要度事件表格(标题/情绪/重要度/摘要/链接)
3. 📊 **数据总览** — M1→M6 管道统计数据
4. 📈 **情绪分布** — 利好/利空/中性比例条 + 重要度分布
5. 📋 **事件类型 TOP 10**
日报输出:`data/reports/intl_news_daily_{YYYYMMDD}.html`(约 9KB),同时自动上传到
`https://echart.doorcome.cn/research/{YYYYMMDD}/intl_news_daily_{YYYYMMDD}.html`
### 11.4 国内定时调度
```cron
# crontab<国内服务器>)— 每天 3 次
# 全流程:SSH 触发海外打包 → 下载 → 管道串行 M2→M6 → 日报
0 7 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh
0 12 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh
0 18 * * * cd /home/pi/intlnews && bash scripts/domestic_full.sh
```
`domestic_full.sh` 统一完成:远程打包 → 同步 → 管道 → 日报。
---
## 12. M8 — MCP 服务
### 12.1 启动
```bash
uv run en-news mcp-server
```
### 12.2 可用 Tool
| Tool | 功能 | 示例 |
|------|------|------|
| `search_news` | 语义检索新闻 | `search_news("美联储利率决议")` |
| `search_by_stock` | 美股代码检索 | `search_by_stock("AAPL")` |
| `search_by_sentiment` | 按情绪检索 | `search_by_sentiment("加息", sentiment="negative")` |
| `get_today_events` | 当日重要事件 | `get_today_events(importance_min=4)` |
| `get_stats` | 系统统计 | `get_stats()` |
### 12.3 Claude Code 配置
在 Claude Code 的 MCP 配置中添加:
```json
{
"mcpServers": {
"intl-news": {
"command": "uv",
"args": ["run", "en-news", "mcp-server"],
"cwd": "/home/pi/intlnews"
}
}
}
```
---
## 13. 数据目录结构
```
data/
├── raw/ # M1: 原始抓取
│ └── {source_id}/{YYYYMMDD}/
│ ├── {url_hash}.html
│ ├── {url_hash}.md
│ └── index.jsonl
├── processed/ # M2: 正文提取
│ └── {source_id}/{YYYYMMDD}/
│ └── {url_hash}.json
├── dedup/ # M3: 指纹库
│ ├── fingerprints.sqlite3
│ └── {YYYYMMDD}/
│ ├── uniques/{url_hash}.json
│ └── index.json
├── events/ # M4: 翻译+事件
│ └── {YYYYMMDD}/
│ └── {url_hash}.json
├── embeddings/ # M5: 向量
│ └── {YYYYMMDD}/
│ └── {url_hash}.json
├── qdrant_storage/ # M6: Qdrant 本地存储
└── reports/ # M7: 日报
└── intl_news_daily_{YYYYMMDD}.html
```
---
## 14. 定时任务
### 14.1 时间线
```
海外 国内
───────────────────────────── ─────────────────────────
06:00 crawl (≈60min) 07:00 全流程(打包→下载→管道→日报)
12:00 crawl (≈60min) 12:00 全流程
18:00 crawl (≈60min) 18:00 全流程
22:00 crawl (≈60min) (夜间 crawl 结果次日 07:00 处理)
```
国内 `domestic_full.sh` 流程:`SSH触发海外打包 → 下载 → M2→M3→M4→M5→M6 → 日报`(串行)。
### 14.2 新闻日定义
- 切分点:`day_cutoff_hour: 6`(凌晨 06:00
- 当天 06:00 至次日 05:59 属于同一个新闻日
- 例如:2026-06-19 04:00 → 新闻日 "20260618"
---
## 15. 常见问题
### Q: 如何新增新闻源?
编辑 `configs/sources.yaml`,添加源配置:
```yaml
- id: "new_source"
name: "New Source Name"
enabled: true
homepage: "https://example.com/finance/"
article_url_pattern: "/news/[^/]+/"
js_render: false
max_articles_per_run: 30
```
### Q: 翻译质量不好怎么办?
1. 调整 `configs/system.yaml``llm.temperature`(降低更保守)
2. 编辑 `prompts/translation_and_extraction.md` 优化 Prompt
3. 切换 Provider`llm.provider: "qwen"`
### Q: Qdrant 检索太慢?
- 本地文件模式已足够快(17 条 < 0.01s
- 数据量 > 10 万条时建议切换到 Docker 模式
- 设置 `QDRANT_URL=http://your-server:6333`
### Q: 如何查看日志?
```bash
tail -f logs/sync.log # 同步日志(国内)
tail -f logs/pipeline.log # 管道日志(国内)
tail -f logs/crawl.log # 抓取日志(海外)
tail -f logs/pack.log # 打包日志(海外)
```
日志自动清理:每周日凌晨 3 点删除 14 天前的 `.log` 文件(`scripts/cleanup_logs.sh`)。
### Q: 数据如何备份?
```bash
# 备份整个 data 目录
tar czf intlnews_backup_$(date +%Y%m%d).tar.gz data/
```
---
## 附录:技术栈
| 组件 | 技术 |
|------|------|
| 语言 | Python 3.11 |
| 包管理 | uv + pyproject.toml |
| 抓取 | Crawl4AI + Playwright |
| 正文提取 | trafilatura |
| 去重 | SimHash + SQLite |
| LLM | DeepSeek v4-flashOpenAI SDK |
| Embedding | DashScope text-embedding-v3 |
| 向量库 | Qdrant(本地文件模式) |
| MCP | FastMCP |
| CLI | Typer |
| 配置 | YAML + .env |
| 数据模型 | Pydantic v2 |