WeKnora 融合方案
版本 0.2 · 2026-09-29 · 状态:已定稿(双核定位),按 S0–S4 路线推进(S0 待执行) v0.1(2026-09-27)将 WeKnora 定位为"消费端、单向流";v0.2 按用户 2026-09-29 拍板升级为 WeKnora = 研报后台核心知识库,xgb_wiki 的数据处理逻辑与复杂逻辑尽量下沉 WeKnora 通用能力侧。v0.1 的导入管道(原阶段 0/1)已按原方案完成实施并验收(4810 篇对账),其结论继续有效;问答、图谱、消费方向按本版重排。 与 融合实施计划 的关系:本文件定架构与决策(why),实施计划定执行顺序、步骤与验收(how)。 调研依据:WeKnora v0.8.2(部署实例
7.weknora,commit 4df7ccbb)源码级验证 + 本项目代码实测盘点;关键结论均附源码位置,见 §8。
1. 定位:双核,不是单事实源
| 能力 | xgb_wiki(事实源 + 领域引擎) | WeKnora(后台核心知识库) | 判定 |
|---|---|---|---|
| 研报全文问答 / 语义检索 | ~~/api/ask 全量上下文塞 prompt,无检索、无引用~~(v0.2 起下线) |
RAG(检索增强生成)管线 + 引用溯源 + 多轮会话 + Wiki/Agent 三入口 | WeKnora 独占,问答整体迁离 xgb 站点 |
| 知识图谱 | ~~graph.db LLM 抽取三元组 + /graph ECharts 页~~(v0.2 起退役) |
Neo4j 检索图谱(本体直写)+ Wiki 知识页与图谱可视化页 | WeKnora 接管,本体定义仍归 xgb_wiki |
| 精确结构化查询(时间窗热度/活跃天数/评级筛选) | SQL + 规则式 nlq(自然语言查询),精确 | 做不了(RAG 是语义近似,无时间权重) | xgb_wiki 永远是唯一事实源,经 MCP(Model Context Protocol,模型上下文协议)工具供 WeKnora Agent 反查 |
| 本体定义(8 实体 / 11 关系)与开放字典 | src/kg/ontology.py + data/*.json,人工审校资产 |
只消费(Wiki 页 / Neo4j 实例由它生成) | xgb_wiki 保留 |
| 每日简报 / 静态站 | 已有,贴合需求 | 无此形态 | 不动 |
数据流向仍以写入单向为原则:结构化库 → WeKnora(文档推送、Wiki 页生成、Neo4j 直写),不做反向回写;WeKnora 侧内容只作为消费端增强(S4 可选回流:报告页语义相关推荐)。"唯一事实源"指结构化口径(热度、时间窗、关联证据)不变,语义层(检索、问答、图谱浏览)由 WeKnora 承接。
2. 总体架构(双核)
内网 MySQL ──每夜 sync──▶ data/xgb_wiki.db(L1:事实源 + 领域引擎,不动)
│
┌─────────────────────┼──────────────────────────────┐
▼ ▼ ▼
refresh_daily/ push_to_weknora.py Wiki 本体页生成
trends/静态站CI │ (S2 新增 runner)
▼ ▼
┌─────────────────────────────────────────────────┐
│ WeKnora(L2:后台核心知识库) │
│ 文档库 4844 篇(vector+keyword 混合检索+标签) │
│ Wiki 知识页 + 图谱可视化页(S2 启用) │
│ Neo4j 检索图谱(S2 直写)· RAG 问答 · Agent 工具箱 │
└─────────────────────────────────────────────────┘
▲ MCP 双向(S1/S3) ▲ 检索回流(S4 可选)
① WeKnora MCP endpoint → ZCode 直连检索/问答 │
② mcp_server.py --http → 注册进 WeKnora 工具箱 │
xgb web 仅剩精确查询(nlq),报告页可选挂相关推荐
与 v0.1 的差异:① /api/ask 与 qa.py 整体退役(问答迁离 xgb 站点,入口 = WeKnora UI / ZCode / 官方嵌入聊天组件(embed));② 图谱双通道接管——检索侧 Neo4j 直写(保留 v0.1 路径 B)+ 浏览侧 Wiki 本体页(v0.2 新增,替代 /graph 页);③ 精确结构化查询经 MCP 反向注入 WeKnora Agent(原阶段 3 不变)。
3. 文档导入管道(已实施,2026-09-28 全量验收)
v0.1 §3 全部结论经实施验证有效,本节记录最终口径;细节不再重复,见 git 历史(a8f0cac…9429969)。
- 通道(拍板:保留 MD 组装,不切原文直传):
src/integrations/weknora/export.py组装篇级 Markdown(collect():34 复用parse_sections小节 + 存量观点按 seq 对齐;build_markdown():81 观点内嵌小节开头;build_metadata():128),scripts/sync/push_to_weknora.py推送(限速分批,Ark embedding 账号级 429 教训)。观点内嵌是检索语义密度资产,组装逻辑属领域资产保留。 - 幂等三件套:本地推送进度标记
data/weknora_push.json(已推 report_id 清单,每批落盘)+ 服务端文档 ID 映射data/weknora_map.json+ 月份标签 YYYY-MM(build_tag_names():118)。manual 导入的自定义 metadata 被服务端丢弃(实测),source_id 服务端查重不可用,本地推送进度标记是唯一幂等防线。 - 最终基线(2026-09-29 核对,2026-10-03 补推 9/25–9/30 共 34 篇后为 4844 条):推送进度标记与文档映射各 4844 条,数据窗口 2025-01-01 → 2026-09-30(9/29 基线 4810 条时曾与库内 knowledges=4810、chunks=45365、21 个月份标签完全对账)。
- 模型:embedding = doubao-embedding-vision(dim 2048,换型需清库重灌);chat 默认已切 doubao-seed-2-1-pro(
7.weknora/config/builtin_models.yaml,早于本方案注册的 ark-code-latest);无 rerank(租户未配时检索优雅回退纯向量排序)。
4. 知识图谱接管(S2):本体直写 Neo4j + Wiki 本体页
图谱管理整体移交 WeKnora,本体定义不迁移:src/kg/ontology.py(8 实体 / 11 关系,:21-166)与三个开放字典仍是唯一本体源,WeKnora 侧只存实例。现有两套"图谱"模型(主库本体实例 vs graph.db 简化抽取图,5 实体 4 关系)以主库本体为准统一,graph.db 管线整体退役(见 §5 退役清单)。
4.1 检索侧:本体直写 Neo4j(沿用 v0.1 路径 B)
v0.1 §4 结论不变,摘要如下(源码证据见 §8):
- WeKnora 图谱检索与抽取完全解耦:检索只认 Neo4j 数据形状(label=
ENTITY+KB ID 去连字符;name/chunks/attributes/kg属性)与 Postgreschunks表合法记录;关系类型自由字符串。外部直写三元组完全可行。 - 配置组合:
GraphEnabled=false(零 LLM 抽取成本)+ExtractConfig.Enabled=true+ 最小 few-shot 非空——聊天管线实体检索与 Agent 工具query_knowledge_graph均工作。 - 节点四要素:label /
name(必须)/chunks(chunk ID list,缺失会 panic)/attributes;kg填真实文档 ID 以获得删除级联。chunk_id 指向该报告在 WeKnora 分块后的真实 chunk(is_enabled=true),"实体→原文引用"由此桥接。 - 运维红线:WeKnora 侧重解析/重导入会删图谱不重建 → 须重跑直写脚本;孤立实体(无关系)不会被检索返回。
- 代码放置:
src/integrations/weknora/graph.py(bolt 客户端 + APOC merge Cypher 复刻)+scripts/kg/sync_weknora_graph.py(查回 chunks → 主库三元组 → 实体名↔chunk 文本匹配挂载 → 直写)。
4.2 浏览侧:Wiki 本体页(v0.2 新增,替代 /graph 页)
调研结论(WeKnora v0.8.2 源码级):Wiki 是完整 API 化的子系统,页面可编程创建,不依赖它的 LLM 逐篇生成管线:
| 能力 | 端点 / 证据 | 说明 |
|---|---|---|
| 页面 CRUD | POST/PUT/GET/DELETE /api/v1/knowledgebase/{kbId}/wiki/pages(frontend/src/api/wiki/index.ts) |
页面字段:slug / title / page_type / content(Markdown)/ summary / aliases 别名 / source_refs / in_links / out_links / page_metadata / version |
| 页面类型 | entity / concept / synthesis / comparison(+summary) | 映射建议:个股/券商=entity,题材=concept,产业链=synthesis,环节随所属链页内小节 |
| 互链与图谱数据 | 正文 [[wiki-link]] 互链;GET …/wiki/graph?mode=overview\|ego¢er=&depth= |
overview 返回连接度 top-500 页,ego 以某页为中心展开邻域(WikiBrowser.vue 全屏图谱视图,支持类型过滤/搜索/bloom 扩展) |
| 人工编辑共存 | 更新带 version 乐观锁,冲突返回 409 + current_version;last_edit_source 区分 pipeline/agent/user/revert;修订历史 + 一键回滚 |
xgb_wiki 推送与人工润色可共存,不会静默覆盖 |
| 链接重建 | POST …/wiki/rebuild-links |
批量改页后重算互链 |
| 官方嵌入 | 仅 chat 组件 iframe(frontend/embed.html,channel+token,CSP(内容安全策略)frame-ancestors 嵌套白名单);Wiki 图谱页无独立 embed 形态 |
xgb /graph 页退役后导航指向 WeKnora UI(外链);iframe 直嵌主 UI 需实测登录态与 CSP,作为备选(决策点 D8) |
通道设计:主库表 → 生成器 → Wiki 页。题材页内容 = 链位置(chain/segment/order/isBottleneck)+ 时间窗徽标口径 + 关联个股(theme_stock 按衰减热度排序)+ 近期推荐观点(report_section 抽 top N)+ source_refs 关联原文文档;链页 = 环节序列 + 各环节题材清单;全部经 [[…]] 互链,同义词进 aliases(复用 kg_schema.py:30-47 的 SYNONYMS 表思路)。生成器放 scripts/kg/push_wiki_pages.py(S2),幂等键 = slug + version 乐观锁。
两项待实测(S2 试点先做,均为 go/no-go 门):
- Wiki 能力开关与 LLM 扇出的关系:v0.1 关闭 wiki_enabled 的理由是"Agent 逐篇蒸馏昂贵"。需在试点 KB(或新 KB)验证:开启 wiki 能力后是否会对存量 4844 篇自动排队 LLM 生成任务(
wiki/stats的pending_tasks/is_active可观测)。若自动扇出不可关,方案降级为"wiki 能力保持关闭,图谱浏览走 Neo4j 直写数据 + 本站薄视图"(D8 fallback 链末端)。 - API key 能力覆盖:现 key 14 项能力是否含 wiki 路由写权限(rbac 按
knowledgebase/{id}/wiki/*路由组判)。若无,则 wiki 写走服务账号 Bearer 或申请扩展能力(与 D9 一并处理)。
5. 问答迁离与退役清单(S1)
问答(/api/ask,src/web/api.py:26-37 → src/llm/qa.py:130-143)现为"全量本体上下文塞 prompt + 单轮 LLM",无检索、无引用,v0.1 即判定由 WeKnora 承接;v0.2 拍板整体迁离 xgb 站点:链页问答框(templates/chain.html:22-42)与 /api/ask 一并移除,用户新入口 = WeKnora UI(带引用 RAG 问答)、ZCode(经 WeKnora MCP endpoint,S1 接线)、embed 聊天 iframe(如需嵌入任何站点,官方支持)。nlq(规则式自然语言查询)保留不动——精确口径与 RAG 互补。
退役一律走三步:tag 冻结 → 用户确认 → 删除(AGENTS.md 版本管理法),旧版可 git checkout <tag> 复现:
| 阶段 | 退役对象 | tag | 替代 |
|---|---|---|---|
| S1 | src/llm/qa.py、/api/ask 路由、chain.html 问答框 |
ask-frozen |
WeKnora RAG 问答(UI/MCP/embed) |
| S2 | data/graph.db、scripts/kg/build_graph.py、src/kg/{kg_extractor,kg_schema,kg_query,kg_cluster}.py、src/web/views/graph.py、templates/graph.html、静态站 graph 产物 |
graphdb-frozen |
Wiki 本体页 + Neo4j 直写(§4) |
明确保留(勿误伤):src/kg/ontology.py + rdf_export.py(本体源与 Playground 导出)、scripts/kg/{gen_chain_map,extract_viewpoints_llm,export_ontology}.py(链映射与观点资产)、src/llm/{nlq,viewpoint}.py、src/llm/llm_chain.py(链映射与观点升级仍用)。
6. 能力迁移映射表("复杂逻辑下沉"全景)
| xgb_wiki 现有逻辑 | 位置 | 处置 | WeKnora 通用能力承接 |
|---|---|---|---|
| 全量上下文问答 | src/llm/qa.py |
退役(S1) | 混合检索 + 引用溯源 + 多轮会话 |
| LLM 三元组抽取 | src/kg/kg_extractor.py:200-227 |
退役(S2) | 不需要——检索图谱由主库三元组直写(§4.1),本体已人工精校,LLM 二次抽取是降级 |
| 图谱存储/查询/聚类 | kg_schema/kg_query/kg_cluster.py、/graph 页 |
退役(S2) | Wiki 图谱页(overview/ego 浏览);Louvain 聚类浏览由 WeKnora 图谱页承接,领域定制聚类如有需要保留按需跑 |
| HTML→文本渲染 | pipeline/extractors.py:42 strip_html |
保留为保底 | docreader 原生解析(若日后切原文直传再启用;本轮拍板保留 MD 组装) |
| 篇级 MD 组装 | integrations/weknora/export.py |
保留(领域资产) | —(观点内嵌增益,见 §3) |
| 观点单元管线 | content/daily.py parse_sections |
保留(双端共享) | 每日简报数据源 + 导出复用,不可只留 RAG 侧 |
| 文档标签 | export.py:118、tag_weknora.py |
已迁移,可扩展 | KB 标签是 v0.8.2 唯一可用结构化过滤通道;S4 可扩栏目/题材标签 |
| 语义检索/相关推荐 | (无) | 新增回流(S4 可选) | hybrid-search API:报告页"语义相关研报"、题材页相关观点 |
| ETL 同步/校验/回退 | pipeline/sync.py、etl.py |
保留 | 数据工程防护,与 RAG 无关 |
| 热度衰减/时间窗/连涨 | etl.py:149,548-599、content/trends.py |
保留 | 精确时间序列口径;WeKnora 检索无时间权重(实测) |
| 本体 + 开放字典 + chain_map | kg/ontology.py、data/*.json |
保留 | 领域语义资产;WeKnora 侧实例由它生成 |
| 栏目体系 | config.py:75-89 |
保留 | 源库编辑打标口径 |
| 每日强股 is_core 证据 | etl.py:379-403 |
保留 | 领域强证据规则,决定权重体系 |
| NLQ 精确查询 / MCP | llm/nlq.py、scripts/ops/mcp_server.py |
保留 + 反向注入(S3) | 注册进 WeKnora 工具箱,Agent 对话可调精确结构化数据 |
7. MCP 双向集成(S1 方向① / S3 方向②)
- 方向 ①(WeKnora → ZCode,S1,随问答迁离一起做):WeKnora「设置→发布集成→MCP Server」建端点 →
/mcp/<endpoint_id>(Streamable HTTP + Bearer)→ 写入 ZCode 配置。此后 ZCode 会话可直接检索/阅读研报库并ask,成为问答迁离后的主力入口之一。 - 方向 ②(xgb_wiki → WeKnora 工具箱,S3):
scripts/ops/mcp_server.py加--http(FastMCP 原生transport="streamable-http",工具实现与传输解耦,约 10–15 行)→ 常驻(D3:建议 systemd user unit +Restart=on-failure)→ WeKnora「工具箱→MCP 服务」注册(仅 SSE/HTTP,禁 stdio)。效果:WeKnora Agent 对话可调search_themes/hot_streaks/daily_viewpoints拿精确结构化数据,与 RAG 检索互补。
8. 源码证据索引(WeKnora v0.8.2 @4df7ccbb)
| 结论 | 位置 |
|---|---|
| ExtractConfig 结构(few-shot/Tags/CustomInstructions) | internal/types/knowledgebase.go:704-714 |
| 抽取模板注入(系统模板+自定义指令+示例) | internal/application/service/extract.go:342-353 |
| CustomInstructions ≤4000 字符、追加式 | internal/types/prompt_instructions.go:10,14-25 |
| 关系类型入库过滤被注释(枚举不生效) | chat_pipeline/extract_entity.go:214 |
| 聊天管线门控只查 ExtractConfig.Enabled | chat_pipeline/extract_entity.go:120-129 |
| IsGraphEnabled = IndexingStrategy && ExtractConfig | internal/types/knowledgebase.go:883-886 |
| 抽取入队门控 eff.GraphEnabled | knowledge_process_config.go:49,111-112 |
| Agent 工具门控不查 Enabled(只查示例非空) | internal/agent/tools/query_knowledge_graph.go:216 |
| Neo4j label 规则 / APOC merge Cypher | retriever/neo4j/repository.go:32-53, 76-117 |
| 检索 Cypher(CONTAINS + 种子需有关系) | retriever/neo4j/repository.go:271-294 |
| 节点属性裸断言(缺 chunks/attributes 即 panic) | retriever/neo4j/repository.go:209-217 |
| chunk 回表(chunks 表,is_enabled 过滤) | internal/application/repository/chunk.go:138-147 |
| 文档删除级联清理图谱(label+kg) | knowledge_delete.go:546 |
| Wiki 页 CRUD/文件夹/移动/修订/回滚/搜索 API | frontend/src/api/wiki/index.ts(路由 /api/v1/knowledgebase/{kbId}/wiki/*) |
| Wiki 图谱数据 API(overview top-500 / ego / types 过滤) | 同上 getWikiGraph;渲染 frontend/src/views/knowledge/wiki/WikiBrowser.vue |
| Wiki 页版本乐观锁(409 + current_version)/ last_edit_source | 同上 WikiPageUpdatePayload / WikiPage.last_edit_source |
| 官方嵌入仅 chat 组件(embed.html + channel/token + CSP frame-ancestors) | frontend/src/views/embed/EmbedPage.vue、架构文档"Embed Widget"节 |
| Wiki 三支柱定位(RAG / ReAct Agent / Wiki 模式) | README.md:50-61,123-137 |
9. 分阶段路线(S0–S4,细节与验收见实施计划)
| 阶段 | 内容 | 工作量 | 前置 |
|---|---|---|---|
| S0 收尾与加固 | sync 链式挂载(D2 接线)· runner 回归测试 · WeKnora API key 收紧(14 项→最小集)· UI 问答验收(chat 模型已切 seed-2-1-pro) | 半天 | 无 |
| S1 问答迁离 | WeKnora MCP endpoint → ZCode · 移除链页问答框 + /api/ask · qa.py 冻结退役 |
半天 | S0 |
| S2 图谱接管 | 两项 Wiki 待实测 → Wiki 本体页试点(≈50 主题)→ 生成 runner → Neo4j 直写 → /graph 退役 + graph.db 管线冻结退役 |
2–3 天 | S1 |
| S3 精确查询注入 | mcp_server.py --http 常驻 → WeKnora 工具箱注册 |
半天 | 可与 S2 并行 |
| S4 内容回流(可选) | 报告页语义相关推荐 · 题材页相关观点 · 标签体系扩展(栏目/题材) | 按需 | S1 |
10. 风险与对策
| 风险 | 对策 |
|---|---|
| Wiki 能力开启触发存量 4810 篇 LLM 逐篇生成扇出(成本 + 429) | S2 试点 KB 先验证 manual API 建页不排队生成(wiki/stats 观测 pending_tasks);不可控则保持关闭,图谱浏览降级 D8 fallback 链末端 |
| API key 无 wiki 路由写能力 | S2 实测 14 项能力覆盖;缺则服务账号 Bearer 或申请扩展(D9) |
| iframe 嵌入 WeKnora 主 UI 被拦(frame-ancestors 仅对 embed.html 配置;主 UI 需登录态) | D8 fallback:iframe 实测 → 外链跳转 → 本站薄视图(读 wiki/graph API 自渲染) |
| manual 导入自定义 metadata 被服务端丢弃 | 幂等只靠本地推送进度标记与标题回连;结构化过滤走 KB 标签(月份已上线,S4 可扩展) |
| 检索无时间权重(CPO 查询 7 月/9 月混排实测) | 提问带时间词(日期在正文头部,关键词腿可命中)+ 月份标签过滤;时间窗精确问题走 nlq/MCP(S3 后 Agent 可自动选通道) |
| 重解析/重导入删图谱不重建 | 直写 runner 幂等可重跑;运维文档标注"重解析后须重跑" |
| embedding 换型向量不兼容 | 阶段 0 已定型 doubao-embedding-vision;换型=清库重灌,避免 |
| WeKnora 升级 API 漂移 | client.py 已"以实际响应为准";升级前 --dry-run 冒烟 |
| ~~另一台机器存在未同步提交(2026-09-29 提示)~~ 已并轨(同日,远端 staging 五笔) | 远端增量(数据分发方案:GitHub Releases 取数,WeKnora 服务器免 clone 整仓)与融合方案无冲突;本机远端推送已切 SSH |
11. 决策记录
| 日期 | 决策 | 依据 |
|---|---|---|
| 2026-09-27 | 导入粒度 = 篇级文档 + 观点内嵌,不观点独立成篇 | 父子分块天然兼顾命中与上下文;防数量爆炸 |
| 2026-09-27 | 图谱检索侧走路径 B 本体直写,路径 A(ExtractConfig 引导 LLM 抽取)仅作对照实验 | 源码验证检索/抽取解耦;本体已人工校验,LLM 二次抽取是降级 |
| 2026-09-27 | 代码放置按 AGENTS.md 决策表:外部系统封装进 src/integrations/weknora/ |
治理规范 ca474ea 固化 |
| 2026-09-29 | 定位升级:WeKnora = 后台核心知识库(双核),xgb_wiki 复杂逻辑尽量下沉其通用能力侧 | 用户拍板;能力迁移映射表(§6)划定边界 |
| 2026-09-29 | 问答整体迁离 xgb 站点(不做后端代理),qa.py 退役 |
用户拍板;入口收敛到 WeKnora UI / ZCode / embed |
| 2026-09-29 | 图谱浏览走 WeKnora Wiki 页,/graph 页与 graph.db 管线退役 |
用户意向 + 调研结论:Wiki API 完整可编程、官方嵌入仅 chat(D8 定 fallback 链) |
| 2026-09-29 | 导入通道保留 MD 组装,不切原文 HTML 直传 | 用户拍板;观点内嵌是检索质量资产 |
| 2026-09-29 | 本轮交付 = 方案文档(本文件 v0.2 + 实施计划重排) | 用户拍板 |