華為 & 康奈爾新成果!RubikSQL:讓 NL2SQL 像老員工一樣 “懂業務、長記性”
現實問題
隱式意圖
老板問“XXX營收上月咋樣?”,你以為要“上月營收額”,結果他要的是“上月營收同比增長率(YoY)”;做區域銷售趨勢圖,總部數據是個異常值,不刪掉就會讓圖表失真,但老板沒說要刪啊!還有“零售店”和“售貨亭”,明明是類似渠道,老板希望你自動歸為一類,可他就是不明說!
行業黑話
每個公司都有自己的“暗號”:“YoY”在A表是按自然月算,在B表是按財月算;“重要客戶”有的按銷售額定,有的按合作年限定;還有自定義公式,比如“凈利潤=營收-成本-增值稅-服務費”,這些要是沒記牢,寫的SQL必錯!
表結構復雜
實驗室里的表都規規矩矩,企業里的表為了性能,能把你整懵:小表用“exchange='USD'”當條件,大表直接搞個“total_revenue_USD”列;同樣查“營收”,小表查1列,大表要查5列,SQL結構完全不一樣!
上下文敏感
最坑的是“時間”!比如公司每月10號更新數據,5月9號問“本月數據”,實際要4月的(不然查不到);5月10號問“本月數據”,才是5月的。還有用戶身份:歐洲同事問“本地財務數據”,默認要歐元;中國同事問,默認要人民幣,這些細節錯了,老板能把你罵哭!
所以啊,實驗室里“一次查詢一次處理”的思路,在企業里根本不夠用!華為大佬們說了:工業級NL2SQL得是“終身學習者”,要像老員工一樣,慢慢積累業務知識,越用越順手。這就是 RubikSQL 的核心思路——不搞“一錘子買賣”,搞“長期陪伴”!
派別
在講 RubikSQL 之前,先跟小伙伴們梳理下 NL2SQL 的三大主流派別,幫大家理解為啥 RubikSQL 能“脫穎而出”。
LLM 派
上下文工程派:給 LLM 喂“問題+表結構+示例”,讓它生成 SQL。比如優化 prompt,選更合適的示例,都是這個路子。
微調派:用標注數據(NL-SQ L對)微調模型,有的用全量微調,有的用 LoRA(低秩適應),還有用強化學習(RL)的,讓模型更“懂 SQL”。
多智能體派:搞個“流水線”,多個智能體分工合作:有的找表,有的填條件,有的改錯誤。比如用 LLM 當“指揮”,分配任務給各個小工具。
現在還流行“思維鏈(CoT)”,讓模型先寫“解題步驟”,再寫 SQL;還有“知識蒸餾”,用大模型教小模型,讓小模型又快又準。
記憶派
以前的模型都是“用完就忘”,現在想讓它們“記事兒”,就得搞“記憶系統”:有的用檢索(RAG),有的用混合記憶(prompt + RAG + 參數記憶),但目前還沒有統一的最佳方案。
短板
現在最牛的方法,比如 CHASE-SQL、XiYan-SQL,都是“一次查詢一次優化”,沒把“長期積累知識”當回事。雖然有的方法(比如 AskData)注意到了查詢日志的重要性,但要么知識來源單一,要么沒有統一的知識格式,用起來很麻煩。
而 RubikSQL 的厲害之處在于:把“終身學習”和“智能體記憶”融入NL2SQL,還搞了個統一的知識格式(UKF),把所有知識串起來,這就比別人多走了一步!
框架概述
1:RUBIKSQL 概述,展示了其以知識為中心的四階段智能體工作流程。
問題定義
不搞“一刀切”,搞“長期服務”,RubikSQL 把企業 NL2SQL 定義為“終身學習任務”:數據庫 schema 基本不變,但知識要不斷更新。
簡單說,系統有兩個核心模塊:
KB 更新模塊(Mk):從用戶查詢、數據庫文檔里挖知識,更新到知識庫(KB);
SQL生成模塊(Ms):用最新的KB,把用戶的 NL query 轉成 SQL。
目標很簡單:生成的 SQL 執行結果,要盡可能和用戶預期一致。
整體架構
RubikSQL 的核心是“四階段知識驅動流程”,就像老員工成長的四個階段:
數據庫上下文工程:把初始知識(表結構、文檔)變成結構化的“業務手冊”;
用戶查詢增強:從用戶的查詢里挖新知識,更新“業務手冊”;
知識庫索引:把“業務手冊”編好索引,方便快速查找;
知識蒸餾:把大模型的“經驗”教給小模型,讓小模型也能快速干活。
這里有個關鍵:統一知識格式(UKF1.0),就像“業務手冊”的統一模板,不管是表結構、公式、用戶偏好,都按這個模板記,這樣各個模塊之間就不會“雞同鴨講”。
知識庫維護
知識庫(KB)是 RubikSQL 的“大腦”,怎么建好、維護好這個“大腦”,是關鍵中的關鍵。
圖 2:基于 UKF 構建的分層架構,將知識存儲與挖掘同索引及利用分離開來。
統一知識格式
我們想象一下:如果老員工的筆記本又記表結構,又記公式,還記用戶偏好,格式亂七八糟,下次找的時候肯定找不到!UKF1.0 就是給“知識庫”定了個統一模板,不管記啥,都按這6類信息來:
1.元數據
名字(唯一ID,不能改)、類型(比如“表”“公式”“用戶偏好”)、版本、簡短描述(給LLM看的);比如“YoY計算規則”,類型是“Metric”,版本是“v1.0”,簡短描述是“財月同比增長率,分母為去年同期值,分母為0時返回0”。
2.內容
文本描述(比如“YoY公式:(本期-上期)/上期”);半結構化數據(比如公式的參數、表的列名);
內容組合器(content_composer):把知識轉成 LLM 能懂的 prompt,比如把“YoY規則”轉成“計算YoY時,需注意:1. 時間范圍為財月;2. 分母為去年同期值;3. 分母為0返回0”。
3.來源
誰創建的(用戶/系統/智能體)、來自哪(文檔/查詢日志/人工輸入)、所有者是誰(哪個部門);比如“歐洲用戶默認歐元”這個知識,來源是“用戶查詢日志”,所有者是“財務部門”。
4.檢索
檢索知識的標簽(比如“[用戶:歐洲][貨幣:EUR]”)、同義詞(比如“YoY”的同義詞“同比”“同比增長率”)、優先級(重要知識優先級高);這樣查“同比”的時候,能快速找到“YoY規則”。
5.關系
記錄知識之間的關聯,比如“YoY規則”關聯“財月表”“營收列”;就像老員工記“YoY要用A表的B列”,不會搞混。
6.生命周期
創建時間、最后驗證時間、是否過期(比如“2023年YoY規則”2024年可能過期);避免用舊知識犯錯誤。
而且 UKF1.0 還自帶“模板”,比如“表模板”“列模板”“公式模板”,新增知識的時候直接套模板,不用每次都從零開始,超方便!
上下文工程
剛部署 RubikSQL 的時候,知識庫是空的,得先“填貨”,這就是“數據庫上下文工程”,分三步:
1.數據庫剖析
基礎統計:列的類型(數值/文本/時間)、數值列的均值/中位數、文本列的常見值、時間列的格式(比如“YYYYMM”);比如“revenue”列是數值型,均值100萬,“country”列常見值是“China”“USA”;
LLM補描述:如果列沒有描述(比如“dealer_lv4”),讓 LLM 根據列名和數據,生成描述(“經銷商四級分類,如‘零售店’‘ kiosk’”);
智能體工具包:給智能體配“查列信息”“查 table 信息”“執行SQL”的工具,比如智能體想知道“revenue”列在哪張表,直接調用“column_info”工具查。
2.結構化信息提取
企業里有很多文檔(比如《財務指標定義手冊》《數據庫表說明》),RubikSQL 會用 LLM 把這些非結構化文檔,轉成 UKF 格式的知識:
比如文檔里寫“YoY計算:財月同比,分母為去年同期值,分母為0返回0”,LLM會把它轉成“Metric”類型的UKF知識,填好內容、標簽、關系。
3.智能體上下文挖掘
有標注查詢:LLM 對比 NL 和 SQL,提取知識。比如 NL 是“查運行中的核電站”,SQL是“WHERE status='Operational'”,LLM會提取“‘運行中’是‘Operational’的同義詞”“status列在nuclear_power_plants表”;
無標注查詢:雖然沒正確 SQL,但可以讓智能體先生成一個 SQL,再對比現有知識,看有沒有新信息。比如生成的 SQL 里用了“dealer_lv4='零售店'”,而現有知識里沒有“零售店”的同義詞,就把它加進去。
挖出來的知識,還要“去重去錯”:和表結構沖突的刪掉,重復的合并,優先級比人工標注的低(避免出錯)。
用戶查詢增強
用戶用得越多,RubikSQL 的知識越多,這就是“用戶查詢增強”,核心是“CoT 增強的 SQL 剖析”和“查詢合成”。
1.CoT增強的SQL剖析
企業里的 SQL 大多沒注釋,LLM 看不懂“為什么這么寫”,所以 RubikSQL 給 SQL 加“注釋”,把它變成“NL-CoT-SQL” triples(三元組):
加查詢時間:比如“上月數據”,要記查詢時間是“2025-05-01”,這樣下次看就知道“上月”是2025-04;
加表結構:比如查“營收”,返回的列是“2024年營收”“2025年營收”“YoY”,把這個結構記下來,下次用戶問“營收”,就知道要返回這三列;
加知識摘要:比如用了“YoY規則v1.0”,在SQL頭部加注釋“使用YoY規則v1.0:財月同比,分母為0返回0”;
LLM寫注釋:讓 LLM 給 SQL 加“頭部分析”(步驟、注意事項)和“行內注釋”(每個子句的作用)。
比如 SQL 里的“CASE WHEN period='202312' THEN usd_ytd_amt_b ELSE 0 END”,LLM會加注釋“-- 取2023年12月的USD累計金額,其他月份為0”,這樣下次用的時候,LLM一看注釋就懂!
2.查詢合成
為了讓 RubikSQL 學更快,還會“造題”——生成更多 NL-SQL 對:
簡化復雜查詢:比如“A和B部門上月重要客戶增長誰多?”,拆成“A部門上月重要客戶增長多少?”“B部門上月重要客戶增長多少?”;
復雜簡單查詢:比如“查XXX訂單的增值稅”,和“查XXX訂單的折扣”,合成“查XXX訂單的增值稅和折扣”;
跨庫遷移查詢:把A數據庫的查詢,改成B數據庫能用的(比如A庫用“revenue”列,B庫用“total_revenue”列,就改列名)。
造出來的查詢,還要篩選:優先選執行結果非空、符合業務邏輯的,保證質量。
使用知識庫
知識庫建好后,怎么用它生成 SQL?RubikSQL 搞了“知識庫索引”和“多智能體SQL生成”,簡單說就是“快速找知識,精準寫SQL”。
知識庫索引
知識庫的知識太多,得編“目錄”才能快速找到,RubikSQL 用了5種索引:
1.字符串索引
傳統DAAC:一種快速匹配字符串的算法,比如輸入“同比”,能快速找到“YoY”的知識;
LLM 加同義詞:讓小 LLM 給知識加同義詞(比如“運行中”是“Operational”的同義詞),再用DAAC匹配,這樣“查運行中的核電站”也能找到“status='Operational'”的知識;
優點:快!匹配速度和知識數量無關,百萬級知識也能秒查。
2.分面搜索
把知識的標簽(比如“[表:nuclear_power_plants][列:status]”)存在SQL數據庫里,按標簽篩選:
比如想找“nuclear_power_plants表的status列”的知識,直接搜標簽“[表:nuclear_power_plants][列:status]”,精準定位。
3.多向量索引
按“語義”找知識
把知識轉成向量(比如把 NL 查詢、SQL、CoT 都轉成向量),用向量搜索找相似知識:
比如用戶問“查上月營收同比”,向量搜索會找到“查上季度營收同比”的歷史查詢,參考它的SQL結構。
4.圖索引
按“關系”找知識
把知識之間的關系(比如“YoY規則關聯財月表”“財月表關聯營收列”)建成知識圖譜,按關系找:比如找“YoY規則”,能順著關系找到“財月表”“營收列”,不用一個個搜。
5.自主搜索
讓智能體自己找知識
讓 RAG 智能體調用上面的索引,自己決定用哪種方式找知識:
比如用戶問“歐洲同事的本地財務數據”,智能體先用字符串索引找“歐洲”“本地財務”的標簽,再用圖索引找“歐洲用戶關聯歐元”的知識,最后匯總。
SQL生成
生成 SQL 的活兒,交給三個智能體分工:
1.RAG智能體
負責從知識庫找和用戶查詢相關的知識,比如用戶問“上月XXX營收YoY”,它會找:“XXX部門對應的列名”“YoY計算規則”“上月對應的時間范圍”,然后把這些知識匯總給SQL生成智能體。
2.SQL生成智能體
拿著“用戶查詢+RAG 找的知識”,生成帶 CoT 和注釋的 SQL:
比如先寫CoT:“1. 確定時間范圍:上月是2025-04;2. 確定列名:XXX營收列是 revenue_xxx;3. 計算YoY:(2025-04 revenue - 2024-04 revenue)/2024-04 revenue;4. 篩選條件:部門=XXX”,再寫對應的SQL。
3.SQL優化智能體
執行生成的SQL,看有沒有錯:
比如執行報錯“列名不存在”,就查知識庫,發現“revenue_xxx”改成了“revenue_xxx_new”,就修正列名;比如執行結果為空,就檢查時間范圍,發現“上月”應該是 2025-04,而 SQL 寫的是 2025-05,就修正時間。
4.性能提升小技巧
Test-Time Scaling(TTS):讓多個模型生成SQL,刪掉報錯的,選執行結果一致的(多數投票),提高準確率;
級聯(Cascading):先用小模型(14B)生成,結果一致就返回;不一致再用大模型(32B)判斷,又快又準;
知識蒸餾:用大模型(比如671B)生成“NL-CoT-SQL” triples,教小模型(14B),讓小模型也能達到大模型的效果,還更省資源。
基準
以前的 NL2SQL benchmark(比如Spider、BIRD),要么數據庫太多、每個庫的查詢太少,要么不貼近企業實際場景,沒法好好測試 RubikSQL 這種“終身學習者”。所以華為大佬們搞了個新 benchmark——RUBIKBENCH,專門測企業級 NL2SQL!
真實
數據來自企業:基于某跨國車企的財務數據,有“收入”“銷售臺賬”“利潤表”“預算預測”4類表,每個表約4萬行、70列,結構和真實企業一模一樣;
查詢夠多夠真實:目前有 5000+標注查詢,來自財務分析師、高管的真實查詢,比如“Nova品牌在瑞典和西班牙本月庫存減值損失BCR排名”,充滿行業黑話和隱式意圖;
上下文豐富:每個查詢都帶“用戶畫像”(比如歐洲用戶默認歐元)、“查詢時間”,和企業里的場景完全一致。
更合理的評分標準
以前的評分(比如執行準確率EX)太嚴格:列順序不一樣、多一列無關列,就算錯。RUBIKBENCH用了“ bipartite Fβ-score”,更貼近實際:
列順序不一樣?不算錯;多一列無關列?只要核心信息對,扣分少;可以調β值,比如β>1時,更看重“召回率”(把該有的信息都查出來),符合企業需求(漏信息比多信息更可怕)。
有多牛?
測試數據集
選了兩個貼近企業場景的數據集:
BIRD Mini-Dev:19個數據庫,查詢密度高;
KaggleDBQA:8個數據庫,查詢更貼近實際業務。
結果:SOTA!
表 1:在 BIRD Mini-Dev 上的結果
BIRD Mini-Dev:用 gemini-2.5-flash 模型,n=8(TTS,8個模型生成SQL)時,執行準確率77.3%,比之前最好的 CHASE-SQL(74.9%)還高;
圖片
KaggleDBQA:n=8 時,執行準確率 58.9%,比之前最好的 ODIS-Codex(54.8%)高。
錯誤分析
表 3:按難度等級劃分的錯誤分布情況
分析錯誤原因,發現:
40%錯誤是“謂詞錯誤”:比如多了個條件、列名錯了,這是因為知識庫沒記全“列名同義詞”“條件規則”;
20%錯誤是“意圖理解錯”:比如用戶要“YoY”,生成了“環比”,這是因為沒記牢用戶偏好;
只有不到12%錯誤是“模型不會推理”:比如復雜計算邏輯錯了。
圖 3:RUBIKSQL 在 BIRD MiniDev 上的錯誤類型分析。
這說明:NL2SQL 的瓶頸不是模型能力,而是知識庫質量!RubikSQL 的思路完全正確——把重點放在知識庫上,比單純堆模型參數更有用!
總結
反思
RubikSQL 雖然牛,但還有改進空間:
- 結構化信息提取(SIE)還不夠智能,復雜文檔需要人工輔助;
- 多智能體 workflow 是“示例級”,還沒做到最優;
- RUBIKBENCH 還在迭代,未來會加更多查詢和場景。
未來會重點優化:
- 讓 SIE 能自動處理復雜文檔;
- 優化智能體分工,讓生成 SQL 更快;
- 給 RUBIKBENCH 加更多行業數據(比如零售、醫療)。
總結
RubikSQL 的核心貢獻,不是搞了個更牛的模型,而是把“終身學習”和“知識庫”搬進了NL2SQL:
統一知識格式(UKF1.0):解決了知識“雜亂無章”的問題,讓 LLM 和智能體能高效用知識;
知識庫驅動:不依賴“一次性prompt”,而是靠長期積累的業務知識,越用越懂業務;
貼近企業實際:解決了隱式意圖、私有知識、寬表、上下文敏感這些企業痛點;
RUBIKBENCH:給行業提供了一個“真實考場”,推動企業級 NL2SQL 發展。
對咱們打工人來說,RubikSQL 就像一個“懂業務的SQL助手”,以后老板甩來一句模糊的需求,它能自動補全業務邏輯,生成正確的SQL,再也不用猜來猜去啦!



























