Files
zclaw_openfang/docs/superpowers/specs/2026-04-01-knowledge-base-design.md
iven 8898bb399e
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
docs: audit reports + feature docs + skills + admin-v2 + config sync
Update audit tracker, roadmap, architecture docs,
add admin-v2 Roles page + Billing tests,
sync CLAUDE.md, Cargo.toml, docker-compose.yml,
add deep-research / frontend-design / chart-visualization skills

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 19:25:00 +08:00

23 KiB
Raw Permalink Blame History

行业知识库功能设计

日期: 2026-04-01 状态: 设计完成,待实施 范围: SaaS 管理端 + AI Agent 集成

1. 背景与目标

ZCLAW 作为面向中文用户的 AI Agent 桌面端,当前对话能力依赖通用 LLM 知识。行业用户(制造业、医疗、教育、设计)在专业领域提问时,通用模型回答缺乏深度和准确性。

目标: 建立行业知识库系统,让 SaaS 管理员配置行业专业知识,通过 RAG + Agent Tool 混合方案提升 AI Agent 的行业回答精准度。

核心价值:

  • 管理员可系统化管理行业知识(分类、录入、版本控制)
  • AI Agent 自动检索并引用相关知识RAG 注入)
  • Agent 可主动查询知识库Tool 调用)
  • 全生命周期分析看板追踪知识使用效果

2. 设计决策

维度 决策 理由
使用者 SaaS 管理员配置(平台级资源) 当前无多租户架构,知识库作为平台级共享资源,通过角色权限控制访问
AI 集成 RAG + Agent Tool 混合 覆盖自动注入和主动查询两个场景
文档格式 仅 Markdown 简化实现Markdown 是知识的自然格式
审核流程 免审核(直接生效) 小团队高效运作
分析看板 全生命周期分析 数据驱动知识库运营
交付节奏 一次性完整实现 功能完整交付
存储架构 PostgreSQL + pgvector 复用现有基础设施,零新增运维组件
Admin UI 标签页表格Ant Design 风格) 与现有 Admin V2 一致
主键类型 TEXT应用生成 UUID 字符串) 匹配现有所有表的主键约定
向量索引 HNSWpgvector >= 0.5.0 无最低行数要求,召回率优于 IVFFlat
中文检索 依赖向量语义搜索 + keywords 数组匹配 中文无空格分词tsvector 不适用;向量搜索天然跨语言

3. 数据模型

3.1 约定

  • 所有主键使用 TEXT 类型,由 Rust 端 uuid::Uuid::new_v4().to_string() 生成,匹配现有 25 张表的约定
  • 知识库为平台级资源(无 tenant_id通过角色权限控制访问
  • 外键引用 accounts(id) 均为 TEXT 类型

3.2 新增表5 张)

-- 启用 pgvector 扩展
CREATE EXTENSION IF NOT EXISTS vector;

-- 行业分类树
CREATE TABLE knowledge_categories (
    id TEXT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    description TEXT,
    parent_id TEXT REFERENCES knowledge_categories(id),
    icon VARCHAR(50),
    sort_order INT DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    CHECK (id != parent_id)  -- 防止自引用
);

-- 知识条目
CREATE TABLE knowledge_items (
    id TEXT PRIMARY KEY,
    category_id TEXT NOT NULL REFERENCES knowledge_categories(id),
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    keywords TEXT[] DEFAULT '{}',
    related_questions TEXT[] DEFAULT '{}',
    priority INT DEFAULT 0,
    status VARCHAR(20) DEFAULT 'active' CHECK (status IN ('active', 'archived', 'deprecated')),
    version INT DEFAULT 1,
    source VARCHAR(50) DEFAULT 'manual',
    tags TEXT[] DEFAULT '{}',
    created_by TEXT NOT NULL REFERENCES accounts(id),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    -- 内容长度约束:单条最大 100KB
    CHECK (length(content) <= 100000)
);

