feat: 投资资讯日报查询页 + 文档更新 + 拉取服务器最新内容
- 新增 charts/news_reports.php 报告查询导航页(列表+详情一体,fetch API 渲染) - 新增 js/newsReports.js:AI 摘要/新闻联播/财经新闻/公告调研/数据总览固定模块,stats 归一化兼容多种格式 - index-2.php 研究报告卡片改为导航链接,移除 PHP 目录下拉框 - 更新 AGENTS.md/CLAUDE.md(路径、页面清单、数据模式等核实修正) - 同步服务器拉取的文档:quant 使用手册、podcast-docs - 生成 continuation.md 会话检查点
This commit is contained in:
@@ -0,0 +1,254 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>A 股 Deep Research 用户手册 v1.1</title>
|
||||
<style>
|
||||
:root { --bg: #f8f9fa; --card: #fff; --text: #212529; --muted: #6c757d;
|
||||
--accent: #2563eb; --border: #dee2e6; --code-bg: #f1f3f5; --radius: 8px; }
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif; background: var(--bg); color: var(--text); line-height: 1.75; padding-bottom: 4rem; }
|
||||
.container { max-width: 900px; margin: 0 auto; padding: 1.5rem; }
|
||||
header { background: linear-gradient(135deg, #1e293b, #334155); color: #fff; padding: 3rem 0 2rem; text-align: center; }
|
||||
header h1 { font-size: 2rem; }
|
||||
header p { color: #94a3b8; margin-top: .5rem; }
|
||||
nav { background: var(--card); border-bottom: 1px solid var(--border); position: sticky; top: 0; z-index: 10; padding: .75rem 0; }
|
||||
nav a { color: var(--accent); text-decoration: none; margin-right: 1rem; font-size: .9rem; }
|
||||
h2 { font-size: 1.5rem; margin: 2.5rem 0 1rem; padding-bottom: .5rem; border-bottom: 2px solid var(--accent); }
|
||||
h3 { font-size: 1.2rem; margin: 1.8rem 0 .8rem; color: #1e293b; }
|
||||
h4 { font-size: 1rem; margin: 1.2rem 0 .5rem; }
|
||||
p { margin: .6rem 0; }
|
||||
a { color: var(--accent); }
|
||||
code { background: var(--code-bg); padding: .15em .4em; border-radius: 4px; font-family: "SF Mono", "Fira Code", monospace; font-size: .88em; }
|
||||
pre { background: #1e293b; color: #e2e8f0; padding: 1rem 1.2rem; border-radius: var(--radius); overflow-x: auto; font-size: .85em; line-height: 1.6; margin: .8rem 0; }
|
||||
pre code { background: none; padding: 0; color: inherit; }
|
||||
table { width: 100%; border-collapse: collapse; margin: 1rem 0; font-size: .93em; }
|
||||
th, td { border: 1px solid var(--border); padding: .5rem .7rem; text-align: left; }
|
||||
th { background: #f1f5f9; font-weight: 600; }
|
||||
tr:nth-child(even) { background: #fafbfc; }
|
||||
ul, ol { padding-left: 1.5rem; margin: .6rem 0; }
|
||||
li { margin: .25rem 0; }
|
||||
.card { background: var(--card); border: 1px solid var(--border); border-radius: var(--radius); padding: 1rem 1.5rem; margin: 1rem 0; }
|
||||
.badge-ok { background: #d1fae5; color: #065f46; display: inline-block; padding: .1em .5em; border-radius: 10px; font-size: .8em; font-weight: 600; }
|
||||
.badge-warn { background: #fef3c7; color: #92400e; display: inline-block; padding: .1em .5em; border-radius: 10px; font-size: .8em; }
|
||||
.badge-err { background: #fee2e2; color: #991b1b; display: inline-block; padding: .1em .5em; border-radius: 10px; font-size: .8em; }
|
||||
footer { text-align: center; color: var(--muted); font-size: .85em; margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid var(--border); }
|
||||
@media (max-width: 640px) { .container { padding: .8rem; } header h1 { font-size: 1.5rem; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header><div class="container"><h1>A 股 Deep Research 私有投研平台</h1><p>用户手册 v1.1 · 2026-06-17</p></div></header>
|
||||
|
||||
<nav><div class="container">
|
||||
<a href="#概述">概述</a> <a href="#快速开始">快速开始</a> <a href="#cli">CLI 速查</a>
|
||||
<a href="#全链路">全链路</a> <a href="#站点管理">站点管理</a> <a href="#检索">检索</a>
|
||||
<a href="#定时任务">定时任务</a> <a href="#mcp">MCP</a> <a href="#投研">投研</a> <a href="#附录">附录</a>
|
||||
</div></nav>
|
||||
|
||||
<main class="container">
|
||||
|
||||
<h2 id="概述">1. 项目概述</h2>
|
||||
<p><strong>A 股 Deep Research</strong> 是私有化投研平台,自动完成财经新闻抓取 → 正文提取 → 事件抽取 → 向量化 → 语义检索,通过 MCP 协议接入 Cherry Studio / Claude Code,实现「自然语言提问 → 结构化研究报告」。</p>
|
||||
<p><strong>技术栈</strong>: Python 3.11 · Crawl4AI · GNE · DeepSeek/Qwen · DashScope · Qdrant · APScheduler · MCP</p>
|
||||
<p><strong>部署</strong>: 树莓派 5 (ARM64) <code>/home/pi/news/</code></p>
|
||||
|
||||
<h2 id="快速开始">2. 快速开始</h2>
|
||||
|
||||
<h3>2.1 安装</h3>
|
||||
<pre><code>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 抓取需要</code></pre>
|
||||
|
||||
<h3>2.2 验证</h3>
|
||||
<pre><code>uv run pytest -m "not integration" # 应显示 186 passed</code></pre>
|
||||
|
||||
<h2 id="cli">3. 统一 CLI 速查</h2>
|
||||
<p>所有操作通过 <code>a-share</code> 命令完成。</p>
|
||||
|
||||
<table>
|
||||
<tr><th>命令</th><th>功能</th><th>常用参数</th></tr>
|
||||
<tr><td><code>a-share crawl</code></td><td>M1 抓取新闻</td><td><code>--source cls</code></td></tr>
|
||||
<tr><td><code>a-share extract</code></td><td>M2 正文提取</td><td><code>--date 20260616</code></td></tr>
|
||||
<tr><td><code>a-share dedup</code></td><td>M3 三层去重</td><td><code>--date 20260616 --reset</code></td></tr>
|
||||
<tr><td><code>a-share events</code></td><td>M4 LLM 事件抽取</td><td><code>--provider qwen --limit 5</code></td></tr>
|
||||
<tr><td><code>a-share embed</code></td><td>M5 向量化</td><td><code>--model text-embedding-v3</code></td></tr>
|
||||
<tr><td><code>a-share ingest</code></td><td>M6 Qdrant 入库</td><td><code>--date 20260616 --recreate</code></td></tr>
|
||||
<tr><td><code>a-share pipeline</code></td><td>全链路 (M1→M6)</td><td><code>--once --report</code></td></tr>
|
||||
<tr><td><code>a-share discover</code></td><td>分析站点, 生成配置</td><td><code>--name 中文名 --add --extra URL</code></td></tr>
|
||||
<tr><td><code>a-share add-entry</code></td><td>追加入口到已有源</td><td><code>source_id url1 url2 ...</code></td></tr>
|
||||
<tr><td><code>a-share report</code></td><td>生成/上传日报</td><td><code>--date 20260616 --no-upload</code></td></tr>
|
||||
<tr><td><code>a-share search</code></td><td>终端检索知识库</td><td><code>--source --stock --sentiment --top</code></td></tr>
|
||||
<tr><td><code>a-share status</code></td><td>数据总览</td><td>无参数</td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="全链路">4. 全链路一键运行</h2>
|
||||
<pre><code>uv run a-share pipeline --once # 一次跑通 M1→M6
|
||||
uv run a-share pipeline --once --report # 末尾自动生成日报并上传</code></pre>
|
||||
|
||||
<p>耗时约 4-5 分钟 (100 篇): crawler ~3min / extractor ~24s / dedup ~2s / llm ~45s / embedding ~10s / qdrant ~4s</p>
|
||||
<p>只执行部分步骤: <code>uv run a-share pipeline --once --steps crawler,llm</code></p>
|
||||
|
||||
<p><strong>产物路径</strong>: <code>data/raw/</code> (M1) → <code>data/processed/</code> (M2) → <code>data/deduped/</code> (M3) → <code>data/events/</code> (M4) → <code>data/embeddings/</code> (M5) → <code>data/qdrant_storage/</code> (M6)</p>
|
||||
|
||||
<h2 id="站点管理">5. 新闻源管理</h2>
|
||||
|
||||
<h3>5.1 查看已有源</h3>
|
||||
<p>配置文件: <code>configs/sources.yaml</code>。内置财联社 / 东方财富 / 新浪财经 / 证券时报 / 第一财经。</p>
|
||||
|
||||
<h3>5.2 新增站点 (一条命令)</h3>
|
||||
<pre><code># 自动分析 + 写入 sources.yaml
|
||||
uv run a-share discover https://example.com/news/ --name 中文名 --add
|
||||
|
||||
# 仅预览
|
||||
uv run a-share discover https://example.com/news/</code></pre>
|
||||
<p>自动完成: JS 抓取 → 链接提取 → 导航过滤 → 模式聚类 → 正则生成 → yaml 输出。写入时自动空行分隔、序号递增、<code># ---- N. 名称 ----</code> 注释头。</p>
|
||||
|
||||
<h3>5.3 同站多频道</h3>
|
||||
<pre><code># 一次性分析多入口
|
||||
uv run a-share discover https://example.com/news/global \
|
||||
--extra https://example.com/news/china \
|
||||
--extra https://example.com/news/tech \
|
||||
--name 中文名 --add</code></pre>
|
||||
<p>生成的 yaml 自动包含 <code>extra_homepages</code> 字段,抓取时依次访问所有入口,自动去重。</p>
|
||||
|
||||
<h3>5.4 为已有源追加入口</h3>
|
||||
<pre><code>uv run a-share add-entry wallstreetcn https://xxx.com/news/新频道</code></pre>
|
||||
<p>自动去重 — 已存在的 URL 跳过。</p>
|
||||
|
||||
<h3>5.5 验证</h3>
|
||||
<pre><code>uv run a-share crawl --source wallstreetcn</code></pre>
|
||||
|
||||
<h2 id="cninfo">6. cninfo 公告抓取</h2>
|
||||
<p>cninfo(巨潮资讯网)是独立的 A 股公告抓取管道,与新闻抓取分开调度(每天 08:00)。</p>
|
||||
|
||||
<pre><code>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 # 个股日报</code></pre>
|
||||
|
||||
<p>全链路 9 步: 公告→调研→IRM→提取→PDF→去重→LLM→向量→Qdrant。</p>
|
||||
|
||||
<h4>公告关注列表</h4>
|
||||
<pre><code>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 # 只抓关注公司</code></pre>
|
||||
<p>关注公司公告在日报中置顶并 ⭐ 高亮。配置: <code>configs/watchlist.yaml</code>。</p>
|
||||
|
||||
<p><strong>配置</strong>: <code>CNINFO_ENABLED</code> <code>CNINFO_DAYS_BACK</code> <code>CNINFO_MAX_PAGES</code> <code>CNINFO_API_BASE</code> <code>CNINFO_PDF_BASE</code></p>
|
||||
|
||||
<div class="card"><strong>⚠ .env 注意</strong>: 值后面不能跟 <code>#</code> 注释。python-dotenv 会把 <code>#</code> 后内容当成值。注释必须独占一行。</div>
|
||||
|
||||
<h2 id="检索">7. 知识库检索</h2>
|
||||
|
||||
<h3>6.1 终端直接检索</h3>
|
||||
<pre><code>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</code></pre>
|
||||
|
||||
<h3>6.2 Python 检索 (带过滤)</h3>
|
||||
<pre><code>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()</code></pre>
|
||||
<p>支持 8 种过滤: source_id / stock_codes / company_names / industries / sentiment / importance_min / event_types / date_range。</p>
|
||||
|
||||
<h3>6.3 日报</h3>
|
||||
<pre><code>uv run a-share report # 生成今日日报并上传
|
||||
uv run a-share report --date 20260616 # 指定日期
|
||||
uv run a-share report --no-upload # 仅生成不上传</code></pre>
|
||||
<p>HTML 日报含: AI 摘要 (LLM 生成 400-500 字要点) + 数据总览 + 情绪分布 + 事件类型 + 高重要度事件列表。</p>
|
||||
|
||||
<h2 id="定时任务">8. 定时任务部署</h2>
|
||||
|
||||
<h3>7.1 安装 systemd 服务 (一次性)</h3>
|
||||
<pre><code>sudo cp scripts/a-share-research.service /etc/systemd/system/
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable a-share-research</code></pre>
|
||||
|
||||
<h3>7.2 日常操作</h3>
|
||||
<table>
|
||||
<tr><td>启动</td><td><code>sudo systemctl start a-share-research</code></td></tr>
|
||||
<tr><td>停止</td><td><code>sudo systemctl stop a-share-research</code></td></tr>
|
||||
<tr><td>状态</td><td><code>sudo systemctl status a-share-research</code></td></tr>
|
||||
<tr><td>实时日志</td><td><code>journalctl -u a-share-research -f</code></td></tr>
|
||||
</table>
|
||||
<p>默认执行时间: 每天 07:00 / 12:00 / 18:00 / 22:00。7:00 的日报自动覆盖过去 24 小时新闻。</p>
|
||||
|
||||
<h4>修改定时配置</h4>
|
||||
<pre><code># 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</code></pre>
|
||||
|
||||
<h2 id="mcp">8. MCP 服务与 AI Agent</h2>
|
||||
|
||||
<h3>8.1 连接 Cherry Studio</h3>
|
||||
<p>设置 → MCP 服务器 → 添加:</p>
|
||||
<pre><code>{"mcpServers":{"a-share-research":{"command":"uv","args":["run","python","-m","scripts.run_mcp_server"],"cwd":"/home/pi/news"}}}</code></pre>
|
||||
|
||||
<h3>8.2 5 个 MCP 工具</h3>
|
||||
<table>
|
||||
<tr><th>工具</th><th>功能</th><th>示例</th></tr>
|
||||
<tr><td><code>search_news</code></td><td>通用语义检索</td><td><code>search_news("宁德时代固态电池")</code></td></tr>
|
||||
<tr><td><code>search_company_news</code></td><td>按公司检索</td><td><code>search_company_news("价格", company="茅台")</code></td></tr>
|
||||
<tr><td><code>search_industry_news</code></td><td>按行业检索</td><td><code>search_industry_news("政策", industry="半导体")</code></td></tr>
|
||||
<tr><td><code>search_stock_events</code></td><td>按股票代码检索</td><td><code>search_stock_events("事件", stock_code="300750")</code></td></tr>
|
||||
<tr><td><code>search_sentiment_trend</code></td><td>情绪检索+统计</td><td><code>search_sentiment_trend("AI算力", sentiment="all")</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="投研">9. 投研分析模板</h2>
|
||||
<p>在 Cherry Studio 中粘贴 <code>docs/agent_prompt.md</code> 作为 System Prompt:</p>
|
||||
<div class="card"><strong>公司分析</strong>: 分析宁德时代 (300750) 近 30 天的利好利空变化</div>
|
||||
<div class="card"><strong>行业分析</strong>: 分析动力电池行业最近的政策动向和竞争格局</div>
|
||||
<div class="card"><strong>风险排查</strong>: 梳理中旗新材 (001212) 近期面临的主要风险</div>
|
||||
<div class="card"><strong>事件追踪</strong>: 过去一周 A 股有哪些重大监管处罚事件?</div>
|
||||
<div class="card"><strong>情绪趋势</strong>: 近一个月 AI 算力概念的情绪变化趋势如何?</div>
|
||||
|
||||
<h2 id="附录">10. 附录</h2>
|
||||
|
||||
<h3>A. Qdrant 部署模式</h3>
|
||||
<table>
|
||||
<tr><th></th><th>本地文件模式 (默认)</th><th>Docker Server 模式</th></tr>
|
||||
<tr><td>类比</td><td>SQLite</td><td>PostgreSQL</td></tr>
|
||||
<tr><td>进程</td><td>无独立进程</td><td>容器 a_share_qdrant</td></tr>
|
||||
<tr><td>ARM64</td><td><span class="badge-ok">✅</span></td><td><span class="badge-err">❌</span> jemalloc 16K 页崩溃</td></tr>
|
||||
<tr><td>适用</td><td>树莓派 / 单机</td><td>x86 生产 / 远程</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>B. 环境变量</h3>
|
||||
<table>
|
||||
<tr><td><code>LLM_PROVIDER</code></td><td><code>deepseek</code></td><td>M4 LLM</td></tr>
|
||||
<tr><td><code>DEEPSEEK_API_KEY</code></td><td>—</td><td>DeepSeek Key</td></tr>
|
||||
<tr><td><code>DASHSCOPE_API_KEY</code></td><td>—</td><td>百炼 Key (M5/M8)</td></tr>
|
||||
<tr><td><code>EMBEDDING_PROVIDER</code></td><td><code>dashscope</code></td><td>M5 嵌入</td></tr>
|
||||
<tr><td><code>SCHEDULE_TIMES</code></td><td><code>07:00,12:00,18:00,22:00</code></td><td>M7 定时</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>C. 日志文件</h3>
|
||||
<p><code>logs/crawler.log</code> · <code>logs/extractor.log</code> · <code>logs/dedup.log</code> · <code>logs/llm.log</code> · <code>logs/embedding.log</code> · <code>logs/qdrant.log</code> · <code>logs/scheduler.log</code> · <code>logs/mcp_server.log</code> (自动轮转 10MB×5)</p>
|
||||
|
||||
<h3>D. 常见问题</h3>
|
||||
<div class="card"><h4>Q: 某源抓取 0 篇?</h4><p>A: 编辑 <code>configs/sources.yaml</code>,检查 <code>article_url_pattern</code> 正则。或重新 <code>discover</code> 分析。</p></div>
|
||||
<div class="card"><h4>Q: LLM 报错?</h4><p>A: 检查 <code>.env</code> 中 <code>DEEPSEEK_API_KEY</code>。可切换 <code>--provider qwen</code> 测试。</p></div>
|
||||
<div class="card"><h4>Q: Qdrant 搜索无结果?</h4><p>A: <code>uv run a-share status</code> 检查数据量。若 Qdrant 为 0,执行 <code>uv run a-share ingest --date <date> --recreate</code>。</p></div>
|
||||
<div class="card"><h4>Q: 从零重建知识库?</h4><pre><code>rm -rf data/raw data/processed data/dedup data/deduped data/events data/embeddings data/qdrant_storage
|
||||
uv run a-share pipeline --once</code></pre></div>
|
||||
|
||||
</main>
|
||||
<footer><div class="container"><p>A 股 Deep Research 私有投研平台 · 用户手册 v1.1 · 2026-06-17</p></div></footer>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user