偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

百度關(guān)于大模型在研發(fā)領(lǐng)域落地的深度思考

人工智能
今天的主題是探討大模型技術(shù)在研發(fā)領(lǐng)域的發(fā)展及應(yīng)用。眾所周知,大模型在編寫代碼方面已有很多實(shí)際應(yīng)用案例,除了輔助性工作外,我們是否可以利用這一技術(shù)更大規(guī)模地改變我們的工作流程,或者更徹底地改變某些關(guān)鍵環(huán)節(jié)的做法呢?

一、智能研發(fā)工具的發(fā)展

首先來看一下智能研發(fā)工具的發(fā)展歷程和方向。

1. 智能化的發(fā)展背景與落地訴求

圖片

早期的智能化工具,如 GitHub 的 Copilot 工具,大約在兩年半前推出。最初,Copilot 的主要功能是在開發(fā)者編寫代碼時(shí)提供自動(dòng)補(bǔ)全建議。隨著時(shí)間的發(fā)展,其功能逐漸豐富,現(xiàn)在的 Copilot chat 插件支持語言轉(zhuǎn)換、單元測(cè)試等多種功能。

隨著大模型的發(fā)展,所有相關(guān)產(chǎn)品都在迅速升級(jí)進(jìn)化。從最初的輔助編碼開始,到現(xiàn)在能夠與開發(fā)者協(xié)同工作,我們甚至可以將部分任務(wù)完全交給 AI 完成。由代碼補(bǔ)全轉(zhuǎn)變?yōu)榇a生成,不僅是在代碼基礎(chǔ)上生成代碼,更多是在需求的基礎(chǔ)上去生成代碼,從單純的寫代碼轉(zhuǎn)變?yōu)榉?wù)于整個(gè)工程。例如,最近 Copilot 推出的幫用戶搭建單元測(cè)試環(huán)境的功能,已經(jīng)超越了單純的代碼編寫層面。

接下來,將從代碼生成的體量、工具職責(zé)的變化、效果的優(yōu)化、能力的提升以及用戶體驗(yàn)交互方式上的創(chuàng)新等幾個(gè)方面來介紹這一工具近期發(fā)生的變化。

2. Go Fat:更大規(guī)模的代碼補(bǔ)全

圖片

首先是“Go Fat”,也就是代碼補(bǔ)全的規(guī)模在不斷變大。代碼補(bǔ)全是最經(jīng)典的智能開發(fā)形式。在編寫代碼過程中,自動(dòng)出現(xiàn)一行灰色的提示,這并非通過函數(shù)定義等方式自動(dòng)生成,而是基于大模型推測(cè)出一段話。這種形式對(duì)于開發(fā)者來說最容易理解和使用,因?yàn)樗鼘⑶脦讉€(gè)字符的時(shí)間簡(jiǎn)化為按下 Tab 鍵的時(shí)間。在此基礎(chǔ)上,所有工具都希望在符合用戶習(xí)慣的前提下進(jìn)一步升級(jí)。

圖片

從單行代碼的補(bǔ)全,逐步擴(kuò)展到代碼塊,甚至基于注釋生成整個(gè)方法或函數(shù),從而擴(kuò)大補(bǔ)全的范圍。

圖片

然而,隨著模型生成的代碼量的增加,錯(cuò)誤率也會(huì)相應(yīng)上升。尤其是當(dāng)一個(gè)工具或模型在不了解具體業(yè)務(wù)需求的情況下自動(dòng)生成代碼時(shí),錯(cuò)誤率往往更高。一旦錯(cuò)誤率達(dá)到一定比例,比如超過一半,那么人工修正這些錯(cuò)誤所花費(fèi)的時(shí)間將抵消甚至超過工具帶來的效率提升。因此,對(duì)于工具而言,必須通過結(jié)合模型的編程現(xiàn)場(chǎng)、項(xiàng)目需求以及用戶的操作歷史等多維度信息來提升準(zhǔn)確率,使其達(dá)到一個(gè)既準(zhǔn)確又高效的水平。

所有工具都需要解決四個(gè)核心問題:觸發(fā)時(shí)機(jī)、推理邏輯、結(jié)束位置和檢查質(zhì)量。

觸發(fā)時(shí)機(jī)的核心在于判斷何時(shí)能夠補(bǔ)全一塊代碼,何時(shí)應(yīng)僅補(bǔ)全一行代碼。顯然,這取決于代碼中重復(fù)性和規(guī)律性的特點(diǎn)。例如,在存在 if-else,for 或 switch 結(jié)構(gòu)時(shí),代碼往往具有明顯的規(guī)律性,很多 switch 的 case 中的代碼都非常相似,因此許多工具會(huì)在這些場(chǎng)景下觸發(fā)多行代碼的補(bǔ)全。在其他場(chǎng)景下,工具可能還是會(huì)退回到單行補(bǔ)全。另一種特征是注釋,當(dāng)你已經(jīng)寫了一行注釋時(shí),工具可以根據(jù)該注釋進(jìn)一步推理代碼,從而獲得更完整的上下文信息,提高準(zhǔn)確性。觸發(fā)時(shí)機(jī)是通過產(chǎn)品層面的語法樹解析來解決的,以達(dá)到高質(zhì)量、低錯(cuò)誤率的目標(biāo)。

第二是推理邏輯,將什么東西輸入給模型,模型才能更好的推理。最簡(jiǎn)單的情況是將光標(biāo)位置上下的兩段代碼作為輸入,模型在中間插入新代碼。除此之外,模型還可以利用文件依賴關(guān)系和 import 的內(nèi)容來更好地進(jìn)行推斷。例如,當(dāng)你編寫代碼時(shí),通常會(huì)打開其他文件以查看可用的功能或變量,然后返回繼續(xù)編寫。因此,你最近打開的文件在一定程度上可能會(huì)被用到。對(duì)此,在后文中還將進(jìn)行更詳細(xì)的說明。