-- 知识分块RAG 检索核心)
CREATE TABLE knowledge_chunks (
    id TEXT PRIMARY KEY,
    item_id TEXT NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
    chunk_index INT NOT NULL,
    content TEXT NOT NULL,
    embedding vector(1536),
    keywords TEXT[] DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 版本快照
CREATE TABLE knowledge_versions (
    id TEXT PRIMARY KEY,
    item_id TEXT NOT NULL REFERENCES knowledge_items(id) ON DELETE CASCADE,
    version INT NOT NULL,
    title VARCHAR(255) NOT NULL,
    content TEXT NOT NULL,
    keywords TEXT[] DEFAULT '{}',
    related_questions TEXT[] DEFAULT '{}',
    change_summary TEXT,
    created_by TEXT NOT NULL REFERENCES accounts(id),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- 使用追踪
CREATE TABLE knowledge_usage (
    id TEXT PRIMARY KEY,
    item_id TEXT NOT NULL REFERENCES knowledge_items(id),
    chunk_id TEXT REFERENCES knowledge_chunks(id),
    session_id VARCHAR(100),
    query_text TEXT,
    relevance_score FLOAT,
    was_injected BOOLEAN DEFAULT FALSE,
    agent_feedback VARCHAR(20) CHECK (agent_feedback IN ('positive', 'negative')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

3.3 索引

-- 关联索引
CREATE INDEX idx_ki_category ON knowledge_items(category_id);
CREATE INDEX idx_kchunks_item ON knowledge_chunks(item_id);
CREATE INDEX idx_kv_item ON knowledge_versions(item_id);
CREATE INDEX idx_ku_item ON knowledge_usage(item_id);

-- 分类树
CREATE INDEX idx_kc_parent ON knowledge_categories(parent_id);

-- 使用追踪时间范围查询
CREATE INDEX idx_ku_created ON knowledge_usage(created_at);

-- 向量相似度索引HNSW无需预填充数据召回率优于 IVFFlat
CREATE INDEX idx_kchunks_embedding ON knowledge_chunks
    USING hnsw (embedding vector_cosine_ops)
    WITH (m = 16, ef_construction = 64);

-- 关键词数组索引GIN支持 && 重叠操作符)
CREATE INDEX idx_ki_keywords ON knowledge_items USING GIN(keywords);
CREATE INDEX idx_kchunks_keywords ON knowledge_chunks USING GIN(keywords);

3.4 Embedding 维度说明

vector(1536) 对应 OpenAI text-embedding-ada-002。若切换到其他 embedding 提供商:

  • Zhipu embedding-3: 2048 维
  • Qwen text-embedding-v2: 1536 维
  • Doubao: 1024 维

约束: 同一知识库内所有条目必须使用相同维度的 embedding 模型。切换模型时需执行 re-embedding见 5.4 节)。维度值存储在 config_items 表中category: knowledge_base, key: embedding_dimension),迁移时据此动态创建列。

4. API 设计

4.1 核心请求/响应类型

// === 分类 ===
#[derive(Deserialize)]
pub struct CreateCategoryRequest {
    pub name: String,
    pub description: Option<String>,
    pub parent_id: Option<String>,
    pub icon: Option<String>,
}

#[derive(Deserialize)]
pub struct UpdateCategoryRequest {
    pub name: Option<String>,
    pub description: Option<String>,
    pub parent_id: Option<String>,
    pub icon: Option<String>,
}

#[derive(Serialize)]
pub struct CategoryResponse {
    pub id: String,
    pub name: String,
    pub description: Option<String>,
    pub parent_id: Option<String>,
    pub icon: Option<String>,
    pub sort_order: i32,
    pub item_count: i64,        // 该分类下的条目数
    pub children: Vec<CategoryResponse>,  // 树形嵌套
    pub created_at: String,
    pub updated_at: String,
}

// === 知识条目 ===
#[derive(Deserialize)]
pub struct CreateItemRequest {
    pub category_id: String,
    pub title: String,
    pub content: String,
    pub keywords: Option<Vec<String>>,
    pub related_questions: Option<Vec<String>>,
    pub priority: Option<i32>,
    pub tags: Option<Vec<String>>,
}

#[derive(Deserialize)]
pub struct UpdateItemRequest {
    pub category_id: Option<String>,
    pub title: Option<String>,
    pub content: Option<String>,
    pub keywords: Option<Vec<String>>,
    pub related_questions: Option<Vec<String>>,
    pub priority: Option<i32>,
    pub status: Option<String>,
    pub tags: Option<Vec<String>>,
    pub change_summary: Option<String>,
}

#[derive(Deserialize)]
pub struct ListItemsQuery {
    pub page: Option<i64>,
    pub page_size: Option<i64>,
    pub category_id: Option<String>,
    pub status: Option<String>,
    pub keyword: Option<String>,
}

#[derive(Serialize)]
pub struct ItemResponse {
    pub id: String,
    pub category_id: String,
    pub category_name: String,
    pub title: String,
    pub content: String,
    pub keywords: Vec<String>,
    pub related_questions: Vec<String>,
    pub priority: i32,
    pub status: String,
    pub version: i32,
    pub source: String,
    pub tags: Vec<String>,
    pub created_by: String,
    pub reference_count: i64,  // 引用次数(从 knowledge_usage 统计)
    pub created_at: String,
    pub updated_at: String,
}

// === 搜索 ===
#[derive(Deserialize)]
pub struct SearchRequest {
    pub query: String,
    pub category_id: Option<String>,
    pub limit: Option<i64>,    // 默认 5, 最大 10
    pub min_score: Option<f64>, // 最低相关性阈值,默认 0.5
}

#[derive(Serialize)]
pub struct SearchResult {
    pub chunk_id: String,
    pub item_id: String,
    pub item_title: String,
    pub category_name: String,
    pub content: String,
    pub score: f64,
    pub keywords: Vec<String>,
}

// === 分析 ===
#[derive(Serialize)]
pub struct AnalyticsOverview {
    pub total_items: i64,
    pub active_items: i64,
    pub total_categories: i64,
    pub weekly_new_items: i64,
    pub total_references: i64,
    pub avg_reference_per_item: f64,
    pub hit_rate: f64,           // 命中率
    pub injection_rate: f64,     // 注入率
    pub positive_feedback_rate: f64,
    pub stale_items_count: i64,  // 90天未引用
}

4.2 分类管理6 个端点)

