ABCoder 在大模型編程領(lǐng)域的探索
前言
大語(yǔ)言模型(以下簡(jiǎn)稱大模型或 LLM) 真正意義上火出圈,應(yīng)該算是 OpenAI 發(fā)布 ChatGPT 后(22 年底)。從這個(gè)時(shí)間開(kāi)始,到現(xiàn)在為止,已經(jīng)過(guò)了很長(zhǎng)一段時(shí)間了,市面上也出現(xiàn)了一些編程工具,比如 MarsCode、Copilot 或者 Cursor 等比較火的結(jié)合 IDE 的插件和工具。而實(shí)際上:經(jīng)過(guò)了這么長(zhǎng)時(shí)間的 LLM 產(chǎn)品發(fā)展,大家的編程方式真的被改變了嗎?
近一年多以來(lái),我們?cè)?LLM 編程領(lǐng)域做了比較多的落地嘗試,有一些成果,也發(fā)現(xiàn)了一些問(wèn)題,可以把它們簡(jiǎn)單歸納為三個(gè)方面:
- 意圖識(shí)別不準(zhǔn)。尤其對(duì)于復(fù)雜編程問(wèn)題的描述和傳遞,在編程領(lǐng)域?qū)τ诖竽P蛠?lái)說(shuō)是一個(gè)比較大的問(wèn)題。
- 復(fù)雜任務(wù)無(wú)從下手。工程化的編程任務(wù)相對(duì)復(fù)雜或具備一定的理解成本,大模型無(wú)法準(zhǔn)確、完備地把這類問(wèn)題系統(tǒng)地做出來(lái)。簡(jiǎn)單來(lái)說(shuō),其實(shí)是大模型本身缺乏了一些處理編程任務(wù)的標(biāo)準(zhǔn)流程,也就是所謂的 SOP。
- 生成效果不理想。有些工具能夠識(shí)別到意圖,也能夠做到 SOP 的拆解,但整個(gè)大模型或者結(jié)合大模型的一些應(yīng)用,它帶來(lái)的一些生成效果往往達(dá)不到我們的預(yù)期。原因可能在于其解決問(wèn)題或者編程相關(guān)的一些上下文缺失或者模型本身的局限。
ABCoder Show
基于此,我們圍繞 LLM 解決編程問(wèn)題做了一些探索,將這個(gè)過(guò)程中的思考和實(shí)踐沉淀成了 ABCoder 這個(gè)項(xiàng)目,也是我們今天分享的主角。嘗試通過(guò) ABCoder 來(lái)彌補(bǔ)或者解決前言中提到的一些問(wèn)題,提升 LLM 在編程領(lǐng)域的表現(xiàn)能力。接下來(lái)我將會(huì)通過(guò)一個(gè)實(shí)機(jī)演示來(lái)具體說(shuō)明。(可通過(guò)文末視頻鏈接觀看 demo 內(nèi)容)
這條鏈路是從需求溝通到對(duì)應(yīng)的 IDL 生成,到項(xiàng)目生成,這幾個(gè)標(biāo)高亮的部分都是通過(guò) ABCoder 進(jìn)行輔助增強(qiáng)的一個(gè)流程。
當(dāng)項(xiàng)目正式部署起來(lái)之后,繼續(xù)根據(jù)新的需求進(jìn)行調(diào)整,我們通過(guò) ABCoder 理解存量項(xiàng)目,更新它,然后部署新的更新后的項(xiàng)目??梢钥吹?,最后的項(xiàng)目也跑起來(lái)了。之后,我們將這個(gè)項(xiàng)目通過(guò) ABCoder 進(jìn)行項(xiàng)目的拆解。使用 ABCoder 對(duì)其進(jìn)行理解和壓縮,對(duì)應(yīng)生成了高質(zhì)量項(xiàng)目文檔。
ABCoder 簡(jiǎn)介
ABCoder 背景
ABCoder 出現(xiàn)的背景來(lái)自于我們對(duì)大模型在語(yǔ)義化場(chǎng)景下的一些能力涌現(xiàn)的觀察,大模型在一定程度上具備理解問(wèn)題、解答問(wèn)題的能力。這為我們開(kāi)啟了一條充滿希望的道路,我們期望借助大模型的能力,在這條道路上實(shí)現(xiàn)一些與編程領(lǐng)域相關(guān)的應(yīng)用。
但實(shí)際上,在我們落地的過(guò)程中也發(fā)現(xiàn)了一些問(wèn)題,包括大模型在處理多層次邏輯,或者涉及到復(fù)雜的一些算法設(shè)計(jì),亦或是在大型的系統(tǒng)架構(gòu)時(shí),大模型的表現(xiàn)都沒(méi)有達(dá)到我們最初的預(yù)期。時(shí)間線回到去年年底,為了嘗試優(yōu)化、解決我們遇到的問(wèn)題,我們發(fā)起了 ABCoder 項(xiàng)目。
什么是 ABCoder
ABCoder 的命名來(lái)源于 AI-Based Coder 的縮寫(xiě)。核心是圍繞 LLMs 構(gòu)建一套編程增強(qiáng)的解決方案。它能夠通過(guò)彌補(bǔ)模型缺乏的編程經(jīng)驗(yàn)和復(fù)雜邏輯思維能力,在編程和算法設(shè)計(jì)以及大型系統(tǒng)構(gòu)建中穩(wěn)定發(fā)揮 LLM 的涌現(xiàn)能力。
從左邊的架構(gòu)圖可以看到,它一共分了四層:
- 第一層 Sources 層,是 ABCoder 將要處理的知識(shí)源,包括 Wikis——編程項(xiàng)目相關(guān)的一些用戶文檔,Grammar ——對(duì)應(yīng)的編程語(yǔ)言,自身的語(yǔ)法、規(guī)則以及對(duì)應(yīng)配套的工具鏈。最為重要的是 Repos,在 ABCoder 里,Repos 是我們第一優(yōu)先級(jí)(first class)處理的知識(shí),是我們圍繞著 LLM、幫助 LLM 去理解所有編程任務(wù)的一個(gè)最核心的知識(shí)來(lái)源。
- 在幫助我們理解和解析 Repos 的過(guò)程中,我們做了第二層 Parsers 層。這一層我們做了大量的實(shí)踐,包括實(shí)現(xiàn)了基于 AST 和 LSP 的 Parsers,能夠?qū)?duì)應(yīng)的 Repos,也就是語(yǔ)言的整個(gè)項(xiàng)目打包解析為面向 LLM 的更加親和的知識(shí)原料。
- 第三層是工具層,主要是一些基礎(chǔ)能力的封裝,包括數(shù)據(jù)加載的工具 Loaders,Indexing 或 Retrieval 等相似度檢索相關(guān)的工具封裝。
- 最后是 Workflows 層和 LLMs 層,Workflows 層承載的是幫助模型構(gòu)建 SOP 的角色,它有機(jī)的將 LLMs 結(jié)合進(jìn)來(lái),驅(qū)動(dòng)整個(gè)模型正常運(yùn)轉(zhuǎn)。Workflows 層有三個(gè)圖例,最左邊是 sequence 的 workflows,它是一條串型的執(zhí)行鏈路;中間是分支或者并行的 workflows;最后有一個(gè) circle,這是 circle 范式的應(yīng)用,目前主流的一些 Agent 都基于 circle 這樣的方式來(lái)呈現(xiàn)。在這個(gè)基礎(chǔ)上,我們通過(guò)結(jié)合大量的 workflows 和 LLMs 進(jìn)行有機(jī)的交互,實(shí)現(xiàn)它對(duì)上面整個(gè)的應(yīng)用支持。
回到真正內(nèi)核的部分,整個(gè) ABCoder 沒(méi)有太多復(fù)雜的概念,主要是兩個(gè)詞,RAG 和慢思考。這套系統(tǒng)就是為了去彌補(bǔ)模型在處理編程任務(wù)時(shí)缺乏的一些編程經(jīng)驗(yàn),我們通過(guò) RAG 的方式去彌補(bǔ)編程經(jīng)驗(yàn)的缺失,通過(guò) workflows 彌補(bǔ)多級(jí)流轉(zhuǎn),讓模型的生成慢下來(lái),也就是經(jīng)過(guò)多輪的迭代來(lái)嘗試逼近一個(gè)更為準(zhǔn)確的答案。
ABCoder 的實(shí)現(xiàn)
為了更好地讓大家快速地理解 ABCoder 的本質(zhì),我們隨著核心的實(shí)現(xiàn)來(lái)進(jìn)一步闡述。熟悉 RAG 架構(gòu)的同學(xué)其實(shí)很清楚了,為了實(shí)現(xiàn) RAG,我們有兩條具體的實(shí)現(xiàn)路徑。
第一條是離線路徑,是對(duì)于存量知識(shí)(綠框)的處理,包括用戶文檔、編程語(yǔ)言,以及編程項(xiàng)目都是我們核心需要處理的單位。我們將它們?cè)陔x線路徑上進(jìn)行一些處理,轉(zhuǎn)化為藍(lán)色部分離線知識(shí)庫(kù)的內(nèi)容。
第二條是在線路徑,我們運(yùn)用知識(shí)進(jìn)行工具化以及 Workflows 的封裝,實(shí)現(xiàn)在線路徑上的問(wèn)答或者插件封裝,以及 IDE 上的輔助能力。
離線路徑
在離線實(shí)現(xiàn)側(cè),核心是上圖中的第三點(diǎn),即編程項(xiàng)目離線知識(shí)的制作,對(duì)應(yīng)的是我們開(kāi)發(fā)的 LLM 原生解析器,負(fù)責(zé)處理編程項(xiàng)目。憑借這個(gè)能力,我們將編程項(xiàng)目自身作為一個(gè)知識(shí)來(lái)源,結(jié)合 LLM 來(lái)主動(dòng)生成和豐富用戶文檔,作為用戶文檔的補(bǔ)充。
舉例說(shuō)明,圖中左側(cè)列出來(lái)的是一個(gè)典型的 Hertz 項(xiàng)目的 Layout。我們現(xiàn)在要將這個(gè)項(xiàng)目輸入到 LLM 里,如果單純地去輸入這個(gè)項(xiàng)目本身,那將有若干個(gè)文件;如果將這些文件一股腦灌給 LLM,它也并不能很好地去理解這些文件集合。但實(shí)際上我們的編程項(xiàng)目有一個(gè)內(nèi)在的關(guān)聯(lián)性,這個(gè)關(guān)聯(lián)性是什么呢?可以看到這里有一個(gè)例子,我們通過(guò)解析-壓縮-結(jié)構(gòu)化,得到了上圖右側(cè)部分看起來(lái)像是一棵樹(shù)的結(jié)構(gòu),這個(gè)樹(shù)的結(jié)構(gòu)就是我們?cè)陧?xiàng)目里函數(shù)調(diào)用的一棵樹(shù)。main 對(duì)應(yīng)的是 main 函數(shù),它同時(shí)依賴 register 以及 server.Default 這兩個(gè)函數(shù)節(jié)點(diǎn),它們可能也有額外的子依賴。這個(gè)樹(shù)狀的依賴關(guān)系其實(shí)就是項(xiàng)目中函數(shù)調(diào)用的關(guān)系的呈現(xiàn)。
上圖左下側(cè)可以看到,在這棵樹(shù)下列出了五個(gè)函數(shù)和它的描述所對(duì)應(yīng)的列表。這里有一個(gè)小細(xì)節(jié),就是 1、2、3、4、5 的順序是從這棵樹(shù)葉子節(jié)點(diǎn)開(kāi)始反向往上去理解,直到最上層的 main 函數(shù)。原因非常簡(jiǎn)單,我們?cè)谧?ABCoder 理解時(shí),就是按照這樣的順序一步一步將整個(gè)項(xiàng)目進(jìn)行拆解,最終達(dá)到 main。因此,每一個(gè)函數(shù)只需要關(guān)注自己所調(diào)用的函數(shù)以及本身內(nèi)在的邏輯就夠了,這樣可以一定程度減少我們?cè)诶斫夂瘮?shù)節(jié)點(diǎn)時(shí)模型本身的上下文發(fā)散,或者說(shuō)避免一股腦輸入的信息超過(guò)了我們希望讓它生成或者聯(lián)想的上下文限制的問(wèn)題,來(lái)保證信息準(zhǔn)確、聚焦,達(dá)到很好的理解和壓縮的效果。
以上是我們用函數(shù)作為一個(gè)示例。在處理編程項(xiàng)目時(shí),除了函數(shù)以外,同時(shí)還包括對(duì)類型以及變量的處理。通過(guò)這套語(yǔ)言無(wú)關(guān)的 Schema 抽象,最終得到的就是將編程語(yǔ)言或源代碼作為最后在線路徑上用到的 knowledge,整個(gè)過(guò)程概括為一句話,即圖中紅色框所示 —— Source code as knowledge。
在線路徑
相對(duì)離線路徑,在線路徑方面的實(shí)現(xiàn)非常簡(jiǎn)單。我們將經(jīng)過(guò) ABCoder 處理并消化后的知識(shí),結(jié)合 Retrieval & Augment(檢索&增強(qiáng))來(lái)實(shí)現(xiàn)工具化以及 Workflows 的構(gòu)建和調(diào)用,最終在在線鏈路上就能夠很好地去用到剛剛在離線階段處理的這些源碼知識(shí)了。
應(yīng)用落地
接下面我們來(lái)看看在應(yīng)用側(cè)是怎樣的狀態(tài)。回到整體架構(gòu)圖。有人說(shuō)過(guò)這么一句話:不會(huì)做飯的廚子不是好的程序員,我覺(jué)得這句話很有意思,順著這個(gè)邏輯,我嘗試將我們的架構(gòu)做了一個(gè)形象的拆解,左邊是我們的架構(gòu),右邊映射到的是如果將做飯這個(gè)過(guò)程映射到這套架構(gòu)中,看看每一層究竟對(duì)應(yīng)的是什么樣的角色?
首先,最上面綠色的部分對(duì)應(yīng)的是知識(shí)庫(kù),它就是我們做飯的食材。Repo parsers 對(duì)應(yīng)的是刀具,我們需要將食材通過(guò) Repo parsers 進(jìn)行一些拆解、分割,把它做到適合去炒、蒸或者煮的形態(tài)。之后,結(jié)合大量的 Tools,對(duì)應(yīng)的就是鍋鏟類似的烹飪工具,幫助我們?nèi)ヌ幚聿煌螒B(tài)的食材,或者在不同的階段去處理食材。最下面這層就是 Workflows 菜譜加上 LLMs 廚子,有了菜譜,加上廚子,結(jié)合上面的烹飪工具就能夠做出一鍋好菜了?;剡^(guò)頭來(lái)看 ABCoder 的這套架構(gòu),聰明的小伙伴可能已經(jīng)發(fā)現(xiàn),ABCoder 對(duì)應(yīng)的并不是具體的某一個(gè)應(yīng)用,而是一系列的應(yīng)用,或者說(shuō)其實(shí)是孵化應(yīng)用的基座。
通過(guò) Tools、Workflows 以及知識(shí)庫(kù)進(jìn)行有機(jī)組合我們就能夠嘗試構(gòu)建出一系列的應(yīng)用。上圖是我們內(nèi)部目前正在嘗試的三大應(yīng)用落地方向。
第一個(gè)方向是 SmartComment,它也是 ABCoder 能力最直接的應(yīng)用嘗試,它的目標(biāo)是產(chǎn)出高質(zhì)量的注釋以及相關(guān)的用戶文檔,核心的 workflows 以及 Tools 如圖表中所示,對(duì)應(yīng)的知識(shí)庫(kù)就是 ABCoder 解析完之后的倉(cāng)庫(kù)語(yǔ)料。其他幾個(gè)方向也可以在圖表中看到。
應(yīng)用落地的里程碑
以上提到的三大應(yīng)用制定了近期和遠(yuǎn)期的里程碑。當(dāng)前,三大應(yīng)用方向近期的里程碑已經(jīng)陸陸續(xù)續(xù)達(dá)成。在遠(yuǎn)期上,SmartComment 將在半年到一年的時(shí)間內(nèi),探索出一套文檔工程相對(duì)應(yīng)的實(shí)現(xiàn),即 Code2Wiki,就是通過(guò)源碼的方式去補(bǔ)充用戶文檔的數(shù)量以及質(zhì)量。在 Wiseman 側(cè),遠(yuǎn)期是希望實(shí)現(xiàn)從需求溝通到全自動(dòng)化研發(fā)流程的構(gòu)建。語(yǔ)言翻譯側(cè),不僅僅要做到項(xiàng)目本身的翻譯,遠(yuǎn)期將實(shí)現(xiàn)的是一套漸進(jìn)式的翻譯流,包括項(xiàng)目以及研發(fā)人力的 A2B 轉(zhuǎn)換,共同成長(zhǎng)。
未來(lái)規(guī)劃與展望
關(guān)于開(kāi)源
在開(kāi)源方面,ABCoder 將會(huì)以圍繞 CloudWeGo 構(gòu)建 AI 驅(qū)動(dòng)的微服務(wù)生態(tài)體系作為我們的核心目標(biāo)。
在關(guān)鍵路徑上,我們后續(xù)將對(duì) CloudWeGo 所有的組件進(jìn)行 ABCoder 索引化,剛剛在 demo 里看到的處理 Hertz 的這套流程,將會(huì)無(wú)縫應(yīng)用到 CloudWeGo 下的所有組件。之后,ABCoder 的應(yīng)用將走進(jìn) CloudWeGo 社區(qū),包括在研發(fā)行為以及社區(qū)生態(tài)上,為研發(fā)社區(qū)賦能。最后,當(dāng)應(yīng)用成熟度打磨到一定階段,將在 CloudWeGo 上完成正式開(kāi)源,之后以社區(qū)的方式進(jìn)行持續(xù)迭代和演進(jìn)。
關(guān)于展望
在內(nèi)部,ABCoder 提供的是編程語(yǔ)言結(jié)合 LLM 的一套解決方案,其終極理想形態(tài)被稱為「空」?!缚铡故且惶渍Z(yǔ)言中立的編程范式,它是完全 LLM 原生的一套編程模式,期望能夠?yàn)檎麄€(gè)生產(chǎn)流程以及后面的發(fā)布流程,打通整個(gè)相關(guān)生態(tài)。
在外部,ABCoder 的表現(xiàn)在一定程度上依賴模型本身的能力。外部陸續(xù)發(fā)布的一些模型,也讓我們看到了一些眼前一亮的突破,包括模型本身在深度和廣度上的突破。近期一個(gè)叫做 OpenAI O1 的模型發(fā)布是一個(gè)比較好的例子。它通過(guò)引入類似強(qiáng)化學(xué)習(xí)的方式,在模型中內(nèi)置一條思維鏈,主動(dòng)將模型的生成降速,結(jié)合多輪思考和評(píng)估能夠有效解決更加復(fù)雜的問(wèn)題,其表現(xiàn)出的能力也是之前其他的模型未曾帶來(lái)的。結(jié)合這類模型,或許在未來(lái)也會(huì)持續(xù)突破目前LLM 在編程領(lǐng)域的一些能力邊界。