天天看點

用ChatGPT搭建代碼知識庫,提升開發效率

作者:騰訊技術工程

作者:teng,騰訊前端開發工程師

ChatGPT 是一種強大的自然語言處理模型。在工作中,我們可以借助其卓越的自然語言生成能力,快速檢索代碼資訊,使程式員們能更加專注于業務邏輯的實作和優化。然而,由于它的知識庫僅覆寫至 2021 年 9 月前的資訊,一些新的技術文檔無法被查詢到,例如我們公司前端經常使用的開源架構 TDesign。本文講解了本人為了解決這一痛點的實驗過程,即通過應用 embedding 技術并結合 AST 解釋器,實作了對 TDesign 代碼知識庫的自然語言查詢。在 30 個常見用例的測試下,查詢精度達到了 90%。常用元件的檢索時間從平均 10 分鐘縮短至 2 分鐘,進而提升了前端研發效率 20%。

1. 知識庫搭建

ChatGPT 的資料覆寫範圍僅至 2021 年 9 月前,這意味着如果出現了 2021 年 9 月之後的新資訊或技術,ChatGPT 可能無法提供準确的答案或建議。例如,前端開發中經常使用的公司開源項目 TDesign 就是一個例子:

用ChatGPT搭建代碼知識庫,提升開發效率

幸運的是,針對這個問題,業界已經提供了解決方案——建構知識庫,一般有兩種路徑:

首選的方法是對開源的大型語言模型(LLM)進行全面或部分的微調,采用 fine-tune 或者 LoRA 技術。這種方法的優點在于,它能使 LLM“記住”特定的領域知識,進而在擁有特定知識背景的條件下進行交流,如“貓娘”或“客服機器人”等。此外,因為采用了私有部署,這種方案适合用于一些尚未公開的公司内部知識。然而,這種微調方案的缺點在于,它需要大量的 GPU 算力支援,且調試過程耗時較長。

第二種方法是利用嵌入技術(embedding)。通過嵌入模型,将特定知識轉化為向量,然後将這些向量存入相應的向量資料庫中。在查詢階段,通過相似度查詢,比對出關聯的 topK 結果,然後将這些結果提供給 LLM,生成相應的答案。這種方法的優點在于,OpenAI 提供了對應的 text-ada-embedding-002 模型,價格合理,效果也相當出色。然而,其缺點是可能不适合處理内部資料,存在資料洩露的風險。這裡我要特别提醒一下,資料安全,人人有責。大家在實踐過程中一定要防止敏感資料洩露的風險。

在對兩種方案進行對比分析後:

1、考慮到 TDesign 已經在公網開源,是以相關資料并不涉及敏感資訊;

2、目前公司的算力資源較為緊張,且微調方案的調試時間成本偏高;

我最終決定選擇embedding 方案進行實施。

最終效果如下:

Q: 在 TDesign 中,如何校驗表單,寫出代碼:

用ChatGPT搭建代碼知識庫,提升開發效率

2. 實作過程

實作原理圖

用ChatGPT搭建代碼知識庫,提升開發效率

這裡面我着重講一下資料準備和處理過程。

1. 資料格式:

這裡主要參考了 github 上面的 MrRanedeer 項目: https://github.com/JushBJJ/Mr.-Ranedeer-AI-Tutor ,借鑒他的知識描述方式和資訊組織的格式,綜合對比之後采用了 JSON 的資料格式;

用ChatGPT搭建代碼知識庫,提升開發效率

2. 資料準備:

