为什么 Data Agent 需要 RAG Text-to-SQL 管道解决的是「命中指标 → 拼 SQL → 执行」的确定性路径 。但企业问数场景里还有大量半结构化知识 :
知识类型
示例
适合载体
指标定义
销售收入 = 已确认订单含税金额
MySQL bi_metric
取数逻辑
宽表 dws_sales_metric_wide,index_name='销售收入'
MySQL bi_metric_extract_logic
业务规则
客户留存率分母为上月活跃客户
Markdown + 向量
口径说明
华东区与华北区组织层级差异
Markdown + 向量
FAQ
「新增客户数」是否含试用客户
Markdown + 向量
RAG(检索增强生成) 在 Data Agent 中的定位:当结构化元数据无法直接命中时,从知识库召回相关片段,辅助域分类、指标消歧、结果解释——而不是让 LLM 凭空编造口径。
知识分层架构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 flowchart TB subgraph L1["L1 结构化元数据(主路径)"] BD[bi_domain 业务域] BM[bi_metric 指标定义] BL[bi_metric_extract_logic 取数逻辑] BT[bi_table 表白名单] end subgraph L2["L2 向量知识库(fallback)"] MD[Markdown 文档] CH[(Chroma 向量索引)] BGE[bge-m3 Embedding] end subgraph L3["L3 运行时上下文"] QA[qa_history 会话历史] FB[qa_feedback 用户反馈] end Q[用户问题] --> RET[retrieve_all] RET -->|优先| L1 RET -->|未命中/低分| L2 MD --> BGE --> CH RET --> L3
设计原则:MySQL 优先、向量兜底 。生产 SQL 生成只依赖 L1;L2 用于解释、消歧与运营沉淀。
MySQL 结构化检索 指标关键词打分 retrieve_all 对 metrics 分支走 MySQL LIKE + 打分排序(虚构示例):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 SELECT m.metric_code, m.metric_name, m.domain_code, ( CASE WHEN m.metric_name = '销售收入' THEN 10 ELSE 0 END + CASE WHEN m.alias LIKE '%销售收入%' THEN 5 ELSE 0 END + CASE WHEN m.keywords LIKE '%华东区%' THEN 2 ELSE 0 END ) AS scoreFROM bi_metric mWHERE m.status = 1 AND ( m.metric_name LIKE '%销售收入%' OR m.alias LIKE '%销售收入%' OR m.keywords LIKE '%销售收入%' )ORDER BY score DESC LIMIT 5 ;
取数逻辑关联 命中 M_SALES_REVENUE 后,关联取数逻辑与表白名单:
1 2 3 4 5 6 7 8 9 10 11 12 13 SELECT l.metric_code, l.table_code, l.index_name_value, l.default_filter, t.table_name_cn, t.is_whitelistedFROM bi_metric_extract_logic lJOIN bi_table t ON t.table_code = l.table_codeWHERE l.metric_code = 'M_SALES_REVENUE' AND t.is_whitelisted = 1 ORDER BY l.is_default DESC , l.priority DESC LIMIT 1 ;
返回:table_code = dws_sales_metric_wide,index_name_value = 销售收入,default_filter = is_valid = '1'。
Chroma 向量 fallback 何时触发
条件
行为
MySQL metrics 最高分 < 阈值(如 3)
走向量检索
用户问业务规则类(「留存率怎么算」)
并行走向量
域分类结果为「未知」
扩大向量 top_k
索引构建流程 1 2 3 4 5 6 flowchart LR A[扫描 knowledge/ 目录] --> B[按 H2 切分 chunk] B --> C[清洗:去 front-matter] C --> D[bge-m3 向量化] D --> E[写入 Chroma collection] E --> F[记录 doc_id + source_path]
chunk 策略 :以 Markdown ## 标题为边界,每块 200–800 字;元数据附带 domain、metric_tags、updated_at。
检索示例(Python 伪代码) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def retrieve_vector (question: str , top_k: int = 5 ) -> list [dict ]: embedding = embed_model.encode(question) results = chroma_collection.query( query_embeddings=[embedding], n_results=top_k, where={"domain" : {"$in" : ["销售运营域" , "通用" ]}}, ) return [ { "content" : doc, "source" : meta["source_path" ], "score" : 1 - distance, } for doc, meta, distance in zip ( results["documents" ][0 ], results["metadatas" ][0 ], results["distances" ][0 ], ) ]
Markdown 知识库规范 建议目录结构(虚构):
1 2 3 4 5 6 7 8 9 10 knowledge/ ├── metrics/ │ ├── 销售收入.md │ ├── 客户留存率.md │ └── 新增客户数.md ├── rules/ │ ├── 区域口径说明.md │ └── 时间周期约定.md └── faq/ └── 常见问法映射.md
指标文档模板 1 2 3 4 5 6 7 8 9 ## 销售收入 - **指标编码** :M_SALES_ REVENUE- **业务域** :销售运营域- **口径** :已确认订单的含税销售金额,不含退款冲减- **数据源** :dws_sales_ metric_wide - **过滤条件** :index_ name = '销售收入' AND is_valid = '1' - **常见维度** :region_ name(华东区、华北区)、period(月/季/年)- **易混淆项** :与「新增客户数」不同,收入是金额类指标
业务规则文档示例 1 2 3 4 5 6 ## 客户留存率口径 - **公式** :本月仍活跃客户数 / 上月活跃客户数 × 100%- **活跃定义** :当月至少产生一笔有效订单- **默认过滤** :is_valid = '1' - **区域维度** :region_ name,支持华东区、华北区下钻
retrieve_all 并行策略 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 sequenceDiagram participant Q as 用户问题 participant R as retrieve_all participant M as MySQL participant V as Chroma participant O as 结果合并 Q->>R: 华东区客户留存率同比 par 并行检索 R->>M: metrics 关键词 R->>M: bi_models 语义模型 R->>M: business_rules 规则表 R->>V: 向量 fallback end M-->>O: 结构化命中列表 V-->>O: 文档片段列表 O-->>Q: 统一 RetrieveResult
合并规则:
metrics 有高分命中 → 标记 primary_metric,进入 SQL 管道
向量片段仅进入 context_for_explain,不参与 SQL 拼接
多指标同分 → 返回 needs_clarification,让用户选择
知识库运营
运营动作
频率
负责人
新增指标同步 MySQL + Markdown
每次指标发布
数据治理
重建 Chroma 索引
每周或文档变更后
平台运维
检索日志分析(低分问法)
每月
产品经理
口径争议沉淀为规则文档
按需
业务 + BI
索引重建脚本(示意) 1 2 3 4 5 python scripts/rebuild_chroma_index.py \ --source knowledge/ \ --collection metric_kb \ --model BAAI/bge-m3
与 Text-to-SQL 的协作边界
阶段
RAG 角色
域分类
辅助关键词扩展(可选)
指标检索
MySQL 主检索,向量补召回
SQL 生成
不参与 ,只用 bi_metric_extract_logic
结果解释
注入向量片段,生成口径说明
追问澄清
参考 FAQ 文档生成建议问法
红线 :向量检索到的表名、字段名不得直接进入 SQL,必须经过表白名单与取数逻辑校验。
本章小结
企业指标知识分三层:结构化元数据(主)、向量 Markdown(辅)、运行时上下文(会话)
retrieve_all 并行检索,MySQL 打分优先,Chroma 作 fallback
Markdown 知识库应有统一模板,与 bi_metric 编码对齐
RAG 服务解释与消歧,不替代元数据驱动的 SQL 生成
思考题
若 MySQL 与 Markdown 对同一指标的口径描述不一致,应以哪个为准?如何发现?
向量 chunk 切太大或太小,分别会导致什么检索问题?
什么类型的用户问题应该只走向量、不查 MySQL?
系列导航
← 返回专题首页