deerflow-code/frontend-web/docs/技能归纳至WeKnora知识库-实现设计.md
2026-09-07 18:24:55 +08:00

89 KiB
Raw Blame History

技能归纳、WeKnora 普通知识库与助手知识库:实现设计

本文档用于指导大模型或开发者实现知识库体系改造。整体包含两条线:一条是“将一个或多个技能归纳到一个 WeKnora Wiki 普通知识库”;另一条是新增自研助手知识库体系。助手知识库像普通知识库一样可以创建多个库,同时系统内置一个全局大库,用于统计全库数据、承接所有 WeKnora 导入沉淀、做全局实体对齐、Wiki 展示和导入审计。

本文档中,技能归纳目标只能是 WeKnora Wiki 普通知识库;助手知识库不接收技能直接归纳,也不接收任意本地文件。普通知识库负责向量化、检索、Wiki 和图谱;助手知识库负责自研存储、WeKnora 导入、实体对齐、Wiki 展示、搜索和导入审计。无论 WeKnora 数据导入到哪个助手知识库,最终都必须沉淀一份到系统全局大库。

最终约束:如果本文历史章节与本节冲突,以本节和“2. 当前边界”中的约束为准。

1. 背景与目标

当前系统已有:

  • 技能管理:后台可管理运行中的技能,技能文件位于 skills/public、skills/custom。
  • 技能地址管理:已经在管理员技能管理页中以标签页形式接入,支持扫描技能内 .md、.py 中的地址并批量替换。
  • WeKnora / LLM Wiki 接入:前后端已有知识库、文档、Wiki 页面、Wiki 图谱等 API。

本次要新增一条管理员工作流:

管理员在“技能管理”页面选择多个技能,再选择一个目标 WeKnora Wiki 普通知识库,点击归纳。系统将每个技能作为独立来源读取、解析、抽取和归纳,把结果写入对应 WeKnora 知识库,并在技能列表和技能详情中展示“该技能已被哪些知识库归纳”。如果需要归纳到多个普通知识库,通过多次操作完成。

用户已确认的业务约束:

  • 一次操作可以选择多个技能,但只能选择一个目标 WeKnora Wiki 普通知识库。
  • 同一个技能可以在不同时间归纳到多个知识库,所以最终关系是技能与知识库多对多。
  • 多知识库归纳通过多次操作完成;每次操作形成一批 技能 x 单目标知识库 任务。
  • V1 只支持归纳到可写 WeKnora Wiki 普通知识库;不支持非 Wiki、FAQ、系统会话存档、只读知识库作为技能归纳目标。
  • 技能归纳时只抽取数据、业务说明、实体、概念、对象、事件、关系等知识;Python、TypeScript、Shell 等代码和脚本类文件完全排除,不读取注释、不抽取函数、不上传、不进入 prompt。
  • 技能里的 Markdown、业务数据文件、表格、PDF、Office、图片等要纳入处理范围。
  • 需要同步三类内容:原始资料、归纳后的 Wiki、实体与关系。
  • 关系来源包括 Markdown 自然语言描述、目录和文件引用、模型自动推断。
  • 允许模型推断关系,但前端不提供逐条实体/关系预览审核。
  • 支持管理员手动点击“重新归纳”;不新增自动文件监听、定时后台同步或技能变更自动远程写入。
  • 解除关联时弹窗让用户选择:保留知识库内容,或删除该技能贡献的内容。
  • 权限仅管理员。
  • 总技能数约 200 个,需要支持批量进度、后台执行、失败重试。
  • 同一目标知识库内,不同技能抽取出的同一实体需要合并。
  • 重归纳时先生成新版本,成功后再替换旧版本;失败时旧版本继续可用。
  • 新增知识库类型区分:普通知识库是 WeKnora,助手知识库是自研存储。
  • 助手知识库支持创建多个库;其中有且只有一个系统全局大库,建议命名为“知识梳理总库”,所有用户可见。
  • 助手知识库只提供 Wiki 页面展示、搜索和数据导入;不落到 WeKnora。
  • 助手知识库数据来源只能是 WeKnora 导出包或从某个 WeKnora 知识库触发导入。
  • WeKnora 已向量化和处理完成的 Wiki、文档、实体、关系、图谱数据默认沉淀到助手知识库;如果导入的是某个自建助手库,也必须同步沉淀到全局大库。
  • 普通知识库需要提供导出或“导入到助手知识库”的功能,把 WeKnora 里已经处理好的数据导入指定助手知识库;导出数据需要包含 Wiki、文档、chunk、实体、关系、图谱。
  • 即使没有配置 WeKnora 地址,也要默认展示助手知识库列表和创建入口,而不是展示空的普通知识库页面。
  • 管理员可切换知识库产品版本:v1 / v2,默认 v1。
  • 助手知识库普通用户只读,管理员可导入、编辑、删除、查看版本和回滚 Wiki 页面。

2. 当前边界

以下能力明确不做,开发实现和验收必须按这些边界收敛:

  • 不支持一次选择多个目标知识库。多知识库归纳通过多次操作完成。
  • 不支持非 Wiki 知识库、FAQ 知识库、系统会话存档知识库、只读知识库作为技能归纳目标。
  • 不直接写 WeKnora 的 Neo4j 或底层图数据库。
  • 不新增自动文件监听、定时后台同步或技能变更自动远程写入。
  • 不在前端提供逐条实体/关系预览审核。
  • 不把远端 WeKnora 内部 ID 暴露为前端业务主键。
  • 不支持技能直接归纳到助手知识库。技能先进入 WeKnora 普通知识库,再由 WeKnora 导出沉淀到助手知识库。
  • 不支持管理员向助手知识库导入任意本地文件;手动导入也必须是 WeKnora 导出包或从某个 WeKnora 知识库触发。
  • 助手知识库 V1 不做页面版本管理,只保留当前合并后的 Wiki 状态和导入审计记录。

3. 术语

术语 含义
技能 DeerFlow 技能目录,通常包含 SKILL.md、代码、配置、示例、文档、数据文件等。
目标知识库 管理员选择的一个 WeKnora Wiki 普通知识库。助手知识库不是技能归纳目标。
普通知识库 WeKnora 知识库,负责向量化、Wiki、文档检索和图谱能力。
助手知识库 DeerFlow 自研知识库类型,支持创建多个库,用于 Wiki 展示、搜索、WeKnora 导入和实体对齐。
知识梳理总库 助手知识库体系中的系统全局大库,有且只有一个,自动统计和沉淀所有助手库与普通知识库导入数据,做全局实体对齐。
自建助手库 管理员创建的普通助手知识库,类似普通知识库列表中的一个库,可导入 WeKnora 普通知识库导出数据。
产品版本 知识库产品形态开关。v1 默认为普通知识库体验,v2 默认为助手知识库体验。
WeKnora 导出包 从普通知识库导出的已处理知识集合,包含 Wiki 页面、文档、chunk、实体、关系、图谱等。
绑定 一个技能与一个目标知识库之间的持久关联。skill_name + target_type + target_id 唯一。
快照 某次扫描技能目录得到的内容版本,包含文件清单、摘要、抽取结果和源 digest。
贡献 某个技能快照对目标知识库内实体、关系、Wiki 页面、原始资料的增量内容。
规范实体 在同一个目标知识库内合并后的实体。多个技能可以贡献到同一个实体。
规范关系 在同一个目标知识库内合并后的关系。多个技能可以给同一关系提供证据。
归纳任务 一次管理员发起的批量操作,可包含多个目标知识库和多个技能 item。
item 归纳任务中的单个技能处理单元。

4. 总体方案

整体采用“双知识库形态 + 本地持久绑定 + 后台任务 + WeKnora 投影 + 助手底库实体对齐”的架构。

flowchart LR
  A[管理员选择多个技能] --> B[选择一个 WeKnora Wiki 目标知识库]
  B --> C[创建归纳任务]
  C --> D[逐技能扫描与解析]
  D --> E[生成技能快照]
  E --> F[LLM 归纳 Wiki 与关系抽取]
  F --> G[按目标 WeKnora Wiki 合并实体/关系]
  G --> H[写入 WeKnora 原始资料与 Wiki]
  G --> I[写入关系投影文档]
  H --> K[校验远端写入]
  I --> K
  K --> L[本地原子激活新版本]
  L --> M[技能页展示已归纳知识库]
  K --> N[WeKnora 导出已处理数据]
  N --> O[导入指定助手知识库]
  O --> P[同步沉淀到知识梳理总库]
  P --> Q[全局实体对齐]
  Q --> S[总库 Wiki 展示与搜索]

关键原则:

  • DeerFlow 本地数据库保存权威绑定关系、版本状态、来源贡献和远端 artifact 映射。
  • WeKnora 保存可检索知识内容,包括原文、Wiki 页面、FAQ、会话存档、关系投影文档和图谱。
  • 不直接写 WeKnora 底层图数据库;关系以 WeKnora API 能力和关系投影文档承接。
  • 重归纳使用 staged artifact,远端写入和校验成功后,本地才激活新版本。
  • 删除或解除关联只影响该技能在目标知识库中的贡献,不误删其他技能共享的实体和关系。
  • 助手知识库可以创建多个库;系统全局大库只有一个,负责汇总全库数据和做跨库实体对齐。
  • WeKnora 的已处理结果可以导入指定助手知识库;无论是否指定自建助手库,都必须同步沉淀到知识梳理总库。
  • 未配置 WeKnora 地址时,默认进入助手知识库页面,展示助手知识库列表、创建入口和知识梳理总库;与 WeKnora 相关的导出导入动作置灰或隐藏。

5. 现有代码落点

实现前必须先读仓库说明:

  • D:/cmzs-clean/deerflow-code/AGENTS.md
  • D:/cmzs-clean/deerflow-code/offline-backend-20260512/backend/AGENTS.md
  • D:/cmzs-clean/deerflow-code/offline-backend-20260512/backend/CLAUDE.md

建议改动位置:

模块 建议文件
后端 router offline-backend-20260512/backend/app/gateway/routers/skill_knowledge.py
后台任务调度 offline-backend-20260512/backend/app/gateway/skill_knowledge_job_dispatcher.py
后台任务执行 offline-backend-20260512/backend/app/gateway/skill_knowledge_job_executor.py
技能归纳核心逻辑 offline-backend-20260512/backend/packages/harness/deerflow/skill_knowledge/
持久化模型 offline-backend-20260512/backend/packages/harness/deerflow/persistence/skill_knowledge/
WeKnora 客户端扩展 offline-backend-20260512/backend/packages/harness/deerflow/integrations/weknora/client.py
助手知识库核心逻辑 offline-backend-20260512/backend/packages/harness/deerflow/assistant_knowledge/
助手知识库持久化 offline-backend-20260512/backend/packages/harness/deerflow/persistence/assistant_knowledge/
助手知识库 Gateway offline-backend-20260512/backend/app/gateway/routers/assistant_knowledge.py
WeKnora 导出到助手库任务 offline-backend-20260512/backend/app/gateway/assistant_knowledge_import_executor.py
前端 API frontend-web/src/strategy-components/api/skill-knowledge.ts
助手知识库前端 API frontend-web/src/strategy-components/api/assistant-knowledge.ts
管理员技能页 frontend-web/src/pages/AdminSkillsPage.tsx
技能行组件 frontend-web/src/components/workspace/settings/skill-settings-page.tsx
WeKnora API hooks frontend-web/src/strategy-components/api/llmwiki.ts
知识库产品版本设置 frontend-web/src/core/system-settings/api.ts