我是直接從 TDesign 的官網( https://tdesign.tencent.com/vue-next/overview )上,提取所需資料,選取的版本是适用于 vue3 的 tdesign-vue-next。

起初,我的計劃是:元件文檔說明 + 元件代碼 few shots ,以讓 chatGPT 直接了解相應元件的規則,然後生成相關的代碼。然而,實踐證明這種做法效果并不理想,即使結合 prompt 提示進行優化,其最終效果也相對有限。(原因估計是太多的特有名詞模型了解不了,導緻産生了幻覺(hullucination))

用ChatGPT搭建代碼知識庫,提升開發效率

最後我決定直接利用 TDesign 中的場景描述和代碼示範。

用ChatGPT搭建代碼知識庫,提升開發效率

調整後的資料結構如下:元件 -> 使用場景 -> {場景描述 & 代碼}。

用ChatGPT搭建代碼知識庫,提升開發效率

3. 資料向量化:

我們将使用常見的 LLM 對接工具 Langchain 和它的 Text Splitter 工具。具體來說,我們使用的是RecursiveCharacterTextSpliter,它能在盡可能保證句子語義完整的前提下根據 ChunkSize 進行分段。但是由于 chunkSize 的局限和知識文章長度的不确定導緻很多時候,切片後語義的丢失。比如:

{"小明的自我介紹": "大家好叫小明,我的愛好是足球和繪畫"},如果文本在小明這裡被截斷,後續搜尋"小明的介紹",大機率不會将"小明"和後面的"我的愛好是足球和繪畫"的資訊比對到一起,而導緻在資料召回階段沒辦法得到準确的知識。

關于這一點的優化我會在後面說明。

4. 資料檢索:

這個階段主要是通過提出的問題,搜尋向量資料庫中比對的資訊,與系統 prompt 整合之後傳給 openai competition 完成知識檢索。

代碼如下:

用ChatGPT搭建代碼知識庫,提升開發效率

使用的 prompt 如下:

用ChatGPT搭建代碼知識庫,提升開發效率

3. 效果展示

在 30 個常見的問題中,一共存在 7 個 bad case(錯誤答案,存在大量幻覺(hullucination)),3 個 not perfect(回答正确,但是有瑕疵,比如上傳圖檔實作為上傳檔案),其餘回答正确。正确率 20/30 = 66.7%,可用率 23/30 = 76.7%。

原因分析:

1. 多元度知識比對能力有限,比如同時檢索 form,button,input,select 等元件組合的問題,由于 vectorStore.similaritySearch 過程中 topK 召回的數量有限,且 context 長度有限,會造成多元度知識檢索的能力偏弱

2. 知識切片不連貫導緻的上下文資訊丢失,正如上文提到的小明的例子

{"小明的自我介紹": "大家好叫小明,我的愛好是足球和繪畫"},如果文本在小明這裡被截斷,後面的資訊就丢失了"小明的自我介紹"的上下問資訊,導緻召回失敗。

4. 方案優化

1、針對上面提到兩點影響因素,第一個方案可以通過優化 chunkSize 和 topK 的參數進行微調試錯,但是總的來說當查詢次元提升,所需的上下文資訊也會相應增多,但這可能受到 LLM 的上下文長度限制的限制。關于這一點筆者寫文章時已經拿到了 claude 100k 上下文的 api,會在未來進一步的測試

2、針對第二點切片的導緻的上下問資訊丢失,筆者想出的方案是:通過 JS 解釋器将文檔資訊轉換成 Javascript AST(抽象文法樹),每次切片記錄目前索引所在的 scope 資訊,進而标記出目前切片的上下文資訊。(體驗 AST: https://astexplorer.net/ )

抽象文法樹展示:

用ChatGPT搭建代碼知識庫,提升開發效率

可以看到在抽象文法樹中,如果處理的是 JSON 對象,無論是 key 還是 value 都是能定位到他的字面量字元串的索引區間,是以隻要知道我們每次分片的開始和結束的索引,我們就能定位到他在 AST 中的位置,當知道這個位置之後我們就可以通過算法回溯到目前片段的所有父級 key,也就是說隻要我們的父級 key 足夠語義化,我們上下文的資訊就更加完整。

通過學習 langchain 中 RecursiveCharacterTextSpliter 的源碼,我們是可以通過 indexChunk 的值得到每次切片時的索引。

用ChatGPT搭建代碼知識庫,提升開發效率

通過算法計算,可以得到每個切片的開頭和結尾的一個上下文資訊,效果如下:

用ChatGPT搭建代碼知識庫,提升開發效率

如果套用到前文提到的小明的例子的話,第二段"我的愛好是足球和繪畫"的 scope 資訊就是 {startScope: "小明的自我介紹",endScope: ""},如果我們通過特定格式将他拼接到知識資訊中去就會是:

> > > startScopeStr:"小明的自我介紹"<<<,我的愛好是足球和繪畫>>>endScopeStr:""<<<
           

現在如果使用"小明的興趣愛好"來比對并召回 embedding 片段,并喂給 LLM,就能得到準确的答案了。

最後可以在 prompt 中通過 few shots 進一步優化比對,到此為止優化流程就完成了。

用ChatGPT搭建代碼知識庫,提升開發效率

5. 效果展示

經過上述 AST 優化,最終得到了顯著的優化結果,統計結果顯示,錯誤答案(Bad Case)已減少至 3 個,回答尚有瑕疵(Not Perfect)的數量也降至 2 個。這樣計算下來,正确率達到了 83.3%(25/30),可用率為 90%(27/30)。在目前樣本集下,正确率提升了 15.6%,可用率也提升了 13.3%。

部分效果展示

Q: 如何實作帶搜尋框的穿梭框

用ChatGPT搭建代碼知識庫,提升開發效率

Q: 使用 TDesign,如何幫我實作一個聖杯布局:

用ChatGPT搭建代碼知識庫,提升開發效率

6. 更多的思考

在整個實驗中,我們可以看到,雖然通過 embedding 方案我們可以顯著提升 ChatGPT 對新知識的了解和應用,但這仍然是一個逐漸調優和改善的過程。這引發了我對于以下幾個方向的思考:

  1. 資料品質:項目中用到的高品質 TDesign 文檔,但在處理更複雜的知識庫時,資料品質可能下降。如何在複雜資料下保證資料品質是我們需要深思的問題;
  2. 測試評估:目前測試的方法不夠标準化,無法量化的評估 embedding 的效果,需要制定可量化的評估标準;
  3. 多元度和長篇幅知識整合:對于涉及多個元件和上下文比較長的元件用例的查詢,模型的處理能力有限。我們需要研究如何有效整合多元度和長下文的知識;
  4. 維護模型效果:随着知識庫的更新和擴大,如何有效地更新模型以保持其在新知識上的表現是一個挑戰;
  5. 資料安全:最後還是想要強調一下,切勿使用敏感資料和代碼來進行處理,切勿洩露公司敏感資訊。

引用

[1]langchain.js ⚡ building applications with llms through composability ⚡

[2]vue next for web tdesign 适配桌面端的元件庫,适合在 vue3.x 技術棧項目中使用

[3] https://community.openai.com/t/the-length-of-the-embedding-contents/111471/12

[4] https://github.com/jushbjj/mr.-ranedeer-ai-tutor

繼續閱讀