跳转至

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 属性)与 Postgres chunks 表合法记录;关系类型自由字符串。外部直写三元组完全可行。
  • 配置组合: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&center=&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 门):

  1. Wiki 能力开关与 LLM 扇出的关系:v0.1 关闭 wiki_enabled 的理由是"Agent 逐篇蒸馏昂贵"。需在试点 KB(或新 KB)验证:开启 wiki 能力后是否会对存量 4844 篇自动排队 LLM 生成任务(wiki/stats 的 pending_tasks/is_active 可观测)。若自动扇出不可关,方案降级为"wiki 能力保持关闭,图谱浏览走 Neo4j 直写数据 + 本站薄视图"(D8 fallback 链末端)。
  2. 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 + 实施计划重排) 用户拍板