注意边界:

  • packages/harness/deerflow/* 不能 import app.*。
  • 路由、鉴权、FastAPI app state 等放在 app/gateway/*。
  • 纯扫描、解析、抽取、合并、投影计划生成放在 deerflow.*。
  • 文件 IO、Office/PDF 转换、CPU 密集处理必须通过 asyncio.to_thread,避免阻塞事件循环。

6. WeKnora 能力使用策略

现有 WeKnora 客户端已支持:

  • 创建知识库。
  • 上传文件。
  • 导入 URL。
  • 创建手动文档。
  • 创建、更新、删除、查询 Wiki 页面。
  • 获取 Wiki 图谱。

V1 需要新增或补齐:

  • 目标知识库能力探测:是否启用 Wiki,是否可写,是否支持 GraphRAG / extract_config。
  • 目标知识库分类和能力标识:Wiki、非 Wiki、FAQ、会话存档、只读、图谱可写。
  • 导出已处理数据的能力:Wiki 页面、文档、chunk、实体、关系、图谱。
  • WeKnora 处理完成后的自动沉淀触发点:在文件向量化、Wiki 生成和图谱抽取完成后,创建“导入助手知识库”的后台任务。
  • 如果 WeKnora 当前实例 Swagger 暴露了图谱相关配置更新接口,则在目标知识库启用 graph_enabled 与 extract_config。
  • 如果未暴露稳定的实体/关系写入 API,优先使用“关系投影文档 + Wiki 关系页 + Wiki 链接”让 WeKnora 自己抽取图谱;在配置显式开启时,可通过受控 Neo4j direct writer 写入底层图数据库。

参考官方资料:

实现要求:

  • 以部署实例的 Swagger 为准,不要硬编码未确认的远端 API。
  • 可以封装 probe_capabilities(),返回 wiki_enabled、graph_enabled_supported、extract_config_supported、wiki_page_upsert_supported、file_upload_supported 等能力。
  • GraphRAG 失败不能导致 Wiki 归纳整体回滚。Wiki 与原始资料成功、GraphRAG 写入失败时,绑定状态为 partial_failed,错误信息明确写“图谱投影失败,可重新归纳重试”。
  • 如果 WeKnora 不支持直接导出向量、chunk 或图谱原始结构,导出层应退化为读取 Wiki 页面、文档状态、Wiki graph 和可查询的图谱摘要;助手知识库不强依赖复用 WeKnora embedding 向量。

6.1 目标知识库适配策略

一次归纳任务允许选择多个技能和多个目标知识库。后端不要把它当成一个大事务,而是展开为矩阵:

items = selected_skills x selected_targets

每个 item 对应一个 binding,一个技能归纳到三个目标知识库,就生成三个 binding。父 job 负责展示整体进度,item 独立成功、失败、取消和重试。

当目标是自建助手库时,item 写入顺序是:

写入目标助手库 -> 生成目标库 Wiki/实体/关系 -> 创建总库沉淀任务 -> 总库实体对齐和统计

总库沉淀失败不能让目标助手库写入结果消失,但 item 必须标记为 partial_failed,并允许单独重试“沉淀到总库”。

目标知识库需要通过 adapter 写入:

目标类型 写入策略 Wiki 关系/图谱
WeKnora Wiki 知识库 上传原始资料、upsert Wiki 页面、写 graph projection 写 WeKnora Wiki WeKnora GraphRAG + 可选 Neo4j direct writer
WeKnora 非 Wiki 知识库 上传原始资料和归纳文档,不强制生成 Wiki 不写 WeKnora Wiki,可写本地 sidecar Wiki graph projection 文档 + 可选 Neo4j direct writer
WeKnora FAQ 知识库 把归纳结果转换为 FAQ 条目、来源文档和关系摘要 不写或只写 sidecar Wiki 关系作为 FAQ metadata、projection 文档和图谱边
系统会话存档知识库 把技能归纳结果作为系统会话归档条目写入 sidecar Wiki 展示 关系作为归档 metadata 和图谱边
只读 WeKnora 知识库 不修改远端原库;写本地 sidecar artifact,并生成待推送状态 sidecar Wiki 展示 sidecar graph + 待推送 Neo4j plan
助手知识库 写入指定助手库、实体对齐、生成 Wiki 页面版本;同时异步沉淀到知识梳理总库 写自研 Wiki 写自研实体/关系表;总库做跨库实体对齐

只读目标说明:

  • “支持只读知识库作为目标”不代表绕过远端权限强行写入。
  • 对只读 WeKnora,系统创建本地 sidecar 投影:归纳结果与该远端知识库绑定展示,但远端写入状态为 pending_remote_write。
  • 当管理员后续授予可写权限时,可执行“推送到远端”,把 sidecar staged artifact 写入 WeKnora。
  • 前端必须清楚展示“只读目标:已本地归纳,未写入远端”。

6.2 Neo4j 直接写入设计

需求确认需要支持直接写 WeKnora 的 Neo4j 或底层图数据库。该能力风险较高,必须作为受控能力实现。

必须满足:

  • 通过配置显式开启,例如 weknora.graph.direct_write_enabled = true。
  • 只允许管理员触发。
  • Neo4j 连接串、账号、库名只允许后端配置,不允许前端传入。
  • LLM 不得生成任意 Cypher 并直接执行。
  • graph writer 只能执行代码中预定义的参数化模板。
  • 所有写入使用事务。
  • 每个节点和边都带稳定业务 key、来源 binding、snapshot、job、confidence 和 evidence。
  • 支持 dry-run plan、写入审计、失败重试、回滚计划。

节点 key 建议:

provider = deerflow
scope = target_type + target_id
entity_key = entity_type + normalized_name 或 external_id

边 key 建议:

source_entity_key + predicate + target_entity_key + contribution_scope

Neo4j 写入只作为图谱层加速和展示,不替代本地 contribution 表。本地 contribution 表仍是删除、回滚、重建、审计的权威来源。

6.3 实体/关系预览审核

前端必须提供逐条实体/关系预览审核能力。审核发生在“抽取完成、写入目标前”。

审核对象:

  • 实体。
  • 关系。
  • 实体对齐候选。
  • 关系合并候选。
  • Wiki 页面草稿。

管理员操作:

  • 批准。
  • 拒绝。
  • 编辑名称、类型、谓词、别名、摘要、confidence。
  • 批量批准高置信结果。
  • 批量拒绝低置信结果。

审核模式建议:

模式 说明
required 所有实体/关系必须审核后才能写入。
auto_high_confidence 高置信自动通过,低置信进入审核队列。
off 不阻塞写入,但仍保留预览页面和事后审计。

默认建议 auto_high_confidence。如果用户希望“必须逐条审核”,可在系统设置中改为 required。

审核记录必须入库:

  • 操作人。
  • 操作时间。
  • 原始抽取值。
  • 修改后值。
  • 通过或拒绝原因。
  • 对应 job/item/binding/snapshot。

6.4 自动同步设计

需要支持三类自动同步:

  • 文件监听:技能知识文件变化后自动创建归纳任务。
  • 定时同步:按管理员配置的周期重新扫描并归纳。
  • 技能变更自动远程写入:技能保存、启停、导入后触发相关 binding 同步。

自动同步仍需遵守:

  • 只处理非代码知识文件。
  • 代码文件变化不触发归纳。
  • 自动任务必须 debounced,避免保存过程中连续触发。
  • 自动任务必须走 staged 版本,成功后激活,失败保留旧版本。
  • 同一 binding 同一时间只能有一个 active item。
  • 审核模式为 required 时,自动任务停在 awaiting_review,不写远端。

建议新增配置:

{
  "skill_knowledge_auto_sync": {
    "watch_enabled": true,
    "schedule_enabled": true,
    "schedule_cron": "0 */6 * * *",
    "debounce_seconds": 120,
    "write_remote_enabled": true
  }
}

6.5 远端 ID 暴露与业务 key

需求确认前端需要暴露 WeKnora 远端 ID,并可作为跨系统业务 key 使用。

实现要求:

  • API 返回 remote_refs,包含 provider、remote kind、remote id、slug、url。
  • 前端可以展示、复制、筛选远端 ID。
  • 与外部系统交互时,可使用 provider + remote_id 作为业务 key。
  • 本地数据库仍保留 id 作为 surrogate primary key,避免远端 ID 变更导致本地关系断裂。

建议响应结构:

{
  "id": "local-artifact-id",
  "business_key": "weknora:wiki_page:remote-page-id",
  "remote_refs": [
    {
      "provider": "weknora",
      "remote_kind": "wiki_page",
      "remote_id": "remote-page-id",
      "slug": "skills/example/overview",
      "url": "/llmwiki/kb/xxx/wiki/skills/example/overview"
    }
  ]
}

不要把远端 ID 当作唯一存储来源;本地仍需要维护 mapping、审计和状态。

7. 数据处理范围

归纳一个技能时,扫描技能根目录下所有有效的非代码知识文件。代码类文件不作为知识源,也不影响知识 digest。

必须处理:

类型 策略
.md / .mdx / .txt 直接读取,保留标题、段落、链接、表格和自然语言说明;代码块内容默认跳过,只保留“此处存在示例代码”的弱提示。
.json / .yaml / .yml / .toml / .ini 仅当它们承载业务数据、数据字典、枚举、模板或知识配置时处理;运行配置、依赖配置、工具入口、工程配置不入库。
.csv / .tsv 结构化读取,抽样概要 + 全量原始资料上传。
.xlsx / .xls 使用已有文件转换或表格解析能力,保留 sheet、列名、样例和统计。
.pdf / .docx / .pptx 复用现有 deerflow.utils.file_conversion 或 MarkItDown 路径转文本,同时上传原始文件。
图片 上传原始文件;如果已有 VLM/OCR 能力则抽取图片描述,否则记录为二进制附件。
压缩包 安全解压到临时目录后递归处理,必须限制大小、文件数、路径穿越、符号链接。
其他二进制 记录 manifest 并尝试作为原始附件上传;无法解析时不生成文本摘要。

必须排除:

  • .py
  • .ts
  • .tsx
  • .js
  • .jsx
  • .sh
  • .bat
  • .ps1
  • 其他脚本、源码、构建脚本、依赖锁文件
  • .git
  • node_modules
  • __pycache__
  • .pytest_cache
  • dist
  • build
  • 临时缓存目录
  • 明确生成物和大体积模型文件

必须阻断:

  • .env
  • 私钥、公钥私钥对、证书私钥
  • token、password、secret、access key 等高置信密钥文件

阻断规则是安全底线:发现疑似密钥时,该文件不能上传到 WeKnora,也不能进入 LLM prompt。任务 item 标记为 partial_failed 或 failed,前端展示“因安全策略跳过敏感文件”,并给出文件路径,不输出密钥内容。