第三是結(jié)束位置。由于模型本質(zhì)上是一個(gè)續(xù)寫工具,它根據(jù)前文生成后文,但若不斷續(xù)寫最后一定是錯(cuò)誤的。并且代碼過長(zhǎng)可能會(huì)無法使用,少量代碼行則可能更為實(shí)用。因此,如何適時(shí)地結(jié)束代碼生成是關(guān)鍵問題。然而,正因?yàn)榇a是多行的,沒法僅憑換行符作為 stop sequence 的結(jié)束標(biāo)志,我們需要通過程序方式檢測(cè)模型輸出的內(nèi)容是否應(yīng)結(jié)束。這涉及多種策略,例如:當(dāng)觸發(fā)時(shí)機(jī)為一個(gè)代碼塊時(shí),我們可以在遇到匹配的右括號(hào)時(shí)結(jié)束;如果是 if 里面還有個(gè) if,那等外層的 if 結(jié)束時(shí)結(jié)束;如果觸發(fā)時(shí)機(jī)是一個(gè)注釋,那么連續(xù)的換行或下一個(gè)注釋的出現(xiàn)可能是合適的結(jié)束信號(hào);如果代碼塊之間存在空行時(shí),這通常意味著不同的邏輯塊的開始,因此可以在此結(jié)束。這些策略與觸發(fā)時(shí)機(jī)密切相關(guān),旨在確保代碼塊的適時(shí)結(jié)束。

接下來再看檢查質(zhì)量。在使用模型時(shí),我們偶爾會(huì)遇到一些問題,例如模型生成完全重復(fù)的代碼片段,這是一解決個(gè)顯而易見且需要的問題,但對(duì)于代碼質(zhì)量而言,還存在其他明顯的不符合標(biāo)準(zhǔn)的情況。例如,在訓(xùn)練過程中可能會(huì)遇到數(shù)據(jù)污染,導(dǎo)致模型生成包含韓文字符的注釋。顯然,無論是面向客戶還是我們自己使用,這種情況都是不可接受的。因此,我們的首要任務(wù)是通過策略來屏蔽這些錯(cuò)誤內(nèi)容的輸出,第二就是追加模型訓(xùn)練。除此之外,還有一類模型很容易出現(xiàn)的問題就是代碼過度擬合,生成的代碼與現(xiàn)有代碼過度相似,甚至完全相同,導(dǎo)致無法直接使用,這類問題也要解決掉。最終,通過質(zhì)量檢查和過濾措施,將高質(zhì)量的代碼呈現(xiàn)到用戶面前。

通過上述工作,多行代碼補(bǔ)全的正確率或者用戶采納率,都可以達(dá)到平均值以上。

3. Be Rich:豐富的生成能力

圖片

除了協(xié)助補(bǔ)全代碼,我們還需探索模型在更多場(chǎng)景中的應(yīng)用潛力。一個(gè)顯著的例子便是代碼優(yōu)化。在日常業(yè)務(wù)開發(fā)中,寫面條代碼是再平常不過的事。然而,當(dāng)業(yè)務(wù)已經(jīng)十分繁忙時(shí),再要求他們回頭審視代碼,進(jìn)行重構(gòu)與優(yōu)化,無疑是一種難以接受的工作模式。如果將這類任務(wù)交給模型,能夠得到怎樣的幫助呢?

圖片

首先,模型會(huì)指出代碼中存在重復(fù)部分,并建議將這些重復(fù)的內(nèi)容抽象化,通過創(chuàng)建一個(gè)函數(shù)來封裝它們。其次,模型會(huì)指出代碼中的硬編碼問題,如果未來需要修改這些編碼,而其他地方未同步更新,可能會(huì)導(dǎo)致問題。因此,它建議提取一些常量,以確保所有相關(guān)部分都能通過修改常量來同步更新。第三,它會(huì)指出代碼中存在的類型安全問題,比如某個(gè)類型應(yīng)該是從其他部分獲取的,但代碼中沒有進(jìn)行相應(yīng)的判斷。因此,模型會(huì)建議修改語法,采用問號(hào)點(diǎn)等方式來增強(qiáng)類型安全性。第四,模型會(huì)指出代碼中的命名不規(guī)范問題,并提供一段經(jīng)過優(yōu)化的代碼作為示例,經(jīng)過評(píng)測(cè),這段代碼是可靠的。當(dāng)然,在將這段代碼應(yīng)用到原始代碼之前,我們進(jìn)行了一些工程化處理,以確保它們能夠?qū)?。這樣,你可以直接采納這段代碼,從而自然地實(shí)現(xiàn)一些常見的優(yōu)化,而這些優(yōu)化既不影響業(yè)務(wù)邏輯,又是相對(duì)可靠和正確的。因此,在編碼過程中,我們可以將一部分工作,特別是事后的優(yōu)化和檢查,交給模型來完成,讓它與我們協(xié)同開發(fā)。這與以前模型中只能單純編寫一兩行代碼的情況相比,已經(jīng)有了截然不同的效果。

圖片

再來看另一個(gè)場(chǎng)景,即函數(shù)代碼量過大的情況。當(dāng)我們不小心編寫了一個(gè) 500 行的函數(shù)時(shí),作為工程師的第一反應(yīng)通常是認(rèn)為這個(gè)函數(shù)需要拆分。然而,對(duì)于忙碌的工程師來說,可能會(huì)因?yàn)闀r(shí)間緊張而無法立即進(jìn)行拆分。那么,在這個(gè)場(chǎng)景下,模型能做些什么呢?

以前端場(chǎng)景為例,假設(shè)我們有一個(gè)展示在界面上的組件或者元素。模型首先會(huì)在這個(gè)組件中抽取一些公共的功能,并將它們封裝成一個(gè)函數(shù),使得這個(gè)函數(shù)可以在多個(gè)地方復(fù)用。其次,模型會(huì)在函數(shù)的基礎(chǔ)上再做一層封裝,這在 React 框架中被稱為 hook,這種封裝依然保持了代碼的可復(fù)用性。接下來,模型會(huì)進(jìn)行第三層的拆分,將一個(gè)大組件拆分成多個(gè)小組件。比如,一個(gè)包含框、標(biāo)題和內(nèi)容的組件,模型會(huì)將其拆分成獨(dú)立的標(biāo)題、內(nèi)容和布局(框)組件。這樣的拆分有助于從代碼實(shí)踐的角度將組件分離成不同的層次,然后再通過組合的方式將它們重新整合在一起。當(dāng)然,這并不是通過簡(jiǎn)單的 prompt 就能實(shí)現(xiàn)的。這背后其實(shí)是我們平時(shí)大量實(shí)踐經(jīng)驗(yàn)的積累,需要將這些經(jīng)驗(yàn)轉(zhuǎn)化為復(fù)雜的 prompt,并轉(zhuǎn)化為一系列類似于 One-shot 或 Few-shots 的例子,放入模型的上下文中。

