P1 AIP
知识库:让 AI 查数时"懂业务口径"
业务规则、指标口径、操作手册这类"人脑里的知识",写进知识库后会被自动分块、向量化、版本管理,并在 NLQ 查数时作为 RAG 上下文注入 Text2SQL——AI 看到"本月销售额 = 订单金额 - 退款金额"这样的口径,生成的 SQL 才更对。看完这 3 个故事,你就能把一条业务口径变成 AI 的"业务常识"。
数据工程师
业务分析师
知识库
文档
版本
RAG
共 3 个故事
能 / 不能速览
✅ 这个主题能做
- 多级目录组织文档,text / markdown / html 三种格式内容直传
- 自动分块:500 字符 / 重叠 50,rune 级切割不拆散中文,块级 SHA256 去重
- 版本管理:内容变化自动新建版本,可回滚,单文档最多 20 个版本
- 混合检索:语义(向量 0.6)+ 关键词(LIKE 0.4)加权融合
- 作为 RAG knowledge 通道,把业务口径注入 Text2SQL prompt
- embedding key 缺失时自动降级伪随机向量,链路不断(degraded 标记)
⛔ 这个主题做不了
- 没有文件上传 / URL 导入 / API 推送,只能文本内容直传
- 没有 PDF 解析器,只支持 text / markdown / html
- 知识问答未接入:问"什么是 X"仍返回占位提示(知识库只服务 RAG 召回)
- 索引是同步执行,长文档创建 / 更新请求会等分块向量化完成
- 无 DashScope key 时语义检索质量降级(伪随机向量中文命中率下降)
适用角色
本主题面向两个角色:
- 数据工程师:知识库的管理员,负责建目录、写文档、维护版本、配标签。
- 业务分析师:知识库的受益者,口径写进知识库后 NLQ 查询更准;也可以自己补充业务规则。
知识库页面在 /knowledge,登录即可用(protected),无需 admin。
能力速览(能做什么)
目录管理
多级目录树组织文档,parent_id 嵌套,创建 / 查询目录树。
文档接入与分块
text / markdown / html 直传,解析器注册表可扩展;滑动窗口 500/50 rune 级分块。
版本与回滚
内容哈希(SHA256)变化自动建版本,RestoreVersion 回滚,20 版本上限裁剪。
混合检索
语义向量 0.6 + 关键词 LIKE 0.4,min-max 归一化融合,filterActive 过滤。
RAG 通道
RAG 多路召回中的 knowledge 通道调用 KnowledgeService.Search,拼成业务知识段落注入 Text2SQL。
标签
文档打标签,GET /knowledge/tags 聚合全部 active 文档标签。
调整指南(怎么调整)
- 改分块粒度:块大小与重叠是常量(500/50),想改需改代码重新部署;文档写短一点自然分块更细。
- 改检索权重:语义 0.6 / 关键词 0.4 是常量;想让精确术语(编号)更易命中,多写关键词、少用口语。
- 改文档内容:更新文档内容自动建新版本并重建索引(先清理旧向量 + 旧 chunk),改完立即影响 RAG 检索。
- 改检索质量:embedding key 缺失时检索走降级向量,配置 DashScope key 后重建文档索引即可恢复正常。
- 改删除行为:删除是软删(archived)+ 清向量 + 检索侧 active 过滤,删完不会再命中。
做得好的场景
知识库在"口径说明类文档"上收益最明显:
- 口径即文档:把"销售额 = 订单金额 - 退款金额""价格含税不含税"这类规则写进知识库,RAG 查数自动带上,AI 生成的 SQL 更贴合业务。
- 版本可追溯:口径改过几次、什么时候改的,版本列表一目了然,改错了能一键回滚。
- 删改即时生效:文档更新 / 删除立刻影响 RAG 检索,不残留旧口径误导模型。
限制与不足
以下是明确的边界,使用前先知道:
- 无问答入口:知识库只作为 RAG 通道,不直接回答"什么是 X";knowledge_qa 意图仍返回占位提示。
- 接入方式单一:仅文本内容直传,无文件上传 / URL / PDF。
- 同步索引:创建 / 更新长文档会阻塞到向量化完成,接口响应随文档长度增长。
- 降级向量:无 embedding key 时是确定性伪随机向量,语义检索质量下降(degraded=true)。
- 检索上限:默认 topK 10、最大 50;混合权重为常量,不可在界面调整。
场景故事
故事 1
数据工程师把"销售额口径说明"写进知识库,检索立刻命中
场景:建文档 + 检索
角色:数据工程师
耗时:约 5 分钟
- 背景
- 陈工负责演示库的元数据质量。业务同事总问"销售额到底怎么算的"——orders 表里 sales_amount 是已成交金额,但没人写下来。他把口径整理成 markdown 文档,登录 http://127.0.0.1:18080(admin / admin1),进入知识库页(/knowledge),建目录、写文档。
- 传统做法对比
- 以前口径记在群里、Excel 里、人脑子里,问一次解释一次;现在写进知识库自动分块向量化,检索秒级命中,还能被 NLQ 查数时自动带上。
- 角色
- 数据工程师(知识库内容维护者)。
- 操作步骤
-
- 在 /knowledge 创建目录"指标口径"
- 创建文档:标题"销售额口径说明",format=markdown,内容含 "## 销售额\n本月销售额 = 订单金额 - 退款金额,指已成交订单的实付金额"
- 给文档打标签 ["销售", "口径"]
- POST /knowledge/search 检索"销售额怎么算"验证命中
- 系统响应
- 创建文档返回(201)索引进度:
{
"code": 0, "message": "created",
"data": {
"document": { "id": 1, "title": "销售额口径说明", "format": "markdown",
"status": "active", "version": 1 },
"chunk_count": 2, "indexed": 2, "failed": 0, "degraded": false
},
"trace_id": "uuid"
}
检索"销售额怎么算"命中该文档(分数 0.82),并返回命中的 chunk 内容片段。
- 结果洞察
- 陈工注意到 chunk_count=2——文档按 500 字符滑动窗口被切成 2 块并向量化入库;degraded=false 表示这次是真实 embedding(DashScope key 已配置)。检索用"语义 + 关键词"两路融合:语义路召回同义改写问法,关键词路命中"销售额"这个精确词。
- 调整建议
- 检索时把 top_k 调大(默认 10、上限 50)看更多候选;文档里把业务同义词(销售额 / 成交额 / GMV)都写进去,关键词路命中率更高;给文档打标签便于后续筛选。
- 动手试一试
- 登录:admin / admin1。页面路径:/knowledge。操作:建目录 → 建 markdown 文档"销售额口径说明" → POST /knowledge/search,body {"query":"销售额怎么算","top_k":10}。预期结果:创建返回 chunk_count>0、degraded 反映 embedding key 状态;检索返回 document_id=1 且 score 较高。
- 限制提示
- 文档内容必须非空且格式在 text/markdown/html 内,否则 400;没有 DashScope key 时创建返回 degraded=true,语义路是伪随机向量,检索分数仅供参考;知识库只服务 RAG 召回,不直接回答"什么是 X"。
故事 2
口径改了:更新文档自动建版本 v2,回滚一键回到 v1
场景:版本管理
角色:数据工程师
耗时:约 5 分钟
- 背景
- 财务新规:从本月起"销售额"要加上赠品折算金额。陈工更新了"销售额口径说明"文档,财务后来又说新规暂缓执行——他需要把口径改回去。知识库的版本管理让他两步完成:先看改了什么版本,再回滚。
- 传统做法对比
- 以前口径文档改完就覆盖了,旧版本找不回来,返工靠翻聊天记录;现在内容哈希变化自动新建版本,每个版本有 change_note,回滚走更新路径自动重建索引,两分钟搞定。
- 角色
- 数据工程师(知识库维护者)。
- 操作步骤
-
- PUT /knowledge/documents/1 更新内容(加一句"含赠品折算")
- GET /knowledge/documents/1/versions 查看版本列表(v1 / v2)
- POST /knowledge/documents/1/versions/1/restore 回滚到 v1
- GET /knowledge/documents/1 确认当前版本与内容
- 系统响应
- 更新后文档版本变为 2 并重建索引:
{
"id": 1, "title": "销售额口径说明", "format": "markdown",
"status": "active", "version": 2
}
版本列表返回两条(v2 最新 / v1 初始),回滚后:{
"id": 1, "title": "销售额口径说明", "format": "markdown",
"status": "active", "version": 3
}
content 恢复为 v1 口径(回滚走更新路径,新建 v3 而非覆盖 v2)。
- 结果洞察
- 版本机制的核心是"内容哈希触发新版本":内容没变只更新元数据(标题 / 目录 / 标签)不会建版本;内容变了自动建版本并重建索引(先清理旧向量 + 旧 chunk)。回滚后 version=3 而不是 1,保留了完整历史——财务说"再改回去"也有据可查。单文档最多保留 20 个版本,超限自动裁剪最旧。
- 调整建议
- 重要变更用 change_note 说明改了什么、为什么改;回滚前先看版本列表,别回错目标;多个人维护同一文档时,以版本记录为准对齐口径。
- 动手试一试
- 登录:admin / admin1。页面路径:/knowledge → 文档详情。操作:更新内容 → 看版本列表 → 回滚 v1。预期结果:更新后 version=2、回滚后 version=3;GET .../versions 始终保留全部历史(≤20 条)。
- 限制提示
- 版本上限 20 个,超限最旧版本会被自动删除;回滚目标是"等于当前版本"时不动作;版本内容存的是解析后的纯文本,markdown 的代码块会在解析阶段被移除。
故事 3
知识库口径让 NLQ 查数更准:AI 看到"销售额定义"才选对列
场景:RAG 联动
角色:业务分析师 + 数据工程师
耗时:约 10 分钟
- 背景
- 王姐在 /chat 问"查询订单的平均金额",之前 AI 老把 price(单价)当金额,平均下来 99.5 元明显不对。陈工把"销售额 = 实付金额(sales_amount),非单价(price)"写进知识库后,让王姐再问一次,看 RAG 是否把口径带给了 Text2SQL。
- 传统做法对比
- 以前模型只能靠列名猜,price 和 sales_amount 都像金额,问法稍含糊就答错;现在知识库把口径写清楚,RAG 召回时自动把"业务知识"段落注入 prompt,模型按定义选列,一次问对。
- 角色
- 数据工程师(写口径文档)+ 业务分析师(验证 NLQ 结果)。
- 操作步骤
-
- 陈工在知识库写文档"金额口径":orders 表 sales_amount=订单实付金额、price=商品单价
- 王姐在 /chat 输入"查询订单的平均金额",看返回的 sql_query
- 对比注入口径前后两次查询的 SQL 列选择
- POST /knowledge/search {"query":"平均金额"} 验证命中"金额口径"
- 系统响应
- 写入口径文档后,NLQ 返回的 SQL 从 price 变成 sales_amount:
// 写入口径前(模型猜列):
sql_query: "SELECT AVG(price) FROM orders"
explanation: "订单的平均单价"
// 写入口径后(RAG knowledge 通道注入"业务知识"段落):
sql_query: "SELECT AVG(sales_amount) FROM orders"
explanation: "订单的平均销售金额(口径:销售额=实付金额)"
检索验证:POST /knowledge/search 命中"金额口径"文档,score 0.9。
- 结果洞察
- 知识库文档进入了 RAG 四路召回中的 knowledge 通道:RAG 调 KnowledgeService.Search(query, 15),把命中的【标题】+内容拼成"业务知识"段落注入 Text2SQL prompt。模型看到"sales_amount=订单实付金额、price=商品单价"的定义后,按定义选列,平均值从 99.5(单价)变成约 1294.1(实付金额,6470.5 ÷ 5)。王姐对这演示库 5 笔订单的销售金额做了核对,口径和列选择都对上了。
- 调整建议
- 把容易混淆的字段口径都写成文档(金额 / 数量 / 日期范围);更新文档后让用户重新查询(改完即时影响 RAG);如果检索没命中,先检查文档状态是否 active、关键词是否与问法一致。
- 动手试一试
- 登录:admin / admin1。操作:先问"查询订单的平均金额"记下 SQL;去 /knowledge 建"金额口径"文档,再问一次。预期结果:第一次多用 price,第二次 SQL 改为 sales_amount(或至少 sql_explanation 提到"实付金额");知识库检索能命中"金额口径"。
- 限制提示
- 知识库检索失败(embedding / 向量库异常)不会中断 RAG 链路,只跳过 knowledge 通道,结果可能回到"靠列名猜";knowledge 通道权重 0.25,命中与否取决于问题与文档的相关度;模型仍可能结合上下文自行判断,口径文档只是增加命中概率而非保证。
常见问题
知识库能直接回答"什么是销售额"吗?
不能。知识库只作为 RAG 的 knowledge 通道,把文档上下文注入 Text2SQL;"什么是 X"这类问题会命中 knowledge_qa 意图并返回占位提示。独立的知识问答入口属未来版本。
文档更新后旧内容还会被检索到吗?
不会。内容变化会重建索引(清理旧 chunk + 旧向量)并新建版本;删除文档会软删(archived)+ 清向量 + 检索侧 active 过滤三重保障,旧内容不会再命中。
没配 DashScope key 还能用吗?
能。embedding 会自动降级为确定性伪随机向量,索引与检索链路不断;创建文档返回 degraded=true,语义检索质量下降,但关键词路(LIKE)仍可用。
分块是怎么切的?
滑动窗口:块大小 500 字符、重叠 50 字符,按 rune 切割不拆散 UTF-8 多字节字符(中文 / emoji);同一文档内重复块按 SHA256 去重;全空白内容返回一个块。
为什么 markdown 文档里的代码块不见了?
Markdown 解析器会去除 ``` 围栏代码块,避免代码噪音进入 RAG 上下文(代码与业务语义无关且占 Token);HTML 解析器同理会剥离 script/style 与标签,只提取纯文本。
主题小结
一句话:知识库 = 目录 + 文档 + 版本 + 分块 + 混合检索,把企业业务规则变成 AI 的"业务常识"并注入 NLQ 查询。记住边界:只做 RAG 召回不做问答、只支持文本直传无文件上传、无 PDF、同步索引、无 key 时语义降级。口径类文档收益最大——写清楚、常维护、勤回滚。