解密Prompt系列15. LLM Agent之數據庫應用設計:DIN & C3 & SQL-Palm & BIRD

上一章我們主要講搜索引擎和LLM的應用設計,這一章我們來嘮嘮大模型和DB數據庫之間的交互方案。有很多數據平臺已經接入,可以先去玩玩再來看下面的實現方案,推薦

  • sql translate:簡單,文本到SQL,SQL到文本雙向翻譯,新手體驗
  • ai2sql:功能更全,包括語法檢查,格式化等
  • chat2query:可處理複雜query和實時數據
  • OuterBase:加入電子表格的交互和可視化模塊

本章會提到的前置知識點有Chain-of-thought,Least-to-Most Prompt,Self-Consistency Prompt,建議不熟悉的同學先看下解密Prompt系列9. 模型複雜推理-思維鏈基礎和進階玩法

DB Agent設計

和數據庫進行交互的應用設計,主要涉及以下幾個子模塊

  • Decomposition:把SQL生成任務,拆分成先定位表,再定位表字段,最後基於以上信息生成SQL的多個子問題,降低每一步的任務難度,和上文輸入的長度
  • Schema Linking:數據表較多的數據庫,不能一次性把所有表schema都作爲上文輸入,需要先針對問題篩選相關的數據表和相關字段
  • Schema description:如何描述Table和Column讓模型更好理解每張表是做什麼的,每個字段有哪些含義。以及在真實世界中龐大數據庫中的表字段往往存在很多噪音,甚至需要領域知識,和詳細字段描述才能明確每張表每個字段究竟是做什麼的。
  • self-correction:對SQL執行結果,或者代碼本身進行自我修正,提高SQL語句準確率

下面我們分別基於C3, DIN-SQL, SQL-PALM,BIRD這四篇論文了解DB應用中可以提升SQL生成效果的各個子模塊,前三篇都是基於傳統的Spider數據集,BIRD則提出了全新的難度更高更符合真實世界應用的新基準A Big Bench for Large-Scale Database Grounded Text-to-SQLs

DIN-SQL

>

DIN-SQL是當前Spider榜單上的榜一大哥。走的是子問題拆解的方案,把SQL生成的任務像思維鏈一樣拆解成幾個固定的任務,串聯執行,主要包含以下4個模塊

1. Schema Linking