這是我非常期望的開發(fā)類工具所能達(dá)到的效果,將我們具有豐富經(jīng)驗(yàn)的工程師的實(shí)踐融入到產(chǎn)品中,讓所有人都能享受到這些經(jīng)驗(yàn)所帶來的好處。

4. Seek Deep:更深度地了解全庫

圖片

接下來,來看看產(chǎn)品的第三個(gè)進(jìn)度,這主要體現(xiàn)在它對(duì)整個(gè)代碼庫的了解程度上。最初的工具對(duì)代碼庫沒有任何感知,只是根據(jù)光標(biāo)前后的內(nèi)容憑感覺生成代碼,這在實(shí)際業(yè)務(wù)中很容易出錯(cuò)。因此,后來的工具都發(fā)展出了全庫代碼索引的概念。簡(jiǎn)單來說,全庫代碼索引是通過向量化 embedding 技術(shù),將代碼庫中的所有代碼進(jìn)行索引,然后根據(jù)用戶的需求將其轉(zhuǎn)化為向量,并進(jìn)行向量的相似度計(jì)算,從而找到相關(guān)的代碼。這個(gè)過程雖然復(fù)雜,但效果卻比較明顯。

例如,當(dāng)你詢問一個(gè)方法的作用時(shí),如果工具沒有了解整個(gè)代碼庫,它可能只會(huì)告訴你這個(gè)方法看起來像是一個(gè)用于對(duì)話的方法,并逐行解釋代碼。然而,這對(duì)于大多數(shù)工程師來說并沒有太大的價(jià)值。但如果工具了解整個(gè)代碼庫,它就能為你梳理出整條業(yè)務(wù)流程,并生成一個(gè)流程圖。這個(gè)流程圖并不是簡(jiǎn)單的函數(shù)調(diào)用關(guān)系,而是真正業(yè)務(wù)層面上的流程。

當(dāng)你需要啟動(dòng)一個(gè)會(huì)話時(shí),工具會(huì)分情況根據(jù)你調(diào)用的方法,分析出下游做了哪些復(fù)雜的流程,并分析出整個(gè)業(yè)務(wù)流程。特別是當(dāng)你剛接觸一個(gè)代碼庫,還不熟悉其業(yè)務(wù),但又急需完成一個(gè)需求或修復(fù)一個(gè)bug時(shí),這種效果會(huì)非常明顯。

5. Create By Trust:值得信賴的工作

圖片

再審視我們當(dāng)前所使用的這些工具,還存在一個(gè)問題,即其生成的結(jié)果常常會(huì)產(chǎn)生幻覺。一旦這種現(xiàn)象發(fā)生,用戶的信任度便會(huì)大幅下降。那么,我們應(yīng)如何解決這一問題呢?在特定情境下,例如執(zhí)行某個(gè)命令時(shí),該命令可能會(huì)在運(yùn)行過程中突然報(bào)錯(cuò)。面對(duì)此類錯(cuò)誤,我們可以將其提交給模型,并結(jié)合一系列工程調(diào)優(yōu)手段進(jìn)行修復(fù)。模型能夠精確地指出錯(cuò)誤所在,具體到文件的某一行或某幾行代碼,這是因?yàn)槲覀儞碛姓{(diào)用棧(step trace)信息。在修復(fù)問題后,我們可以清晰地觀察到代碼的變化。

這種做法的優(yōu)勢(shì)在于,當(dāng)你再次執(zhí)行該命令時(shí),若看到命令成功運(yùn)行,顯示為綠色,你便能自然而然地確認(rèn)問題已被解決。在這種可驗(yàn)證的場(chǎng)合下使用模型,我們可以以極低的成本迅速判斷模型輸出的正確性,若發(fā)現(xiàn)錯(cuò)誤,則將其撤回即可。在這種情境下,我們與模型之間的協(xié)同配合,其效率遠(yuǎn)高于人工逐行審查模型輸出的代碼。

6. AT Your Hand:更貼合現(xiàn)場(chǎng)的交互

圖片

接下來,我們探討一下交互方面的問題。當(dāng)前的眾多工具,包括我們自主開發(fā)的以及其他大模型應(yīng)用,一個(gè)最顯著的特征就是在界面邊緣添加一個(gè)側(cè)邊欄,內(nèi)置對(duì)話框以供聊天,這已成為大模型的主要使用方式。然而,對(duì)話框在編寫代碼時(shí)卻帶來了一個(gè)顯著問題:它會(huì)打斷編寫者的思路。當(dāng)我們?nèi)褙炞⒂诰帉懘a時(shí),視線始終聚焦于代碼區(qū)域。如果此時(shí)需要查看對(duì)話框,就必須將視線從代碼上移開,轉(zhuǎn)至側(cè)邊欄,這無疑會(huì)打斷我們的編程節(jié)奏。對(duì)于編程人員而言,專注力至關(guān)重要。因此,現(xiàn)有的許多工具已開始嘗試將對(duì)話框融入代碼區(qū)域中,我們稱之為“行間對(duì)話(inline chat)”。在行間對(duì)話模式下,你可以直接在代碼光標(biāo)處與工具進(jìn)行交互。例如,當(dāng)你需要編寫某段代碼時(shí),只需簡(jiǎn)單說明需求,大模型便會(huì)根據(jù)需求調(diào)用并返回相應(yīng)的代碼。

此外,還可以選擇一段代碼,請(qǐng)求工具根據(jù)需求進(jìn)行修改,如添加邊界條件檢測(cè)、判斷返回值是否正確,甚至進(jìn)行代碼優(yōu)化等,工具會(huì)在你的代碼基礎(chǔ)上進(jìn)行編輯,并以紅綠塊的形式展示修改內(nèi)容。若你滿意修改結(jié)果,點(diǎn)擊確認(rèn)即可保留;若不滿意,則點(diǎn)擊取消,修改內(nèi)容將被撤銷。這種方案能夠讓你在專注編寫代碼的同時(shí),通過自然語言與大模型進(jìn)行交互,從而更加高效地完成編程任務(wù)。

以上就是我們產(chǎn)品在交互方面的發(fā)展。

二、企業(yè)落地智能研發(fā)經(jīng)驗(yàn)

1. 在企業(yè)中踏實(shí)落地開發(fā)智能化

圖片

