首页
/ Langchain-Chatchat 知识库元数据持久化指南:knowledge_base_repository 数据层函数全解析

Langchain-Chatchat 知识库元数据持久化指南:knowledge_base_repository 数据层函数全解析

2026-09-08 14:18:31作者:裘晴惠Vivianne

本篇技术指南聚焦 Langchain-Chatchat 中知识库元数据(知识库名称、简介、向量库类型、嵌入模型等)的数据库持久化层实现——即 knowledge_base_repository 模块。知识库的“创建 / 查询 / 校验 / 删除 / 详情读取”都经由这里与数据库打交道,它是 KBService、知识库 HTTP 接口乃至 Agent 本地知识库工具之间的数据枢纽。读完本文,你将完整掌握该 Repository 层 6 个核心函数的签名、语义、内部实现与调用链,并能在二次开发中正确复用它们。

模块定位:Repository 层与 knowledge_base

Langchain-Chatchat 将「知识库」拆分为两层概念:磁盘/向量库中的实际内容,与数据库中记录的元数据。前者由 server/knowledge_base 下的各个 KBService 实现类负责,后者统一由 Repository 层封装 SQLAlchemy 查询,避免业务代码直接拼接 ORM 查询。

本模块的底层表结构与 ORM 模型定义在 knowledge_base_model.py 中:

字段 类型 说明
id Integer 主键自增 知识库 ID
kb_name String(50) 知识库名称(业务上的唯一标识)
kb_info String(200) 知识库简介(注释标明“用于 Agent”,即作为 Agent 选择工具的知识库说明)
vs_type String(50) 向量库类型,如 faiss / milvus / pg / es / zilliz / chromadb / relyt / default
embed_model String(50) 嵌入模型名称
file_count Integer 默认 0 该知识库中的文件数量
create_time DateTime 默认 now 创建时间

文件末尾还定义了对应的 Pydantic 模型 KnowledgeBaseSchemafrom_attributes = True),用于把 ORM 实例安全地转换为 JSON 友好的数据对象。这一点会直接影响后文 list_kbs_from_db 的返回值形态。

Repository 层的 6 个函数全部位于 knowledge_base_repository.py 中,均被 @with_session 装饰器修饰。从 session.py 的源码可以看到,with_session 会自动创建 session_scope() 上下文,把 session 作为第一个位置参数注入被装饰函数,并在函数正常返回后自动 commit()、异常时自动 rollback()。因此调用方无需手动传入 session,也无需自行提交,例如 kb_api.pyListResponse(data=list_kbs_from_db()) 的直接调用。

add_kb_to_db:知识库记录的“存在则更新,不存在则插入”

该函数是知识库元数据的唯一写入口,同时承担「新建」与「更新」两种职责(即 upsert):

@with_session
def add_kb_to_db(session, kb_name, kb_info, vs_type, embed_model):
    kb = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.kb_name.ilike(kb_name))
        .first()
    )
    if not kb:
        kb = KnowledgeBaseModel(
            kb_name=kb_name, kb_info=kb_info, vs_type=vs_type, embed_model=embed_model
        )
        session.add(kb)
    else:  # update kb with new vs_type and embed_model
        kb.kb_info = kb_info
        kb.vs_type = vs_type
        kb.embed_model = embed_model
    return True

参数语义

参数 类型 说明
session Session 数据库会话(由 @with_session 自动注入)
kb_name str 知识库名称,作为查询与唯一标识依据
kb_info str 知识库简介,用于 Agent 理解该知识库用途
vs_type str 向量库类型标识
embed_model str 所使用的嵌入模型名称

核心逻辑:先用 kb_name.ilike(kb_name) 做大小写不敏感查询;查不到则 session.add 一条新记录(file_countcreate_time 走模型默认值);查得到则就地更新 kb_infovs_typeembed_model 三个可变字段。由于 with_session 在函数返回后统一提交,add_kb_to_db(...) 恒返回 True 表示操作成功。调用示例:add_kb_to_db('技术文档库', '存储技术相关文档', 'es', 'BERT')

