2026-10-20-knowledge-unify-design.md 6.4 KB

设计:菌群知识并入 dan_knowledge_base(统一知识库管理)

日期:2026-10-20 状态:已批准(用户确认方案 B:表保留备用 + 删页面)

意图与为什么

health_knowledge_base 原本设计为"健康指标库"(维生素/氨基酸等结构化条目,含 normal_range/suggestion),但实际从未导入任何指标条目——表里只有 2026-10-20 从 microbiome_article 迁入的 809 篇菌群文章(item_type='article')。它已退化成一张"菌群文章表",设计中的多态模型优势从未体现。

dan_knowledge_base 是「知识库管理」页的数据源(39 条案例报告,source_type='file'),且已存在 source_type 字段天然支持多来源,无 title 唯一约束,809 篇可零冲突迁入。

两个知识入口并存导致管理员维护割裂(要记"菌群文章在健康知识库、案例在知识库",新增内容要先想放哪)。合并到单表后:一个页面、一个入口、一套维护。

关键判断:向量库本来就是同一个检索空间(collection cfc_knowledge),菌群文章与案例报告靠 metadata.source 分流(microbiome / dan_knowledge),合并存储表不改变检索行为。

目标

  1. 809 篇菌群文章迁入 dan_knowledge_base(source_type='article'),成为唯一知识条目表
  2. 管理端「知识库管理」页统一展示 39 案例 + 809 文章,支持长文详情查看
  3. langgraph 两个源仍按 metadata.source 分流,管理端「向量知识库」统计口径不变
  4. 删除 health-knowledge.vue 页面和路由
  5. health_knowledge_base 表保留置空(未来指标条目备用,不 DROP)

非目标

  • 不创建/迁移任何指标条目数据(维生素/氨基酸等)——health_knowledge_base 留空备用
  • 不合并向量库 source 分类(microbiome 与 dan_knowledge 两块统计口径保留)
  • 不强制为 809 篇文章绑定维度/标签体系(可后续人工绑定)
  • 不改动「统一知识库管理」页(knowledge_base_section 是 AI 模块文本配置,无关)

约束

  • 生产 DB:JD Cloud RDS MySQL 8.0.34,库 zxyj。部署前备份目标表
  • langgraph 全量重建索引约 20–30 分钟(SiliconFlow 429 限流退避,~1000-1400 块/分)
  • 管理端 API 统一 POST
  • 代码改动走 /app/cfc(git cfclub 分支),部署按 AGENTS.md 流程(备份 → 构建 → 部署 → 验证 → 失败回滚)
  • MySQL 8.0 不支持函数索引(需要表达式唯一时改用 STORED 生成列)
  • 已确认:809 篇 title 全部 ≤ 200 字符(varchar(200) 够用),content 为 mediumtext(最长 25K 字符)

已决策(用户确认)

迁移映射:

health_knowledge_base dan_knowledge_base 说明
item_name title 文章标题
description content 正文(markdown)
— source_type='article' 标记来源(现有案例为 'file')
source source_url 原 microbiome_article 表名标记
— status=1 启用
— sort=0 默认排序

接口与数据源:

  • 后端 /api/admin/knowledge-base/list 支持 sourceType(精确匹配)与 excludeSourceType(排除)参数(不传则返回全部,向后兼容)
  • langgraph get_dan_knowledge_base 传 excludeSourceType='article'(39 条案例,排除菌群文章)。不用 sourceType='file':KnowledgeDialog 写 sourceType 有 manual/file/url 三值,精确匹配 'file' 会漏掉未来新增的其他来源案例
  • langgraph get_microbiome_articles 改拉 dan_knowledge_base(sourceType='article',必须 ORDER BY id 升序稳定分页——所有文章 sort=0,SortUtil 只在前端传 sort 时生效,否则重蹈旧分页 bug),字段映射 title/content
  • HealthKnowledgeBaseController.article/list 改查 dan_knowledge_base(或直接由 langgraph 调用 /api/admin/knowledge-base/list)

category 处理:丢弃 category(dan_knowledge_base 无此字段,不 ALTER 表)。依据:Chroma metadata.category 写了但从不被读取或过滤;health_butler_graph 读 category 走 /api/health/knowledge/query(读 health_knowledge_base 原表),不读 Chroma。langgraph 输出空字符串。

页面:删除 health-knowledge.vue 页面及 health-knowledge 路由;「知识库管理」页(views/admin/knowledge/index.vue)承载全部内容。

留给 builder

  1. 前端「知识库管理」页 source_type 标识列/筛选与长文详情对话框的具体实现方式
  2. 后端 list 接口 sourceType 参数的实现细节(MyBatis-Plus 条件拼接位置)
  3. 迁移脚本幂等处理(重跑不重复插入:按 title+source_type 去重或先删再插)
  4. 809 篇文章的标签/维度绑定策略(默认不绑定,列表不强制要求维度选择)

实施顺序建议

顺序设计关键点(builder check 修正):旧 langgraph 无 sourceType 过滤,DB INSERT 后若其定时同步触发,会把 848 条全部索引为 dan_knowledge 造成双重索引。因此 langgraph 新镜像先构建好(不部署),DB INSERT 后立即替换容器 + 触发全量重建,缩短窗口期;重建是全量(先删后插),可自愈清理任何窗口期脏数据。

  1. 后端:改造 /api/admin/knowledge-base/list 支持 sourceType/excludeSourceType + 构建部署(向后兼容,无风险)
  2. langgraph:改造 get_dan_knowledge_base(excludeSourceType='article')与 get_microbiome_articles(sourceType='article' + ORDER BY id)+ 镜像构建(后台,暂不部署)
  3. DB:备份 health_knowledge_base + INSERT 809 篇到 dan_knowledge_base(source_type='article',保留原始 created_at/updated_at 避免 pub_date 元数据跳到 2026-10-20)+ 校验
  4. 部署 langgraph:替换容器 + 触发全量重建索引(约 20–30 分钟)
  5. 前端:知识库管理页增强(source_type 标识/筛选 + 长文详情)+ 删 health-knowledge 页面(Layout.vue:235 菜单项 + router/index.js:772 路由,共享 perm knowledge:base 不影响角色)+ 构建部署
  6. 验证:管理端 848 条 / 向量库 by_source 不变 / 检索命中 / 无 ERROR
  7. 清理:DELETE FROM health_knowledge_base WHERE item_type='article'(只删文章,不清表——KnowledgeBaseDataImporter 可能插入 bacteria/indicator/nutrient 行,langgraph /query 仍读该表)