代码排除规则:

  • 不读取源码内容。
  • 不抽取源码注释。
  • 不抽取函数、类、import、依赖、入口、调用链。
  • 不上传源码文件。
  • 不把源码路径作为 Wiki 知识展示;最多在管理员任务详情中显示“已跳过代码类文件数量”。
  • 计算 source_digest 时只包含知识文件;纯代码变更不应导致技能归纳状态变为 stale。

8. 中间表示 IR

扫描和抽取后生成统一 IR,后续 Wiki 生成、实体合并、远端投影都基于 IR,而不是直接从文件内容临时拼装。

建议结构:

{
  "skill": {
    "name": "example-skill",
    "display_name": "示例技能",
    "description": "从 SKILL.md 和元数据提取",
    "source_root": "skills/public/example-skill",
    "source_digest": "sha256:..."
  },
  "files": [
    {
      "path": "SKILL.md",
      "kind": "markdown",
      "sha256": "...",
      "size": 12345,
      "text_digest": "sha256:...",
      "title": "Example Skill",
      "summary": "文件摘要",
      "anchors": [
        {
          "id": "heading-install",
          "line_start": 12,
          "line_end": 36,
          "text_digest": "sha256:..."
        }
      ],
      "references": [
        {
          "target_path": "data/schema.yaml",
          "evidence": "Markdown link or import",
          "confidence": 1.0
        }
      ],
      "safety": {
        "status": "allowed",
        "warnings": []
      }
    }
  ],
  "entities": [
    {
      "local_id": "ent_001",
      "type": "tool",
      "name": "web_search",
      "aliases": ["网络搜索"],
      "description": "用于检索外部信息的工具",
      "attributes": {
        "entrypoint": "config.yaml tools.web_search"
      },
      "evidence": [
        {
          "file_path": "config.yaml",
          "line_start": 10,
          "line_end": 20,
          "quote": "短证据,不包含敏感信息"
        }
      ],
      "confidence": 0.94
    }
  ],
  "relations": [
    {
      "local_id": "rel_001",
      "source_local_id": "ent_001",
      "predicate": "used_by",
      "target_local_id": "ent_002",
      "description": "web_search 被示例技能用于首步检索",
      "relation_source": "llm_inferred",
      "evidence": [
        {
          "file_path": "SKILL.md",
          "line_start": 22,
          "line_end": 28,
          "quote": "短证据"
        }
      ],
      "confidence": 0.88
    }
  ],
  "wiki": {
    "skill_page": {
      "slug": "skills/example-skill/overview",
      "title": "示例技能",
      "content": "Markdown Wiki 内容"
    },
    "pages": []
  }
}

IR 需要版本化:

  • extractor_version:扫描、解析、提示词和抽取 schema 的整体版本。
  • prompt_hash:LLM 抽取提示词 hash。
  • model_name:抽取模型名。
  • source_digest:技能目录内容 digest。

只要 source_digest + extractor_version + prompt_hash + model_name 相同,就可以复用已有 snapshot,避免 200 个技能批量时反复抽取。

9. 关系抽取规则

关系来源分三类:

来源 示例 置信度策略
确定性结构关系 目录包含文件、Markdown 链接、数据文件引用、业务配置引用 confidence = 1.0
显式文本关系 Markdown 中写明“本技能依赖 A”、“输出 B”、“调用接口 C” LLM 抽取,但要求证据;通常 0.75 以上
模型推断关系 从上下文推断某工具服务于某步骤、某配置控制某行为 必须有证据片段和解释;无证据不得入库

无人工审核的前提下,必须设置阈值:

  • confidence >= 0.75:写入 Wiki 关系页和图谱投影文档。
  • 0.50 <= confidence < 0.75:只写入技能 Wiki 的“可能关系”小节,不进入规范关系。
  • confidence < 0.50:丢弃。

每条关系都必须包含:

  • source
  • predicate
  • target
  • confidence
  • relation_source
  • evidence

如果没有证据路径和证据文本,不允许写入规范关系。

建议谓词归一化:

原始表达 规范 predicate
依赖、需要、requires depends_on
调用、使用、uses uses
生成、输出、produces produces
读取、输入、consumes consumes
配置、控制 configures
包含、目录下有 contains
引用、链接到 references
替换、迁移到 replaces
属于 belongs_to

实现可以先内置有限谓词表,再允许保留 custom_predicate,但 UI 与关系页要展示规范谓词。

10. 同一知识库内的实体合并

实体合并范围只在一个目标知识库内生效,不跨知识库合并。

规范实体 key:

kb_mapping_id + entity_type + normalized_name

normalized_name 规则:

  • Unicode NFKC 归一化。
  • trim。
  • 多空白折叠成单空格。
  • ASCII 字母转小写。
  • 中英文标点归一化。
  • 去除无意义包裹符号,例如反引号、引号。

如果实体带有明确外部 ID,可优先使用:

kb_mapping_id + entity_type + external_id_type + external_id

合并规则:

  • normalized_name 相同且 entity_type 兼容:合并。
  • 名称相同但类型不兼容:不合并,例如 config:web_search 和 tool:web_search 可保持两个实体,必要时用 configures 关系连接。
  • LLM 判断别名合并:只有 confidence >= 0.90 且有明确证据时允许。
  • 属性冲突不做最后写入覆盖,必须按来源保留 provenance。

实体贡献示例:

{
  "canonical_entity_id": "ce_123",
  "binding_id": "bind_001",
  "snapshot_id": "snap_001",
  "local_entity_id": "ent_001",
  "attributes": {
    "entrypoint": {
      "value": "config.yaml tools.web_search",
      "evidence": "config.yaml:10"
    }
  },
  "confidence": 0.94
}

删除贡献时:

  • 只删除该 binding 的贡献。
  • 如果规范实体仍有其他贡献,保留实体页并重新生成聚合内容。
  • 如果规范实体贡献数为 0,删除或标记归档该规范实体及其 Wiki 页面。

11. 关系合并

规范关系 key:

kb_mapping_id + source_canonical_entity_id + normalized_predicate + target_canonical_entity_id

合并规则:

  • 同一 key 的关系合并为一条规范关系。
  • 每个技能的证据作为 relation contribution 追加。
  • confidence 可存储最大值、平均值和证据数,但展示优先显示最高置信证据。
  • 如果来源实体或目标实体被删除到无贡献,相关关系也需要重新计算。

关系 Wiki 页面内容必须保留:

  • 关系三元组。
  • 关系说明。
  • 贡献技能列表。
  • 证据路径。
  • 置信度。
  • 最近更新时间。

12. WeKnora 内容投影

每个技能归纳到一个目标知识库后,按目标 adapter 写入三类内容。目标是 WeKnora 时写入 WeKnora;目标是助手知识库或只读 sidecar 时写入 DeerFlow 自研存储。

12.1 原始资料

原始资料分两种:

  • 可直接上传的文件:走 WeKnora 文件上传。
  • 纯文本或需要展开的内容:创建手动文档,保留路径和 fenced code。

原始资料命名建议:

skills/{skill_name}/source/{relative_path}

文档 metadata 建议:

{
  "source_type": "deerflow_skill",
  "skill_name": "example-skill",
  "binding_id": "bind_001",
  "snapshot_id": "snap_001",
  "source_digest": "sha256:...",
  "relative_path": "SKILL.md",
  "artifact_kind": "raw_source"
}

如果 WeKnora 不支持自定义 metadata,则本地 artifact 表必须保存远端 ID、slug、digest、kind 和来源关系。

12.2 技能 Wiki 页面

每个技能至少生成:

skills/{skill_name}/overview
skills/{skill_name}/files
skills/{skill_name}/entities
skills/{skill_name}/relations
skills/{skill_name}/evidence

内容要求:

  • overview:技能用途、输入、输出、依赖、使用方式、风险提示。
  • files:重要文件清单、每个文件摘要、关键入口。
  • entities:该技能贡献的实体,使用 Wiki 链接指向规范实体页。
  • relations:确定关系和高置信推断关系,使用 Wiki 链接指向规范关系页。
  • evidence:证据目录,只包含短摘录和位置,不包含敏感内容。

12.3 规范实体 Wiki 页面

规范实体页 slug:

entities/{entity_type}/{stable_entity_id}-{slugified_name}

页面内容:

  • 实体名称和类型。
  • 别名。
  • 归并来源技能。
  • 聚合描述。
  • 属性表,冲突属性按来源列出。
  • 相关关系列表。
  • 证据索引。

12.4 规范关系 Wiki 页面

规范关系页 slug:

relations/{predicate}/{stable_relation_id}

页面内容:

  • [[source_entity]] --predicate--> [[target_entity]]
  • 中文说明。
  • 贡献技能。
  • 证据。
  • 置信度。
  • 更新时间。

说明:即便 WeKnora Wiki graph 只能展示无类型链接,关系类型也不能丢。类型和证据由关系页保存,Wiki 链接负责把实体页和关系页连接起来。

12.5 图谱投影文档

为提高 WeKnora GraphRAG 抽取成功率,每个 binding 生成一份机器可读关系文档:

skills/{skill_name}/graph-projection.jsonl

每行一个关系:

{
  "source": "web_search",
  "source_type": "tool",
  "predicate": "used_by",
  "target": "example-skill",
  "target_type": "skill",
  "description": "web_search 被 example-skill 用于首步检索",
  "confidence": 0.88,
  "evidence": "SKILL.md:22-28"
}

同时生成一份人类可读 Markdown:

skills/{skill_name}/graph-projection.md

该文档使用短句和固定模板,降低 WeKnora 抽取歧义:

# 技能关系投影:example-skill

- 实体 `web_search`(tool)与实体 `example-skill`(skill)存在 `used_by` 关系。
  - 说明:web_search 被 example-skill 用于首步检索。
  - 证据:SKILL.md:22-28
  - 置信度:0.88

GraphRAG 可用时上传这些投影文档;Neo4j direct writer 开启时,同时把通过审核的规范实体和关系写入底层图数据库;两者都不可用时仍保留 Wiki 关系页和本地关系表。

13. 重归纳一致性

重归纳必须满足“成功后替换,失败不影响旧版本”。

流程:

  1. 读取当前 binding 和 active snapshot。
  2. 重新扫描技能目录,生成新 snapshot。
  3. 如果 digest 未变化且未强制重归纳,可以直接返回 synced。
  4. 在本地创建 staged artifact 记录。
  5. 写入 WeKnora 新版本原始资料、Wiki 页面、关系投影文档。
  6. 校验远端可读取或状态完成。
  7. 在一个数据库事务中:
    • 将旧 artifact 标记为 retired。
    • 将 staged artifact 标记为 active。
    • 将 binding 的 current_snapshot_id 指向新 snapshot。
    • 更新实体和关系贡献。
    • 设置 binding 状态为 synced 或 partial_failed。
  8. 对旧远端文件执行 best-effort 清理。
  9. 清理失败只记录 warning,不回滚已经激活的新版本。

如果第 5 或第 6 步失败:

  • binding 仍指向旧 snapshot。
  • 旧 WeKnora 内容继续有效。
  • staged artifact 标记为 failed。
  • item 状态为 failed 或 partial_failed。
  • 前端显示错误,允许 retry / 重新归纳。

