ChatBI 大模型知识库检索增强(RAG)实战:从 Schema 向量化到 Few-Shot 样本语义重排序(Reranking)
2026/9/23 16:45:14 网站建设 项目流程

ChatBI 大模型知识库检索增强(RAG)实战:从 Schema 向量化到 Few-Shot 样本语义重排序(Reranking)

在企业落地对话式数据分析(ChatBI / Text2SQL)时,如何向大模型准确输入数仓的上下文元数据(Schema Context),是决定 SQL 生成准确率的最核心生命线。

在真实的超大型数仓中:

  • 整个数仓包含3,000 张物理表、数万个字段、以及上万条历史沉淀的优质 SQL 查询样例(Few-Shot Examples)
  • 大模型的上下文窗口(Context Window)无论扩展到多大,如果把全部 3,000 张表的 DDL 统统塞入 Prompt,不仅会引发昂贵的天价 Token 费用与极其漫长的推理延迟,更会导致注意力机制在大海捞针中发生严重的**“中间遗忘(Lost in the Middle)与字段幻觉”**。

检索增强生成(RAG / Retrieval-Augmented Generation)配合两阶段检索重排序(Two-Stage Retrieval & Reranking)是现代 ChatBI 元数据检索的工业级黄金架构:

  • 阶段一(粗排召回 / Dense Embedding Retrieval):利用语义向量模型(如 BGE-M3 / OpenAI text-embedding-3),从上千张表与海量样例中,毫秒级召回 Top 20 个候选候选表与相关 Few-Shot;
  • 阶段二(精排重排序 / Cross-Encoder Reranking):利用专精的重排序模型(如 BGE-Reranker-Large),对候选样本与用户发问进行深度跨注意力(Cross-Attention)交互打分,精准筛选出最具相关性的Top 3 核心物理表与 2 条高价值标准 SQL 样例注入 Prompt!

今天我们系统拆解 ChatBI 两阶段 RAG 元数据检索流水线的完整实现。


ChatBI 两阶段 RAG 检索重排序拓扑模型

[ 用户发问: "上个月华东大区数码 3C 类目的退款率是多少?" ] │ ▼ +-----------------------------------------------------------------------------------------------+ | 阶段一:向量化粗排召回 (Dense Embedding Retrieval - 向量数据库 Qdrant / Milvus) | | - 检索目标:从全库 3,000 张表与 10,000 条 Few-Shot 中向量相似度检索 | | - 输出:快速召回 Top 20 个候选表结构与候选 Few-Shot 样例 (耗时 < 15ms) | +-----------------------------------------------------------------------------------------------+ │ ▼ +-----------------------------------------------------------------------------------------------+ | 阶段二:Cross-Encoder 深度重排序 (Semantic Reranker / 消除向量粗排的语义表面匹配) | | - 机制:将 `(用户提问, 候选表DDL与字段注释)` 输入 Reranker 计算深层交叉注意力相关性得分 | | - 输出:精准锁定【Top 3 核心表 (`dwd_orders`, `dim_user`, `dim_goods`)】与【Top 2 高价值 Few-Shot】| +-----------------------------------------------------------------------------------------------+ │ ▼ +-----------------------------------------------------------------------------------------------+ | 阶段三:动态组装精简 Prompt 并送入代码大模型 (Targeted LLM Code Generation) | | - Prompt 长度压缩 95%!大模型注意力极度聚焦,生成准确率提升至 96% 以上! | +-----------------------------------------------------------------------------------------------+

核心实现代码:Python 两阶段 RAG 检索重排序中枢

