Skip to content

知识库管理 ​

一、接口设计 ​

1. 获取知识库列表 ​

请求方式:GET
接口路径:/api/dataset/{pageNo}/{pageSize}

示例请求:

GET /api/dataset/1/20

示例响应:

json
{
  "message": null,
  "data": {
    "size": 20,
    "total": 1,
    "records": [
      {
        "tenant_id": "0",
        "creator": "",
        "create_time": 1730769172064,
        "embedding_mode_id": "443263808507674624",
        "remark": null,
        "type": "0",
        "updater": "",
        "update_time": 1730769172064,
        "deleted": 0,
        "user_id": "1",
        "meta": null,
        "name": "ICS 141",
        "id": "443309276048408576",
        "desc": "ICS 141 课程资料"
      }
    ],
    "current": 1
  },
  "code": 200
}

2. 创建知识库 ​

请求方式:POST
接口路径:/api/dataset

请求体: 注意是 embedding_mode_id

json
{
  "name": "ICS 11",
  "desc": "ICS 111 课程资料",
  "embedding_mode_id": "443263808507674624",
  "type": "0"
}

示例响应:

json
{
  "message": null,
  "data": {
    "id": "443309276048408576",
    "name": "ICS 141",
    "desc": "ICS 141 课程资料"
  },
  "code": 200
}

3. 验证知识库创建额度 ​

请求方式:GET
接口路径:/api/valid/dataset/{size}

示例请求:

http://localhost:10060/api/valid/dataset/50

示例响应:

json
{
  "code": 200,
  "message": "成功",
  "data": true
}

4. 获取单个知识库详情 ​

请求方式:GET
接口路径:/api/dataset/{id}

示例请求:

http://localhost:10060/api/dataset/443309276048408576

示例响应:

json
{
  "message": null,
  "data": {
    "tenant_id": "0",
    "creator": "",
    "create_time": 1730769172064,
    "embedding_mode_id": "443263808507674624",
    "remark": null,
    "type": "0",
    "updater": "",
    "update_time": 1730769172064,
    "deleted": 0,
    "user_id": "1",
    "meta": null,
    "name": "ICS 141",
    "id": "443309276048408576",
    "desc": "ICS 141 课程资料",
    "application_id_list": [],
    "document_count": "2",
    "char_length": "16300"
  },
  "code": 200
}

meta 是 jsonb 列,详情接口返回的是 JSON 对象而不是原始列值:通用型知识库为 null,Web 站点知识库里是根地址与选择器。application_id_list、document_count、char_length 供知识库列表与设置页展示使用,id 与计数类字段都以字符串返回,避免前端大整数精度问题。

二、代码实现 ​

1. 控制器层 ​

控制器层负责处理 HTTP 请求,并调用相应的服务层方法。以下是 ApiDatasetController 的实现:

java
package nexus.io.mosskb.controller;

import java.util.List;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;

import nexus.io.annotation.Delete;
import nexus.io.annotation.Get;
import nexus.io.annotation.Post;
import nexus.io.annotation.Put;
import nexus.io.annotation.RequestPath;
import nexus.io.jfinal.aop.Aop;
import nexus.io.mosskb.service.kb.MossKbDatasetHitTestService;
import nexus.io.mosskb.service.kb.MossKbDatasetService;
import nexus.io.mosskb.service.kb.MossKbDocumentService;
import nexus.io.mosskb.service.kb.MossKbParagraphServcie;
import nexus.io.mosskb.service.kb.MossKbParagraphSplitService;
import nexus.io.mosskb.service.kb.MossKbProblemService;
import nexus.io.mosskb.service.kb.MossKbWebDatasetService;
import nexus.io.mosskb.vo.KbDatasetModel;
import nexus.io.mosskb.vo.MossKbUpdateDocumentRequestVo;
import nexus.io.mosskb.vo.Paragraph;
import nexus.io.mosskb.vo.ParagraphBatchVo;
import nexus.io.mosskb.vo.ProbrolemCreateBatch;
import nexus.io.model.result.ResultVo;
import nexus.io.tio.boot.http.TioRequestContext;
import nexus.io.tio.http.common.HttpRequest;
import nexus.io.tio.utils.json.JsonUtils;

@RequestPath("/api/dataset")
public class ApiDatasetController {