Wiki 页面建议采用稳定 slug upsert。原始资料如果 WeKnora 没有 update API,则创建新远端文档,确认成功后再删除旧远端文档。

14. 解除关联

解除一个技能与一个知识库的绑定时,前端必须弹窗让管理员选择:

选项 行为
保留知识库内容 绑定标记为 detached_keep。WeKnora 远端内容、助手库 Wiki revision 或 sidecar 内容保留为冻结知识,不再随技能重归纳更新。技能页不再显示为“当前归纳”,但可在历史中显示“已解除,内容保留”。
删除该技能贡献的内容 删除该 binding 的原始资料、技能 Wiki 页、关系投影文档、助手库 Wiki revision contribution、sidecar artifact 和实体/关系贡献;共享实体/关系只减少该技能贡献,仍有其他贡献则重建聚合页,没有贡献才删除。

如果删除远端内容部分失败:

  • 本地记录 artifact delete_failed。
  • binding 状态为 detached_delete_pending_cleanup。
  • 提供“重试清理”动作。

不要因为某个共享实体由该技能参与过,就删除其他技能还在使用的实体页。

15. 状态机

绑定状态建议:

状态 含义
pending 已创建绑定,但尚未开始处理。
queued 已进入任务队列。
running 正在处理。
awaiting_review 抽取完成,等待管理员审核实体、关系或 Wiki 草稿。
synced 当前版本已成功归纳到目标知识库。
pending_remote_write 只读目标已完成本地 sidecar 归纳,等待远端具备写权限后推送。
stale 技能源文件已变化,但尚未手动重新归纳。
partial_failed 核心 Wiki/原始资料成功,但部分文件、图谱或清理失败。
failed 当前归纳失败,旧版本若存在则继续有效。
detached_keep 已解除关联,远端内容保留。
detached_delete_pending_cleanup 已解除关联,但删除远端内容未完全成功。
detached_deleted 已解除关联,远端贡献已清理。

item 阶段建议:

scanning
parsing
summarizing
extracting
awaiting_review
merging
uploading_sources
writing_wiki
writing_graph_projection
verifying
activating
cleanup
completed

前端展示时,父任务进度由 item 数量和阶段加权计算,不要只显示一个不可解释的 spinner。

16. 持久化设计

下面是建议表结构,字段命名可按项目现有风格调整。

16.1 skill_knowledge_bindings

保存技能与知识库的多对多关系。

字段 说明
id UUID。
skill_name 技能名。
target_type weknora / assistant。
target_mode wiki / document / faq / conversation_archive / readonly_sidecar。
target_id 目标知识库 ID。WeKnora 使用本地 mapping ID,助手库使用全局 base ID。
remote_business_key 暴露给前端和外部系统的远端业务 key,例如 weknora:kb:xxx,可为空。
status 绑定状态。
active 是否当前有效绑定。
current_snapshot_id 当前激活的技能快照。
source_digest 最近扫描到的技能源 digest。
synced_digest 最近成功归纳的 digest。
last_job_id 最近一次父任务。
last_item_id 最近一次 item。
last_synced_at 最近成功归纳时间。
last_error_code 最近错误码。
last_error_message 最近错误摘要。
created_by 管理员用户。
created_at / updated_at 时间戳。

约束:

unique(skill_name, target_type, target_id)

16.2 skill_knowledge_snapshots

保存技能扫描和抽取结果。

字段 说明
id UUID。
skill_name 技能名。
source_digest 技能目录 digest。
extractor_version 抽取器版本。
prompt_hash 提示词 hash。
model_name 模型名。
manifest_json 文件清单、hash、安全状态。
ir_json 抽取后的 IR;较大时可存 blob 引用。
status ready / failed。
counts_json 文件数、实体数、关系数、跳过数。
created_at 创建时间。

约束:

unique(skill_name, source_digest, extractor_version, prompt_hash, model_name)

16.3 skill_knowledge_sync_jobs

保存一次批量归纳任务。

字段 说明
id UUID。
target_count 本次目标知识库数量。
targets_json 目标知识库列表,每项包含 target_type、target_mode、target_id、展示名和远端业务 key。
status queued / running / completed / partial_failed / failed / canceled。
total_count 技能数。
success_count 成功数。
partial_failed_count 部分失败数。
failed_count 失败数。
cancel_requested 是否请求取消。
created_by 管理员用户。
created_at / started_at / completed_at 时间戳。

16.4 skill_knowledge_sync_items

保存每个技能的任务项。

字段 说明
id UUID。
job_id 父任务。
binding_id 绑定。
target_type 目标类型。
target_mode 目标模式。
target_id 目标 ID。
skill_name 技能名。
snapshot_id 本次输入快照。
status item 状态。
phase 当前阶段。
progress 0-100。
active_dedupe_key 活跃任务去重 key。
lease_owner 执行器标识。
lease_until 租约过期时间。
attempts 尝试次数。
last_error_code 错误码。
last_error_message 错误摘要。
created_at / updated_at / started_at / completed_at 时间戳。

活跃去重 key:

skill_name + target_type + target_id

同一绑定同一时间只能有一个 active item。

16.5 skill_knowledge_artifacts

保存本地到 WeKnora 的远端 artifact 映射。

字段 说明
id UUID。
target_type 目标类型。
target_mode 目标模式。
target_id 目标 ID。
binding_id 绑定,可为空;规范实体/关系聚合页可只属于知识库。
snapshot_id 来源快照。
scope binding / kb_aggregate。
kind raw_source / skill_wiki / entity_wiki / relation_wiki / graph_projection。
stable_key 本地稳定 key。
remote_kind file / manual_document / wiki_page。
remote_id 远端 ID。后端保存完整映射,前端可按权限展示和复制。
wiki_slug Wiki 页面 slug。
content_hash 写入内容 hash。
version 版本号。
status staged / active / retired / failed / delete_failed。
created_at / updated_at 时间戳。

16.6 skill_knowledge_entities

规范实体表。

字段 说明
id UUID。
target_type 目标类型。
target_mode 目标模式。
target_id 目标 ID。
entity_type 实体类型。
normalized_name 归一化名称。
display_name 展示名称。
aliases_json 别名。
description 聚合描述。
stable_slug Wiki slug。
status active / retired。
created_at / updated_at 时间戳。

约束:

unique(target_type, target_id, entity_type, normalized_name)

16.7 skill_knowledge_entity_contributions

规范实体的技能贡献。

字段 说明
id UUID。
canonical_entity_id 规范实体 ID。
binding_id 绑定。
snapshot_id 快照。
local_entity_id IR 中的实体 ID。
attributes_json 该技能贡献的属性。
evidence_json 证据。
confidence 置信度。
status active / retired。
created_at / updated_at 时间戳。

16.8 skill_knowledge_relations

规范关系表。

字段 说明
id UUID。
target_type 目标类型。
target_mode 目标模式。
target_id 目标 ID。
source_entity_id 源规范实体。
predicate 规范谓词。
target_entity_id 目标规范实体。
description 聚合说明。
stable_slug Wiki slug。
status active / retired。
created_at / updated_at 时间戳。

约束:

unique(target_type, target_id, source_entity_id, predicate, target_entity_id)

16.9 skill_knowledge_relation_contributions

规范关系的技能贡献。

字段 说明
id UUID。
canonical_relation_id 规范关系 ID。
binding_id 绑定。
snapshot_id 快照。
local_relation_id IR 中的关系 ID。
relation_source deterministic / explicit_text / llm_inferred。
evidence_json 证据。
confidence 置信度。
status active / retired。
created_at / updated_at 时间戳。

17. 后台任务设计

参考现有 deep research job 的持久化后台任务模式:

  • 任务入库后返回 202 Accepted。
  • 执行器通过 DB 原子条件 claim item。
  • 每个 item 有 lease_owner、lease_until。
  • 执行中定期 heartbeat。
  • 服务重启后可恢复过期 lease。
  • cancel 使用 cancel_requested,任务在阶段边界检查并安全停止。

并发建议:

  • 同时处理技能数:2 到 4。
  • 同时调用 WeKnora 写入:2 到 3。
  • 同时 LLM 抽取:按系统现有限流,建议默认 2。

200 个技能批量时:

  • 父 job 只保存聚合进度,不串行阻塞 HTTP 请求。
  • 每个技能 item 独立失败、独立重试。
  • 前端按 job polling,不为每个技能单独发 N 个请求。
  • 获取技能列表时批量查 binding summary,避免 N+1。
  • 快照缓存可复用,跨知识库只重新投影,不重复解析同一技能内容。

18. 后端 API 设计

新增 router:

/api/skill-knowledge

所有写接口仅管理员可用。

18.1 获取技能绑定摘要

GET /api/skill-knowledge/bindings?skill_names=a,b,c

返回:

{
  "items": [
    {
      "skill_name": "example-skill",
      "knowledge_bases": [
        {
          "binding_id": "bind_001",
          "target_type": "weknora",
          "target_mode": "wiki",
          "target_id": "local-kb-id",
          "knowledge_base_name": "作战知识库",
          "remote_business_key": "weknora:kb:remote-kb-id",
          "status": "synced",
          "last_synced_at": "2026-08-31T10:00:00Z",
          "source_digest": "sha256:...",
          "synced_digest": "sha256:...",
          "stale": false
        }
      ]
    }
  ]
}

18.2 创建归纳任务

POST /api/skill-knowledge/sync-jobs

请求:

{
  "skill_names": ["skill-a", "skill-b"],
  "targets": [
    {
      "target_type": "weknora",
      "target_mode": "wiki",
      "target_id": "local-kb-id"
    },
    {
      "target_type": "assistant",
      "target_mode": "wiki",
      "target_id": "assistant-global-base"
    }
  ],
  "force": false
}

行为:

  • 校验管理员。
  • 校验技能存在。
  • 校验目标知识库存在,并解析目标 adapter。
  • 对只读目标创建 sidecar binding,不强行写远端。
  • 对每个 skill x target upsert binding。
  • 创建父 job 和 item。
  • 如果同一 binding 已有 active item,返回当前 item,不重复创建。
  • 返回 202。

返回:

{
  "job_id": "job_001",
  "status": "queued",
  "skill_count": 2,
  "target_count": 2,
  "total_count": 4,
  "items": [
    {
      "item_id": "item_001",
      "skill_name": "skill-a",
      "target_type": "weknora",
      "target_mode": "wiki",
      "target_id": "local-kb-id",
      "binding_id": "bind_001",
      "status": "queued"
    }
  ]
}

18.3 查询任务

GET /api/skill-knowledge/sync-jobs/{job_id}

返回父 job、item 列表、每个 item 当前阶段、错误摘要、绑定结果。

18.4 取消任务

POST /api/skill-knowledge/sync-jobs/{job_id}/cancel

设置 cancel_requested = true。已激活成功的 item 不回滚;未完成 item 在阶段边界停止。

18.5 重试 item

POST /api/skill-knowledge/sync-items/{item_id}/retry

只允许失败或部分失败 item。重试复用原 binding。

18.6 对单个绑定重新归纳

POST /api/skill-knowledge/bindings/{binding_id}/resync

请求:

{
  "force": true
}

行为:创建一个只包含该 binding 的新 job。

18.7 解除关联

建议使用显式 POST,避免 DELETE body 兼容性问题:

POST /api/skill-knowledge/bindings/{binding_id}/detach

请求:

{
  "remote_content_action": "keep"
}

或:

{
  "remote_content_action": "delete"
}

返回解除结果、清理状态和仍被共享的实体/关系数量。

18.8 知识库反查技能

GET /api/skill-knowledge/knowledge-bases/{knowledge_base_id}/skills

用于知识库详情页展示“该知识库由哪些技能归纳而来”。

18.9 可选:源状态扫描

POST /api/skill-knowledge/source-status

请求:

{
  "skill_names": ["skill-a", "skill-b"],
  "knowledge_base_id": "local-kb-id"
}

只做本地快速 fingerprint 比对,标记是否可能 stale,不写 WeKnora。

18.10 审核队列

GET /api/skill-knowledge/reviews?job_id=xxx
POST /api/skill-knowledge/reviews/{review_id}/approve
POST /api/skill-knowledge/reviews/{review_id}/reject
PUT /api/skill-knowledge/reviews/{review_id}
POST /api/skill-knowledge/reviews/bulk-approve
POST /api/skill-knowledge/reviews/bulk-reject

审核通过后 item 才能进入写入阶段。审核模式为 off 时,接口仍保留预览和审计能力。

18.11 自动同步配置

GET /api/skill-knowledge/auto-sync-settings
PUT /api/skill-knowledge/auto-sync-settings
POST /api/skill-knowledge/bindings/{binding_id}/enable-auto-sync
POST /api/skill-knowledge/bindings/{binding_id}/disable-auto-sync

自动同步设置只允许管理员修改。

19. 前端交互设计

19.1 技能管理页

在 AdminSkillsPage.tsx 的“技能列表”页签增加:

  • 技能行 checkbox。
  • 顶部批量操作按钮:“归纳到知识库”。
  • 支持全选当前页、清空选择。
  • 选择状态跨前端分页保留。
  • 技能较多时保持现有搜索/过滤能力。

点击“归纳到知识库”打开弹窗:

  • 显示已选技能数量。
  • 多选目标知识库。
  • 按类型分组展示:WeKnora Wiki、WeKnora 非 Wiki、FAQ、系统会话存档、只读 sidecar、助手知识库。
  • 只读目标要展示“本地归纳,暂不写远端”的状态说明。
  • 助手知识库作为目标时,提示“直接写入知识梳理底库,不经过 WeKnora”。
  • 二次确认文案说明:“将生成原始资料、Wiki 页面和关系内容;抽取完成后进入实体/关系预览审核。”

提交后:

  • 创建后台 job。
  • 跳转或打开“归纳任务”抽屉/页签。
  • 展示总进度、成功、失败、部分失败。
  • 任务运行中每 2-3 秒 polling。
  • item 到达 awaiting_review 时,显示“待审核”并提供审核入口。

19.1.1 实体/关系审核页

审核页按 job 聚合展示:

  • 左侧筛选:技能、目标知识库、类型、置信度、来源。
  • 中间列表:实体、关系、实体对齐候选、关系合并候选、Wiki 草稿。
  • 右侧详情:原始值、模型解释、证据、目标写入位置。

管理员可以:

  • 单条批准、拒绝、编辑。
  • 批量批准高置信结果。
  • 批量拒绝低置信结果。
  • 修改实体类型、名称、别名。
  • 修改关系 predicate、说明、confidence。
  • 查看远端 ID 或 sidecar ID。

审核完成后,任务继续写入目标知识库。

19.2 技能行提示

SkillRow 增加归纳状态区域:

  • 未归纳:不显示或显示弱提示“未归纳”。
  • 已归纳:显示 已归纳至 N 个知识库。
  • 展开或悬浮可看到知识库 chips:
    • 知识库名称
    • 状态
    • 最近归纳时间
    • stale 标识

每个绑定提供动作:

  • 查看知识库。
  • 重新归纳。
  • 解除关联。
  • 失败时重试。

状态建议:

状态 UI 文案
synced 已归纳
stale 待重新归纳
running 归纳中
partial_failed 部分完成
failed 失败
detached_keep 已解除,内容保留

19.3 解除关联弹窗

弹窗必须让管理员明确选择:

  • 保留知识库内容。
  • 删除该技能贡献的内容。

弹窗文案应提醒:

  • 删除只删除该技能贡献,不删除其他技能共享的实体与关系。
  • 若删除远端内容失败,可稍后重试清理。

19.4 归纳任务页签

建议在管理员技能管理页新增第三个页签:

技能列表 | 技能地址管理 | 归纳任务

任务列表显示:

  • 创建时间。
  • 目标知识库。
  • 操作人。
  • 总技能数。
  • 成功 / 部分失败 / 失败。
  • 状态。
  • 操作:查看详情、取消、重试失败项。

详情显示 item:

  • 技能名。
  • 目标知识库。
  • 目标类型。
  • 当前阶段。
  • 进度。
  • 错误摘要。
  • 绑定状态。

19.6 自动同步设置

管理员可在技能归纳设置中配置:

  • 是否开启文件监听。
  • 是否开启定时同步。
  • 同步周期。
  • 自动写远端开关。
  • 审核模式。
  • 单个 binding 是否参与自动同步。

19.5 知识库详情反向展示

如果现有 WeKnora / LLM Wiki 页面有知识库详情入口,增加“来源技能”区域:

  • 技能名。
  • 归纳状态。
  • 最近归纳时间。
  • 查看技能。
  • 重新归纳。

20. stale 检测与自动同步

系统既要支持手动重新归纳,也要支持自动同步。stale 检测负责判断“源知识文件是否变化”;自动同步负责在配置允许时创建后台任务并远程写入。

本地标识 stale:

  • 技能编辑、启停、删除等已知写操作完成后,查找相关 binding 并标记 stale。
  • 技能列表加载时可做轻量 fingerprint:路径、大小、mtime。
  • 真正归纳时计算完整 SHA digest。
  • 如果归纳过程中源文件变化,最终激活前再次校验 expected digest;不一致则失败并标记 stale,避免一个版本混入两次源内容。
  • 代码文件和脚本文件不参与 fingerprint,也不触发 stale。

自动同步:

  • 当 watch_enabled 开启时,知识文件变化后自动创建相关 binding 的归纳任务。
  • 当 schedule_enabled 开启时,scheduler 按周期扫描并归纳 stale binding。
  • 当技能保存、导入、删除或启停时,可触发相关 binding 的自动任务。
  • 自动任务必须遵循审核模式;如果需要审核,任务停在 awaiting_review。
  • 自动任务必须遵循 staged 激活;失败不覆盖旧版本。

21. 权限与安全

权限:

  • 所有归纳、重归纳、解除关联、取消、重试接口仅管理员。
  • 读接口如果包含后台任务错误或源文件路径,也建议仅管理员。

文件安全:

  • 技能根必须限制在 skills/public 或 skills/custom。
  • 禁止路径穿越。
  • 默认不跟随 symlink;如果要支持 symlink,必须确认 resolved path 仍在技能根内。
  • 压缩包解压必须限制总大小、文件数量、单文件大小、目录层级。
  • 不执行技能代码。
  • 不读取或上传密钥文件。
  • 日志和错误信息不得包含文件全文、token、secret。

远端安全:

  • 不新增外部 URL 抓取能力。
  • 如果技能内容中包含 URL,只作为文本关系或知识内容处理,不主动访问。
  • WeKnora 调用失败时,记录错误摘要和 request id,不记录认证头。

22. LLM 抽取设计

抽取可分两级:

  • 小技能:一次性把文本摘要和结构信息送入模型。
  • 大技能:先按文件或章节生成局部摘要与候选实体关系,再合并。

提示词需要明确:

  • 只基于提供的内容抽取,不凭空编造。
  • 允许推断,但推断必须有 evidence。
  • 输出必须符合 JSON schema。
  • 不输出敏感信息。
  • 关系必须有 confidence。
  • 低置信关系要标记,不进入规范关系。

建议 schema:

{
  "summary": {
    "purpose": "技能用途",
    "inputs": ["输入"],
    "outputs": ["输出"],
    "usage": "使用方式",
    "risks": ["风险"]
  },
  "entities": [
    {
      "id": "ent_001",
      "type": "skill|tool|api|file|config|dataset|concept|workflow|external_system|output",
      "name": "实体名",
      "aliases": [],
      "description": "描述",
      "attributes": {},
      "evidence": [
        {
          "file_path": "SKILL.md",
          "line_start": 1,
          "line_end": 3,
          "quote": "短证据"
        }
      ],
      "confidence": 0.9
    }
  ],
  "relations": [
    {
      "id": "rel_001",
      "source_entity_id": "ent_001",
      "predicate": "uses",
      "target_entity_id": "ent_002",
      "description": "关系描述",
      "relation_source": "explicit_text|llm_inferred",
      "evidence": [],
      "confidence": 0.86
    }
  ]
}

模型输出后必须做程序校验:

  • JSON schema 校验。
  • entity id 存在性校验。
  • relation source/target 必须存在。
  • evidence path 必须来自本次 manifest。
  • confidence 必须在 0 到 1。
  • 敏感内容二次扫描。

23. 后端实现步骤

建议按以下顺序实现。

23.1 持久化层

新增 deerflow.persistence.skill_knowledge:

  • SQL model。
  • memory store,用于测试或无 DB 环境。
  • repository API。
  • migration 或 create_all 接入。

Repository API 建议:

class SkillKnowledgeStore:
    async def upsert_binding(...)
    async def list_bindings(...)
    async def create_job(...)
    async def create_items(...)
    async def claim_next_item(...)
    async def heartbeat_item(...)
    async def complete_item(...)
    async def fail_item(...)
    async def create_or_get_snapshot(...)
    async def stage_artifacts(...)
    async def activate_snapshot(...)
    async def detach_binding(...)

23.2 扫描与解析

新增:

deerflow/skill_knowledge/scanner.py
deerflow/skill_knowledge/parsers.py
deerflow/skill_knowledge/safety.py
deerflow/skill_knowledge/digest.py

输出 manifest 和初始文本块。

23.3 抽取与归纳

新增:

deerflow/skill_knowledge/extractor.py
deerflow/skill_knowledge/wiki_builder.py

职责:

  • 构造 prompt。
  • 调用项目已有模型封装。
  • 解析 JSON。
  • 校验 schema。
  • 构建技能 Wiki 页面内容。

23.4 实体关系合并

新增:

deerflow/skill_knowledge/merge.py

职责:

  • 名称归一化。
  • 实体 upsert。
  • 关系 upsert。
  • 贡献增删。
  • 共享实体/关系重建计划。

23.5 WeKnora 投影

新增:

deerflow/skill_knowledge/projector.py
deerflow/skill_knowledge/target_adapters.py
deerflow/skill_knowledge/graph_writer.py

职责:

  • 根据 IR 和聚合结果生成 artifact plan。
  • 按目标知识库类型选择 adapter。
  • 调用 WeKnora client 上传原文、FAQ、会话归档或 Wiki 页面。
  • 为只读目标写本地 sidecar artifact。
  • 上传 graph projection docs。
  • 在配置允许时通过受控 graph writer 写 Neo4j。
  • 校验远端状态。

