要让Skywork AI真正读懂企业内部文档、不再胡编乱造,该怎么办?答案是:必须亲手搭建一套匹配中文语义特性的RAG知识库,并在检索环节做针对性优化。这不是调几个API就能解决的事,而是从文档切片、向量生成到索引策略的全链路重控。我们来聊聊具体的操作:按业务线与文档类型分类清洗;用中文标点和标题结构智能切片;选用BAAI/bge-small-zh-v1.5模型向量化并在Milvus建IVF_FLAT索引;三路召回+摘要重排,将答非所问压至5%以下。

准备知识源:先分类再清洗,跳过这步后续全白干
把所有PDF、Word、Excel、扫描件统一扔进一个文件夹,是无效操作。先按业务线(如「产品中心」「客户服务」「合规法务」)建一级目录,再在每类下按文档类型(制度/FAQ/会议纪要/技术方案)建二级子目录。【未分类直接上传会导致向量库混入大量无关噪声,后续检索时召回结果中30%以上内容与问题无关】
对扫描件启用OCR识别,优先选用支持中文字体抗锯齿和表格结构还原的引擎;对Word/PDF中的页眉页脚、修订痕迹、自动编号列表做批量清除——这些非正文内容若保留在文本中,会严重稀释embedding向量的语义浓度。
完成分类与清洗后,将每个子目录打包为独立ZIP,命名格式为「部门_文档类型_日期」,例如「客户服务_FAQ_20260528.zip」。
智能切片:拒绝硬截断,用语义边界代替字数限制
方法一:用LangChain的RecursiveCharacterTextSplitter配置中文适配参数。设置separators为['\n\n', '\n', '。', '!', '?', ';', ':', '、', ',', ''],chunk_size设为384,chunk_overlap设为64。这套组合能自动识别段落空行和中文标点,避免把「用户需在提交前确认协议第3.2条」硬切成两段,丢失关键条件。
方法二:对带明确章节结构的文档(如SOP手册),改用MarkdownHeaderTextSplitter。指定headers_to_split_on = [("#", "level1"), ("##", "level2"), ("###", "level3")],系统会按标题层级切分,并自动注入section_path元数据。后续检索时可强制限定在「# 退货流程 ## 退款时效」范围内召回,大幅压缩误检面。
注意:切片后立即人工抽检10个片段,确认是否出现半句话、孤立项、无主语短句——这类片段必须回退修改切分逻辑,不能留到向量化阶段。
向量化与入库:选对模型+建对索引,否则查得越快错得越稳
第一步:选用BAAI/bge-small-zh-v1.5嵌入模型。该模型在中文长尾词、专业术语、缩略语(如“SLA”“POC”“UAT”)上召回率比text-embedding-3-small高22%,且768维向量在Milvus中单次查询延迟稳定在35ms内,适合企业实时问答场景。
第二步:创建Milvus集合时显式声明索引。执行create_index操作时,指定index_type="IVF_FLAT"、metric_type="COSINE"、params={"nlist": 256};【数据量超5万片段仍未建索引,首次查询将触发FLAT全量比对,单次响应超8秒,用户必然放弃重试】
第三步:插入数据时绑定元数据。除chunk_content和embedding外,必须写入book_id(对应原始文件名哈希)、section_path(来自标题切分)、chunk_type(paragraph/table/equation)、clean_content(已清洗纯文本的tsvector格式),四项缺一不可。
检索优化:三路召回+摘要重排,把“答非所问”压到5%以下
① 启动向量召回:将用户问题向量化后,在Milvus中检索top_k=50的原始片段
② 同步触发关键词召回:对问题提取核心实体(用LTP或SparkNLP),在PostgreSQL的tsvector字段上执行phrase search,取交集过滤掉向量召回中明显偏离的20%结果
③ 对剩余30个片段调用轻量级rerank模型(如bge-reranker-base)打分,只保留前8个送入大模型上下文
关键动作:在rerank前,用BGE模型对每个片段生成32字以内检索摘要(非通用摘要)。例如原文“供应商须在收到PO后48小时内确认交期,超时未确认视为自动弃单”,摘要强制输出为“供应商PO确认时效及弃单规则”。这种摘要专为匹配用户提问中的“多久”“怎么算”“后果”等意图而生,比原文匹配效率提升3.7倍。
完成上述四步后,执行python rag_server.py --mode deploy --config config/skywork-prod.yaml。