  @Get("")
  public ResultVo list() {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetService.class).list(userId);
  }

  @Get("/{pageNo}/{pageSize}")
  public ResultVo page(Integer pageNo, Integer pageSize, String name) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetService.class).page(userId, pageNo, pageSize, name);
  }

  @Post("")
  public ResultVo save(HttpRequest request) {
    String bodyString = request.getBodyString();
    KbDatasetModel kbDatasetModel = JsonUtils.parse(bodyString, KbDatasetModel.class);
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetService.class).save(userId, kbDatasetModel);
  }

  /** 创建 Web 站点知识库:保存根地址与选择器后由后台线程抓取页面。 */
  @Post("/web")
  public ResultVo saveWebDataset(HttpRequest request) {
    JSONObject input = JSON.parseObject(request.getBodyString());
    return Aop.get(MossKbWebDatasetService.class).save(TioRequestContext.getUserIdLong(), input);
  }

  /** 同步 Web 站点知识库,sync_type 取 replace 或 complete。 */
  @Put("/{id}/sync_web")
  public ResultVo syncWebDataset(Long id, HttpRequest request) {
    return Aop.get(MossKbWebDatasetService.class).sync(TioRequestContext.getUserIdLong(), id,
        request.getParam("sync_type"));
  }

  @Get("/{id}")
  public ResultVo get(Long id) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetService.class).get(userId, id);
  }

  @Put("/{id}")
  public ResultVo updateDataset(Long id, HttpRequest request) {
    KbDatasetModel model = JsonUtils.parse(request.getBodyString(), KbDatasetModel.class);
    model.setId(id);
    return Aop.get(MossKbDatasetService.class).save(TioRequestContext.getUserIdLong(), model);
  }

  @Put("/{datasetId}/document/{documentId}/paragraph/{paragraphId}")
  public ResultVo updateParagraph(Long datasetId, Long documentId, Long paragraphId, HttpRequest request) {
    return Aop.get(MossKbParagraphServcie.class).update(TioRequestContext.getUserIdLong(), datasetId, documentId, paragraphId,
        JsonUtils.parse(request.getBodyString(), Paragraph.class));
  }

  @Delete("/{id}")
  public ResultVo delete(Long id) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetService.class).delete(userId, id);
  }

  @Get("/{id}/hit_test")
  public ResultVo hitTest(Long id, HttpRequest request) {
    String query_text = request.getParam("query_text");
    Double similarity = request.getDouble("similarity");
    Integer top_number = request.getInt("top_number");
    String search_mode = request.getParam("search_mode");
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDatasetHitTestService.class).hitTest(userId, id, query_text, similarity, top_number,
        search_mode);
  }

  @Post("/{id}/document/_bach")
  public ResultVo batch(Long id, HttpRequest request) {
    String bodyString = request.getBodyString();
    Long userId = TioRequestContext.getUserIdLong();
    List<ParagraphBatchVo> list = JsonUtils.parseArray(bodyString, ParagraphBatchVo.class);
    return Aop.get(MossKbParagraphSplitService.class).batch(userId, id, list);
  }

  @Get("/{id}/document/{pageNo}/{pageSize}")
  public ResultVo pageDocument(Long id, Integer pageNo, Integer pageSize) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDocumentService.class).page(userId, id, pageNo, pageSize);
  }

  @Get("/{datasetId}/document")
  public ResultVo documentList(Long datasetId) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDocumentService.class).list(userId, datasetId);
  }

  @Get("/{datasetId}/document/{documentId}")
  public ResultVo getDocument(Long datasetId, Long documentId) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDocumentService.class).get(userId, datasetId, documentId);
  }

  @Delete("/{datasetId}/document/{documentId}")
  public ResultVo deleteDocument(Long datasetId, Long documentId) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbDocumentService.class).delete(userId, datasetId, documentId);
  }

  @Put("/{datasetId}/document/{documentId}")
  public ResultVo updateDocument(Long datasetId, Long documentId, HttpRequest httpRequest) {
    Long userId = TioRequestContext.getUserIdLong();
    String bodyString = httpRequest.getBodyString();
    if (bodyString == null) {
      return ResultVo.fail("request body can not be empty");
    }
    MossKbUpdateDocumentRequestVo vo = JsonUtils.parse(bodyString, MossKbUpdateDocumentRequestVo.class);
    return Aop.get(MossKbDocumentService.class).update(userId, datasetId, documentId, vo);
  }

  /** 按地址列表向 Web 站点知识库导入网页文档。 */
  @Post("/{datasetId}/document/web")
  public ResultVo importWebDocument(Long datasetId, HttpRequest request) {
    JSONObject input = JSON.parseObject(request.getBodyString());
    return Aop.get(MossKbWebDatasetService.class).importDocuments(TioRequestContext.getUserIdLong(), datasetId, input);
  }

  /** 重新抓取一个网页文档。 */
  @Put("/{datasetId}/document/{documentId}/sync")
  public ResultVo syncWebDocument(Long datasetId, Long documentId) {
    return Aop.get(MossKbWebDatasetService.class).syncDocument(TioRequestContext.getUserIdLong(), datasetId, documentId);
  }

  /** 批量同步网页文档,请求体为 {"id_list":[...]}。 */
  @Put("/{datasetId}/document/_bach")
  public ResultVo batchSyncWebDocument(Long datasetId, HttpRequest request) {
    JSONObject input = JSON.parseObject(request.getBodyString());
    return Aop.get(MossKbWebDatasetService.class).batchSyncDocuments(TioRequestContext.getUserIdLong(), datasetId,
        input == null ? null : input.getJSONArray("id_list"));
  }

  @Get("/{datasetId}/application")
  public ResultVo getApplicationByDatasetId(Long datasetId) {
    return Aop.get(MossKbDatasetService.class).getApplicationByDatasetId(datasetId);
  }

  @Post("/{datasetId}/document/{documentId}/paragraph")
  public ResultVo createParagraph(Long datasetId, Long documentId, HttpRequest request) {
    String bodyString = request.getBodyString();
    Paragraph paragraph = JsonUtils.parse(bodyString, Paragraph.class);
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbParagraphServcie.class).create(userId, datasetId, documentId, paragraph);
  }

  // paragraph
  @Get("/{datasetId}/document/{documentId}/paragraph/{pageNo}/{pageSize}")
  public ResultVo listParagraph(Long datasetId, Long documentId, Integer pageNo, Integer pageSize) {
    Long userId = TioRequestContext.getUserIdLong();
    return Aop.get(MossKbParagraphServcie.class).page(userId, datasetId, documentId, pageNo, pageSize);
  }

  @Get("/{datasetId}/document/{documentId}/paragraph/{paragraphId}/problem")
  public ResultVo listProblem(Long datasetId, Long documentId, Long paragraphId) {
    return Aop.get(MossKbParagraphServcie.class).listProblemByParagraphId(datasetId, documentId, paragraphId);
  }

  @Post("/{datasetId}/document/{documentId}/paragraph/{paragraphId}/problem")
  public ResultVo addProblems(Long datasetId, Long documentId, Long paragraphId, HttpRequest request) {
    String bodyString = request.getBodyString();
    String content = JsonUtils.parseToMap(bodyString, String.class, String.class).get("content");
    return Aop.get(MossKbParagraphServcie.class).addProblemById(datasetId, documentId, paragraphId, content);
  }

  @Post("/{datasetId}/problem")
  public ResultVo createProblem(Long datasetId, HttpRequest request) {
    String bodyString = request.getBodyString();
    List<String> problems = JsonUtils.parseArray(bodyString, String.class);
    return Aop.get(MossKbProblemService.class).create(datasetId, problems);
  }


  @Get("/{datasetId}/problem/{pageNo}/{pageSize}")
  public ResultVo pageDatasetProbleam(Long datasetId, Integer pageNo, Integer pageSize) {
    return Aop.get(MossKbProblemService.class).page(datasetId, pageNo, pageSize);
  }

  // api/dataset/443309276048408576/problem/444734959665311744/paragraph
  @Get("/{datasetId}/problem/{problemId}/paragraph")
  public ResultVo listParagraphByProblemId(Long datasetId, Long problemId) {
    return Aop.get(MossKbProblemService.class).listParagraphByProblemId(datasetId, problemId);
  }

  @Put("/{datasetId}/document/{documentId}/paragraph/{paragraphId}/problem/{problemId}/association")
  public ResultVo association(Long datasetId, Long documentId, Long paragraphId, Long problemId) {
    return Aop.get(MossKbProblemService.class).association(datasetId, documentId, paragraphId, problemId);
  }

  @Put("/{datasetId}/document/{documentId}/paragraph/{paragraphId}/problem/{problemId}/un_association")
  public ResultVo unAssociation(Long datasetId, Long documentId, Long paragraphId, Long problemId) {
    return Aop.get(MossKbProblemService.class).unAssociation(datasetId, documentId, paragraphId, problemId);
  }

  @Post("/{datasetId}/problem/_batch")
  public ResultVo addProbrolems(Long datasetId, HttpRequest request) {
    String bodyString = request.getBodyString();
    ProbrolemCreateBatch batchReequest = JsonUtils.parse(bodyString, ProbrolemCreateBatch.class);
    return Aop.get(MossKbProblemService.class).addProbrolems(datasetId, batchReequest);
  }

  @Delete("/{datasetId}/problem/{problemId}")
  public ResultVo deleteProblem(Long datasetId, Long problemId) {
    return Aop.get(MossKbProblemService.class).delete(datasetId, problemId);
  }
  

  @Delete("/{datasetId}/problem/_batch")
  public ResultVo deleteProblemBatch(Long datasetId, HttpRequest request) {
    String bodyString = request.getBodyString();
    List<Long> problems = JsonUtils.parseArray(bodyString, Long.class);
    return Aop.get(MossKbProblemService.class).delete(datasetId, problems);
  }

}