23.6 Gateway

新增:

app/gateway/routers/skill_knowledge.py
app/gateway/skill_knowledge_job_dispatcher.py
app/gateway/skill_knowledge_job_executor.py
app/gateway/skill_knowledge_watcher.py
app/gateway/skill_knowledge_scheduler.py

在 app 初始化中注册:

  • store。
  • dispatcher。
  • watcher。
  • scheduler。
  • router。

23.7 前端

新增:

frontend-web/src/strategy-components/api/skill-knowledge.ts
frontend-web/src/components/workspace/skills/skill-knowledge-sync-dialog.tsx
frontend-web/src/components/workspace/skills/skill-knowledge-bindings.tsx
frontend-web/src/components/workspace/skills/skill-knowledge-jobs-panel.tsx

修改:

  • AdminSkillsPage.tsx:技能列表批量选择、归纳弹窗、归纳任务页签。
  • skill-settings-page.tsx:SkillRow 展示归纳知识库 chips 和操作。
  • 知识库详情页:展示来源技能。

23.8 助手知识库

新增:

offline-backend-20260512/backend/packages/harness/deerflow/assistant_knowledge/
offline-backend-20260512/backend/packages/harness/deerflow/persistence/assistant_knowledge/
offline-backend-20260512/backend/app/gateway/routers/assistant_knowledge.py
offline-backend-20260512/backend/app/gateway/assistant_knowledge_import_executor.py
frontend-web/src/strategy-components/api/assistant-knowledge.ts
frontend-web/src/pages/AssistantKnowledgePage.tsx

职责:

  • 初始化唯一全局助手知识库“知识梳理”。
  • 从 WeKnora 导出包导入 Wiki、文档、chunk、实体、关系、图谱。
  • 做全局实体对齐和关系合并。
  • 生成助手库 Wiki 页面。
  • 建立搜索索引。
  • 支持普通用户只读、管理员导入和维护。
  • 支持知识库产品版本 v1 / v2 切换。

23.9 审核队列

新增:

offline-backend-20260512/backend/packages/harness/deerflow/persistence/skill_knowledge/review_model.py
frontend-web/src/components/workspace/skills/skill-knowledge-review-panel.tsx

职责:

  • 保存实体、关系、对齐候选、Wiki 草稿的审核项。
  • 支持批准、拒绝、编辑、批量处理。
  • 审核完成后唤醒对应 item 继续写入。
  • 保留完整审计。

24. 测试计划

后端测试:

测试 覆盖点
test_skill_knowledge_scanner.py 文件扫描、排除目录、敏感文件阻断、压缩包安全。
test_skill_knowledge_extractor.py LLM 输出 schema 校验、低置信关系过滤、证据路径校验。
test_skill_knowledge_entity_merge.py 同知识库实体合并、跨知识库不合并、属性冲突 provenance。
test_skill_knowledge_repository.py 绑定唯一、多对多、状态机、detach keep/delete。
test_skill_knowledge_jobs.py job/item claim、lease、重试、取消、崩溃恢复、200 item 聚合进度。
test_skill_knowledge_weknora_projection.py Wiki slug upsert、artifact staged/active、GraphRAG 不可用 partial_failed。
test_skill_knowledge_api.py 管理员鉴权、目标知识库校验、创建任务、查询任务、解除关联。
test_skill_knowledge_target_adapters.py Wiki、非 Wiki、FAQ、会话存档、只读 sidecar、助手库目标写入。
test_skill_knowledge_review.py 实体/关系逐条审核、编辑、批量批准、审核阻塞写入。
test_skill_knowledge_auto_sync.py 文件监听、定时同步、代码文件变化不触发、staged 自动写入。
test_skill_knowledge_graph_writer.py Neo4j 参数化写入、事务、审计、回滚计划、禁用任意 Cypher。
test_assistant_knowledge_repository.py 唯一全局底库、来源、导入任务、实体关系贡献。
test_assistant_knowledge_import.py WeKnora 导出包导入、实体对齐、关系合并、搜索索引。
test_assistant_knowledge_api.py 普通用户只读、管理员写入、未配置 WeKnora 场景。

前端测试:

  • 管理员技能页可以多选技能并打开知识库选择弹窗。
  • 知识库选择弹窗支持多选目标,包含 Wiki、非 Wiki、FAQ、会话存档、只读 sidecar 和助手知识库。
  • 创建 job 后显示进度并 polling。
  • 抽取后进入实体/关系审核页,审核通过后继续写入。
  • 技能行展示已归纳知识库 chips。
  • 重归纳按钮调用正确接口。
  • 解除关联弹窗必须选择 keep/delete。
  • 200 个技能绑定摘要使用批量接口,不触发 N+1。
  • 未配置 WeKnora 时仍能展示助手知识库初始化入口。
  • 普通知识库详情页可触发导入到助手知识库。
  • 助手知识库搜索、Wiki 页面、来源列表按权限展示。

建议命令:

cd offline-backend-20260512/backend
PYTHONPATH=. uv run pytest tests/test_skill_knowledge_*.py -v
PYTHONPATH=. uv run pytest tests/test_harness_boundary.py -v
cd frontend-web
pnpm typecheck
pnpm test -- skill-knowledge

25. 验收场景

必须通过:

  • 管理员选择 3 个技能归纳到 2 个目标知识库,生成 1 个 job、6 个 item、6 个 binding。
  • 同一个技能随后归纳到另一个知识库,新增第二个 binding,技能行显示已归纳至 2 个知识库。
  • 技能可以直接归纳到助手知识库,并生成实体对齐、Wiki 页面版本和搜索索引。
  • 同一个技能同一个 digest 重复归纳,不产生重复 Wiki 页面或重复实体关系。
  • 两个技能在同一知识库中抽取出同名同类型实体,只生成一个规范实体页,并列出两个贡献技能。
  • 解除其中一个技能并选择删除内容后,共享实体仍保留另一个技能贡献。
  • 关系必须带 evidence 和 confidence;低于 0.75 的推断关系不进入规范关系。
  • 重归纳成功后,新版本替换旧版本;旧 artifact 进入 retired。
  • 重归纳失败时,旧版本继续显示为当前版本。
  • 解除关联选择保留内容后,远端 Wiki 和文档保留,但 binding 不再参与后续重归纳。
  • 非管理员访问写接口返回 403。
  • 非 Wiki、FAQ、系统会话存档知识库可作为目标,并通过对应 adapter 写入。
  • 只读知识库可作为目标,结果写入本地 sidecar,远端状态显示 pending_remote_write。
  • 直接 Neo4j 写入只在配置开启时执行,且只使用参数化 graph writer。
  • 自动文件监听和定时同步可以创建后台任务,代码文件变化不会触发同步。
  • 前端可逐条审核实体/关系,也可按策略批量处理。
  • 前端展示 WeKnora 远端 ID,并可复制业务 key。
  • WeKnora GraphRAG 不可用时,原始资料和 Wiki 成功,状态为 partial_failed,可重试图谱投影。
  • 200 个技能批量归纳时,页面显示整体进度,失败技能可单独重试,后端没有 N+1 查询。
  • 技能中出现 .env 或私钥时,该文件不上传、不进 prompt,页面显示安全跳过。
  • 技能中的 .py、.ts、.sh 等代码文件不读取、不上传、不摘要,代码文件变化不触发知识 stale。
  • 未配置 WeKnora 时,助手知识库仍可初始化和查看。
  • 管理员可从普通知识库触发导入到助手知识库。
  • 管理员可向助手知识库导入本地文件,安全扫描通过后生成 Wiki 页面版本。
  • WeKnora 导出包中的 Wiki、文档、chunk、实体、关系、图谱都能进入助手底库。
  • 助手底库把多个来源中的同一人或同一对象合并为一个实体 Wiki 页。
  • 助手 Wiki 支持历史版本、对比和回滚。
  • 助手知识库普通用户只读,管理员可导入、重导、删除来源。

26. 分阶段交付

第一阶段:数据模型与 API 骨架

  • 建表和 store。
  • 绑定列表、创建 job、查询 job、detach API。
  • 管理员鉴权。
  • 前端技能行能展示空绑定状态。

第二阶段:扫描、快照与后台任务

  • 技能目录扫描。
  • 文件 digest 和 manifest。
  • job/item 执行器、lease、heartbeat、失败重试。
  • 200 技能批量进度。

第三阶段:Wiki 归纳与原始资料上传

  • LLM 摘要和 Wiki 页面生成。
  • WeKnora 原文上传。
  • Wiki page upsert。
  • staged/active 替换。

第四阶段:实体关系合并与关系投影

  • 规范实体和关系表。
  • contribution 机制。
  • 关系 Wiki 页面。
  • graph projection docs。
  • GraphRAG 能力探测和 partial_failed。

第五阶段:完整前端体验

  • 多选技能归纳弹窗。
  • 归纳任务页签。
  • 技能行 chips、详情、重归纳、解除关联。
  • 知识库详情来源技能反查。

第六阶段:安全、测试、文档收口

  • 敏感文件阻断。
  • 压缩包安全。
  • 崩溃恢复。
  • README / CLAUDE 更新。
  • 后端和前端测试。

第七阶段:助手知识库与产品版本

  • 新增唯一全局助手知识库“知识梳理”。
  • 新增 WeKnora 导出到助手库导入任务。
  • 新增技能直接导入助手知识库。
  • 新增管理员本地文件导入助手知识库。
  • 新增助手库实体对齐、关系合并和 Wiki 展示。
  • 新增助手库搜索。
  • 新增助手库 Wiki 页面版本管理、对比和回滚。
  • 新增知识库产品版本 v1 / v2 切换。
  • 处理未配置 WeKnora 时的助手库默认展示。

第八阶段:多目标、审核、自动同步和底层图写入

  • 支持一次选择多个目标知识库。
  • 支持非 Wiki、FAQ、系统会话存档和只读目标 adapter。
  • 支持实体/关系逐条审核。
  • 支持文件监听、定时同步、技能变更自动远程写入。
  • 支持受控 Neo4j direct writer。
  • 支持远端 WeKnora ID 作为业务 key 暴露给前端。

27. 给实现大模型的硬性指令

实现时必须遵守:

  • 先完整阅读根目录 AGENTS.md、后端 AGENTS.md、后端 CLAUDE.md。
  • 不要回滚用户已有改动。
  • 支持直接写 WeKnora 的 Neo4j,但必须通过受控 graph writer、显式配置、参数化模板、事务和审计。
  • 支持把远端 WeKnora ID 作为前端业务 key 暴露,但本地仍保留 surrogate id。
  • 不要让 deerflow.* import app.*。
  • 不要执行技能里的代码。
  • 不要读取、上传、摘要或展示技能里的代码文件、脚本文件和代码块内容。
  • 不要上传或提示词输入密钥文件。
  • 技能可以直接归纳到助手知识库,必须走同样的安全扫描、审核和实体对齐。
  • 不要创建多个助手知识库;助手知识库只有一个全局“知识梳理”底库。
  • 自动 watcher、定时同步和技能变更远程写入必须使用 staged 激活、去重、审核和失败保留旧版本。
  • 重归纳必须 staged 写入,成功后再激活。
  • 删除绑定贡献时必须按 contribution refcount 处理共享实体和关系。
  • 助手知识库需要 Wiki 页面版本管理、版本对比、回滚和导入任务审计。
  • 直接写 Neo4j 必须通过受控 graph writer 和参数化模板,不允许执行 LLM 生成的任意 Cypher。
  • 远端 WeKnora ID 可以作为前端业务 key 暴露,但本地仍要保留 surrogate id 和 mapping。
  • 后端代码变更后按仓库要求更新相关 README / CLAUDE。
  • 涉及文件编辑使用 apply_patch 或项目正常格式化工具,不做无关重构。

