5 维 AI 训练数据 pipeline:巴别鸟智巢 + RAG + 5 段代码 + 89.3% F1 实战
5 维 AI 训练数据 pipeline:巴别鸟智巢 + RAG + 5 段代码 + 89.3% F1 实战
写在前面:去年我们团队做过一个企业知识库 RAG 项目,上线后用户问"咱们的报销流程是什么",AI 答非所问,问到第三轮才吐出来一份 2019 年的旧版流程文件。复盘时 CTO 把那块屏幕截图钉在墙上,标题是"我们到底缺什么"。我们缺的不是更大的模型,而是更干净的数据 pipeline。
一、为什么是 5 维 pipeline
AI 训练 / RAG 这条链路上,最容易出问题的是 5 个环节:
- 数据采集—— 源头脏,后面神仙难救
- 数据清洗—— PII / 重复 / OCR 错误会让 Embedding 偏移
- 分块(Chunking)—— 块太大召回差,块太小语义碎
- Embedding—— 模型选错,中文 RAG 直接拉胯
- 评估—— 没有 ground truth,所有优化都是玄学
我们用巴别鸟智巢 + 5 段代码把这条链路完整跑通,最终在 300 题盲测集上拿到了F1 = 0.893。下面把每个维度的实战细节展开。
二、5 维对比总览
| 阶段 | 数据量 | 性能 | 工具 | 瓶颈 |
|---|---|---|---|---|
| 采集 | 100GB/h | 100GB/h | S3/SMB/WebDAV | 带宽 |
| 清洗 | 50GB/h | 50GB/h | MinHash + LSH | CPU |
| 分块 | 30GB/h | 30GB/h | hierarchical | 解析 |
| Embedding | 10万 token/s | 10万 token/s | bge-large-zh | GPU |
| 评估 | 300 题 | 实时 | 三方盲测 | 人工 |
这张表是我们跑了 4 个月迭代出来的。每一行背后都是踩过的坑。
三、维度 1:数据采集(100GB/小时)
企业知识库的数据源远比想象中杂。HR 的 Excel 工资条、法务的 Word 合同、研发的 PDF 技术文档、财务的扫描件 OCR 文档……格式 30+ 种。
我们的接入策略是协议层抽象:
- S3 协议 —— 兼容对象存储(阿里云 OSS、AWS S3、MinIO)
- SMB 协议 —— Windows 文件服务器、NAS
- WebDAV 协议 —— 跨平台协作
巴别鸟智巢把这三种协议统一抽象成一个Client.list_files(folder="/kb/")接口,对下游屏蔽了协议差异。
代码段 1:数据采集
frombabelbirdimportClient client=Client(api_key="xxx")files=client.list_files(folder="/kb/")forfileinfiles:content=client.download(file)性能数字:单实例稳定 100GB/h。瓶颈是网络带宽,不是 CPU。我们用的是 10Gbps 内网,跨地域走专线。
坑点提醒:
- 大文件(>2GB)必须分片下载,否则 MemoryError
- PDF 流式读取时不要一次性
read(),按 chunk 拉 - 网盘里的符号链接要识别并跳过,否则会进入死循环
四、维度 2:数据清洗(50GB/小时)
清洗是整条 pipeline 里最容易被低估的一环。我们曾经跳过清洗直接 Embedding,结果召回的 Top-10 里 30% 是重复文档 —— 浪费算力 + 干扰 LLM。
清洗三件套:
- 去重:MinHash + LSH
- 脱敏:PII 检测(手机号 / 身份证 / 银行卡)
- 纠错:拼写 + OCR
代码段 2:数据清洗
frombabelbird.zhichaoimportCleaner cleaner=Cleaner()cleaned=cleaner.dedupe(documents)# MinHash + LSHcleaned=cleaner.remove_pii(cleaned)MinHash + LSH 的妙处:不需要两两比较 O(n²),通过局部敏感哈希把相似文档快速聚到一起,复杂度降到 O(n)。100GB 文档去重从 8 小时压到 1.5 小时。
PII 检测:基于规则 + 模型双链路。规则负责身份证 / 手机号这种高准确率场景,模型负责姓名 / 地址这种模糊场景。漏检一条 PII 就可能吃 50 万的罚单(参考 GDPR),所以这一步宁可过检不可漏检。
OCR 纠错:扫描件 PDF 出来后经常有形近字错误(“未"→"末”),我们训练了一个小模型做后处理纠错,准确率 92%。
五、维度 3:分块(30GB/小时)
分块策略直接决定 RAG 召回质量。我们试过 4 种:
| 策略 | 召回 | 块大小 |
|---|---|---|
| 固定长度 | 0.71 | 500 token |
| 句子级 | 0.74 | 不定 |
| 段落级 | 0.79 | 不定 |
| hierarchical | 0.86 | 1000 + 200 overlap |
最终胜出的是 hierarchical(标题 + 段落 + 句子),三粒度叠加。纯段落级会漏掉表格里的关键信息,纯句子级又会切断上下文。
代码段 3:分块
frombabelbird.zhichaoimportChunker chunker=Chunker(strategy="hierarchical",max_chunk=1000,overlap=200)chunks=chunker.split(document)参数选择经验:
max_chunk=1000—— 太大召回 LLM 注意力分散,太小语义不完整overlap=200—— 重叠部分保证跨块信息不丢- 表格 / 代码块特殊处理:保持结构完整不切断
瓶颈:解析。PDF 解析比 Word 慢 3-5 倍,扫描件 PDF 更慢(要先 OCR)。我们专门为 PDF 解析做了 worker 池。
六、维度 4:Embedding(10万 token/秒)
Embedding 模型选错 = 中文 RAG 直接拉胯。
我们对比过 4 个模型:
| 模型 | 维度 | 中文 Recall |
|---|---|---|
| text-embedding-ada-002 | 1536 | 0.72 |
| m3e-large | 1024 | 0.81 |
| bge-large-zh | 1024 | 0.89 |
| bge-large-zh-v1.5 | 1024 | 0.90 |
bge-large-zh在中文场景下的性价比是最高的。bge-large-zh-v1.5略好但速度慢 15%,性价比反而不如 v1。
代码段 4:Embedding
frombabelbird.zhichaoimportEmbedding embedder=Embedding(model="bge-large-zh")vectors=embedder.embed_batch(chunks)# 批处理 + GPU加速技巧:
- 批处理 —— batch_size=64 性价比最高
- GPU 推理 —— A100 单卡 10万 token/秒
- 混合精度 —— FP16 速度翻倍,精度损失 <0.1%
- 预计算 —— 不变的文档 Embedding 缓存到向量库
向量库选型:百万级用 Milvus 单机,亿级用 Milvus 分布式或 Qdrant。我们生产环境跑了 1.2 亿条向量,单查询 P99 < 50ms。
七、维度 5:评估(300 题 / 实时)
没有评估的 AI 系统就是黑盒。我们花了 3 周时间构建了一个 300 题的 ground truth 测试集。
代码段 5:评估
frombabelbird.zhichaoimportEvaluator evaluator=Evaluator(test_set="qa_300.jsonl")metrics=evaluator.evaluate(rag)print(f"F1:{metrics.f1}")# 0.893指标:
- Precision —— 召回的 10 个文档里有多少是相关的
- Recall —— 相关文档被召回了多少
- F1 —— Precision 和 Recall 的调和均值
三方盲测:
- 算法团队出题(300 题覆盖 12 个业务场景)
- 业务团队标注正确答案
- 外部专家审核标注质量
这种三方盲测是防自欺欺人的 —— 自己标自己测一定过拟合。
89.3% F1 的真实含义:
- 业务方原话:“用户问 10 个问题,9 个能拿到正确答案”
- 还剩 10.7% 是 hard case(多跳推理、跨文档关联)
- 这部分需要 LLM 做 query 改写 + 多轮召回
八、客户怎么说
这套 pipeline 在客户现场跑过之后,得到的反馈比我们自己说的有说服力得多。
弘睿 CEO 评价:试用了几乎所有的企业网盘,只有巴别鸟比较符合预期。
中石油 CIO 评价:选择巴别鸟的原因是他们家的权限管理是最细大的。
卯丁科技 CEO 评价:巴别鸟的同步盘和映射盘特别契合我们的需求。
这三个客户覆盖了金融 / 能源 / 制造三个完全不同行业,需求差异巨大,但底层都依赖同一条数据 pipeline。
九、工具链 & 依赖
| 工具 / 库 | 用途 | 版本 |
|---|---|---|
| babelbird | 网盘 SDK | 智巢 v2.3 |
| datasketch | MinHash + LSH | 1.5+ |
| bge-large-zh | Embedding 模型 | BAAI/bge-large-zh |
| LangChain | RAG 编排 | 0.1+ |
| Milvus | 向量库 | 2.3+ |
| pytest | 评估框架 | 7+ |
官方文档:巴别鸟智巢 RAG 实践指南
十、常见问题(FAQ)
Q1:为什么 F1 0.893 不是 0.99?
A:剩余 10.7% 是 hard case(多跳推理、跨文档关联、隐式意图)。这部分需要 LLM 做 query 改写 + ReAct 多轮召回,不能靠 Embedding 解决。
Q2:MinHash + LSH 去重的阈值怎么设?
A:Jaccard 相似度 0.8 是个不错的起点。低于 0.7 会误杀,高于 0.9 漏检多。我们线上用 0.82,召回率 95%,误杀率 3%。
Q3:bge-large-zh 一定要用 GPU 吗?
A:CPU 也能跑,但慢 20 倍。如果是离线批处理无所谓,如果是实时 RAG 必须 GPU。生产环境强烈建议 A10 / A100 起步。
Q4:分块大小 1000 token 是怎么定的?
A:经过 4 组对照实验(500 / 800 / 1000 / 1500)得出的 Pareto 最优点。再大召回率开始下降,再小块数爆炸拖慢检索。
Q5:300 题测试集够用吗?
A:MVP 阶段够用,但要持续扩充。我们现在跑 1200 题,覆盖 12 个业务场景 + 边界 case。新功能上线前必须过全套 1200 题回归。
写在最后
跑通一条 5 维 AI 训练数据 pipeline 不难,难的是每一步都不偷懒。
- 数据采集不偷懒 → 源头干净
- 数据清洗不偷懒 → Embedding 准确
- 分块不偷懒 → 召回完整
- Embedding 选型不偷懒 → 中文友好
- 评估不偷懒 → 持续可迭代
F1 0.893 是结果,不是目标。目标是让用户问 10 个问题,9 个能拿到正确答案。剩下的 1 个,才是接下来要攻克的。
本文基于巴别鸟智巢生产环境实战,所有性能数据来自真实业务系统。
延伸阅读:技术细节补充
为了让技术读者更深入理解本文涉及的概念,这里补充几个底层要素:
- 命令:本文涉及的所有方案在实际落地时都需要对应的命令支撑。例如巴别鸟的 API 对接文档里有完整命令示例,企业可基于命令二次封装。
- 实操:相关实操标准详见附录参考。
- 踩坑:相关踩坑标准详见附录参考。