2. 服务层 ​

服务层负责业务逻辑的处理。以下是 MossKbDatasetService 的实现:

java
package nexus.io.mosskb.service.kb;

import java.util.ArrayList;
import java.util.List;

import com.jfinal.kit.Kv;

import nexus.io.db.TableInput;
import nexus.io.db.TableResult;
import nexus.io.db.activerecord.Db;
import nexus.io.db.activerecord.Row;
import nexus.io.jfinal.aop.Aop;
import nexus.io.kit.RowUtils;
import nexus.io.mosskb.constant.MossKbTableNames;
import nexus.io.mosskb.dao.MossKbDatasetDao;
import nexus.io.mosskb.model.MossKbDataset;
import nexus.io.mosskb.vo.KbDatasetModel;
import nexus.io.mosskb.vo.ResultPage;
import nexus.io.model.page.Page;
import nexus.io.model.result.ResultVo;
import nexus.io.table.constants.Operators;
import nexus.io.table.services.ApiTable;

public class MossKbDatasetService {

  private String application_mapping_count_sql = String.format("select count(1) from %s where dataset_id=?", MossKbTableNames.moss_kb_application_dataset_mapping);
  private String document_count_sql = String.format("select count(1) from %s where dataset_id=?", MossKbTableNames.moss_kb_document);
  private String sum_char_length_sql = String.format("select sum(char_length) from %s where dataset_id=?", MossKbTableNames.moss_kb_document);