Method Path 说明
GET /api/v1/knowledge/categories 树形列表(含每节点 item_count
POST /api/v1/knowledge/categories 创建分类
PUT /api/v1/knowledge/categories/:id 更新分类(含父级循环检测)
DELETE /api/v1/knowledge/categories/:id 删除分类(有子分类或条目时拒绝)
PATCH /api/v1/knowledge/categories/reorder 批量更新 sort_order
GET /api/v1/knowledge/categories/:id/items 分类下条目分页列表

4.3 知识条目 CRUD7 个端点)

Method Path 说明
GET /api/v1/knowledge/items 分页列表(筛选/搜索)
POST /api/v1/knowledge/items 创建条目(触发异步 embedding
GET /api/v1/knowledge/items/:id 条目详情
PUT /api/v1/knowledge/items/:id 更新条目(触发异步 re-embedding
DELETE /api/v1/knowledge/items/:id 删除条目(级联删除 chunks + versions
POST /api/v1/knowledge/items/batch 批量创建(单次最多 50 条)
POST /api/v1/knowledge/items/import Markdown 文件导入(单次最多 20 个文件)

4.4 版本控制3 个端点)

Method Path 说明
GET /api/v1/knowledge/items/:id/versions 版本历史列表
GET /api/v1/knowledge/items/:id/versions/:v 查看特定版本
POST /api/v1/knowledge/items/:id/rollback/:v 回滚到指定版本(创建新版本)

4.5 检索2 个端点,内部调用)

Method Path 说明
POST /api/v1/knowledge/search 语义搜索(向量 + 关键词混合)
POST /api/v1/knowledge/recommend 关联推荐(基于当前条目的关键词重叠)

4.6 分析看板5 个端点)

Method Path 说明
GET /api/v1/knowledge/analytics/overview 总览统计(含命中率/注入率/反馈率)
GET /api/v1/knowledge/analytics/trends 使用趋势(支持 day/week/month 粒度)
GET /api/v1/knowledge/analytics/top-items 高频引用排行(支持分类筛选)
GET /api/v1/knowledge/analytics/quality 质量指标(按分类分组)
GET /api/v1/knowledge/analytics/gaps 知识缺口检测(低分查询聚类)

4.7 权限模型