import json import requests from typing import List, Dict, Any class ChatBIRetrievalEngine: def __init__(self, embedding_model, reranker_model): self.embed_model = embedding_model self.reranker = reranker_model def retrieve_schema_and_fewshots(self, user_query: str, schema_knowledge_base: List[Dict[str, Any]], top_k_final: int = 3) -> List[Dict[str, Any]]: """ 执行向量粗排召回 + Cross-Encoder 精排重排序两阶段检索 """ print(f"\n🔍 [Step 1] 正在对提问: '{user_query}' 执行向量粗排召回 (Top 15)...") # 1. 模拟向量数据库 Dense Retrieval 粗排召回 Top 15 # 在生产中使用 Qdrant / Milvus 的 client.search(collection, query_vector, limit=15) coarse_candidates = schema_knowledge_base[:15] print(f"🎯 [Step 2] 正在使用 Cross-Encoder Reranker 执行深度语义精排...") # 2. 构造 (Query, Candidate_Document) 文本对送入重排序模型打分 pairs = [] for cand in coarse_candidates: doc_text = f"表名: {cand['table_name']} | 业务域: {cand['domain']} | 包含核心字段: {', '.join(cand['columns'])}" pairs.append([user_query, doc_text]) # 模拟调用 BGE-Reranker-Large 计算交叉相关性得分 # scores = self.reranker.compute_score(pairs) # 模拟打分结果 scores = [0.95, 0.88, 0.82, 0.45, 0.32, 0.15, 0.12] + [0.05] * (len(pairs) - 7) for cand, score in zip(coarse_candidates, scores): cand['rerank_score'] = score # 3. 按精排得分降序排列,截取最终 Top K ranked_results = sorted(coarse_candidates, key=lambda x: x['rerank_score'], reverse=True) final_top_k = ranked_results[:top_k_final] print(f"✅ 精排完成!成功锁定相关性最高的 Top {top_k_final} 张核心物理表!") for rank, item in enumerate(final_top_k, 1): print(f" Rank {rank}: [{item['table_name']}] (相关性得分: {item['rerank_score']:.3f})") return final_top_k

真实测试案例输出与 Prompt 组装验证

1. 用户提问:

查一下上个月华东大区在数码 3C 品类的净支付成交额与退款率

2. 两阶段 RAG 检索输出结果:

Rank 1: [dw_prod.dwd_trade_orders] (得分: 0.950 - 包含 pay_amount, is_refund, category) Rank 2: [dw_prod.dim_user] (得分: 0.880 - 包含 region_name, city_name) Rank 3: [dw_prod.dim_goods] (得分: 0.820 - 包含 category_l1_name, sku_name)

3. 动态组装后的极致精炼 System Prompt(仅消耗 450 Tokens!):

【已挂载的相关数据表 Schema】: 1. dw_prod.dwd_trade_orders (order_id, user_id, sku_id, pay_amount, is_refund, dt) 2. dw_prod.dim_user (user_id, region_name, city_name) 3. dw_prod.dim_goods (sku_id, category_l1_name, sku_name) 【已挂载的最佳实践 Few-Shot 样例】: -- 样例: 统计华东大区某品类退款率 SELECT SUM(pay_amount) AS total_gmv, ROUND(SUM(CASE WHEN is_refund=1 THEN pay_amount ELSE 0 END) * 1.0 / NULLIF(SUM(pay_amount), 0), 4) AS refund_rate FROM dw_prod.dwd_trade_orders o JOIN dw_prod.dim_user u ON o.user_id = u.user_id WHERE o.dt BETWEEN '2026-08-01' AND '2026-08-31' AND u.region_name = '华东大区';

生产落地的三条核心红线

  1. 粗排阶段必须结合 BM25 关键词混合检索(Hybrid Search):纯向量检索容易忽略精准的英文缩写或代号(如sku_idGMV);将Dense 向量检索与 Sparse BM25 倒排索引按 7:3 权重加权融合(RRF / Reciprocal Rank Fusion),大幅提升生僻字段召回率。
  2. 表结构元数据在入库前必须包含“大白话业务同义词(Synonyms Expansion)”:在表注释中不仅写user_id,更通过 LLM 离线丰富其同义词:“买家ID、用户编码、会员账号、客户编号”,确保语义向量模型精准命中。
  3. Few-Shot 样例库必须设立“金标淘汰与更新闭环”:定期审计 Few-Shot 向量库中的 SQL 样例,若底层物理表下线或口径重构,立即从向量库中同步删除,防止老旧错误样例误导模型。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询