從企業(yè)和團(tuán)隊(duì)的角度來看,大模型無疑是一個(gè)極具潛力的工具,這一點(diǎn)我們都普遍認(rèn)同。然而,當(dāng)我們將工具下放至每個(gè)個(gè)體時(shí),卻會(huì)發(fā)現(xiàn)大家的接受程度參差不齊。有些人認(rèn)為大模型對(duì)他們的幫助極大,工作效率有了百分之五六十甚至翻倍的提升,他們非常樂意接受并使用這一工具。而另一些人則可能覺得不習(xí)慣,偶爾的錯(cuò)誤會(huì)讓他們感到困擾,覺得需要花費(fèi)額外的時(shí)間去校對(duì)和修正,因此對(duì)大模型持保留態(tài)度。還有一些人可能習(xí)慣于原有的工作模式,不愿意因?yàn)橐氪竽P投龀龈淖儯麄兏鼉A向于等待,直到大模型成為主流后再考慮使用。

面對(duì)這種差異,如果團(tuán)隊(duì)希望大模型能夠盡快被大家接受并發(fā)揮作用,那么我們需要做兩件事情:

第一,建立大家對(duì)大模型的心智認(rèn)知。讓大家在日常工作的方方面面都能感受到大模型的存在,使他們?cè)谟龅絾栴}時(shí)能夠自然而然地想到“或許我可以試試用大模型來解決”,這種心智的建立需要時(shí)間和持續(xù)的引導(dǎo)。

第二,增強(qiáng)大家對(duì)大模型效果的信心。雖然大模型在使用過程中可能會(huì)偶爾出現(xiàn)錯(cuò)誤,但是不是兩次三次,實(shí)際上可能是一百次才可能出錯(cuò)兩次,這種錯(cuò)誤是相對(duì)較少的。只有當(dāng)大家真正相信大模型即高效又準(zhǔn)確時(shí),大家才能愿意去接受它。

針對(duì)這兩件事情,我們的處理方式如下:首先,我們思考的是,在何種情況下能讓大家真正感受到大模型始終存在。若僅將大模型的應(yīng)用局限于編寫代碼的過程中,這顯然是不充分的。因?yàn)樵诰帉懘a時(shí),大模型無非充當(dāng)了一個(gè) IDE 插件的角色,一旦關(guān)閉,其存在感便蕩然無存。此后,我們也可能忘記啟動(dòng)大模型以輔助其他工作。

2. 感知存在:融合 Devops 必經(jīng)鏈路

圖片

對(duì)于工程師而言,有一個(gè)不可或缺的環(huán)節(jié),即整個(gè) Devops 鏈路。從需求提出,通過需求平臺(tái),到編寫代碼,再到代碼評(píng)審、文檔查閱、測(cè)試、構(gòu)建、編譯驗(yàn)證,直至最后的部署,這些步驟都是不可或缺的。代碼提交后,必須查看流水線狀態(tài);測(cè)試結(jié)果出來后,必須進(jìn)行分析;部署上線后,還需確認(rèn)線上運(yùn)行情況及上線進(jìn)度。我們希望在這些環(huán)節(jié)中融入大模型的應(yīng)用,即便不期望大模型能帶來顯著的幫助,也希望能通過頻繁的接觸,使工程師們?cè)诿鎸?duì)問題時(shí),能夠自然而然地想到大模型。

圖片

因此,我們?cè)诋a(chǎn)品中嘗試引入了以下幾個(gè)功能。

首要的是智能化的基于大模型的代碼評(píng)審。代碼評(píng)審對(duì)我們來說是一個(gè)必不可少的環(huán)節(jié),所有代碼必須經(jīng)過評(píng)審才能入庫。在這個(gè)環(huán)節(jié),我們引入了大模型來分析提交的代碼差異,并為大家提供一些推薦。具體推薦的內(nèi)容其實(shí)并不是最重要的,關(guān)鍵在于大模型能夠發(fā)現(xiàn)一些典型的問題。將這一功能應(yīng)用到我們公司內(nèi)部后,目前的結(jié)果是,在所有的代碼評(píng)審環(huán)節(jié)的評(píng)論中,有 20% 是由大模型生成的。其中,有 15% 被大家認(rèn)為確實(shí)是有用的,是一個(gè)很好的功能,而非廢話。這個(gè)數(shù)字對(duì)我們來說其實(shí)并不高,因?yàn)?15% 的正確率,如果放在正常產(chǎn)品中,通常會(huì)引起質(zhì)疑,擔(dān)心會(huì)有錯(cuò)誤。但我們的主要目標(biāo)并不是追求極高的正確率,而是讓大家感受到大模型在協(xié)助他們工作。

圖片

因此,我們并未將該功能作為產(chǎn)品下線,而是持續(xù)保留在第二個(gè)環(huán)節(jié),即流水線編譯失敗的階段。當(dāng)編譯失敗時(shí),大模型會(huì)自動(dòng)運(yùn)行,分析失敗的原因,查看日志,提出可能的問題,并建議開發(fā)者通過哪些關(guān)鍵詞搜索網(wǎng)絡(luò),或者檢查代碼中可能存在的問題。這個(gè)功能并不直接產(chǎn)生任何代碼。

如果從大模型編寫代碼的角度來看,這個(gè)功能產(chǎn)生的代碼量為零,但它仍然能夠讓開發(fā)者隨時(shí)隨地感受到大模型的存在。因此,我們一直將該功能保留在線上,幫助大家進(jìn)行最基礎(chǔ)、最簡(jiǎn)單的分析。通過這樣不斷地向開發(fā)者推送大模型的能力,我們公司內(nèi)部目前已有超過 80% 的工程師在開發(fā)階段持續(xù)使用大模型相關(guān)的工具。

3. 效果信心:利用 CICD 確保效果

圖片

接下來,要探討的是如何讓工程師對(duì)大模型生成的結(jié)果有信心。在這方面,我們有一個(gè)非常有效的做法。我們所有的正規(guī)項(xiàng)目都配備了 CICD 流水線,它本質(zhì)上就是檢查代碼的正確性,確保代碼能夠成功編譯和運(yùn)行。這個(gè)流水線為我們提供了一個(gè)最基礎(chǔ)、最可靠的信心保障,即我們提供的代碼至少是編譯通過的,能夠運(yùn)行的。