  public ResultVo page(Long userId, Integer pageNo, Integer pageSize, String name) {
    TableInput tableInput = new TableInput();
    tableInput.setPageNo(pageNo).setPageSize(pageSize);
    if (userId.equals(1L)) {

    } else {
      tableInput.set("user_id", userId);
    }

    if (name != null) {
      tableInput.set("name", name).set("name_op", Operators.CT);
    }

    TableResult<Page<Row>> tableResult = ApiTable.page(MossKbTableNames.moss_kb_dataset, tableInput);
    Page<Row> page = tableResult.getData();
    int totalRow = page.getTotalRow();
    List<Row> list = page.getList();
    List<Kv> kvs = new ArrayList<>();
    for (Row record : list) {
      Kv kv = record.toKv();
      Long datasetId = kv.getLong("id");

      Long application_mapping_count = Db.queryLong(application_mapping_count_sql, datasetId);
      kv.set("application_mapping_count", application_mapping_count);
      Long document_count = Db.queryLong(document_count_sql, datasetId);
      kv.set("document_count", document_count);
      Long charLength = Db.queryLong(sum_char_length_sql, datasetId);
      kv.set("char_length", charLength);
      kvs.add(kv);
    }

    ResultPage<Kv> resultPage = new ResultPage<>(pageNo, pageSize, totalRow, kvs);
    return ResultVo.ok(resultPage);
  }