方案是用10-Shot Prompt + zero-shot COT的引導詞(Let's think Step by Step),讓模型逐步思考給出針對用戶問題,應該查詢的表,以及表中需要查詢的字段,過濾條件字段,和Join條件字段。

Schema Link的輸出會作爲後續SQL生成任務的輸入,幫助模型先定位字段,再編寫SQL。Prompt如下

2. Classification

把用戶的提問按查詢的難易程度分成以下3類

  • easy:單表查詢
  • medium:允許多表Join,但是沒有嵌套查詢
  • hard:多表Join + 嵌套查詢

之所以要進行難易程度劃分,其實是後面sql生成部分,每種難度使用了不同的In-Context Few-shot和prompt指令。

3. SQL Generation

對應以上的3種分類,論文采用的3種few-shot-prompt如下

  1. easy:直接使用指令+表結構+ schema Link + few-shot

  1. Medium:表結構和schema Link同上,指令加入了zero-shot的思維鏈激活,思維鏈每一步對應SQL sub query。But這裏有些奇怪的是論文中Medium部分的few-shot很多也是單表查詢不需要join的,困惑臉......

  1. Hard: few-shot是加入多表查詢和嵌套結構的樣例

4. Self Correction

論文的自修正並未引入SQL執行,只針對SQL本身,修復一些小的語法錯誤,例如缺少DESC,DISTINCT等,通過zero-shot指令來讓模型對生成的SQL直接進行修正。指令如下

instruction = """#### For the given question, use the provided tables, columns, foreign keys, and primary keys to fix the given SQLite SQL QUERY for any issues. If there are any problems, fix them. If there are no issues, return the SQLite SQL QUERY as is.
#### Use the following instructions for fixing the SQL QUERY:
1) Use the database values that are explicitly mentioned in the question.
2) Pay attention to the columns that are used for the JOIN by using the Foreign_keys.
3) Use DESC and DISTINCT when needed.
4) Pay attention to the columns that are used for the GROUP BY statement.
5) Pay attention to the columns that are used for the SELECT statement.
6) Only change the GROUP BY clause when necessary (Avoid redundant columns in GROUP BY).
7) Use GROUP BY on one column only.
"""

後面的C3和SQL-PALM都是用DIN-SQL作爲基準進行評估,所以DIN的效果指標我們直接放到後面的部分。

C3

在DIN-SQL提出的Few-shot方案的基礎上,C3使用chatgpt作爲基座模型,探索了zero-shot的方案,這樣可以進一步降低推理成本。並且在生成效果上和DIN-SQL不相上下。

論文實現有很多細節,個人感覺比較重要的是以下兩個部分,其他細節不做贅述

Clear Prompting

C3也通過Schema Linking先定位問題相關的數據表和查詢字段。不過在指令構建上,論文認爲在編寫指令時,簡潔的文本格式(clear layout),以及不引入不相關的表結構(clear context),會降低模型理解難度,對模型效果有很大提升。下面我們分別看下這兩個部分

Clear Layout

後面的SQL-Palm也進行了類似的消融實驗,對比符合人類自然語言描述的Table Schema,使用符號表徵的prompt效果顯著更好,在執行準確率上有7%左右的提升。

Clear Context

把整個數據庫的全部表結構放入schema linking Context,一方面增加了推理長度,一方面會使得模型有更大概率定位到無關的查詢字段。因此C3通過以下兩步先召回相關的數據表和表字段,再進行schema linking

  1. 數據表召回

C3使用以下zero-shot指令,讓大模型基於數據表schema,召回問題相關的數據表。這一步作者採用了self-consistency來投票得到概率最高的Top4數據表。當前的一些開源方案例如ChatSQL等,也有采用相似度召回的方案,更適合低延時,面向超大數據庫的場景。不過需要先人工先對每張表生成一段表描述,描述該表是用來幹啥的,然後通過Query*Description的Embedding相似度來篩選TopK數據表。

instruction = """Given the database schema and question, perform the following actions: 
1 - Rank all the tables based on the possibility of being used in the SQL according to the question from the most relevant to the least relevant, Table or its column that matches more with the question words is highly relevant and must be placed ahead.
2 - Check whether you consider all the tables.
3 - Output a list object in the order of step 2, Your output should contain all the tables. The format should be like: 
["table_1", "table_2", ...]
"""
  1. 表字段召回

在以上得到問題相關的數據表之後,會繼續執行表字段召回的操作,同樣使用了Self-Consistency多路推理投票得到概率最高的Top5字段。這一步同樣可以使用相似度召回,尤其在中文場景,以及垂直領域的數據表場景,直接使用字段名並不足夠,也需要對錶字段名稱生成對應的描述,然後使用相似度進行召回。

instruction = '''Given the database tables and question, perform the following actions: 
    1 - Rank the columns in each table based on the possibility of being used in the SQL, Column that matches more with the question words or the foreign key is highly relevant and must be placed ahead. You should output them in the order of the most relevant to the least relevant.
    Explain why you choose each column.
    2 - Output a JSON object that contains all the columns in each table according to your explanation. The format should be like: 
    {
        "table_1": ["column_1", "column_2", ......], 
        "table_2": ["column_1", "column_2", ......],
        "table_3": ["column_1", "column_2", ......],
         ......
}

self-consistency

Schema Linking之後,c3沒有像DIN一樣去判斷問題的難度,而是用統一的zero-Prompt來對所有問題進行推理。不過在推理部分引入了Self-Consistency的多路投票方案。

針對每個問題會隨機生成多個SQL,然後去數據庫進行執行,過濾無法執行的sql,對剩餘sql的執行結果進行分組,從答案出現次數最多的分組隨機選一個sql作爲最終的答案,也就是基於sql執行結果的major vote方案。

效果上c3在spider數據集上,使用乾淨簡潔的zero-shot-prompt+self-consistency,基本打平了Few-shot的DIN-SQL,

SQL-Palm

  • SQL-PALM: IMPROVED LARGE LANGUAGE MODEL ADAPTATION FOR TEXT-TO-SQL
  • 嘗試了微調方案並顯著超越了以上的DIN-SQL

SQL-Palm是谷歌最新的NL2SQL的論文,使用的是他們的Palm2,不過未提供代碼。和以上兩種方案不同的是,SQL-Palm沒有進行問題拆解,而是直接基於few-shot prompt進行sql的推理生成,並且嘗試了微調方案,微調後的模型會顯著超越DIN-SQL。

指令構建和以上的C3有兩點相似

  • Self-consistency: 同樣使用了基於執行結果的多路投票來選擇sql
  • clean prompt:同樣實驗對比了偏向於人類自然表達的表結構表述和符號化的簡潔表結構描述,結論和以上C3相同。在有few-shot樣本時,指令長啥樣影響都不大,在zero-shot指令下,符號化的簡潔表結構描述效果顯著更好。對比如下上圖是符號化表結構,下圖是自然語言式的表結構描述

論文同樣對模型self-correction做了嘗試,嘗試方向和DIN不同,不是直接對SQL語句進行校準,而是當SQL執行錯誤時,基於錯誤信息讓模型進行SQL修正。但是論文提到,並沒找到很好的Debug的自修正方案,修正後對效果沒有顯著提升。

BIRD

  • Can LLM Already Serve as A Database Interface?A BIg Bench for Large-Scale Database Grounded Text-to-SQLs
  • DuSQL: A large-scale and pragmatic Chinese text-to-SQL dataset.
  • https://bird-bench.github.io/

如果說前三篇還有一丟丟“象牙塔文學”,那BIRD確實一步跨入了紀實文學的領域。論文的核心是推出了新的更貼合實際應用場景的超大規模+存在數據噪聲+依賴領域知識的NL2SQL基準數據集。在該數據集上,雖然DIN依舊是SOTA,但是和人工標註的執行準確率對比來看,只能說“前路阻且長”

只所以在Spider基準中有85%+執行準確率的SOTA模型,在BIRD裏面表現驟降,除了BIRD使用的數據集噪聲更多,數據集更大更復雜之外,一個核心原因是現實應用中,只像以上3篇論文那樣使用原始表格的schema來描述數據表,是遠遠不夠滴。

往往需要引入額外的表/字段描述,以及領域知識才能讓模型更好理解每張表每個字段的作用,包括但不限於以下幾個方面

  • 表名稱/字段縮寫(Schema Description):現實場景的table name和column name,往往業務同學自己使用都不知道是啥意思,因此治理後的數據倉庫中往往需要人工維護表描述和字段描述。例如b_fund_stock_bond_industry_share_d數據表的描述是每日全量基金股票債券持倉佔比的,sw_classify_one_type_name字段的描述是申萬一級行業分類,就這?只給表名稱你想讓模型自己猜到?
  • 字段取值說明(Value Illustration):部分表字段的取值是縮寫或者專有名詞,例如status字段往往會使用代碼來指代例如基金申購,贖回等不同狀態,這時就需要對字段取值進行說明。
  • 領域知識(Domain Knowledge):領域數據庫往往需要補充領域知識才能理解,以下Ref1-3的論文有更具體的說明
    • 計算類(Numeric Reason):例如如何基金單位淨值 = 基金總淨值/基金總份額
    • 指標類(Indicator):例如詢問股票近期波動率,模型需要補充知識說明哪些指標反映波動率
    • 指代類(Synonym):例如用戶詢問某ETF基金,模型需要知道指數基金也是ETF基金的另一種說法

BIRD在人工進行數據標註時,對每張表都提供了對應的以上字段描述和補充知識信息,用來幫助標註同學理解表內容。在使用大模型生成SQL時,以上知識會作爲prompt輸入模型,如下

並且論文對比了是否使用External Knowledge在測試集和驗證集上的效果,提升十分顯著。當然因爲論文的重點在數據集構建,因此並未對如何更好的引入知識進行更詳盡的討論,期待後文ing~

想看更全的大模型相關論文梳理·微調及預訓練數據和框架·AIGC應用,移步Github >> DecryPrompt


Reference

  1. Towards knowledge-intensive text-to-SQL semantic parsing with formulaic knowledge
  2. Bridging the Generalization Gap in Text-to-SQL Parsing with Schema Expansion
  3. FinQA: A Dataset of Numerical Reasoning over Financial Data
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章