Skip to content

Weben 模块概览

Weben(Word Embedded Brain Expansion Network)是 Fredica 的知识网络模块,负责从视频/文章等素材中提取概念,构建个人知识图谱。


模块职责

位置职责
后端数据库shared/commonMain/db/weben/SQLite 数据模型 + JDBC 实现
后端 API 路由shared/commonMain/api/routes/Weben*REST 接口(见下表)
前端工具函数fredica-webui/app/util/weben.ts数据类型定义 + 格式化工具
前端 API 调用fredica-webui/app/util/materialWebenApi.tsAPI 封装 + 响应类型
前端守卫fredica-webui/app/util/materialWebenGuards.ts响应归一化(防御 legacy 数据)
前端路由页面fredica-webui/app/routes/weben.*UI 路由(见下节)

数据模型

WebenSource(weben_source 表)

来源代表一个可产出概念的知识来源,可选关联 material_id

kotlin
data class WebenSource(
    val id: String,
    val materialId: String?,          // 关联素材库 material.id,外部 URL 时为 null
    val url: String,                  // 资源地址;无外部 URL 时为 "material://<id>"
    val title: String,
    val sourceType: String,           // bilibili_video | local_file | web_article
    val bvid: String?,
    val durationSec: Double?,
    val qualityScore: Double,         // 0–1,用于图谱置信度加权
    val analysisStatus: String,       // pending | analyzing | completed | failed
    val workflowRunId: String?,       // 关联 WorkflowRun(状态对账用)
    val progress: Int,                // 0–100,由任务图动态计算
    val createdAt: Long,
)

已知 legacy 问题:旧版数据可能将 material_id 存为空字符串 ""WebenSourceDb.toSource() 已修正为 takeIf { it.isNotBlank() },前端 normalizeWebenSource() 也做了等效守卫。

WebenConcept(weben_concept 表)

kotlin
data class WebenConcept(
    val id: String,
    val canonicalName: String,
    val conceptType: String,          // 逗号分隔的多类型,如 "术语,数据结构"
    val briefDefinition: String?,
    val confidence: Double,           // 0–1
    val firstSeenAt: Long,
    val lastSeenAt: Long,
    val createdAt: Long,
    val updatedAt: Long,
)

关联表:WebenConceptAlias(别名)、WebenConceptSource(来源摘录)、WebenNote(用户笔记)。

WebenExtractionRun(weben_extraction_run 表)

一次概念提取操作的完整上下文,供审计/复现用。

字段说明
source_id关联来源
material_id冗余存储,方便查询
llm_model_id使用的 LLM 模型
prompt_scriptGraalJS 脚本(生成 prompt 用)
prompt_text实际发给 LLM 的 prompt
llm_input_jsonLLM 请求体
llm_output_rawLLM 原始输出
concept_count本次导入的概念总数

API 路由

来源

路由方法说明
WebenSourceListRouteGET列表(可按 material_id 过滤),含双层状态对账
WebenSourceGetRouteGET单条来源详情(含 concept_count

概念

路由方法说明
WebenConceptListRouteGET分页列表(可按 source_id/material_id 过滤)
WebenConceptGetRouteGET详情(含 aliases / sources / notes)
WebenConceptUpdateRoutePOST更新定义/类型
WebenConceptTypeHintsRouteGET可用类型 + 颜色标签
WebenConceptBatchImportRoutePOST批量导入(legacy,新代码用 ExtractionRunSave)

提取历史

路由方法说明
WebenExtractionRunSaveRoutePOST保存提取运行(同时 upsert 概念)
WebenExtractionRunListRouteGETsource_id 列表(摘要,无大字段)
WebenExtractionRunGetRouteGET单条完整详情(含 prompt/output)

笔记

路由方法说明
WebenNoteSaveRoutePOST创建/更新笔记
WebenNoteDeleteRoutePOST删除笔记

状态对账(Reconcile)

WebenSourceListRoute 在每次查询时对非终态(pending/analyzing)来源进行状态对账:

  1. workflowRunId 为 null → failed
  2. WorkflowRun 已删除 → failed
  3. WorkflowRun 终态(failed/cancelled/completed)→ 同步
  4. WorkflowRun 非终态,读 Task 实际状态推导

首次启动保护WebenSourceReconcileGuard):按 material_id 查询时,每个 material 每次 APP 启动只对账一次,后续轮询走零开销快速路径。


前端路由结构

/weben                          weben._index.tsx        知识网络首页(来源 + 概念总览)
/weben/sources/:id              weben.sources.$id.tsx   来源详情(单页滚动,含提取记录)
/weben/concepts                 weben.concepts._index.tsx  概念库列表
/weben/concepts/:id             weben.concepts.$id.tsx  概念详情(定义编辑 + 笔记 + 来源)

来源概念筛选应作为 /weben/concepts 页面的过滤器功能实现(source_id query param), 而不是在来源详情页中重复展示概念列表。


前端守卫函数

materialWebenGuards.ts 中的 normalizeWebenSource(data: unknown): WebenSource | null 用于对 API 响应做防御性归一化:

  • material_id: "" | " "null(legacy 空串问题)
  • 入参非法(null / 非对象 / 缺少 id)→ 返回 null

使用约定:凡是从 API 接收 WebenSource 对象处,均应经过此函数,不直接 as WebenSource 强转。


常见陷阱

  • WebenExtractionRunSaveRoute.ensureSource() 收到 material_id: "" 时会创建 URL 为 "material://" 的来源记录。已修复:调用前用 takeIf { it.isNotBlank() } 归一化。
  • WebenConceptListRoutesource_id 过滤时概念数可能与 WebenSourceGetRouteconcept_count 不一致(后者是实时 count,前者依赖分页 limit)。
  • 提取记录列表接口(WebenExtractionRunListRoute)只返回摘要字段,展开详情需再调 WebenExtractionRunGetRoute

相关文档

Fredica — AI 视频工坊