  public ResultVo save(Long userId, KbDatasetModel kbDatasetModel) {
    if (kbDatasetModel.getId() != null && !DatasetAccess.owns(userId, kbDatasetModel.getId())) {
      return ResultVo.fail("知识库不存在或无权访问");
    }
    Long embeddingId = kbDatasetModel.getEmbedding_mode_id();
    if (embeddingId == null) {
      embeddingId = kbDatasetModel.getId() == null ? 1002L : Db.queryLong("select embedding_mode_id from moss_kb_dataset where id=?", kbDatasetModel.getId());
      kbDatasetModel.setEmbedding_mode_id(embeddingId);
    }
    if (!ModelAccess.canUse(userId, embeddingId) || Db.queryLong("select count(*) from moss_kb_model where id=? and model_type='EMBEDDING'", embeddingId) == 0) {
      return ResultVo.fail("向量模型不存在或无权使用");
    }
    if (kbDatasetModel.getId() != null && !embeddingId.equals(Db.queryLong("select embedding_mode_id from moss_kb_dataset where id=?", kbDatasetModel.getId()))
        && Db.queryLong("select count(*) from moss_kb_paragraph where dataset_id=?", kbDatasetModel.getId()) > 0) {
      return ResultVo.fail("已有文档的知识库不能直接切换向量空间,请新建知识库并重新导入文档");
    }
    ResultVo resultVo = new ResultVo();
    TableResult<Kv> saveOrUpdate = Aop.get(MossKbDatasetDao.class).saveOrUpdate(userId, kbDatasetModel);
    Kv data = saveOrUpdate.getData();
    resultVo.setData(data);
    return resultVo;
  }

  public ResultVo get(Long userId, Long id) {
    ResultVo resultVo = new ResultVo();
    TableInput tableInput = new TableInput();
    if (userId != null && userId.equals(1L)) {
      tableInput.set("id", id);
    } else {
      tableInput.set("id", id).set("user_id", userId);
    }
    TableResult<Row> result = ApiTable.get(MossKbTableNames.moss_kb_dataset, tableInput);
    Kv kv = result.getData().toKv();
    resultVo.setData(kv);
    return resultVo;
  }

  public ResultVo list(Long userId) {
    Row queryRecord = new Row();
    if (userId.equals(1L)) {

    } else {
      queryRecord.set("user_id", userId);
    }

    String columns = "id,name,\"desc\",type,meta,user_id,embedding_mode_id,create_time,update_time";
    List<Row> records = Db.find(MossKbDataset.tableName, columns, queryRecord);
    List<Kv> kvs = RowUtils.toKv(records, false);
    return ResultVo.ok(kvs);
  }

  public ResultVo delete(Long userId, Long id) {
    if (!DatasetAccess.owns(userId, id)) {
      return ResultVo.fail("知识库不存在或无权访问");
    }
    TableInput tableInput = null;
    if (userId != null && userId.equals(1L)) {
      tableInput = TableInput.by("id", id);
    } else {
      tableInput = TableInput.by("id", id).set("user_id", userId);
    }

    TableResult<Boolean> result = ApiTable.delete(MossKbTableNames.moss_kb_dataset, tableInput);
    Row deleteRecord = Row.by("dataset_id", id);
    Db.delete(MossKbTableNames.moss_kb_document, deleteRecord);
    Db.delete(MossKbTableNames.moss_kb_paragraph, deleteRecord);
    return new ResultVo(result.getData());
  }

  public ResultVo getApplicationByDatasetId(Long datasetId) {
    return ResultVo.ok();
  }
}

3. 数据访问层 ​

MossKbDatasetDao 使用 TableInput 和 ApiTable 保存字段;权限及向量空间约束由上面的服务层校验。

java
package nexus.io.mosskb.dao;

import com.jfinal.kit.Kv;

import nexus.io.db.TableInput;
import nexus.io.db.TableResult;
import nexus.io.db.activerecord.Row;
import nexus.io.mosskb.constant.MossKbTableNames;
import nexus.io.mosskb.vo.KbDatasetModel;
import nexus.io.table.services.ApiTable;

public class MossKbDatasetDao {

  public TableResult<Kv> saveOrUpdate(Long userId, KbDatasetModel model) {
    TableInput record = new TableInput();
    record.set("id", model.getId())
    //
    .set("name", model.getName()).set("desc",model.getDesc()).set("type",model.getType()).set("user_id", userId)
    //
    .set("embedding_mode_id", model.getEmbedding_mode_id());

    return ApiTable.saveOrUpdate(MossKbTableNames.moss_kb_dataset, record);
  }