典型调用场景:在 kb_service/base.pyKBService.create_kb() 中,先为磁盘上的文档目录建目录,再调用本函数写入元数据,随后才调用 do_create_kb() 初始化具体向量库;update_info()base.py#L168-L176)也复用本函数更新简介——因为 upsert 语义天然安全,业务层无需区分“新增还是更新”。

list_kbs_from_db:按文件数量条件列出知识库

@with_session
def list_kbs_from_db(session, min_file_count: int = -1):
    kbs = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.file_count > min_file_count)
        .all()
    )
    kbs = [KnowledgeBaseSchema.model_validate(kb) for kb in kbs]
    return kbs

min_file_count 为文件数量下限,默认 -1,即“不对文件数量做限制”(任意 file_count > -1 均成立)。查询命中后,每个 ORM 实例都会被 KnowledgeBaseSchema.model_validate(kb) 转换为 Pydantic 对象再返回——因此当前版本返回的是 KnowledgeBaseSchema 对象列表(含 idcreate_time 等完整字段),而非纯字符串名称数组;下游通过 kb.kb_namekb.kb_info 属性访问字段即可。这也解释了为什么本模块文档示例中的“返回 ['知识库B', '知识库C']”只是早期版本的语义,现代码以对象列表为准。

调用场景

  • server/utils.py 中构造 Agent 本地知识库工具时,会遍历 list_kbs_from_db() 的结果生成提示词模板,逐个拼出 "{kb_name}: {kb_info}",告诉 Agent 有哪些本地知识库可用;
  • kb_api.py#L16-L18list_kbs API 直接将其包进 ListResponse 返回;
  • kb_service/base.py#L287-L289KBService.list_kbs() 类方法同样转发该函数。

kb_exists:知识库存在性校验

@with_session
def kb_exists(session, kb_name):
    kb = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.kb_name.ilike(kb_name))
        .first()
    )
    status = True if kb else False
    return status

通过 ilike 做不区分大小写的匹配,命中即返回 True,否则返回 False,可直接用于条件判断。典型用法是 KBService.exists()base.py#L291-L293),业务中常用于“添加同名知识库前的去重校验”与“执行操作前的存在性确认”。调用示例:数据库中已存在「技术文档库」时,kb_exists(session, "技术文档库") 返回 True;查询不存在的库名则返回 False

load_kb_from_db:加载知识库运行所需的三元组

@with_session
def load_kb_from_db(session, kb_name):
    kb = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.kb_name.ilike(kb_name))
        .first()
    )
    if kb:
        kb_name, vs_type, embed_model = kb.kb_name, kb.vs_type, kb.embed_model
    else:
        kb_name, vs_type, embed_model = None, None, None
    return kb_name, vs_type, embed_model

该函数聚焦「服务实例化」真正需要的三个字段,返回 (kb_name, vs_type, embed_model) 三元组;未命中时三者均为 None。注意这里的返回值是重新赋值的本地变量,与入参同名,但语义是“库内规范化后的名称”。

关键调用点kb_service/base.py#L422-L426KBServiceFactory.get_service_by_name()

@staticmethod
def get_service_by_name(kb_name: str) -> KBService:
    _, vs_type, embed_model = load_kb_from_db(kb_name)
    if _ is None:  # kb not in db, just return None
        return None
    return KBServiceFactory.get_service(kb_name, vs_type, embed_model=embed_model)

这段代码正是“数据库元数据 → 具体向量库服务”的路由桥梁:先从库里读出 vs_type 与 embed_model,再据此实例化 faiss、milvus、pg 等对应的 KBService 实现;若记录不存在(返回 (None, None, None))则返回 None,调用方据此给出 404 响应。可以推断,load_kb_from_db 是连接“持久化元数据”与“向量库运行时”的关键纽带,服务重启后系统正是靠它把每个知识库恢复出来。

delete_kb_from_db:删除指定知识库记录

@with_session
def delete_kb_from_db(session, kb_name):
    kb = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.kb_name.ilike(kb_name))
        .first()
    )
    if kb:
        session.delete(kb)
    return True

同样以大小写不敏感的 ilike 定位记录,命中则 session.delete(kb) 删除,未命中则静默跳过;无论哪种情况都返回 True 表示“流程已完成”。它只负责清理 knowledge_base 表中的元数据行,不触碰磁盘文件与向量库内容——真正的物理清理由调用方负责。