在這個(gè)場(chǎng)景中,我們最深入的一個(gè)應(yīng)用就是使用大模型來編寫單元測(cè)試(UT)。這并不是簡(jiǎn)單地讓大模型根據(jù)重要代碼生成單元測(cè)試用例,而是有一系列的處理流程。首先,大模型會(huì)刪除不需要測(cè)試的代碼,因?yàn)楸A暨@些代碼會(huì)干擾大模型。同時(shí)受限于大模型的上下文長(zhǎng)度和成本,它會(huì)通過代碼依賴關(guān)系添加更多的相關(guān)代碼,以確保大模型能夠生成有效的單元測(cè)試。在生成單元測(cè)試后,大模型并不會(huì)直接將其交給用戶。因?yàn)榇藭r(shí)并不知道這些代碼是否正確,所以它會(huì)運(yùn)行這些單元測(cè)試,并生成一個(gè)測(cè)試報(bào)告,根據(jù)這個(gè)報(bào)告大模型會(huì)進(jìn)行翻譯,從最基礎(chǔ)的 Json 中獲取關(guān)鍵信息,例如如果我們用的是國內(nèi)的模型,它就會(huì)把英文改成中文。

這個(gè)報(bào)告通常會(huì)反映兩類問題。第一類問題是單元測(cè)試是否通過。如果單元測(cè)試失敗,可能是單元測(cè)試本身寫錯(cuò)了,也可能是業(yè)務(wù)邏輯有問題。我們會(huì)通過另一個(gè)模型來判斷是哪種情況,并相應(yīng)地修正單元測(cè)試或業(yè)務(wù)邏輯。修正單元測(cè)試可能包括修改斷言、刪除錯(cuò)誤的單元測(cè)試或讓大模型修復(fù)錯(cuò)誤的單元測(cè)試。第二類問題是覆蓋率不夠。如果大模型生成的單元測(cè)試覆蓋率太低,我們會(huì)讓模型有針對(duì)性地去提升覆蓋率。我們會(huì)從覆蓋率報(bào)告中找出哪些行沒有被覆蓋,然后分析這些行是在哪些分支條件下,讓大模型解釋這個(gè)未覆蓋的分支是什么判斷條件,再將這個(gè)解釋吐回給大模型,讓大模型注意到這個(gè)情況,再讓大模型根據(jù)情況補(bǔ)充更多的單元測(cè)試。

通過不斷提升單元測(cè)試的正確性和覆蓋率,我們最終會(huì)得到一組既正確又全面的單元測(cè)試。然后,我們會(huì)通過增刪用例,將這些單元測(cè)試組合起來,生成最終的單元測(cè)試代碼交給用戶。

圖片

通過使用文心的小模型來進(jìn)行不同復(fù)雜度的單元測(cè)試,我們能夠在模型規(guī)模幾乎小了 10 倍的情況下,達(dá)到與 GPT-4 基本相同的覆蓋率效果。當(dāng)然,這是在實(shí)驗(yàn)室環(huán)境下可以多輪運(yùn)行的結(jié)果。然而在實(shí)際用戶使用時(shí),我們不能接受長(zhǎng)時(shí)間的運(yùn)行,因?yàn)槟菚?huì)影響用戶體驗(yàn)。所以我們對(duì)時(shí)間上會(huì)有要求。

我們最終產(chǎn)品化的效果:首先,生成正確率要達(dá)到 100%,因?yàn)橹灰a能運(yùn)行,那它一定是正確的;其次,行覆蓋率要達(dá)到 30% 以上;最后,整個(gè)過程的耗時(shí)要小于 30 秒。對(duì)于大模型一個(gè)比較大的生成任務(wù)來說,30 秒已經(jīng)是一個(gè)相對(duì)較短的時(shí)間了,而且在這個(gè)時(shí)間內(nèi),我們能夠提供 30% 的覆蓋率,這是我們產(chǎn)品化的最終結(jié)果。

對(duì)于用戶來說,這個(gè)能力幾乎是一個(gè)純收益的事情。他們不再需要管理代碼,只需要試錯(cuò)、生成并保存即可。這在我們內(nèi)部提供了大量的大模型代碼生成量,也是用戶非常喜歡的一個(gè)能力。

圖片

由于該過程本就正確無誤,無需用戶手動(dòng)保存文件,因此我們將其融入到代碼管理之中。當(dāng)提交代碼后,大模型會(huì)自動(dòng)基于你的代碼生成單元測(cè)試,并再次提交一份包含單元測(cè)試的代碼補(bǔ)丁。對(duì)于這份代碼,你幾乎無需進(jìn)行額外的審查,直接合并即可,因?yàn)槠湔_性已經(jīng)得到了保證?;谶@樣的設(shè)計(jì),我們可以讓用戶在全新的開發(fā)階段也無需關(guān)注單元測(cè)試的編寫,同時(shí)仍然能夠獲得具有高覆蓋率和正確性的單元測(cè)試代碼。

三、開發(fā)者智能工具使用實(shí)踐

1. 形式變革:智能時(shí)代理念

圖片

作為個(gè)體,在使用這些工具時(shí)應(yīng)該采取哪些實(shí)踐方法以更有效地發(fā)揮工具的作用呢?

未來,AI 與我們的關(guān)系絕不僅僅是工具與人之間的簡(jiǎn)單關(guān)聯(lián),因此我們不會(huì)僅僅停留于使用 AI 的階段,而是致力于與 AI 實(shí)現(xiàn)真正的協(xié)同工作。所謂協(xié)同,意指在某些情況下,我們會(huì)將任務(wù)分配給 AI 完成,而在其他情況下,則親自處理。并非指在一項(xiàng)任務(wù)中,我僅負(fù)責(zé)前半部分而 AI 負(fù)責(zé)后半部分?;诖耍以趯?shí)踐中形成了一些個(gè)人的準(zhǔn)則。

2. 作為開發(fā)者擁抱智能化實(shí)踐

圖片

首先,關(guān)于代碼檢索這一任務(wù),我認(rèn)為讓 AI 來完成是一個(gè)極為出色的選擇。其次,當(dāng)我利用 AI 來處理事務(wù)時(shí),如何加強(qiáng)上下文信息,從而提升 AI 的準(zhǔn)確率。第三,我會(huì)分享如何管理自己的知識(shí),使其能夠與 AI 有效關(guān)聯(lián)。最后,我們將討論如何與 AI 進(jìn)行協(xié)同分工。

3. 一種全新的找代碼方法

圖片