权限 说明 授予角色
knowledge:read 查看分类、条目、版本、分析 admin, super_admin
knowledge:write 创建/编辑/导入条目和分类 admin, super_admin
knowledge:admin 删除、回滚 super_admin
knowledge:search 内部检索Agent/中间件) 系统内部

5. RAG 管道

5.1 入库管道(写入路径)

管理员创建/编辑 Markdown
    ↓
内容分块Markdown 标题层级 + 500-1000 token 固定切分 + 50 token 重叠)
    ↓
Worker 异步生成 embedding调用 models 表中 is_embedding=true 的模型)
    ↓
存入 knowledge_chunkscontent + embedding + keywords
    ↓
自动创建 knowledge_versions 快照
    ↓
更新 knowledge_items.version++

分块策略:

  1. 优先按 Markdown 标题(#, ##, ###)自然分段
  2. 超长段落按 500-1000 token 切分
  3. 相邻块之间保留 50 token 重叠,避免语义断裂
  4. 每个块继承父级标题作为上下文前缀

Embedding 生成:

  • 复用现有 embedding 提供商配置OpenAI, Zhipu, Doubao, Qwen, DeepSeek, Local/TF-IDF
  • 通过 Worker 系统异步处理,不阻塞管理员操作
  • 模型选择: 从 config_items 读取 knowledge_base.embedding_model_id,默认使用第一个 is_embedding=true 的模型

5.2 检索管道(读取路径)

用户提问
    ↓
relay 层知识注入(在 chat_completions handler 内调用)
    ↓
1. 生成查询 embedding
2. 混合检索:
   a) HNSW 向量余弦相似度(权重 0.7
   b) keywords 数组重叠匹配(权重 0.2
   c) related_questions 文本包含匹配(权重 0.1
3. 合并排序,取 Top-K默认 5 条)
4. token 预算控制(不超过 context window 的 20%
5. 格式化注入 system prompt
    ↓
记录到 knowledge_usage检索事件
    ↓
LLM 生成回答

混合检索公式:

final_score = 0.7 * cosine_similarity + 0.2 * keyword_overlap_count / max_keywords + 0.1 * related_question_match

token 预算控制:

  • 最大注入 token 数 = min(context_window * 0.2, 2000)
  • 按相关性排序,截断超出预算的低分块
  • 注入格式: [行业知识 #N] 标题\n内容

集成方式: 在 relay::handlers::chat_completions 内部,转发到上游 LLM 之前调用 knowledge::service::search_and_inject()。不使用 Axum 中间件层,而是作为 handler 内的业务逻辑步骤,与现有的 stream 处理管道自然集成。

5.3 Agent Tool

tool: knowledge_search
params:
  query: string        # 搜索查询
  category?: string    # 限定分类
  limit?: number       # 返回数量 (默认 3, 最大 10)
返回:
  items: Array<{
    title: string
    content: string     # 匹配的知识片段
    category: string
    relevance: number   # 相关性分数
  }>

Agent 在判断需要行业专业知识时主动调用此工具。通过 SaaS API 调用 POST /api/v1/knowledge/search

5.4 Re-embedding 策略

当 embedding 模型切换时(维度或提供商变化):

  1. 检测触发: 管理员在分析看板页点击"重建索引"按钮
  2. 执行流程:
    • 创建 re-embedding Worker 任务,按 batch每批 100 条 item分片
    • 每个 batch: 删除旧 chunks → 重新分块 → 生成新 embedding → 写入新 chunks
    • 通过 SpawnLimiter 控制并发,防止连接池耗尽
  3. 原子性: 每个 item 的 re-embedding 在单个事务内完成(删旧 chunk + 写新 chunk
  4. 状态追踪: 在 config_items 中记录 knowledge_base.reindex_statusidle/running/completed/failed
  5. 失败处理: 单条 item 失败不影响其他 item记录到 operation_logs支持重试

6. Admin UI 设计

6.1 页面结构

在 Admin V2 侧边栏新增"知识库"菜单组,包含 3 个子页面:

页面 1: 知识条目(默认页)

  • 顶部 Tab: 知识条目 | 批量导入
  • 条目列表 Tab: Ant Design Table
    • 列: 标题、分类、关键词Tag、引用次数、状态StatusTag、更新时间、操作
    • 筛选: 分类下拉、状态筛选、关键词搜索输入框
    • 操作: 新增Modal、编辑Modal、删除Popconfirm、查看版本历史Drawer
  • 批量导入 Tab:
    • Markdown 文件上传Ant Design Upload支持多文件单次最多 20 个)
    • 分类选择(下拉选择导入到哪个分类下)
    • 导入预览(文件列表 + 标题预览)+ 确认按钮

页面 2: 分类管理

  • 树形组件Ant Design Tree
  • 拖拽排序
  • 内联编辑(新增/重命名/删除)
  • 每个节点显示条目数量
  • 删除前检查是否有子分类或关联条目

页面 3: 分析看板

  • 总览卡片: 条目总数、本周新增、活跃率、平均引用次数
  • 使用趋势图: 折线图(检索/命中/注入三条线,日/周/月粒度切换)
  • 高频引用排行: 表格(支持按分类筛选)
  • 质量指标: 命中率、注入率、正向反馈率、过期知识标记90天未引用
  • 知识缺口: 缺失主题、查询频率、建议分类

6.2 新增文件

admin-v2/src/
├── pages/
│   ├── KnowledgeItems.tsx      # 知识条目页
│   ├── KnowledgeCategories.tsx  # 分类管理页
│   └── KnowledgeAnalytics.tsx   # 分析看板页
├── services/
│   └── knowledgeService.ts     # API 调用封装
├── types/
│   └── knowledge.d.ts          # 类型定义
└── components/
    └── knowledge/
        ├── ItemForm.tsx         # 条目编辑表单Modal
        ├── ItemDetail.tsx       # 条目详情抽屉
        ├── VersionHistory.tsx   # 版本历史Drawer
        ├── ImportPanel.tsx      # 批量导入面板
        └── AnalyticsCharts.tsx  # 分析图表组件

6.3 路由注册

// router/index.tsx 新增(使用现有 lazy 加载模式)
{ path: 'knowledge/items', lazy: () => import('@/pages/KnowledgeItems').then(m => ({ Component: m.default })) },
{ path: 'knowledge/categories', lazy: () => import('@/pages/KnowledgeCategories').then(m => ({ Component: m.default })) },
{ path: 'knowledge/analytics', lazy: () => import('@/pages/KnowledgeAnalytics').then(m => ({ Component: m.default })) },

6.4 侧边栏导航

// AdminLayout.tsx navItems 新增
{
  path: '/knowledge/items',
  name: '知识库',
  icon: BookOutlined,
  permission: 'knowledge:read',
  group: '资源管理',
},
{
  path: '/knowledge/categories',
  name: '分类管理',
  icon: FolderOutlined,
  permission: 'knowledge:read',
  group: '资源管理',
},
{
  path: '/knowledge/analytics',
  name: '知识分析',
  icon: BarChartOutlined,
  permission: 'knowledge:read',
  group: '资源管理',
},

7. SaaS 后端实现

7.1 新增模块

crates/zclaw-saas/src/
└── knowledge/
    ├── mod.rs       # 模块注册 + 路由定义pub fn routes() -> Router<AppState>
    ├── types.rs     # 请求/响应/DTO 类型(见 4.1 节)
    ├── handlers.rs  # 23 个 API handler
    ├── service.rs   # 业务逻辑CRUD + 检索 + 分析)
    └── chunk.rs     # 分块 + embedding 生成 + re-embedding

7.2 模块注册

// lib.rs 新增
pub mod knowledge;

// main.rs build_router() 新增
.merge(zclaw_saas::knowledge::routes())

7.3 新增 Worker

// workers/generate_embedding.rs
use crate::state::AppState;
use crate::workers::Worker;
use serde::{Deserialize, Serialize};
use sqlx::PgPool;

#[derive(Serialize, Deserialize)]
pub struct GenerateEmbeddingArgs {
    pub item_id: String,
}

pub struct GenerateEmbedding;

impl Worker for GenerateEmbedding {
    type Args = GenerateEmbeddingArgs;

    fn name(&self) -> &str {
        "generate_embedding"
    }

    async fn perform(&self, db: &PgPool, args: Self::Args) -> crate::error::SaasResult<()> {
        // 1. 从 knowledge_items 读 content
        // 2. 调用 chunk.rs 分块
        // 3. 调用 embedding 提供商生成向量
        //    (通过 relay 模块的 provider 客户端,复用现有 HTTP 客户端)
        // 4. 删除旧 chunks写入新 knowledge_chunks
        // 5. 更新 knowledge_items.updated_at
        Ok(())
    }
}

// main.rs Worker 注册新增
state.dispatcher.register::<GenerateEmbedding>();

7.4 Cargo 依赖

# zclaw-saas/Cargo.toml 新增
[dependencies]
pgvector = { version = "0.4", features = ["sqlx"] }

pgvector crate 提供 pgvector::Vector 类型,支持 sqlx 的 Encode/Decode,可直接用于读写 vector(N) 列。

7.5 迁移文件

crates/zclaw-saas/migrations/20260402000002_knowledge_base.sql

包含: pgvector 扩展启用 + 5 张表 + 所有索引(见第 3 节)。

8. Docker 变更

将 PostgreSQL 镜像切换为 pgvector 版本:

# docker-compose.yml
services:
  db:
    image: pgvector/pgvector:pg16-alpine  # 原 postgres:16-alpine

使用 Alpine 变体保持与原有配置一致。

9. 权限种子数据

在迁移文件中通过应用层兼容的方式更新权限(permissions 列为 TEXT 类型存储 JSON 数组字符串):

-- 以应用层可解析的格式追加权限
-- super_admin: 追加 knowledge:read, knowledge:write, knowledge:admin, knowledge:search
UPDATE roles
SET permissions = REPLACE(
    permissions,
    ']',
    ', "knowledge:read", "knowledge:write", "knowledge:admin", "knowledge:search"]'
)
WHERE name = 'super_admin'
AND permissions NOT LIKE '%knowledge:read%';

-- admin: 追加 knowledge:read, knowledge:write, knowledge:search
UPDATE roles
SET permissions = REPLACE(
    permissions,
    ']',
    ', "knowledge:read", "knowledge:write", "knowledge:search"]'
)
WHERE name = 'admin'
AND permissions NOT LIKE '%knowledge:read%';

10. 内容限制与防护

限制项 实现位置
单条内容最大长度 100KB (100,000 字符) 数据库 CHECK 约束 + API 验证
批量创建最大条数 50 条/次 API handler 验证
文件导入最大文件数 20 个/次 API handler 验证
单文件最大大小 5MB Upload 中间件限制
搜索结果最大数量 10 条 API 参数上限
分类树最大深度 3 层 API handler 递归检测
分类名称最大长度 100 字符 数据库 VARCHAR 约束
标题最大长度 255 字符 数据库 VARCHAR 约束

11. 验证方案

11.1 后端验证

  1. 数据库迁移: 启动 SaaS 服务,确认 pgvector 扩展和 5 张表创建成功
  2. CRUD API: 用 curl 测试分类和条目的完整 CRUD 流程
  3. 分块 + Embedding: 创建条目后检查 knowledge_chunks 表有正确分块和向量
  4. 混合检索: 调用 /api/v1/knowledge/search 验证向量+关键词混合结果
  5. 版本控制: 编辑条目后检查 knowledge_versions 快照正确性,验证回滚
  6. 分析 API: 注入测试数据后验证 5 个分析端点返回正确统计
  7. 分类循环检测: 尝试设置循环父级关系,确认被拒绝
  8. 内容限制: 尝试提交超长内容,确认被 CHECK 约束拒绝

11.2 前端验证

  1. 分类管理: 树形 CRUD + 拖拽排序
  2. 条目 CRUD: 创建、编辑、删除、列表筛选
  3. 批量导入: Markdown 文件上传导入
  4. 版本历史: 查看历史版本 + 回滚
  5. 分析看板: 图表渲染 + 数据联动

11.3 集成验证

  1. RAG 注入: 在桌面端对话中提问行业相关问题,验证知识被检索和注入
  2. Agent Tool: 在对话中触发 Agent 主动查询知识库
  3. 使用追踪: 对话后检查 knowledge_usage 表有检索记录
  4. 分析闭环: 对话后查看分析看板数据更新
  5. Re-embedding: 切换 embedding 模型后触发重建,验证向量正确更新