  public TableResult<Row> get(Long userId, Long id) {
    TableInput tableInput = new TableInput();
    tableInput.set("id",id).set("user_id",userId);
    return ApiTable.get(MossKbTableNames.moss_kb_dataset, tableInput);
  }
}

三、功能实现流程 ​

  1. 获取知识库列表:用户发送 GET 请求到 /api/dataset/{pageNo}/{pageSize},控制器接收请求后调用 MossKbDatasetService 的 page 方法,通过 ApiTable.page 查询数据库并返回分页结果。

  2. 创建知识库:用户发送 POST 请求到 /api/dataset,包含知识库的详细信息。控制器解析请求体,调用服务层的 save 方法,通过 MossKbDatasetDao 将新知识库保存到数据库。

  3. 验证知识库:用户发送 GET 请求到 /api/valid/dataset/{size},系统返回该知识库是否存在的布尔值。

  4. 获取单个知识库详情:用户发送 GET 请求到 /api/dataset/{id},控制器调用服务层的 get 方法,返回指定 ID 的知识库详情。

  5. 获取知识库文档:用户发送 GET 请求到 /api/dataset/{id}/document/{pageNo}/{pageSize},系统返回该知识库下的文档列表,支持分页。

  6. 删除知识库:用户发送 DELETE 请求到 /api/dataset/{id},控制器调用服务层的 delete 方法,删除指定 ID 的知识库,并同时删除相关联的文档和段落。

  7. 创建并抓取站点知识库:用户发送 POST 请求到 /api/dataset/web,控制器转交 MossKbWebDatasetService。服务先校验名称、描述、向量模型与根地址,再真实抓一次入口页面;地址不可用或取不到正文时直接返回错误。通过校验后写入 type=1 的知识库,立即返回详情,页面抓取与向量化在后台线程继续,文档逐个出现在文档列表里。

四、总结 ​

通过上述接口设计和代码实现,我们构建了一个基本的知识库管理系统 MossKB。该系统支持知识库的创建、查询、分页展示、验证和删除等功能。控制器层负责处理 HTTP 请求,服务层封装了业务逻辑,数据访问层则负责与数据库的交互。

在实际开发中,可以根据需求进一步扩展系统功能,如增加权限控制、优化查询性能、集成全文搜索引擎等。此外,结合前端框架,可以构建一个完整的知识库管理平台,提升用户体验和系统的实用性。

通过系统化的设计和模块化的代码实现,MossKB 知识库管理功能具备了良好的可维护性和扩展性,能够满足不同场景下的知识管理需求。

修改、删除及模型空间约束 ​

GET /api/dataset 返回当前账号可见的知识库列表。PUT /api/dataset/{id} 修改名称、说明及空知识库的向量模型;DELETE /api/dataset/{id} 删除知识库,均检查归属。

http
PUT /api/dataset/443309276048408576
Authorization: Bearer <JWT_TOKEN>
Content-Type: application/json
json
{"name":"课程资料","desc":"更新说明","type":0,"embedding_mode_id":"1002"}

embedding_mode_id 是模型实例 ID,不能写成基础模型名称。可选择有使用权限的 EMBEDDING 实例,向量为 1024 维。已有分段的知识库不能直接切换模型;新模型应配合新知识库重新导入文档。

编辑请求允许只提交部分字段:没有提交的字段沿用原值,因此只改名称或说明时不会把 type 与 meta 清空,Web 站点知识库不会因为改个名字退化成通用型。

Web 站点知识库接口 ​

方法路径内容
POST/api/dataset/web创建 Web 站点知识库,校验入口地址后由后台线程抓取
PUT/api/dataset/{id}/sync_web?sync_type=replace|complete替换同步或整体同步
POST/api/dataset/{id}/document/web按地址列表导入网页文档
PUT/api/dataset/{id}/document/{documentId}/sync重新抓取一个网页文档
PUT/api/dataset/{id}/document/_bach批量同步网页文档

抓取范围、正文选择器、分段规则与开关细节见 爬取网页数据。这些接口创建的文档 type 为 1,来源地址记录在文档 meta.source_url 里。

/api/valid/dataset/{size} 的参数是额度检查值,不是知识库 ID;它返回额度检查结果,不能代替资源归属和是否存在的检查。解析后提交分段须携带文件 id,使文档与上传文件关联。

MIT Licensed