我們先來探討代碼檢索這一任務(wù),這是我認(rèn)為在代碼編寫領(lǐng)域中,AI 有可能真正超越人類的一項(xiàng)能力。人通常是如何尋找代碼的呢?我們往往會(huì)根據(jù)所需代碼的大致要求,先在腦海中構(gòu)想在代碼里面的方法名或者變量名,然后利用全局搜索功能進(jìn)行查找。如果搜不到就換個(gè)名字繼續(xù)搜,如果找到了,就進(jìn)一步檢查該函數(shù)被哪些其他函數(shù)調(diào)用,以及函數(shù)內(nèi)部調(diào)用了哪些其他函數(shù),即我們常說的“Go to Definition,Go to Reference”。通過這一系列的步驟,我們最終在腦海中匯總這些信息,得出一個(gè)結(jié)果。

然而如果整個(gè)代碼庫都具備 embedding 的向量能力,那么我們的模型就有辦法準(zhǔn)確地定位到代碼庫中的任意代碼片段。其次,模型天生就具備總結(jié)和解釋的能力,這使得它能夠在代碼檢索方面發(fā)揮出色。因此,我們?cè)O(shè)想了一個(gè)未來的場(chǎng)景:在尋找代碼時(shí),我們可以直接使用自然語言進(jìn)行搜索,而無需再糾結(jié)于具體的變量名或方法名。

在此,我有兩個(gè)實(shí)踐建議:第一,我們應(yīng)該描述要找的功能或需求,而不是局限于描述自己的代碼。第二,如果我們尋找的目標(biāo)不僅僅是代碼本身,而是對(duì)代碼進(jìn)行整理和總結(jié)后的結(jié)論,那么我們可以直接讓模型為我們生成這個(gè)結(jié)論。

這里有兩個(gè)典型的例子來說明這一點(diǎn)。左邊第一個(gè)例子是要找代碼,關(guān)于在應(yīng)用程序中查找創(chuàng)建應(yīng)用表單的實(shí)現(xiàn)位置。如果我自己去找,可能會(huì)嘗試使用與“創(chuàng)建應(yīng)用”相關(guān)的詞匯,如“create”等,進(jìn)行搜索,但很可能無法找到。因?yàn)檫@個(gè)代碼庫的命名方式較為特殊,它將創(chuàng)建應(yīng)用的功能命名為“fork”。我自己很難想到這個(gè)詞,但模型卻能夠幫我找到正確的位置。它指出在“fork”目錄下有“Info”和“UI”兩個(gè)文件,這兩個(gè)文件共同實(shí)現(xiàn)了創(chuàng)建應(yīng)用的功能。整個(gè)過程模型只用了大約二十秒,而我自己可能需要花費(fèi)五分鐘甚至更長(zhǎng)時(shí)間來嘗試不同的關(guān)鍵詞進(jìn)行搜索。

第二個(gè)例子是關(guān)于總結(jié)系統(tǒng)暴露的路由數(shù)量。我并不是在尋找具體的代碼,而是希望模型能夠幫我總結(jié)在某個(gè)目錄下系統(tǒng)暴露了多少個(gè)路由,并給出它們的詳細(xì)信息。模型同樣出色地完成了這項(xiàng)任務(wù)。它列出了所有的路由,包括它們的請(qǐng)求方法(如 POST、GET 等)、目標(biāo)地址以及所在的文件位置。而我如果要自己去做這件事情,可能需要逐個(gè)打開 Controller 文件,查找其中的注解來識(shí)別路由,然后再將這些信息記錄下來。這同樣是一個(gè)非常耗時(shí)的過程,但模型只用了十幾秒就完成了。

因此,在代碼檢索這件事情上,模型的表現(xiàn)確實(shí)非常出色和可靠。

4. 讓相關(guān)代碼先走一步

圖片

接下來關(guān)注的是,我們?cè)趯?shí)際應(yīng)用中如何提升模型的表現(xiàn),以優(yōu)化輸出結(jié)果。這主要依賴于對(duì)大模型 prompt 的編寫,因?yàn)樘崾驹~的質(zhì)量直接影響模型的表現(xiàn)。然而在代碼檢索或相關(guān)應(yīng)用中,用戶往往無法直接輸入提示詞,而是依賴于產(chǎn)品內(nèi)置的邏輯。這些內(nèi)置邏輯主要基于以下幾個(gè)核心原則。

圖片

第一,關(guān)于編寫 import 語句,建議盡早進(jìn)行。我了解到許多開發(fā)者并不習(xí)慣首先編寫 import 語句,因?yàn)?IDE(集成開發(fā)環(huán)境)通常會(huì)在使用時(shí)自動(dòng)補(bǔ)全。然而,如果你能夠預(yù)見到將會(huì)使用到某些模塊或庫,并提前將它們寫入 import 語句中,大模型就能提前知道。因?yàn)槟愕拈_發(fā)工具會(huì)根據(jù) import 語句自動(dòng)查找并補(bǔ)全所需的依賴,從而增強(qiáng)模型的準(zhǔn)確性。

第二,如果你正在處理與當(dāng)前任務(wù)相關(guān)的文件,建議將它們打開并放置在旁邊。例如,當(dāng)你在編寫一個(gè) Controller 時(shí),它可能會(huì)依賴于 Service 層,而 Service 層又可能依賴于 DAO(數(shù)據(jù)訪問對(duì)象)。將這些相關(guān)的文件都打開并放置在視野內(nèi),開發(fā)工具都會(huì)讀取這些當(dāng)前打開的文件,并從中提取有用的信息提供給模型。

圖片

比如需要補(bǔ)充一個(gè)名為“APPID”的信息,如果僅依賴模型進(jìn)行單獨(dú)補(bǔ)充,它可能會(huì)生成一個(gè)毫無意義的字符串,如“134567”,這樣的結(jié)果顯然不符合你的期望。然而,如果你已經(jīng)打開了一個(gè)包含環(huán)境變量的文件,并且該文件中有關(guān)于“APPID”的環(huán)境變量設(shè)置,那么模型或開發(fā)工具就能自動(dòng)讀取這個(gè)環(huán)境變量,并將其準(zhǔn)確地補(bǔ)充到所需位置。這種能夠智能識(shí)別并利用當(dāng)前環(huán)境中已有信息的細(xì)節(jié)處理非常出色。

圖片

