# 知识库建好了但够不够用?向量检索量化覆盖率,找到你的知识盲区
知识库建好了但够不够用向量检索量化覆盖率找到你的知识盲区背景政务热线RAG系统上线前最怕的不是回答错了而是答不上来。知识库是从各种政策文档、办事指南里整理出来的几千条问答。热线那边积累了十几万条真实来电记录。问题来了知识库能覆盖多少真实问题哪些问题是知识库的盲区不能拍脑袋说差不多够了吧。得量化。思路把热线问题逐条向量化去Milvus知识库里搜看最高相似度是多少。相似度 ≥ 0.85知识库里有高度匹配的答案覆盖了相似度 0.6 ~ 0.85知识库里有相关的但不精确可能需要补充相似度 0.6知识库里几乎没有相关内容纯盲区逐条跑完统计三个区间的比例覆盖率一目了然。实现第一步热线问题向量化defvectorize_text(text):urlhttp://localhost:11434/api/embeddingsdata{model:bge-m3:latest,prompt:text}responserequests.post(url,jsondata)ifresponse.status_code200:returnresponse.json().get(embedding,[])returnNone本地Ollama bge-m3零API费用。第二步逐条搜索知识库frompymilvusimportMilvusClient clientMilvusClient(urihttp://your_milvus_host:19530,tokenyour_token,db_namedefault)search_params{metric_type:COSINE,params:{radius:0.0}}注意radius0.0——我们要看到每条问题和知识库的最高相似度不管多低都返回不能设过滤阈值。pathnamed:\\q\\覆盖率分析.txtfileopen(pathname,w,encodingutf-8)foriteminhotline_questions:question_textitem[Question]question_vectorvectorize_text(question_text)# 在知识库中搜索最相似的10条resclient.search(collection_nameknowledge_base,data[question_vector],limit10,output_fields[uid,Question],search_paramssearch_params)ifres[0].__len__()0:best_matchres[0][0]file.write(question_text\tstr(best_match[entity][uid])\tstr(best_match[distance])\tbest_match[entity][Question]\n)else:file.write(question_text\t无匹配\t0.0\t\n)file.close()第三步统计覆盖率输出文件每行四列热线问题\t知识库uid\t最高相似度\t知识库问题按相似度分三档统计区间含义建议动作≥ 0.85高度覆盖直接可用0.6 ~ 0.85部分覆盖需补充精确答案 0.6知识盲区需新建知识条目实际跑出来覆盖率大致分布脱敏示意高度覆盖≥0.85约 60% 部分覆盖0.6~0.85约 25% 知识盲区0.6约 15%这15%就是知识库的盲区。拿着这份清单去找业务部门补知识比拍脑袋差不多够了吧靠谱得多。进阶按业务分类统计覆盖率盲区不是均匀分布的。社保缴费这种高频话题知识库覆盖率高特殊工种提前退休这种低频但专业的问题覆盖率可能很低。把热线问题先分类参保、缴费、社保卡、养老、医疗……再按类别统计覆盖率就知道哪个业务线的知识库最缺参保类覆盖率 82% ← 不错 缴费类覆盖率 78% ← 还行 社保卡覆盖率 65% ← 得补了 特殊工种覆盖率 31% ← 严重不足优先补分类可以用LLM做一句话搞定defclassify_question(question_text):prompt(question_text 分类为参保、缴费、社保卡、养老保险、失业保险、医疗保险、工伤保险、生育保险、人事、就业培训、就业、社保档案、其他档案、其他之间那一类问题只需返回分类的那几个字)responseclient.chat.completions.create(modeldeepseek-chat,messages[{role:user,content:prompt}],streamFalse)returnresponse.choices[0].message.content分类成本很低——一条问题一次LLM调用几厘钱。关键参数参数值为什么radius0.0不设过滤全部返回需要看到每条的真实相似度limit10只看Top-10取最高的那个distance作为覆盖率指标metric_typeCOSINE余弦相似度和去重时的标准一致Embeddingbge-m3和知识库入库时的模型必须一致否则向量空间不同踩坑1. Embedding模型必须和知识库一致知识库入库时用的bge-m3检索时也必须用bge-m3。换成别的模型比如bge-large-zh-v1.5向量空间不同相似度没有可比性。我在换模型时就踩过——换了之后覆盖率从60%跳到85%不是知识库变好了是两套模型的相似度标尺不一样。2. radius0.0不是所有Milvus版本都支持早期版本radius不支持0.0会报错。升到2.4就行了。3. limit别设太小有些问题的最佳匹配可能不在Top-3里。设10比较稳妥既能看到最好的匹配又不会因为排序噪声误导判断。总结知识库覆盖率可以量化把真实问题逐条向量化搜知识库看最高相似度分三档统计≥0.85 / 0.6~0.85 / 0.6盲区一目了然按业务分类统计覆盖率知道该补哪个方向的知识全程Embedding用本地Ollama唯一花钱的是分类那一步LLM调用成本忽略不计