这一点在 KBService.drop_kb()base.py#L109-L115)中体现得非常清晰:先调用 do_drop_kb() 让子类实现销毁各自的向量库/索引,再调用 delete_kb_from_db(self.kb_name) 清掉元数据行。HTTP 层对应的则是 kb_api.pydelete_kb 的“先 clear_vs()drop_kb()”流程。建议在调用后通过查询或其他途径验证删除确实生效,因为返回值恒为 True

get_kb_detail:读取知识库完整信息字典

@with_session
def get_kb_detail(session, kb_name: str) -> dict:
    kb: KnowledgeBaseModel = (
        session.query(KnowledgeBaseModel)
        .filter(KnowledgeBaseModel.kb_name.ilike(kb_name))
        .first()
    )
    if kb:
        return {
            "kb_name": kb.kb_name,
            "kb_info": kb.kb_info,
            "vs_type": kb.vs_type,
            "embed_model": kb.embed_model,
            "file_count": kb.file_count,
            "create_time": kb.create_time,
        }
    else:
        return {}

该函数返回字段最全(6 个字段)的字典形式详情;未命中时返回空字典 {},便于调用方用 if detail: 做存在性判断。命中时的典型返回示例:

{
    "kb_name": "技术文档库",
    "kb_info": "存储技术相关文档的知识库",
    "vs_type": "ElasticSearch",
    "embed_model": "BERT",
    "file_count": 100,
    "create_time": "2023-04-01T12:00:00",
}

从源码的调用关系看,get_kb_detailKBService 各实现类共同服务于知识库详情展示链路:get_kb_details()base.py#L434)会把 list_kbs_from_folder() 的磁盘目录结果与数据库中的记录合并比对,而 knowledge_base.py(WebUI 页面)通过 get_kb_details() 渲染知识库列表。可以推断 get_kb_detail 面向单库粒度、被包装进更上层的服务后,为 WebUI 与 API 提供稳定的详情数据源。

会话与事务:你真正需要记住的三件事

阅读本模块文档时有一处需要注意:原文档“注意”中写道“此函数不负责提交数据库会话,调用者需要自行决定是否提交”。但结合当前仓库 session.py@with_session 实现,6 个函数都已被装饰器包裹,函数返回后 wrapper 会自动 commit、异常时自动 rollback 并抛出,因此业务调用方无需也无法手动注入 session。实际操作中建议遵循以下三点:

  1. 调用时不要传 sessionwith_session 会自动创建并注入,显式多传会破坏参数绑定,直接写 add_kb_to_db(kb_name, kb_info, vs_type, embed_model) 即可;
  2. 异常处理交给装饰器:查询失败会回滚并向上抛出,业务层捕获后返回 5xx 或对应错误提示即可;
  3. 注意查询匹配规则:所有查询都基于 ilike 做大小写不敏感的模糊匹配,因此命名相近的知识库(如 Samplessamples)会被视为同一库;创建新库前请先用 kb_exists 校验,避免误覆盖元数据。

小结:六个函数的分工一览

函数 职责 返回值 主要消费方
add_kb_to_db 新增/更新知识库元数据(upsert) True KBService.create_kb() / update_info()
list_kbs_from_db 按文件数下限列出知识库 KnowledgeBaseSchema 对象列表 list_kbs API、Agent 工具提示词构造、KBService.list_kbs()
kb_exists 校验知识库是否存在 bool KBService.exists()、建库去重
load_kb_from_db 读取 (kb_name, vs_type, embed_model) 三元组(未命中为三个 None KBServiceFactory.get_service_by_name() 路由
delete_kb_from_db 删除元数据行 True KBService.drop_kb()delete_kb API
get_kb_detail 读取完整详情字典 dict(未命中为 {} 知识库详情/WebUI 展示链路

配合 knowledge_base_model.md 了解表结构、session.md 理解会话机制、kb_service/base.mdkb_api.md 掌握上层服务与 HTTP 接口的完整脉络,即可对 Langchain-Chatchat 知识库元数据从建库到删除的整个生命周期形成闭环认识,并据此安全地进行自定义 Repository 或 Service 扩展。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.74 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
595
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.63 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
518
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
389