關(guān)于 import 語句,在導(dǎo)入了某個(gè)模塊或庫后,模型或開發(fā)工具就能自動(dòng)在這個(gè)文件或庫中尋找你所需的方法。例如,如果你要調(diào)用一個(gè)名為 getPrice 的方法,并且該方法接受一個(gè)參數(shù),那么如果你已經(jīng) import 了這個(gè)方法,模型就能準(zhǔn)確地為你補(bǔ)全這段代碼,包括方法名和參數(shù)傳遞。然而,如果你沒有導(dǎo)入相應(yīng)的模塊,模型在嘗試補(bǔ)全代碼時(shí)可能會(huì)遇到困難,因?yàn)樗鼰o法確定你應(yīng)該調(diào)用的方法的確切名稱。在這種情況下,模型可能會(huì)給出一些與你的意圖不符的建議,比如 getTotal、getAmount 或其他任何可能的方法名。因此,import 語句的使用,對(duì)于確保模型能夠準(zhǔn)確補(bǔ)全代碼,效果非常好。

圖片

再來看之前提到的代碼補(bǔ)全問題,如果將其置于對(duì)話模式下進(jìn)行考慮。這里舉一個(gè)最簡(jiǎn)單的對(duì)話例子來說明,有一個(gè)普通的需求,即編寫一個(gè)組件,該組件的功能是向后端接口發(fā)送請(qǐng)求,并接收返回列表數(shù)據(jù),同時(shí)在表格中展示這些數(shù)據(jù)。這是我們?cè)谌粘9ぷ髦薪?jīng)常會(huì)遇到的任務(wù)。

如果我直接對(duì)模型表述這個(gè)需求,模型可能會(huì)根據(jù)當(dāng)前社區(qū)中最流行的技術(shù)方案來為我生成代碼。例如,如果模型認(rèn)為 React 框架很流行,且通常使用 Axios 來發(fā)送請(qǐng)求,那么它可能會(huì)按照這種方式來編寫代碼。然而,這樣的代碼在我們的具體業(yè)務(wù)中是否真正有價(jià)值呢?這并不一定。因?yàn)槲覀兊臉I(yè)務(wù)可能會(huì)采用不同的社區(qū)框架,如果生成的代碼沒有基于我們實(shí)際使用的框架,那么這些代碼對(duì)我們來說就可能是無用的。

圖片

那我應(yīng)該怎么做呢?在這個(gè)對(duì)話之前,我引用了一個(gè)在前端的項(xiàng)目文件 package.json,這個(gè)文件記錄了項(xiàng)目中安裝的所有第三方依賴的聲明。我僅僅做了這一件事情,其他的內(nèi)容都沒有改變。模型似乎注意項(xiàng)目中使用了 antd 和 react-query 這兩個(gè)庫,因此它決定使用這兩個(gè)庫來為我編寫代碼。在發(fā)送請(qǐng)求時(shí),它選擇了使用 react-query 的 useQuery,接下來是 antd 的表格,并聲明了表格的列(columns)屬性。

這樣生成的代碼與我的實(shí)際需求匹配度高,而且在我的實(shí)際業(yè)務(wù)場(chǎng)景中可以直接使用,幾乎不需要進(jìn)行任何修改。因此我們?cè)诰帉憣?duì)話時(shí),通過引用幾個(gè)非常核心的文件作為參考,可以立即將代碼的質(zhì)量從 0 分提升到七八十分的效果。這是我們?cè)趯?duì)話實(shí)踐中得出的一個(gè)經(jīng)驗(yàn)。

而且,這個(gè)方法不僅適用于前端 JavaScript 項(xiàng)目中的 package.json,還適用于其他編程語言和框架。比如 Java 項(xiàng)目中的 pom.xml 和 gradle 文件,PHP 項(xiàng)目中的 composer.json 文件,以及 Python 項(xiàng)目中的 requirements.txt 文件。我認(rèn)為在任何需要生成有用代碼的對(duì)話中,都可以無腦地將這些文件提供給模型作為參考,這樣生成的代碼就是有用的。

5. 你就慣著她吧

圖片

最后,我們來探討一些更理論層面的內(nèi)容。模型就擺在那里,它的能力如何,是否優(yōu)秀,這都是既定的。那么作為使用者,應(yīng)該如何去適應(yīng)模型呢?適應(yīng)的程度應(yīng)該達(dá)到這樣的程度,即了解模型執(zhí)行的時(shí)間。比如,當(dāng)我輸入一個(gè)“if”時(shí),我知道模型后續(xù)不會(huì)只生成一行代碼,而是會(huì)展開成四五行代碼。因此,我會(huì)耐心地等待 2 秒,因?yàn)槲矣X得生成這些代碼可能需要這個(gè)時(shí)間。同樣地,如果我知道在某個(gè)情境下,模型只會(huì)生成一行代碼,并且這個(gè)過程可能非常迅速,比如 500 毫秒,那么我就會(huì)相應(yīng)地調(diào)整我的等待時(shí)間。如果模型在預(yù)定的時(shí)間內(nèi)沒有給出反饋,那么我就會(huì)停止等待。這是一種適應(yīng)。

另外,我還需要學(xué)會(huì)在何時(shí)給模型提供更好的推理上下文。之前也討論過,模型在某些情況下會(huì)表現(xiàn)得更加準(zhǔn)確,而在其他情況下則可能不盡如人意。比如,當(dāng)我在處理與業(yè)務(wù)高度相關(guān)的邏輯時(shí),如果模型不了解具體的業(yè)務(wù)需求,那么它的預(yù)測(cè)結(jié)果很可能就不準(zhǔn)確。在這種情況下,我就會(huì)選擇自己編寫代碼,而不是等待模型的反饋。相反,如果編寫的是一段通用的算法模型,并且模型能夠通過函數(shù)名來推斷出我的需求,那么即使模型需要 3 秒、5 秒,我也會(huì)耐心地等待,因?yàn)槟P蜕傻拇a通常會(huì)比我自己編寫的更加高效和準(zhǔn)確。

此外,還需要認(rèn)識(shí)到模型并不是完美的,因此我們需要充分發(fā)揮模型的優(yōu)勢(shì),同時(shí)避免它的缺點(diǎn)。有些任務(wù),比如找代碼、解釋代碼、讀代碼以及局部的重構(gòu)和改寫等,模型通常能夠比我更加高效地完成。而有些任務(wù),模型則可能無法勝任,這時(shí)就需要親自上陣。通過與模型的長(zhǎng)期磨合,我們逐漸積累了這種經(jīng)驗(yàn)。

總結(jié)起來,人和模型都有自己的擅長(zhǎng)領(lǐng)域,而人擅長(zhǎng)技術(shù)選型、任務(wù)規(guī)劃以及創(chuàng)造型的工作。

6. Focus, Let AI Run The Errands

圖片

