运行手册
命令均在仓库根目录执行。设计背景见 设计方案,模块职责见 整体架构,发布到线上见 publishing.md。
0. 环境准备(一次性)
pip install -r requirements.txt # flask, pymysql, python-dotenv, requests, bs4, lxml
cp <凭据项目>/.env .env # 内网 MySQL + LLM 凭据(本机为 2_xuangubao 项目)
- Python 3.13;MySQL 仅内网可达、只读账号
- LAS 图片解析依赖全局 skill
las-document-parse(默认路径C:\Users\seuzx\.zcode\skills\,可用环境变量LAS_SKILL_DIR覆盖;Windows 下用其自带.venv/Scripts/python.exe) - LLM 链映射可选:
.env配LLM_API_KEY(Ark API);不配则链映射由 agent/人工维护
1. 数据构建与更新
完整的同步规则、校验清单、备份恢复与排障见 数据同步指南,本节为速查。
python scripts/sync_data.py # 增量同步(默认):MySQL → data/xgb_wiki.db
python scripts/sync_data.py --full # 全量重建(首次建库 / 改 chain_map、字典、提取器后)
python scripts/sync_data.py --check # 仅环境检查(MySQL 连通/源表结构/磁盘/本地库)
python scripts/sync_data.py --log 5 # 查看最近 5 条同步日志
python scripts/refresh_trends.py # 只重算时间窗/活跃天数/theme_daily(纯 SQLite,无需 MySQL/内网)
python app.py # 启动 Web → http://127.0.0.1:5010
同步流程(src/sync.py 编排,增量/全量同一套防护):环境检查 → 备份
(data/backups/,保留 1 份)→ 写 *.tmp-sync 临时库 → 数据校验 → 原子替换。
环境检查失败:停止并报告,不触碰数据;校验失败:报告错误并回退(正式库全程未写)。
每次同步(含失败)写入 sync_log 表与 data/xgb_wiki.sync.log。退出码:0 成功 /
2 环境失败 / 3 校验失败已回退。同步前先停 Web 服务(替换库文件与打开的连接冲突)。
增量规则:按水位 etl_meta.wm_live_id/wm_digest_id(源表主键最大 id)拉取新增行;
源端 is_deleted=1 的 live 研报连同关联一并剔除;源行内容编辑不检测(无更新时间戳),
需要时跑 --full。板块字典每次全量刷新;report_broker/rating_event 每次从已存正文
全量重建(自愈历史孤儿引用);聚合统计(出现次数/衰减热度/时间窗/theme_daily/
链映射)每次同步后全量重算。校验项:SQLite 自检、水位一致、计数守恒、外键孤儿不新增
(历史遗留孤儿记 W3 警告不阻断)、新行必填字段、聚合与明细一致、抽样与 MySQL 逐字段
比对(细节见 src/sync.py 模块注释)。
注意:--full 全量重建会把 image_asset 重置为未解析状态(丢失已付费的 LAS 解析
结果,见 §3),除非确有必要(建库/提取器改版),日常更新一律用增量。
etl_meta.ref_date 为源数据基准时间,可用来判断库的新鲜度。
时间窗(cnt_5d/10d/20d/30d、streak_days、theme_daily)由 src/trends.py 在 ETL 内重算;改窗口/活跃天数口径后,脱离内网也可单独跑 refresh_trends.py 回填(活跃天数为现算指标不落列)。
对外查询(MCP / skill / CLI)
python scripts/mcp_server.py --cli "近5天热门题材" # 命令行(--json 出结构化)
python scripts/mcp_server.py # MCP server(stdio):search_themes /
# theme_detail / daily_themes / hot_streaks
python scripts/install_skill.py # 安装 skill → ~/.zcode/skills/(xgb-wiki 查询 + xgb-sync 数据同步)
改 nlq 解析规则(src/nlq.py)或 trends 口径后,重跑 run_tests.py 第 9/10 节验证三端一致性。
静态站发布(CI 自动)
push master 触发 .github/workflows/deploy-site.yml:全功能测试 → 构建静态站 → Cloudflare Pages(https://xgb-wiki-site.pages.dev/)。需仓库 Secrets:CLOUDFLARE_API_TOKEN(Pages Edit 权限)+ CLOUDFLARE_ACCOUNT_ID,详见 docs/publishing.md。本地立即发布用 python scripts/deploy_site.py(需 wrangler 登录)。
2. 链映射维护(chain_map.json)
python scripts/gen_chain_map.py # 默认:出现≥5次的题材,每批10个
python scripts/gen_chain_map.py --min-count 8 --batch 20
流程:LLM 生成候选 → 人工审校 data/chain_map.json(补链名/环节名/segmentType/order/isBottleneck,确认后 manual: true)→ python scripts/build_wiki.py 重新载入。
规则:manual: true 条目重跑生成不会覆盖;环节名尽量用研报原文词汇;segmentType 必须落在开放字典内,新类型先走字典转正(§4)。
3. 图片解析(LAS,计费 + 1 QPM)
# 方式一:页面上点"AI解析"(POST /image/<id>/parse,异步提交,前端轮询)
# 方式二:批量队列(默认400张,65秒/张节流 ≈ 7小时/400张)
python scripts/parse_queue.py 100
- 解析候选规则(自动挑选):① 评级事件研报配图;② contextText 含"产业链/格局/架构"的图
- 结果按 imageId 缓存进 SQLite(重复执行不重复计费),并从解析文本回填
image_depicts_theme - 成本参考:normal 0.02 元/页;当前库 12691 张图中已解析 265 张,禁止全量解析
- 单张失败置
parse_status='failed',可重试
4. 开放字典维护
遇到 待审核 标签的数据或 _pending 区有条目时:
- 打开对应字典(
data/segment_types.json/reason_types.json/event_types.json) - 把
_pending中的键移入types,补label(segment 类还需补stageTag与display) python scripts/build_wiki.py重跑生效——schema 页/RDF 枚举实时跟随,无需迁移
5. 本体导出与 Playground
python scripts/export_ontology.py # → data/output/xgb-a-chain/(.rdf + metadata.json)
- 本地镜像(
/Ontology-Playground/):本体 schema 变更后需重建镜像 catalogue——python scripts/build_playground_catalogue.py(把build_schema()输出写入镜像catalogue.json单条目)→python scripts/localize_playground.py汉化(幂等)。整体更换 Playground 版本(重镜像构建产物到data/output/playground/)后同样重跑这两步 - 推送到 fork Pages:见 publishing.md
6. 提取器已知坑(extractors.py)
- 每日强股正文历史格式带空格("1 、 国光电气"、"( 1 ) 大涨题材 :"),提取前已做归一化;改动
_QIANGGU_SECTION_RE前先跑样例单测 - 研报来源块五段式:
券商,分析师,S编号,原标题,日期;评级事件从 sourceTitle 的"-事件类型报告"识别 - 图片在正文
<img>;image_str字段全库仅 1 条非空,勿用 - digest 的
plates字段不可用,题材从正文大涨题材行解析(仅 live 用 plates)
7. AI 问答与观点 LLM 升级
python scripts/extract_viewpoints_llm.py # LLM 重提核心观点(全部 is_core 段落)
python scripts/extract_viewpoints_llm.py --limit 50 # 只补缺(reason 为空的行)
- 问答无需单独启动:
POST /api/ask(Playground NL 查询、链页"问一问"共用),由src/qa.py构建上下文(链内=环节/题材/核心个股/卡脖子/近期推荐及理由;全局=全链概览+热门题材+评级事件)调用 ark-code-latest - 观点脚本幂等(只处理 reason 为空的行);要全量重提需先清空(见脚本头部注释)
- LLM 不可用时 Playground NL 自动回退本地引擎,链页问答框显示错误信息
8. 常见问题
| 现象 | 处置 |
|---|---|
| ETL 连不上 MySQL | 内网限制,需在内网环境运行;先 sync_data.py --check 定位(连接/源表/磁盘/本地库逐项报告);凭据看 .env 是否与凭据项目(2_xuangubao)一致 |
/ontology 枚举缺新类型 |
字典没转正或没重跑 build;见 §4 |
| 推荐时间线只有 evidenceQuote 没有 reason | 规则引擎没匹配到信号句(正常降级);如需补齐走 extract_viewpoints_llm.py |
| Playground/链页问答报 401 | .env 改过 key 但服务是旧进程:Werkzeug 重载子进程继承旧环境变量。config.py 已用 load_dotenv(override=True) 防复发;最稳妥:netstat -ano \| findstr :5010 找 PID → taskkill //F //PID <pid> → 重启 python app.py。判断特征:直连 python 正常而服务端 401 |
| Playground 镜像显示英文/空白 | 重镜像后没跑 localize_playground.py;深链引导依赖 catalogue 里 official/xgb-a-chain 条目存在 |
| 图片解析超时 | LAS 1 QPM 限流属正常;队列脚本自带 65s 间隔,勿并发多开 |
| 图形视图节点挤成一排不可读 | 布局勿用 breadthfirst(环节单行展开 5000px+,缩放 0.2);保持 cose 力导向 |
| 全功能回归 | python scripts/run_tests.py(205 项:路由/内容/API/RDF/数据完整性/观点覆盖/时间窗/NL/MCP/静态站/CI/数据同步) |
9. 红线
.env绝不提交;MySQL 只读,严禁任何写操作(ETL 只 SELECT,写入一律落 SQLite)- LAS 解析计费且限流,禁止全量解析(仅三类触发场景,见 §3);同步
--full会重置图片解析状态,日常更新一律用增量(见 数据同步 §9) data/xgb_wiki.db随仓库管理,提交前确认无敏感数据(正文来自付费产品,仓库保持私有)