28. 实现任务清单

  • 新增 skill_knowledge 持久化模型和 store。
  • 新增绑定、job、item、artifact、entity、relation、contribution 表。
  • 新增管理员 router /api/skill-knowledge。
  • 接入知识库能力校验,支持 Wiki、非 Wiki、FAQ、会话存档、只读 sidecar 和助手知识库。
  • 支持一次选择多个目标知识库,并按 技能 x 目标 生成 item。
  • 新增技能扫描器,支持全部非代码知识文件、安全排除和 digest。
  • 技能扫描器完全排除代码文件、脚本文件和 Markdown 代码块内容。
  • 新增 snapshot 缓存。
  • 新增 LLM 抽取器,输出 schema 校验。
  • 新增 Wiki 页面生成器。
  • 新增实体归一化与合并逻辑。
  • 新增关系归一化与合并逻辑。
  • 新增 WeKnora artifact projector。
  • 新增 target adapters。
  • 新增 graph projection 文档生成和上传。
  • 新增受控 Neo4j direct graph writer。
  • 新增实体/关系审核队列。
  • 新增后台 job dispatcher / executor。
  • 新增文件 watcher、定时同步 scheduler、技能变更自动写入触发。
  • 实现 resync 成功替换、失败保留旧版本。
  • 实现 detach keep/delete。
  • 技能变更后标记 binding stale。
  • 前端新增 skill-knowledge.ts API。
  • 技能管理页新增多选归纳入口。
  • 新增选择知识库弹窗。
  • 新增归纳任务页签。
  • 技能行展示已归纳知识库状态。
  • 实现重归纳、重试、取消、解除关联 UI。
  • 知识库详情展示来源技能。
  • 新增唯一全局助手知识库“知识梳理”。
  • 新增助手知识库持久化模型、来源、导入任务、Wiki、实体、关系、贡献表。
  • 新增 WeKnora 导出到助手知识库任务。
  • 支持技能直接导入助手知识库。
  • 支持管理员本地文件导入助手知识库。
  • 导出范围覆盖 Wiki、文档、chunk、实体、关系、图谱。
  • 助手知识库实现全局实体对齐和关系合并。
  • 助手知识库生成 Wiki 页面并支持搜索。
  • 助手知识库支持 Wiki 页面版本管理、对比、发布和回滚。
  • 新增知识库产品版本 v1 / v2 设置,默认 v1。
  • 未配置 WeKnora 时仍展示助手知识库创建或初始化入口。
  • 助手知识库普通用户只读,管理员可导入、重导、删除。
  • 后端测试覆盖核心状态机和安全边界。
  • 前端测试覆盖主要交互。
  • 更新后端 README / CLAUDE 与必要前端文档。

29. 风险与处理

风险 处理
WeKnora 图谱 API 在部署版本不稳定 以 Swagger 能力探测为准;Wiki 关系页和 graph projection 文档作为稳定方案。
LLM 推断关系误判 强制 evidence、confidence 阈值、低置信不进入规范关系。
200 技能批量耗时长 后台 job、item 并发、snapshot 缓存、前端批量查询。
重归纳中断导致新旧混杂 staged artifact + 本地事务激活 + 失败保留旧版本。
删除共享实体误删其他技能知识 contribution refcount,删除只移除该 binding 贡献。
敏感信息进入知识库 文件级安全阻断、prompt 前二次扫描、日志脱敏。
技能目录处理阻塞 Gateway 文件 IO 和转换统一 asyncio.to_thread。
技能源文件归纳中变化 expected digest 校验,不一致则失败并标记 stale。

30. 新增:普通知识库与助手知识库双体系

本节是基于新需求的补充设计。后续实现以本节为准;如果本节与前文旧的 WeKnora-only 表述冲突,优先采用本节。

30.1 产品形态

系统需要区分两类知识库:

类型 存储 用途 可见性 写入来源
普通知识库 WeKnora 文档向量化、Wiki、检索、图谱、技能归纳目标 按现有 WeKnora 逻辑 技能归纳、现有 WeKnora 导入
助手知识库 DeerFlow 自研库 全局知识梳理、实体对齐、Wiki 展示、搜索、版本管理 所有人可见,普通用户只读 WeKnora 导出、WeKnora 自动沉淀、技能直接归纳、管理员本地文件导入

产品版本开关:

  • v1:默认值,优先展示现有普通知识库体验。
  • v2:优先展示助手知识库体验。
  • 管理员可在系统设置中切换版本。
  • 如果未配置 WeKnora,即使当前版本默认是 v1,页面也应展示助手知识库创建/初始化入口;WeKnora 相关能力隐藏或置灰,并提示“未配置普通知识库服务”。

建议新增系统设置项:

{
  "knowledge_base_product_version": "v1"
}

30.2 助手知识库定位

助手知识库只有一个全局底库,建议默认名:

知识梳理

它不是 WeKnora 的另一个知识库,也不向 WeKnora 写数据。它是 DeerFlow 自己维护的结构化知识底库。

助手知识库对用户展示:

  • Wiki 页面列表。
  • Wiki 页面详情。
  • Wiki 页面版本、对比和回滚。
  • 实体页。
  • 关系页。
  • 搜索。
  • 数据导入记录。

助手知识库内部可以存实体、关系、贡献、来源、搜索索引,但前端主体验以 Wiki 为中心,不做复杂图数据库管理页。

权限:

  • 普通用户:可查看、搜索。
  • 管理员:可初始化助手知识库、从 WeKnora 导入、重新导入、删除导入来源、编辑或删除 Wiki 页面。

30.3 数据来源

助手知识库的数据来源包括 WeKnora、技能归纳和管理员本地文件。

支持四种触发方式:

方式 说明
自动沉淀 WeKnora 普通知识库完成文档向量化、Wiki 生成和图谱抽取后,默认创建一个导入任务,把处理结果沉淀到助手知识库。
手动导入 管理员在普通知识库页面点击“导入到助手知识库”或“导出到知识梳理”,本质仍是导出 WeKnora 数据后导入助手库。
技能直接归纳 管理员在技能管理页选择助手知识库作为目标,系统直接写入自研助手底库。
本地文件导入 管理员在助手知识库页面上传本地文件,系统安全扫描后抽取实体、关系和 Wiki 页面。

限制:

  • 普通用户不能写入助手知识库。
  • 本地文件导入必须走敏感信息扫描、文件类型白名单、大小限制和导入审计。
  • 技能直接归纳仍然完全排除代码文件、脚本文件和 Markdown 代码块内容。

30.4 WeKnora 导出范围

从 WeKnora 导入助手知识库时,需要尽可能导出全部已处理数据:

  • 知识库元数据。
  • Wiki 页面。
  • Wiki 页面之间的链接。
  • 已上传文档信息。
  • 已向量化完成的 chunk 文本、chunk metadata、来源文档映射。
  • WeKnora 可读取的实体。
  • WeKnora 可读取的关系。
  • WeKnora 可读取的图谱节点和边。
  • 技能归纳产生的 source metadata,例如 skill_name、binding_id、snapshot_id。

说明:

  • 助手知识库不强依赖复用 WeKnora embedding 向量。若 WeKnora 不暴露 embedding 原始向量,导入 chunk 文本和 metadata 即可。
  • 如果 WeKnora 不暴露稳定的图谱导出 API,则使用现有 Wiki graph、关系投影文档、Wiki 关系页和可查询接口重建实体关系。
  • 导入过程要记录能力缺失:例如“已导入 Wiki 与文档,图谱 API 不可用,关系由 Wiki 关系页重建”。

导出包建议:

{
  "export_id": "wk_export_001",
  "source": {
    "type": "weknora",
    "knowledge_base_id": "local-kb-id",
    "knowledge_base_name": "作战知识库",
    "exported_at": "2026-09-01T10:00:00Z"
  },
  "wiki_pages": [],
  "documents": [],
  "chunks": [],
  "entities": [],
  "relations": [],
  "graph": {
    "nodes": [],
    "edges": []
  }
}

30.5 助手库实体对齐

助手知识库的核心价值是把来自不同 WeKnora 普通知识库、不同技能来源、不同 Wiki 页中的同一实体合并。

实体对齐范围是全局助手库:

assistant_base_id + entity_type + normalized_name

如果存在更强 ID,则优先:

assistant_base_id + entity_type + external_id_type + external_id

对齐规则:

  • 确定性同一:证件号、统一社会信用代码、装备编号、系统唯一 ID 等完全一致,直接合并。
  • 高置信名称同一:同类型实体 normalized name 一致,合并。
  • 模型推断同一:允许模型判断“张三”“张三同志”“Zhang San”是否同一人,但必须给出 evidence 和 confidence。
  • confidence >= 0.90 的模型对齐可以自动合并。
  • 0.70 <= confidence < 0.90 的模型对齐不自动合并,可记录为候选别名或候选关联。
  • confidence < 0.70 丢弃。

合并后必须保留来源贡献:

  • 来自哪个 WeKnora 知识库。
  • 来自哪个 Wiki 页面或 chunk。
  • 来自哪个技能 binding。
  • 证据文本。
  • 导入任务 ID。

属性冲突不覆盖:

  • 不同来源给出不同姓名、职务、时间、地点、数值时,按来源分组展示。
  • Wiki 页面中展示“多来源信息”而不是最后写入覆盖。

30.6 助手库关系对齐

关系 key:

assistant_base_id + source_assistant_entity_id + normalized_predicate + target_assistant_entity_id

关系来源:

  • WeKnora 图谱边。
  • WeKnora Wiki graph 链接。
  • 技能归纳时写入 WeKnora 的关系页。
  • graph projection 文档。
  • 模型从 WeKnora 导出包中推断的高置信关系。

关系合并后保留多个证据贡献。

关系 Wiki 页面建议:

assistant/relations/{predicate}/{stable_relation_id}

关系页内容:

  • 源实体。
  • 关系类型。
  • 目标实体。
  • 关系描述。
  • 来源知识库。
  • 来源 Wiki 页。
  • 证据和置信度。

30.7 助手库 Wiki 生成

助手库最终以 Wiki 页面展示。

页面类型:

页面 slug 示例 说明
首页 assistant/home 知识梳理总览、实体数量、来源数量、最近导入。
来源页 assistant/sources/{source_id} 某个 WeKnora 知识库导入结果。
实体页 assistant/entities/{type}/{entity_id}-{name} 对齐后的全局实体页面。
关系页 assistant/relations/{predicate}/{relation_id} 对齐后的全局关系页面。
主题页 assistant/topics/{topic} 从 WeKnora Wiki 分类或目录生成。

