xgb_wiki 设计方案
版本 2.1 · 2026-09-01 · 状态:已实施(M1–M7 全部完成 + 数轮增量:时间窗/每日题材/NL 查询/MCP/CI 部署/增量同步) - v2.1 变更:数据同步由"删库全量重建"改为增量水位同步,新增 sync.py 五阶段编排(环境检查/备份/临时库/数据校验/失败回退)与 sync_log 日志,顺手修复 get_broker_id lastrowid 历史孤儿(详见 数据同步指南 与 §7 增量7) - v2.0 变更:数据范围由"近 30 天"扩至全量(2023-11 → 2026-08 共 7767 篇);推荐观点提取落地为规则引擎(LLM 版为可选升级,§2.5);Ontology-Playground 改为本地镜像 + 汉化内嵌(§5.2);补充实际产出的数据画像(§1.2) - v1.1 变更:segmentType 等类型字段改为开放字典机制(§2.6);新增推荐观点模型(§2.5,提及关系带观点属性 + 推荐时间线展示)
目标:将选股宝 MySQL 数据整理为本体(Ontology)形式展示——题材的产业链位置、关联个股(出现次数/衰减热度/最近提及)、评级事件、引用的原始研报与图片。 本体格式遵循 Ontology-Playground 规则,schema 可在其 GitHub Pages 在线浏览。
配套文档:整体架构 · 数据模型 · 名词解释 · 运行手册 · GitHub Pages 发布
1. 数据事实基础(2026-08-30 实测)
1.1 数据源(MySQL xuangubao,内网只读)
| 表 | 用途 | 关键事实 |
|---|---|---|
live_tuoshui_news |
主源,单篇研报 | 4342 行;plates 字段解析出题材,格式零失败 |
tuoshui_msgs |
每日汇总(6 栏目) | 3425 行;正文完整可读(is_premium 仅 APP 端标记,库里存全文) |
plate_rank_infos |
板块字典 | 606 板块 + 三值分类(0概念/1行业/2风格) |
plate_stocks |
板块成分股 | 仅 69 热门板块 6505 行(历史被裁剪),带入选理由 desc |
结构详情见凭据项目 2_xuangubao/docs/脱水研报数据库Wiki文档.md(v2.0,已实测核对)——本仓库外交叉引用,仅本地可用。
1.2 全量数据画像(2026-08-30 构建,数据截至 2026-08-28)
入库规模(data/xgb_wiki.db):
| 对象 | 数量 | 说明 |
|---|---|---|
| Report 研报 | 7797 | live 4359 + digest 3438,时间跨度 2023-11-01 → 2026-09-01 |
| Theme 题材 | 605 | 板块字典 + 正文解析合并(另含待审核负 id 题材) |
| Stock 个股 | 2975 | |
| Broker 券商 | 116 | |
| Chain 产业链 | 19 | chain_map 人工确认 |
| Segment 环节 | 173 | |
| RatingEvent 评级事件 | 25 | 首次覆盖 12 / 维持 10 / 上调 3(首次覆盖全库稀缺,优先展示;由正文重建自愈,见 数据同步) |
| ImageAsset 图片 | 12746 | 已解析 390 / 其余选择性解析 |
| 推荐观点 | 979 条带 reason 的个股提及 | 规则引擎提取 |
链映射(data/chain_map.json):300 个题材完成映射,全部 manual: true(人工确认);题材量 Top 链:消费 43 / 化工材料 36 / AI算力 19 / 人工智能软件 17 / 新能源 16 / 医药生物 16 / 汽车 16。
1.3 关键约束
- 数据库无产业链结构:全库无 parent/上下游字段,需 LLM 生成 + 人工审校构建
- LAS 解析限流 1 QPM(las-document-parse skill,normal 0.02 元/页)→ 必须选择性解析,禁止全量
- MySQL 仅内网可达;凭据复用凭据项目
.env(本机为2_xuangubao),绝不入库 - digest 的
plates字段不可用(仅 live 有),digest 题材从正文解析
2. 本体 Schema(8 实体 / 11 关系)
定义文件:src/ontology.py(build_schema(),被 /ontology 页与 RDF 导出共用)。完整字段级数据字典见 data-model.md。
2.1 实体
| 实体 | 标识属性 | 属性 | 说明 |
|---|---|---|---|
| Chain 产业链 | chainId* | name, description | 如"AI算力""新能源",LLM 归纳生成 + 人工确认 |
| Segment 环节 | segmentId* | name, segmentType, stageTag, orderNo, isBottleneck | 见 2.2 详解 |
| Theme 题材 | plateId* | name, classification(概念/行业/风格), occurrenceCount, firstSeenAt, lastSeenAt, decayScore | 来自 plates 解析 + 大涨题材行 |
| Stock 个股 | code* | name | |
| Broker 券商 | brokerId* | name | live 标题前缀 + 研报来源块提取;语义=被引用的研报来源,非发布者 |
| Report 研报 | reportId* | title, column(栏目), displayTime, summary, isPremium | 指选股宝研报条目(live/digest 两源) |
| RatingEvent 评级事件 | eventId* | eventType(开放字典: 首次覆盖/上调/下调/目标价/增持/维持), eventDate, analystName, analystLicense | 从研报来源块提取 |
| ImageAsset 图片 | imageId(URL哈希) | url, contextText, parseStatus(unparsed/pending/parsed/failed), parsedType(产业链图/数据图表/其他), parsedContent | 正文 <img> 全量登记,按需解析 |
* Playground 规则:每实体必须且仅一个 isIdentifier: true 属性。
命名约定:实体/关系的显示名已中文化(如 name="产业链"、"提及题材"),技术 id 保留英文(chain、report_mentions_theme)——SQLite 表名、RDF 类名、正则/代码引用均走英文 id,中文只做展示层。
2.2 Segment 环节模型(核心设计)
环节 ≠ 上中下游。 正文实测出现四种链形态,stage 降级为派生标签,环节本质用"角色类型 + 自由命名 + 顺序"表达:
segmentType(角色类型,内置默认六类,开放扩展——见 2.6 开放字典):
material 材料资源 (铟、硅料、ABF膜、"磷化铟成了AI新瓶颈")
process 工艺制造 (封装环节"承上启下"、拉晶、电芯)
component 核心部件 (光模块、MLCC、SOFC连接体、液冷)
infrastructure 配套设施 (AIDC、电力设备、检测)
service 服务 (油服、代工、运维)
application 下游应用 (新能源车、机器人、AI应用)
stageTag(派生粗分组,仅供泳道视图,映射关系在字典中定义、随类型扩展):
material→上游 | process/component→中游 | application→下游 | infrastructure/service→配套
orderNo:链内顺序,供需/工序型链有意义(硅料1→硅片2→电池3→组件4),组件型链仅展示排序
isBottleneck:卡脖子标记,正文出现"瓶颈/卡脖子/咽喉/供给紧缺/自主可控"用语时置真
name:自由命名,用研报原文词汇(铟/衬底/封装/载板/油服/AIDC)
展示自适应由字典驱动,不写死类型分支:环节普遍有 orderNo → 横向流程带(箭头);以分组型类型(component/material 等)为主 → 按字典分组卡片;链内出现字典未登记的类型 → 自动落入"其他"分组不报错,待人工审核登记。
2.3 关系(11 条)
| # | 关系 | 方向/基数 | 属性 |
|---|---|---|---|
| 1 | segment_part_of_chain | Segment → Chain, 多对一 | |
| 2 | theme_located_at_segment | Theme ↔ Segment, 多对多 | evidence(来源研报) |
| 3 | theme_associates_stock | Theme ↔ Stock, 多对多 | occurrenceCount, firstSeenAt, lastSeenAt, decayScore, evidence(plates共现/大涨题材行) |
| 4 | report_mentions_theme | Report ↔ Theme, 多对多 | 推荐观点属性:reason, reasonType, evidenceQuote, isCore, viewDate |
| 5 | report_mentions_stock | Report ↔ Stock, 多对多 | 同上:每次提及即一条"时间点+对象+原因"的推荐记录 |
| 6 | report_cites_broker | Report ↔ Broker, 多对多 | analystName, analystLicense, sourceTitle(原始研报标题), citedDate |
| 7 | rating_event_targets_stock | RatingEvent → Stock, 多对一 | |
| 8 | rating_event_issued_by_broker | RatingEvent → Broker, 多对一 | |
| 9 | rating_event_cited_in_report | RatingEvent → Report, 多对一 | |
| 10 | report_cites_image | Report → ImageAsset, 一对多 | |
| 11 | image_depicts_theme | ImageAsset ↔ Theme, 多对多 | (图片解析结果反哺题材证据) |
语义全景(Broker 修正后):
选股宝 Report ──引用(含分析师/原始报告/日期)──▶ Broker 券商
│ 提及题材/个股 提及图片 ▲
▼ │ 发出(多对一)
Theme/Stock ◀──位于环节──── Segment──属于── Chain
▲ ▲
│ 针对(多对一) │ 定位(多对多)
RatingEvent 评级事件 ──引用自───┘(回溯到Report原文)
要点:券商与 Report 是引用关系(一篇脱水研报引多家券商);券商与 RatingEvent 是发出关系(多对一);分析师不设独立实体,作为关系属性保留。
2.4 衰减热度模型
decayScore = Σᵢ exp(-ln2 × 距今天数(tᵢ) / H) × wᵢ H=半衰期60天,w=权重(核心1.0/共现0.3),均在 src/config.py 可配
每次提及按时间指数衰减后求和。明细时间戳已在关联表中(每篇 Report 都有 displayTime),精确计算零成本。
展示三列:出现次数(原始)/ 衰减热度(颜色梯度红→灰)/ 最近提及("X天前")。
2.4b 时间窗与活跃天数模型(2026-08-30 增量)
衰减热度回答"总体还热吗",但跟进近期热点需要显式的时间窗口径(src/trends.py,纯 SQLite 可重算,scripts/refresh_trends.py 可脱离内网回填):
| 指标 | 定义 | 用途 |
|---|---|---|
cnt_5d/10d/20d/30d |
截至最新研报日的滚动窗口内被提及的研报篇数(自然日口径) | 题材页徽标、任意窗口排行(配合 theme_daily 现算) |
theme_daily 表 |
(day, theme_id, cnt, core_cnt) 每日题材提及 | 时间轴视图与任意窗口查询的基础表 |
| 活跃天数 | 所选时间窗口内出现过的数据日数(数据日 = 有研报发布的日子,周末无数据不断连) | 每日题材页主指标;仅选定周期(1/3/5/10/20日,1日=当日维度)后统计展示,未选定默认隐藏 |
| 产业链活跃天数 | 链上任一题材当日被提及即计该链当日活跃 | 发现"连续多日出现的产业链" |
| 活跃个股 | 窗口内被推荐的个股 → 关联题材(theme_stock 关联 ∩ 窗口内活跃题材,历史题材窗口内未出现不展示) | 题材↔个股关联图(题材节点唯一,连线=关联) |
决策:早期"连涨天数"(从最后一次提及往前数连续数据日,全局口径)已废弃为后端指标(theme.streak_days 列保留但不再展示)——用户实际需要的是"窗口内出现了几天",且必须挂在明确选定的周期下才有意义。
2.5 推荐观点模型(提及即推荐记录)
脱水研报的核心价值是"某时间点推荐某标的的原因"——如每日强股的标准结构:1、鼎捷数智:物理AI (1)大涨题材:人工智能大模型 …(2)研报深度复盘(东吴证券…)。设计上不新增第 9 个实体,而是把 report_mentions_stock / report_mentions_theme 两条提及关系升级为携带观点属性的关系实例(Playground 原生支持关系属性):
每次提及 = 一条推荐记录:
viewDate 时间点(取研报 displayTime)
reason 推荐原因摘要(≤50字)
reasonType 催化类型(开放字典:业绩/订单/政策/技术进展/供需价格/产能/事件催化/资金动向)
evidenceQuote 原文关键句(规则定位,零成本,供人工核对)
isCore 是否该文核心推荐标的(每日强股"N、"编号行 = True;plates 共现 = False)
区分强度:isCore=True(结构性推荐,来自大涨题材行/研报来源块)参与推荐时间线与热度加权(权重 1.0);isCore=False(仅共现提及)只计次数(权重 0.3)。
提取实现——两档:
| 档位 | 实现 | 状态 |
|---|---|---|
| 规则引擎(当前) | src/viewpoint.py:每日强股结构段取信号句(含"涨停/催化/受益/利好…"信号词的句子)为 reason,按 8 类催化关键词字典分类 reasonType;live 研报标题即编辑观点 |
✅ 已上线,979 条个股推荐记录 |
| LLM 提取(可选升级) | 复用凭据项目的 MiniMax/Ark 模式,配 LLM_API_KEY 后对 evidenceQuote 生成 ≤50 字摘要 |
预留,未配置 key |
展示:个股页/题材页的推荐时间线——按时间倒序,每条 = 日期 + 催化类型标签 + 原因摘要 + 来源研报链接(含图片缩略图);顶部聚合催化类型分布("近半年推荐理由:技术进展 40% / 订单 25%…")。
2.6 开放字典机制(可扩展性)
segmentType 六类只是数据归纳的起点,不是封闭分类。三个类型字段全部走注册表驱动:
| 字典文件 | 管理对象 | 内置默认 |
|---|---|---|
data/segment_types.json |
segmentType(环节角色)+ 各自的 stageTag 映射 + 展示方式(flow/group) | 六类 |
data/reason_types.json |
reasonType(催化类型) | 八类 |
data/event_types.json |
eventType(评级事件类型) | 首次覆盖/上调/下调/目标价/增持/维持 |
扩展流程:链映射/观点提取遇到字典外类型 → 以"待审核"标记写入数据(不丢数据、不报错)→ 汇总到字典文件的 _pending 区 → 人工审核后转正(补 label/分组/映射)→ 下次 ETL 自动生效。SQLite 中类型字段存字符串,加类型零迁移;本体页与 RDF 导出的 enum 值从字典实时生成。
3. 数据提取规则(ETL)
规则实现:src/extractors.py(正则提取器)+ src/etl.py(逐行处理与聚合;同步编排见 src/sync.py)。已知坑见 运行手册 §6。
| 目标 | 来源 | 方法 |
|---|---|---|
| 题材出现 | live.plates, digest 大涨题材行 |
"ID,名称;…" 解析;N、个股:X(1)大涨题材:Y(2) 行解析(更强证据) |
| 个股×题材 | 研报 plates × stocks 共现 + 大涨题材直接配对 | 共现为弱证据(isCore=0),大涨题材行为强证据(isCore=1),evidence 字段区分 |
| 推荐观点 | 每日强股"N、"编号段 / live 标题 | 规则引擎(信号句 + 催化关键词字典),见 §2.5 |
| 券商引用 | live 标题 + digest 研报来源块 | 标题正则 ^([一-龥]{2,10}证券)[::];来源块正则 ([一-龥]{2,10}证券),([一-龥·]{2,6}),(S\d{10,}),(.+?),?(\d{4}年\d{1,2}月\d{1,2}日) |
| 评级事件 | 研报来源块 sourceTitle | 匹配 首次覆盖/上调/下调/目标价/增持/维持 分类 eventType |
| 图片登记 | 两表 content HTML | <img[^>]+src="…"> 提取 + 上下文文本(前后各100字)存 contextText |
| 产业链映射 | LLM/agent + 证据句 | 见第 4 节 |
图片解析策略(LAS,1 QPM 约束下)
- 全量登记零成本:所有
<img>入 ImageAsset(unparsed 状态) - 选择性解析,仅三类触发:①评级事件相关研报的图;②contextText 含"产业链/格局/架构"的图;③用户点击时按需解析
- URL 级结果缓存(按 imageId 落 SQLite);批量队列按 65 秒/张节流(1 QPM 余量)
- 解析结果写 parsedType/parsedContent,并提取涉及的题材回填
image_depicts_theme
前端图片展示
研报详情页图片内联缩略图,点击弹大图;已解析的图旁标注解析摘要(涉及题材/数据点);未解析的图点击触发按需解析任务(POST /image/<id>/parse,异步,页面轮询状态)。
4. 产业链映射(chain_map.json)
- 生成方式:LLM/agent(Ark API,
src/llm_chain.py)+ 证据驱动——把题材的研报关键句("最上游的铟""封装环节承上启下"这类原文)喂给模型,归纳:所属链、环节名(用原文词汇)、segmentType、orderNo、isBottleneck、证据句出处 - 范围:出现次数 ≥5 的题材首批覆盖(当前 300 个已映射且全部人工确认),其余入"未分类"待补
- 文件格式
data/chain_map.json:
{
"磷化铟": {
"chain": "AI算力", "segment": "上游材料", "segmentType": "material",
"order": 1, "isBottleneck": true, "manual": false,
"evidence": [{"reportId": 4342, "quote": "最上游的铟,95%以上是锌矿冶炼的副产品…"}]
}
}
- 人工审校:
manual: true的条目重跑 LLM 不覆盖;审校通过后入库(当前 300 条均为 manual:true) - 幂等:可反复增量补全,不影响已确认条目
5. 展示方案
5.1 xgb_wiki Web(Flask + Bootstrap + SQLite,实例数据)
实现:app.py + templates/(11 个页面),端口 5010。公网镜像为 Cloudflare Pages 静态站(scripts/build_static_site.py 生成,GitHub Actions 自动构建部署,见 publishing.md)。
| 页面 | 内容 |
|---|---|
/ |
产业链×环节×题材总览矩阵(19链,题材按衰减热度排序,显示次数/热度/最近提及;未映射题材单独分组) |
/timeline |
每日题材:页面级时间周期(1/3/5/10/20日,未选隐藏活跃统计)+ 推荐概述(当日/窗口主线/核心摘录)+ 日期热力条(越红=当日提及越多)+ 单日明细表(活跃天数列)+ 题材↔个股关联图(Cytoscape,题材节点唯一不重复,连线=关联;可切列表视图)+ 活跃题材/活跃产业链侧栏 + 前端自然语言查询 |
/chain/<id> |
链详情:图形视图(Cytoscape:链→环节→题材→核心个股四层网络,环节按 segmentType 六色、题材尺寸/颜色映射衰减热度、个股🟢可点击可开关、一键导出 PNG)+ 卡片视图(流程带/分组卡片,卡脖子红标)切换 + 链内 AI 问答框 |
/theme/<plate_id> |
核心页:产业链位置(同链相邻环节题材)、时间窗徽标(5/10/20/30日 + 近5日活跃天数)、关联个股表(次数/热度/最近提及,热度色阶)、推荐时间线、引用研报列表(含图片缩略图) |
/stock/<code> |
个股页:所属题材、推荐时间线(催化类型分布聚合)、涉及的评级事件 |
/ratings |
评级事件列表,可按 eventType 筛选(首次覆盖优先展示),每条回链原文 |
/brokers /broker/<id> |
券商列表/券商页:被哪些脱水研报引用 + 发出的评级事件 |
/report/<live\|digest>/<id> |
研报原文渲染(题材/个股/券商/评级事件标注 + 配图,图片可 AI 解析) |
/ontology |
本体 schema 展示页,内嵌 Ontology-Playground embed widget(RDF 由 /ontology.rdf 同源供给) |
/Ontology-Playground/ |
本地镜像的 Playground 完整应用(见 5.2),NL 查询已接 ark-code-latest |
GET /api/nlq |
规则式自然语言查询(nlq.py,无 LLM):时间窗/活跃天数/链/题材/日期;静态站前端、MCP/CLI 三端同口径 |
POST /api/ask |
AI 问答端点(qa.py):链内(chain 参数限定上下文)/全局,返回回答 + 实体链接 |
5.2 Ontology-Playground(schema 层,双形态)
形态 A:本地镜像(当前默认)。data/output/playground/ 为 Playground 构建产物的本地镜像,catalogue.json 替换为仅含本项目单条目(official/xgb-a-chain);scripts/localize_playground.py 对镜像做 UI 汉化(幂等,重镜像后需重跑)。app.py 以 /Ontology-Playground/ 原始绝对路径托管,并在 index.html 注入引导脚本——无 hash 访问时自动跳到本项目本体深链。优点:无外网依赖,内网可用。
形态 B:GitHub Pages(fork catalogue)。fork 的 Pages 已启用(https://seuzxh.github.io/Ontology-Playground/ ):
- xgb_wiki 生成 catalogue 条目(
.rdf+metadata.json,scripts/export_ontology.py→data/output/xgb-a-chain/) - 推送到 fork 的
catalogue/community/或official/,fork 重新构建(npm run catalogue:build)+ push,Pages 自动更新 - 限制:Playground 只渲染 schema(实体/关系类型),不渲染实例数据(题材×个股×次数等),实例展示由 5.1 Web 承担
详细发布步骤见 publishing.md。
5.3 RDF 导出格式要点(Playground parser 兼容)
实现:src/rdf_export.py,语法对齐 catalogue/official/finance/finance.rdf 实测格式。
owl:Class+rdfs:label/comment+ont:icon(emoji) +ont:color(hex);entity id = 类名首字母小写owl:DatatypeProperty+rdfs:domain(完整URI精确匹配) +ont:isIdentifier+ont:propertyType;enum 用ont:enumValues(从开放字典实时生成)owl:ObjectProperty+ont:fromEntityId/ont:toEntityId+ont:cardinalitymetadata.json:{name: "A股题材产业链", description, category: "finance", icon: "📈", tags: ["A股","题材","产业链"], author}(additionalProperties: false)- 导出后过
npm run validate+ round-trip 校验
6. 项目结构与技术栈
xgb_wiki/
├── app.py # Flask 入口(端口 5010,含时间轴/Playground 镜像/RDF/NL 查询路由)
├── requirements.txt # flask, pymysql, python-dotenv, requests, beautifulsoup4, lxml, mcp, pyyaml
├── .env # 凭据(gitignore;本机复制自 2_xuangubao 项目)
├── CLAUDE.md # agent 工作说明
├── README.md # 项目速览
├── .github/workflows/ # deploy-site.yml:push master → 测试+构建 → Cloudflare Pages
├── skills/ # 对外 skill 定义:xgb-wiki(查询语法/口径/红线)+ xgb-sync(同步用法/退出码/回退/红线)
├── src/
│ ├── config.py # DB/LLM/LAS 配置 + 衰减参数 + 栏目字典
│ ├── ontology.py # 本体 schema 定义(Playground 格式,enum 从字典实时生成)
│ ├── etl.py # MySQL → SQLite 搬运:全量/增量共用逐行提取与聚合
│ ├── sync.py # 同步编排:环境检查/备份/临时库/校验/回退/sync_log
│ ├── trends.py # 时间窗/活跃天数/活跃个股/关联图/概述(纯 SQLite 可重算)
│ ├── nlq.py # 规则式自然语言查询(无 LLM)
│ ├── extractors.py # 大涨题材段/研报来源块/图片 等正则提取器
│ ├── viewpoint.py # 推荐观点提取(规则引擎版;LLM 为可选升级)
│ ├── llm_chain.py # 证据驱动的链映射 LLM 客户端
│ ├── qa.py # LLM 问答(上下文构建→LLM→实体链接)
│ ├── image_parser.py # LAS 按需/队列解析(1 QPM 节流 + 结果缓存 + 题材回填)
│ └── rdf_export.py # Playground 兼容 RDF/XML + metadata.json
├── scripts/
│ ├── sync_data.py # 数据同步入口(默认增量;--full/--check/--log)
│ ├── build_wiki.py # 全量重建别名(走 sync.py 完整防护流程)
│ ├── refresh_trends.py # 只重算时间窗/活跃天数/theme_daily(无需内网)
│ ├── gen_chain_map.py # 生成/补全链映射(--min-count --batch)
│ ├── parse_queue.py # 图片解析批量队列入口(默认 400 张)
│ ├── export_ontology.py # 导出本体文件 → data/output/xgb-a-chain/
│ ├── build_playground_catalogue.py # 镜像 catalogue.json 重建(schema 变更后)
│ ├── localize_playground.py # Playground 镜像汉化(幂等)
│ ├── build_static_site.py # 静态研报站生成 → data/output/site/(不入库)
│ ├── deploy_site.py # 本地手动发布 Cloudflare Pages(默认走 CI)
│ ├── mcp_server.py # MCP server(stdio 4 工具)+ --cli 自然语言查询
│ ├── install_skill.py # 安装 skill → ~/.zcode/skills/
│ └── run_tests.py # 全功能测试(172 项)
├── templates/ static/ # 5.1 的页面(Bootstrap 5 CDN;Cytoscape 本地 vendor)
├── data/
│ ├── xgb_wiki.db # SQLite 实例数据(随仓库管理)
│ ├── chain_map.json # 产业链映射(300 题材,人工审校)
│ ├── segment_types.json # 环节角色字典(含 stageTag 映射/展示方式,开放扩展)
│ ├── reason_types.json # 催化类型字典(开放扩展)
│ ├── event_types.json # 评级事件类型字典(开放扩展)
│ └── output/
│ ├── xgb-a-chain/ # .rdf + metadata.json(catalogue 条目)
│ ├── playground/ # Playground 本地镜像(汉化后)
│ └── site/ # 静态站构建产物(gitignore,CI/本地构建生成)
└── docs/ # 文档站(本目录,见 README.md 导航)
技术栈:Python 3.13 · Flask 3 · Bootstrap 5(CDN)· sqlite3 · pymysql · BeautifulSoup4/lxml(HTML 解析)· Ark API(可选 LLM)· mcp(对外 MCP server)· PyYAML(CI 测试校验)· LAS(图片解析,经全局 skill)。
7. 实施记录
| 阶段 | 内容 | 状态 | 验收结论 |
|---|---|---|---|
| M1 | 脚手架 + .env + git init | ✅ | 目录就绪 |
| M2 | ETL:题材/个股统计、券商引用、评级事件、图片登记 入 SQLite | ✅ | 题材统计正确;提取抽样人工核对达标 |
| M3 | 链映射(证据驱动)→ chain_map.json;推荐观点提取 | ✅ | 300 题材映射全部人工确认;观点走规则引擎(979 条) |
| M4 | Flask 页面 + 衰减分 + 推荐时间线 + 图片点击查看 | ✅ | 页面可交互 |
| M5 | 图片按需解析队列(LAS)+ image_depicts_theme 回填 | ✅ | 265 张已解析 |
| M6 | RDF 导出 + Playground 验证 | ✅ | 本地镜像 + 汉化内嵌;fork catalogue 推送流程就绪 |
| M7 | CLAUDE.md + README + git 提交 | ✅ | 文档齐备(本目录 v2.0 为最新一轮整理) |
| 增量1 | 近 5 个月数据处理——推荐观点规则引擎 + 图片解析队列 | ✅ | commit c1d2595 |
| 增量2 | LLM 配置 + embed 嵌入 + 图片证据更新 + chain_map 全量确认 | ✅ | commit c3e2aeb |
| 增量3 | Playground 本地镜像(默认只展示本项目本体) | ✅ | commit 5634671 |
| 增量4 | Playground 全面汉化(120+ 处)+ 实体/关系显示名中文化 | ✅ | commit 5002d26 |
| 增量5 | 链页 Cytoscape 图形视图 + PNG 导出 | ✅ | commit 3df48c8 |
| 增量6 | AI 问答(ark-code-latest)接入 wiki 与 Playground + 个股进图 | ✅ | commit 166e43c |
| 增量7 | 数据同步改造:增量水位同步 + 环境检查/数据校验/失败回退/同步日志 + 券商引用自愈重建(详见 docs/sync.md) | ✅ | 2026-09-01 |
8. 已确认的决策记录
| 决策 | 结论 | 时间 |
|---|---|---|
| 项目位置 | E:\Quant_projs\4. xuangubao\xgb_wiki |
08-30 |
| 数据源 | 仅 live_tuoshui_news + digest 正文(plates 字段不可用于 digest) | 08-30 |
| 产业链构建 | LLM 批量生成 + 人工审校(chain_map.json) | 08-30 |
| Segment 模型 | 六类 segmentType + 派生 stageTag,不硬套上中下游 | 08-30 |
| 类型可扩展 | segmentType/reasonType/eventType 全部注册表驱动(json 字典 + _pending 待审区),加类型零迁移 | 08-30 |
| 推荐观点 | 不新增实体,提及关系带观点属性(reason/reasonType/evidenceQuote/isCore/viewDate);isCore 加权可选 | 08-30 |
| Broker 语义 | 引用关系(多对多带属性),非发布关系;评级事件才多对一 | 08-30 |
| 衰减度 | 指数衰减热度分,半衰期 60 天可配,核心 1.0/共现 0.3 | 08-30 |
| 展示分工 | Playground 展示 schema;xgb_wiki Flask 展示实例;embed widget 互嵌 | 08-30 |
| 图片识别 | las-document-parse skill,全量登记 + 三类按需解析 | 08-30 |
| 观点提取降级 | LLM key 未配置时用规则引擎(信号句+关键词字典),LLM 版为可选升级而非依赖 | 增量1 |
| Playground 内嵌 | 本地镜像 + 汉化 + 深链引导,内网无外网依赖时仍可浏览本体图 | 增量3 |
| 数据范围 | 由近 30 天扩至全量(2023-11 起),ETL 幂等可重复全量重建 | 增量1 |
| 时间窗与活跃天数 | cnt_5d..30d + theme_daily + 窗口内活跃天数;"连涨"(连续数据日全局口径)废弃为后端列 streak_days,不再展示——活跃天数必须挂在用户明确选定的周期下 | 增量4 |
| 活跃个股关联图 | 题材↔个股连线图(题材节点唯一)替代逐股题材徽章列表;个股题材 = theme_stock 关联 ∩ 窗口活跃题材 | 增量4 |
| 自然语言查询 | 规则式(nlq.py,无 LLM):/api/nlq、静态站前端、MCP/CLI 三端同口径;LLM 问答(/api/ask)保留为增强 | 增量4 |
| 对外能力 | MCP server(stdio 4 工具)+ 全局 skill,其他智能体可查题材数据,无需 LLM key | 增量4 |
| 发布通道 | Cloudflare Pages 唯一线上通道,GitHub Actions 自动测试+构建+部署(GitHub Pages 通道移除);静态站产物不入库 | 增量4 |
| 同步机制 | 删库全量重建改为增量水位同步(etl_meta.wm_*);sync.py 编排五阶段(环境检查→备份→临时库→数据校验→原子替换/回退)+ sync_log 双写;校验失败回退=正式库全程只读;report_broker/rating_event 每次由正文自愈重建(清理 lastrowid bug 历史孤儿) | 09-01 |
9. 风险与遗留
- MySQL 仅内网可达(同步需连内网);
.env凭据不入库 - LAS 1 QPM + 按页计费(normal 0.02/detail 0.04 元/页),解析队列必须节流;当前 12426 张未解析图片禁止触发全量
- LLM 链映射一次性 token 成本;观点提取当前零成本(规则引擎),升级 LLM 后约 257 篇/月×1 次调用,走 Ark 账号
- Playground style-validator 命名 lint 可能拒绝导出文件,需按其规范命名
- 每日强股"大涨题材"行格式若改版,提取器需同步维护(正则容错 + 失败计数监控)
data/xgb_wiki.db随仓库管理(约 80MB),持续增长需评估 Git LFS 或改为发布产物- 遗留:① 老格式每日强股(正文无"N、"编号段)约 90/687 篇未被大涨题材提取覆盖;② RDF 导出尚未在 fork 仓库过
npm run validate(需 node 环境)