业务故事站
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 数据工程师把"销售额口径说明"写进知识库,检索立刻命中
背景
陈工负责演示库的元数据质量。业务同事总问"销售额到底怎么算的"——orders 表里 sales_amount 是已成交金额,但没人写下来。他把口径整理成 markdown 文档,登录 http://127.0.0.1:18080(admin / admin1),进入知识库页(/knowledge),建目录、写文档。
传统做法对比
以前口径记在群里、Excel 里、人脑子里,问一次解释一次;现在写进知识库自动分块向量化,检索秒级命中,还能被 NLQ 查数时自动带上。
角色
数据工程师(知识库内容维护者)。
操作步骤
  1. 在 /knowledge 创建目录"指标口径"
  2. 创建文档:标题"销售额口径说明",format=markdown,内容含 "## 销售额\n本月销售额 = 订单金额 - 退款金额,指已成交订单的实付金额"
  3. 给文档打标签 ["销售", "口径"]
  4. 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
背景
财务新规:从本月起"销售额"要加上赠品折算金额。陈工更新了"销售额口径说明"文档,财务后来又说新规暂缓执行——他需要把口径改回去。知识库的版本管理让他两步完成:先看改了什么版本,再回滚。
传统做法对比
以前口径文档改完就覆盖了,旧版本找不回来,返工靠翻聊天记录;现在内容哈希变化自动新建版本,每个版本有 change_note,回滚走更新路径自动重建索引,两分钟搞定。
角色
数据工程师(知识库维护者)。
操作步骤
  1. PUT /knowledge/documents/1 更新内容(加一句"含赠品折算")
  2. GET /knowledge/documents/1/versions 查看版本列表(v1 / v2)
  3. POST /knowledge/documents/1/versions/1/restore 回滚到 v1
  4. 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 看到"销售额定义"才选对列
背景
王姐在 /chat 问"查询订单的平均金额",之前 AI 老把 price(单价)当金额,平均下来 99.5 元明显不对。陈工把"销售额 = 实付金额(sales_amount),非单价(price)"写进知识库后,让王姐再问一次,看 RAG 是否把口径带给了 Text2SQL。
传统做法对比
以前模型只能靠列名猜,price 和 sales_amount 都像金额,问法稍含糊就答错;现在知识库把口径写清楚,RAG 召回时自动把"业务知识"段落注入 prompt,模型按定义选列,一次问对。
角色
数据工程师(写口径文档)+ 业务分析师(验证 NLQ 结果)。
操作步骤
  1. 陈工在知识库写文档"金额口径":orders 表 sales_amount=订单实付金额、price=商品单价
  2. 王姐在 /chat 输入"查询订单的平均金额",看返回的 sql_query
  3. 对比注入口径前后两次查询的 SQL 列选择
  4. 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 时语义降级。口径类文档收益最大——写清楚、常维护、勤回滚。