乐于分享
好东西不私藏

知识库实战2:文档入库全流程:切块、向量化、存储

知识库实战2:文档入库全流程:切块、向量化、存储

繁杂分析交给工具,省心出汇报稿

讲一个经历:把同一批文档用两种切法丢进同一个向量库,结果出来天差地别。

切得太碎的,检索出来全是孤立的短句,答得前言不搭后语。切得太大的更头疼,一段里面混了三四个主题,问"年假怎么休"能给你带到"加班费怎么算"去。

文档入库这件事,我一开始真没当回事,想着切一刀存进去不就完了。结果第一次搭完返工了好几次,前后折腾了快一周。

切块这事,我最早也是瞎切的

那时候哪懂什么切块,以为就是把大文档一刀刀切成小段喂进去就行。搜出来的东西根本没法看,才开始琢磨切多大、怎么切。

参数
怎么设
设错的表现
切多大(chunk_size)
512 到 1024 字,看文档密度
设到 256,一段就一句话,检索出来全是碎片
重叠多少(overlap)
大小的 10%-20%,别省
没设重叠,关键信息刚好卡在两段之间,检索丢了一半
怎么切
按段落或用分隔符,别硬切
按字数硬切,一句话被腰斩,向量直接跑偏

表格和正文混着切这事,让我头疼了好一阵。PDF 表格和纯文本混在一个库,表格被切成碎片,检索出来根本看不懂。

后来我养成的习惯是,表格单独处理,用结构化切块,不要让表格和正文混着切。

后来碰到 PDF、图片、表格混在一起的文档,我都是拿 unstructured 官方 SDK 解析,装好之后几行代码搞定:

# 解析所有格式(unstructured 官方用法)pip install "unstructured[all-docs]"from unstructured.partition.pdf import partition_pdfelements = partition_pdf("年报.pdf")   # PDF / Word / 图片 / 表格 / HTML

切块理清了,接下来是模型

选模型这事,我当时真没当回事,觉得随便挑个开源的就行,结果搜出来的东西全不对路。后来才知道,模型不一样,"相似"的标准也跟着变。

后来我学乖了,选模型就看这几样:

盯什么
怎么判断
注意
MTEB 排名
越高越好,但别只看总分
选跟你语种、任务相关的子项排名
维度
768 起步,1536 稳
维度高检索慢,维度低丢信息,取个中间
支持语种
中文任务别用纯英文模型
混用的话中文部分直接瞎

我见过一个典型情况。

团队用了一个开源英文模型做中文知识库,上线之后搜"加班费怎么算",结果第一条是"加班的定义"。

定义倒是没错,可我问的是怎么算。

向量化落库这一步,我当时用的是 Chroma,几行就进去了:

# 向量化并入库(Chroma,照着跑)pip install chromadbimport chromadbclient = chromadb.Client()col = client.create_collection("docs", metadata={"hnsw:space": "cosine"})col.add(ids=["d1", "d2"], documents=["切好的第1段", "切好的第2段"],        embeddings=[[0.12, 0.34, 0.91], [0.56, 0.78, 0.10]])  # 用 bge 模型转出的向量

索引这事,我一开始也没管

向量存进库之后,还有个事我一开始根本没想起来:索引是要维护的。刚开始几百份的时候不觉得,涨到 3000 份,插入慢了、检索也慢了。

去查,索引参数从上线那天就没动过,一直用默认值。那阵子我隔三差五就要清一次日志,后来才把这几条补上。

翻多了,发现就这几件事:

# 索引维护就这几件事# 1. 改索引类型,写入多用 IVF,查询多用 HNSW#    collection 配置里:index_type = "hnsw"# 2. 按时间分片,单库扛不住就拆#    partition_key = "month"# 3. 定期重建,碎片化之后慢了就重建#    cron: 0 3 * * 0 rebuild_index.py

有一次排查,检索一次 7-8 秒,库里 5 万多条向量,重建跑完就回到 0.5 秒。我当时看着那个耗时曲线,人都懵了。

后来才反应过来是索引该重建了。

量小的时候那几行代码直接跑就行,量上来之后,这几条迟早得补上。

调完这几样,先跑起来

切块、向量化、存储,这三关我都折腾过一遍,参数也调得七七八八了。剩下的坑,多半出在检索和生成环节,那是下一期要聊的。

大概就这些。下一期聊底座和检索:向量库到底怎么选,检索做不对怎么调。

企业知识库实战系列:

知识库系列1:有没有必要建企业知识库?