实体页结构:

  • 标题:实体名。
  • 类型:人物、组织、地点、装备、事件、概念、数据对象等。
  • 摘要:模型基于多来源融合生成。
  • 别名。
  • 多来源属性。
  • 相关实体。
  • 相关关系。
  • 来源 Wiki 页面。
  • 证据。

助手库 Wiki 页面需要版本管理。每次 WeKnora 导入、技能直接归纳、管理员本地文件导入、实体对齐重建或人工编辑,都生成新 revision。新 revision 先处于 draft 或 staged 状态,发布成功后成为 current。

版本能力:

  • 查看历史版本。
  • 对比两个版本。
  • 回滚到历史版本。
  • 查看版本来源:导入任务、技能归纳任务、人工编辑。
  • 查看版本发布人和发布时间。

30.8 助手库搜索

助手知识库需要支持搜索。

V1 建议实现:

  • Wiki 标题搜索。
  • 实体名称和别名搜索。
  • Wiki 正文全文搜索。
  • 来源知识库过滤。
  • 实体类型过滤。

实现选择:

  • SQLite 可使用 FTS5。
  • PostgreSQL 可使用 tsvector 或 trigram。
  • 如果现有持久化层不方便,先实现数据库 LIKE + normalized name 索引,后续再升级全文索引。

搜索结果只展示 Wiki 页面,不直接展示底层 chunk。

30.9 助手库持久化表

建议新增:

deerflow.persistence.assistant_knowledge

核心表:

assistant_knowledge_base

只允许一条 active 记录。

字段 说明
id UUID。
name 默认“知识梳理”。
status active / disabled。
created_by 初始化管理员。
created_at / updated_at 时间戳。

assistant_knowledge_sources

记录每个来源。来源可以是 WeKnora 知识库、技能归纳或管理员本地导入。

字段 说明
id UUID。
base_id 助手库 ID。
source_type weknora / skill / local_file。
knowledge_base_mapping_id DeerFlow 本地 WeKnora 映射 ID,可为空。
skill_name 技能名,可为空。
upload_batch_id 本地文件导入批次,可为空。
source_name 来源名称。
last_import_job_id 最近导入任务。
status active / import_failed / deleted。
created_at / updated_at 时间戳。

assistant_knowledge_import_jobs

字段 说明
id UUID。
base_id 助手库 ID。
source_id 来源 ID。
trigger auto_after_weknora_indexed / manual_from_weknora / skill_direct / manual_file_upload / scheduled / watcher。
status queued / running / completed / partial_failed / failed。
phase exporting / scanning / parsing / awaiting_review / aligning_entities / aligning_relations / writing_wiki / indexing_search / completed。
counts_json 导入页面、实体、关系、chunk 数。
last_error_message 错误摘要。
created_by 操作人;自动任务可为空或 system。
created_at / completed_at 时间戳。

assistant_knowledge_wiki_pages

字段 说明
id UUID。
base_id 助手库 ID。
slug 全局唯一 slug。
title 标题。
page_type home / source / entity / relation / topic。
current_revision_id 当前发布版本。
content_markdown 当前版本冗余内容,便于列表和搜索。
summary 摘要。
status active / deleted。
search_text 搜索文本。
updated_at 更新时间。

assistant_knowledge_wiki_revisions

保存 Wiki 页面版本。

字段 说明
id UUID。
page_id Wiki 页面。
revision_no 递增版本号。
content_markdown 版本内容。
summary 版本摘要。
source_id 来源,可为空。
import_job_id 导入任务,可为空。
change_type import / skill_sync / manual_edit / entity_rebuild / rollback。
status draft / staged / published / superseded。
created_by 创建人。
created_at / published_at 时间戳。

assistant_knowledge_entities

保存全局对齐后的实体。

字段 说明
id UUID。
base_id 助手库 ID。
entity_type 实体类型。
normalized_name 归一化名称。
display_name 展示名称。
aliases_json 别名。
attributes_json 聚合属性。
wiki_page_id 实体 Wiki 页。
status active / deleted。

assistant_knowledge_entity_contributions

字段 说明
id UUID。
entity_id 全局实体。
source_id WeKnora 来源。
import_job_id 导入任务。
source_wiki_slug 来源 Wiki 页。
source_chunk_id 来源 chunk,可为空。
source_skill_name 来源技能,可为空。
evidence_json 证据。
confidence 置信度。

assistant_knowledge_relations

保存全局对齐后的关系。

字段 说明
id UUID。
base_id 助手库 ID。
source_entity_id 源实体。
predicate 关系类型。
target_entity_id 目标实体。
description 聚合描述。
wiki_page_id 关系 Wiki 页。
status active / deleted。

assistant_knowledge_relation_contributions

字段 说明
id UUID。
relation_id 全局关系。
source_id WeKnora 来源。
import_job_id 导入任务。
source_wiki_slug 来源 Wiki 页。
graph_edge_id WeKnora 图谱边 ID,可为空。
evidence_json 证据。
confidence 置信度。

30.10 助手库 API

新增 router:

/api/assistant-knowledge

建议接口:

GET /api/assistant-knowledge/base
POST /api/assistant-knowledge/base/initialize
GET /api/assistant-knowledge/wiki-pages
GET /api/assistant-knowledge/wiki-pages/{slug}
GET /api/assistant-knowledge/wiki-pages/{slug}/revisions
GET /api/assistant-knowledge/wiki-pages/{slug}/revisions/{revision_id}
POST /api/assistant-knowledge/wiki-pages/{slug}/revisions/{revision_id}/rollback
GET /api/assistant-knowledge/search?q=xxx&type=entity&source_id=xxx
GET /api/assistant-knowledge/entities/{id}
GET /api/assistant-knowledge/relations/{id}
GET /api/assistant-knowledge/sources
GET /api/assistant-knowledge/import-jobs
GET /api/assistant-knowledge/import-jobs/{id}
POST /api/assistant-knowledge/sources/{source_id}/reimport
POST /api/assistant-knowledge/imports/files
POST /api/assistant-knowledge/imports/skills
DELETE /api/assistant-knowledge/sources/{source_id}

新增 WeKnora 普通知识库导出或导入触发接口:

POST /api/llmwiki/knowledge-bases/{knowledge_base_id}/export-to-assistant

行为:

  • 校验管理员。
  • 校验助手知识库已初始化;未初始化则自动创建“知识梳理”或提示管理员确认创建。
  • 校验 WeKnora 知识库已完成处理。
  • 创建 assistant_knowledge_import_jobs。
  • 后台导出 WeKnora 数据并导入助手库。

本地文件导入接口:

POST /api/assistant-knowledge/imports/files

使用 multipart 上传文件。后端必须先完成安全扫描和敏感信息阻断,再进入解析、抽取、审核、实体对齐和 Wiki 版本生成。

技能直接导入接口:

POST /api/assistant-knowledge/imports/skills

请求:

{
  "skill_names": ["skill-a", "skill-b"],
  "force": false
}

该接口也可以由 /api/skill-knowledge/sync-jobs 在目标类型为 assistant 时内部复用。

系统设置接口需要支持:

GET /api/system-settings/knowledge-base-product-version
PUT /api/system-settings/knowledge-base-product-version

30.11 前端页面

知识库入口需要支持产品版本切换。

建议:

  • 管理员设置页提供“知识库版本”切换:v1 普通知识库 / v2 助手知识库,默认 v1。
  • 知识库页面顶部用 Tabs 或 Segmented Control 区分“普通知识库”和“助手知识库”。
  • 未配置 WeKnora 时,普通知识库 tab 隐藏或禁用;助手知识库 tab 正常显示。
  • 助手知识库未初始化时,展示“创建知识梳理库”按钮。
  • 创建后展示 Wiki 首页、搜索框、来源列表、最近导入和页面版本入口。
  • 普通知识库详情页增加按钮:“导入到助手知识库”。
  • 普通知识库列表中可显示“已沉淀到知识梳理 / 待导入 / 导入失败”状态。
  • 助手知识库页面为管理员提供“导入本地文件”和“导入技能”入口。

助手知识库页面建议:

知识梳理
├── 搜索
├── Wiki 首页
├── 实体
├── 关系
├── 来源知识库
├── 导入记录
└── 页面版本

普通用户只看到搜索、Wiki、实体、关系、来源和只读版本历史。管理员额外看到导入、重新导入、删除来源、版本对比和回滚。

30.12 自动沉淀时机

WeKnora 普通知识库完成以下任意流程后,应触发或排队助手库导入:

  • 管理员从技能归纳到 WeKnora 成功。
  • WeKnora 文档上传并完成向量化。
  • WeKnora Wiki 页面生成或更新完成。
  • WeKnora 图谱抽取完成。
  • 管理员手动点击“导入到助手知识库”。

为了避免频繁重复导入:

  • 对每个 WeKnora 知识库维护 last_export_digest。
  • 导出前计算 Wiki 页面、文档 chunk、图谱摘要的 digest。
  • digest 未变化时跳过导入。
  • 同一 WeKnora 知识库同一时间只允许一个 active 导入任务。

30.13 与技能归纳的关系

技能归纳支持两条链路。

链路 A:先进入 WeKnora,再沉淀助手库。

技能知识文件
  -> WeKnora 普通知识库
  -> WeKnora 向量化 / Wiki / 图谱
  -> 导出已处理数据
  -> 助手知识库“知识梳理”
  -> 全局实体对齐
  -> Wiki 展示与搜索

链路 B:直接进入助手知识库。

技能知识文件
  -> 助手知识库“知识梳理”
  -> 实体/关系预览审核
  -> 全局实体对齐
  -> Wiki 页面版本发布
  -> 搜索索引

代码文件在第一步就被排除,不进入后续任何知识库。

30.14 新增测试与验收

新增后端测试:

  • 未配置 WeKnora 时,助手知识库 base 接口可用,普通知识库导入接口返回明确不可用。
  • 初始化助手知识库后,只存在一个 active base。
  • 普通用户可读助手 Wiki,写接口返回 403。
  • 管理员可从 WeKnora 知识库触发导入任务。
  • 管理员可把技能直接导入助手知识库。
  • 管理员可上传本地文件导入助手知识库。
  • WeKnora 导出包包含 Wiki、文档、chunk、实体、关系、图谱时,助手库全部导入。
  • 同一个人或同一对象来自多个 WeKnora 来源时,在助手库合并为一个实体。
  • 模型推断实体对齐 confidence >= 0.90 自动合并,低于阈值不合并。
  • 删除某个来源时,只删除该来源贡献;其他来源贡献仍保留。
  • 助手库搜索能命中 Wiki 标题、实体别名和正文。
  • 助手 Wiki 页面支持 revision、对比和回滚。
  • 技能归纳扫描不读取、不上传、不摘要代码文件,代码文件变化不触发 stale。

新增前端测试:

  • 知识库产品版本默认 v1。
  • 管理员可切换 v1 / v2。
  • 未配置 WeKnora 时仍可看到“创建知识梳理库”。
  • 普通知识库详情页有“导入到助手知识库”按钮。
  • 助手知识库页面展示 Wiki、搜索、来源、导入记录。
  • 助手知识库页面展示页面版本、对比和回滚入口。
  • 普通用户看不到导入、删除、重新导入和回滚动作。