那 AI 擅長(zhǎng)什么呢?AI 模型擅長(zhǎng)記憶和對(duì)細(xì)節(jié)的處理。它們能夠快速地記住大量的信息,幾個(gè) T 的 Token 都是模型的記憶。此外,AI 還擅長(zhǎng)處理一些瑣碎且細(xì)節(jié)豐富的工作,比如局部的代碼優(yōu)化、探索型的數(shù)據(jù)搜索、互聯(lián)網(wǎng)信息的搜集以及歸納總結(jié)等。

所以人類并不應(yīng)該與 AI 在這些方面競(jìng)爭(zhēng)。相反,我們應(yīng)該充分發(fā)揮自己的優(yōu)勢(shì),比如做規(guī)劃、進(jìn)行創(chuàng)造性思考等,將重復(fù)勞動(dòng)、瑣碎的事情交給 AI,這個(gè)稱之為 Focus,專注。“Let AI run the errands”,即讓 AI 處理那些雜七雜八的事情。這是我認(rèn)為當(dāng)真正改變了工作流以后,與AI協(xié)作的最好的關(guān)系。

7. 內(nèi)容總結(jié)

圖片

上圖中對(duì)我們的工具、企業(yè)和個(gè)人在 AI 發(fā)展上做的事情進(jìn)行了總結(jié),在此不做贅述。

圖片

從未來的視角來看,我認(rèn)為將無人駕駛作為一個(gè)比較對(duì)象是十分恰當(dāng)?shù)?。目前,無人駕駛技術(shù)處于 L2 與 L3 之間的發(fā)展階段,而我們的智能研發(fā)則尚處于 L0 與 L1 之間,未來一定會(huì)繼續(xù)發(fā)展,越往后“Transfer of responsibility”即它的職責(zé)將愈發(fā)向 AI 領(lǐng)域偏移。AI 將承擔(dān)越來越多的工作,而人類所需完成的事務(wù)則會(huì)相應(yīng)減少。我認(rèn)為這是一個(gè)極為美好的前景,人類將得以投身于更多富有創(chuàng)新性的工作之中。因此,我們可以滿懷期待地憧憬未來,隨著我們不斷向右前行,最終人類將能夠?qū)W⒂诟邇r(jià)值的事業(yè)。

四、問答環(huán)節(jié)

Q1:分享中提到的了解全庫,將代碼邏輯繪制成圖形是純粹依賴于代碼生成,還是結(jié)合了業(yè)務(wù)上的需求文檔等?按案例中解讀的效果還是比較好的,如果單從代碼的邏輯流出發(fā),很可能得不出那樣比較細(xì)致的關(guān)系。

A1:我們現(xiàn)在的實(shí)現(xiàn)不需要依賴需求文檔,因?yàn)榇蟛糠之a(chǎn)品的需求文檔質(zhì)量的不太高,還有可能是過時(shí)的。所以,首先我們是通過代碼之間的固定調(diào)用關(guān)系,通過語法解析生成代碼的知識(shí)圖譜,其次在代碼層面之上用大模型做代碼的解釋和增加注釋等工作。這些工作將建立自然語言與代碼之間的聯(lián)系,將兩者融合后,運(yùn)用一系列綜合算法進(jìn)行處理。例如,當(dāng)找到一個(gè)代碼塊時(shí),會(huì)提取該代碼塊的解釋,并同時(shí)獲取其調(diào)用關(guān)系的圖譜以及圖譜的解釋。將這些信息整合后,再借助大型模型來生成該代碼塊整體流程的摘要。最終,將生成一個(gè)類似于之前所展示的圖,實(shí)際上這是一個(gè)通過 Mermaid 方法生成的圖,它將以一段 Mermaid 代碼的形式展現(xiàn)。

Q2:代碼關(guān)系抽取等工作是實(shí)時(shí)做的,還是已經(jīng)基于代碼庫離線處理好了?

A2:這些工作肯定是提前處理好的,代碼庫第一次打開時(shí)可能需要幾分鐘處理一遍,后續(xù)代碼修改則增量更新。

Q3:全項(xiàng)目進(jìn)行向量化是在云端做的嗎?如何保障代碼的安全?

A3:這一環(huán)節(jié)確實(shí)是在云端完成的,首先它是安全的。我們將其分為兩個(gè)部分:第一部分是本地代碼傳輸?shù)皆贫诉^程中的網(wǎng)絡(luò)安全性,這一安全主要通過 https 協(xié)議來保障。若需進(jìn)一步增強(qiáng)安全性,我們可以實(shí)施 https 協(xié)議的證書 Auth 校驗(yàn),以此防止通過私有證書進(jìn)行劫持的風(fēng)險(xiǎn)。這是傳輸部分的安全性。第二部分則是存儲(chǔ)環(huán)節(jié)的安全性。我們的方案是不直接存儲(chǔ)任何源代碼內(nèi)容,存下來的是 embedding 向量對(duì)應(yīng)的源代碼文件名和文件對(duì)應(yīng)的范圍,即代碼起始和結(jié)束的行號(hào)與列號(hào),具體的代碼內(nèi)容我們并不存儲(chǔ)。在實(shí)際使用時(shí),我們需要這段代碼時(shí),會(huì)向客戶端發(fā)送一個(gè)請(qǐng)求,讓客戶端根據(jù)提供的信息找到相應(yīng)的代碼段。并且我們會(huì)通過一個(gè)哈希值進(jìn)行校驗(yàn),以確認(rèn)代碼內(nèi)容是否已被修改。如果校驗(yàn)通過,再將這段代碼取回并供給模型使用。因此在存儲(chǔ)方面,我們通過不執(zhí)行任何落盤存儲(chǔ)操作來確保這些代碼本身不會(huì)因我們的安全風(fēng)險(xiǎn)而泄露到外部。

責(zé)任編輯:姜華 來源: DataFunTalk
相關(guān)推薦

2024-12-30 11:57:33

2024-04-09 07:28:05

2011-06-03 16:04:05

SEO分詞

2010-08-12 15:33:00

百度筆試

2011-07-04 12:18:20

百度翻譯

2024-01-09 07:48:07

推薦排序算法策略數(shù)據(jù)背景

2025-01-03 08:26:17

2012-11-25 15:42:47

互聯(lián)網(wǎng)百度搜索

2013-10-12 10:25:20

百度云 Cooliris

2024-06-03 08:30:00

2023-09-19 21:09:18

百度人工智能

2018-10-08 08:30:59

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)