譯者 | 李睿
審校 | 重樓
對于開發(fā)人員來說,逐行仔細(xì)地檢查代碼并試圖掌握算法背后的復(fù)雜邏輯可能是一項(xiàng)繁重乏味的任務(wù),特別是在處理大型和復(fù)雜的代碼庫時(shí)。由于大型代碼庫使得識(shí)別所有潛在的測試場景變得困難重重,因此這種方法既耗時(shí)又令人不堪重負(fù)。幸運(yùn)的是,代碼圖形工具可以將這個(gè)過程實(shí)現(xiàn)自動(dòng)化,并通過圖形方式呈現(xiàn)代碼,從而簡化了任務(wù)并提高整體效率。
本文將探討代碼圖的概念,它們?nèi)绾卧鰪?qiáng)代碼分析、簡化調(diào)試和促進(jìn)影響分析,以及介紹一些能夠簡化這些任務(wù)的工具。還將討論當(dāng)前代碼分析解決方案面臨的挑戰(zhàn),以及使用知識(shí)圖相對于向量數(shù)據(jù)庫在代碼分析方面的優(yōu)勢。
什么是代碼圖?
代碼圖直觀地表示代碼庫中的結(jié)構(gòu)關(guān)系。它將函數(shù)、類和變量映射為節(jié)點(diǎn),并將它們之間的關(guān)系(例如函數(shù)調(diào)用、類繼承和變量依賴)映射為邊。這種結(jié)構(gòu)化表示通過使復(fù)雜的代碼庫更容易理解和導(dǎo)航來增強(qiáng)代碼分析。
代碼圖可以作為路線圖,清晰地展示代碼的不同部分如何組合在一起。為了幫助實(shí)現(xiàn)這一概念,一些工具能夠更輕松地實(shí)現(xiàn)可視化和導(dǎo)航代碼。例如,Visual Studio(2012-2017版)的可視化工具就使用代碼圖使用戶能夠更方便地探索代碼。
將代碼表示為圖形已在編譯器和集成開發(fā)環(huán)境(IDE)中廣泛用于各種任務(wù)。將代碼的圖形結(jié)構(gòu)呈現(xiàn)給任何Graph ML算法都會(huì)創(chuàng)建SOTA結(jié)果。函數(shù)、類和變量可以是代碼庫中的節(jié)點(diǎn)。邊可以表示函數(shù)調(diào)用、變量使用或類繼承。例如,表示函數(shù)的節(jié)點(diǎn)可能有指向表示它所使用變量和它所調(diào)用函數(shù)的節(jié)點(diǎn)的邊。如圖1所示:
圖1 鏈接到兩個(gè)函數(shù)的代碼圖節(jié)點(diǎn)
代碼圖表示允許對代碼的結(jié)構(gòu)和行為進(jìn)行詳細(xì)的分析,從而便于完成代碼導(dǎo)航、影響分析和調(diào)試等任務(wù)。通過將代碼表示為圖形,捕獲了關(guān)于代碼的不同部分如何交互的復(fù)雜細(xì)節(jié),從而使分析和理解復(fù)雜的代碼庫變得更加容易。這是如何實(shí)現(xiàn)的?
將代碼分為以下元素:
- 定義:定義事物(如函數(shù)、類、變量)的地方。
- 引用:這些事物被使用或調(diào)用的地方。
- 符號(hào):代碼中元素的名稱(例如函數(shù)名和類名)。
- 文檔注釋:解釋代碼的注釋,通常以特定格式編寫。
接下來,將看到如何為給定代碼生成圖形的示例。
代碼圖如何增強(qiáng)代碼分析
代碼圖為代碼分析提供了幾個(gè)好處:
依賴關(guān)系可視化
使用代碼圖,開發(fā)人員或測試人員可以可視化代碼不同部分之間的依賴關(guān)系。這樣就很容易看出函數(shù)、類和模塊是如何相互依賴的。
想象一個(gè)大型的代碼庫,其中有一個(gè)函數(shù)calculate_volume,還有一個(gè)calculate_area函數(shù),并依賴于輔助函數(shù)來獲取長度和寬度。代碼圖將清楚地說明這些依賴關(guān)系,允許開發(fā)人員快速識(shí)別潛在的問題或需要優(yōu)化的領(lǐng)域。
簡化調(diào)試
代碼圖通過顯示函數(shù)和類如何交互來簡化調(diào)試。假設(shè)開發(fā)人員正在調(diào)試calculate_volume函數(shù)的問題。通過查看代碼圖,他們可以很快發(fā)現(xiàn)問題可能是由calculate_area函數(shù)(稱為calculate_volume)中的問題引起的。然后,開發(fā)人員可以將調(diào)試工作集中在calculate_area及其依賴項(xiàng)get_length和get_width上。
影響分析
開發(fā)人員可以快速評(píng)估代碼一部分的更改對其他部分的影響。這是因?yàn)樗麄兛梢詸z查哪些函數(shù)或類依賴于他們要修改的代碼。因此,他們可以做出明智的決定。
改進(jìn)代碼質(zhì)量
識(shí)別和理解代碼關(guān)系有助于維護(hù)和改進(jìn)代碼質(zhì)量,但是如何實(shí)現(xiàn)呢?現(xiàn)在,開發(fā)人員可以找出代碼重復(fù)的地方,然后可以重構(gòu)代碼以改進(jìn)代碼庫。
代碼分析RAG解決方案面臨的挑戰(zhàn)
大型代碼庫
由于代碼量巨大,檢索增強(qiáng)生成(RAG)模型難以檢索相關(guān)的代碼片段。當(dāng)處理一個(gè)龐大的軟件系統(tǒng)時(shí),RAG模型會(huì)得到1000個(gè)代碼片段,為了選出最好的一個(gè),可能會(huì)閱讀數(shù)百個(gè)看起來相似的代碼片段。
代碼冗余
RAG模型可能產(chǎn)生冗余的代碼,導(dǎo)致代碼重復(fù),并可能降低效率。例如,在為某個(gè)任務(wù)生成不變代碼時(shí),RAG模型可能會(huì)提供多個(gè)看起來相似的解決方案,而比較它們并找出最佳方案似乎非常困難。
在代碼分析中使用知識(shí)圖優(yōu)于向量數(shù)據(jù)庫的優(yōu)勢
對于代碼分析,知識(shí)圖與向量數(shù)據(jù)庫相比具有幾個(gè)優(yōu)勢??梢酝ㄟ^一個(gè)例子來理解這一點(diǎn)。假設(shè)開發(fā)人員給出了這個(gè)提示。
- 提示:搜索有關(guān)updateInventory()的代碼。
以下查看知識(shí)圖譜和向量數(shù)據(jù)庫將提供什么結(jié)果。
知識(shí)圖譜(Knowledge Graph)
查詢返回一個(gè)詳細(xì)的圖表,突出顯示直接或間接調(diào)用updateInventory()的每個(gè)方法、類和服務(wù)。因此,在將結(jié)果提供給查詢之前,知識(shí)圖譜將檢查所有相關(guān)的函數(shù)、類和服務(wù)以及它們與updateInventory()的關(guān)系,如下所示:
訂單服務(wù)(OrderService):調(diào)用updateInventory()來更新庫存水平。
- 退貨服務(wù)(ReturnService):該函數(shù)用于在處理退貨時(shí)重新補(bǔ)貨。
- 審計(jì)服務(wù)(AuditService):它記錄庫存更改以用于審計(jì)。
- 外部API(ExternalAPI):該函數(shù)與外部API交互以同步庫存數(shù)據(jù)。
- 性能指標(biāo)(PerformanceMetrics):該圖表包括性能數(shù)據(jù),顯示updateInventory()在高峰時(shí)段存在瓶頸。
這將確保返回的結(jié)果準(zhǔn)確可靠,因?yàn)榭紤]了與updateInventory()相關(guān)的所有組件及其與它的關(guān)系。這有助于代碼圖表示準(zhǔn)確的代碼可視化。
向量數(shù)據(jù)庫
向量數(shù)據(jù)庫對于查找相似的代碼片段很有用,但不能有效地表示詳細(xì)的場景關(guān)系。搜索返回的函數(shù)在結(jié)構(gòu)和內(nèi)容上都類似于updateInventory。為什么? 向量數(shù)據(jù)庫可以基于相似性搜索或歐幾里德距離提供結(jié)果。
Plain Text
[FunctionX] --similar_to--> [updateInventory]
[FunctionY] --similar_to--> [updateInventory]
[FunctionZ] --similar_to--> [updateInventory]
采用代碼圖可視化代碼
示例1
其中一個(gè)示例演示了Python中的基本函數(shù)定義和調(diào)用。它顯示了簡單的算術(shù)運(yùn)算,例如乘法、加法和打印結(jié)果。
示例2
另一個(gè)示例演示了一個(gè)簡單的遞歸函數(shù),用于計(jì)算數(shù)字的階乘,以及如何在主函數(shù)中調(diào)用它。
網(wǎng)上有許多代碼圖工具,您可以簡單地粘貼整個(gè)代碼。另一種選擇是使用Lucidchart手工制作圖表。
理解代碼圖工作流
可以利用一個(gè)例子來理解它。假設(shè)一個(gè)Python項(xiàng)目有幾個(gè)文件,包括包含函數(shù)calculate_area()的math_utils.py和包含類Circle的shapes.py。索引步驟將提取函數(shù)和類定義及其關(guān)系,例如Circle使用calculate_area()。代碼圖的工作流程通常包括:
步驟1:索引
在這一步驟中,源代碼文件解析代碼庫,提取相關(guān)信息,例如函數(shù)、類、變量及其關(guān)系。
步驟2:構(gòu)建代碼圖
這一示例的代碼圖將包含calculate_area()和Circle的節(jié)點(diǎn),其中一條邊將Circle連接到calculate_area(),表明Circle使用calculate_area()函數(shù)。
步驟3:查詢代碼圖
用戶可以查詢代碼圖來查找Circle類使用的所有函數(shù)。該查詢將通過檢查與函數(shù)連接的節(jié)點(diǎn)和實(shí)體返回一個(gè)函數(shù)列表。這可以使用圖形查詢語言(如Cypher或Gremlin)來完成。
步驟4:可視化和探索
可視化可能會(huì)顯示Circle的節(jié)點(diǎn),其邊指向calculate_area(),表示依賴關(guān)系。這種可視化幫助開發(fā)人員快速識(shí)別代碼實(shí)體之間的關(guān)系。
步驟5:分析和洞察
通過分析代碼圖,可能會(huì)發(fā)現(xiàn)Circle類與calculate_area()函數(shù)緊密耦合,這可能會(huì)導(dǎo)致維護(hù)問題。還可以確定calculate_area()函數(shù)在代碼庫的另一部分重復(fù)。
與OpenAI交互轉(zhuǎn)換查詢
有時(shí),還可以使用OpenAI Codex模型與查詢轉(zhuǎn)換進(jìn)行交互,該模型可以針對多種代碼轉(zhuǎn)換任務(wù)進(jìn)行微調(diào),例如使用OpenAI代碼采樣重構(gòu)現(xiàn)有代碼,并使用SQL Codex Art轉(zhuǎn)換表。例如,給定CSV文件中的數(shù)據(jù)集,編寫SQL查詢從數(shù)據(jù)集提取一些信息。
- 自動(dòng)補(bǔ)全:OpenAI的模型可以使用機(jī)器學(xué)習(xí)補(bǔ)全不完整的代碼,減少開發(fā)人員的時(shí)間。
- 代碼轉(zhuǎn)換:模型可以將代碼從一種編程語言轉(zhuǎn)換為另一種編程語言,這使得在語言之間重新定位項(xiàng)目變得很簡單。
- CodeOpt:OpenAI公司開源了他們的代碼優(yōu)化模型,從而有助于提高代碼的性能??偟膩碚f,這節(jié)省了大量的計(jì)算資源,以換取更高的效率。
- 代碼解釋:它幫助模型將晦澀的代碼片段轉(zhuǎn)換為更簡單的單詞,這使得開發(fā)人員更容易理解和相互學(xué)習(xí)代碼。
詳盡的知識(shí)圖譜模式
知識(shí)圖模式是對數(shù)據(jù)所在位置的本質(zhì)的理解。它定義了所有細(xì)節(jié)、實(shí)體之間的關(guān)系、屬性或概念,以及知識(shí)圖譜中呈現(xiàn)的所有內(nèi)容。它提供了一種組織和連接數(shù)據(jù)的標(biāo)準(zhǔn)化方法,允許機(jī)器解釋這些信息的意義和關(guān)系。
以下利用一個(gè)關(guān)于電影的假設(shè)知識(shí)圖來理解這一點(diǎn):
實(shí)體
(1)電影:表示一個(gè)電影實(shí)體。
- 屬性:片名(字符串)、上映日期(日期)、導(dǎo)演(人物)、類型(字符串)、評(píng)分(浮動(dòng))、票房收入(浮動(dòng))、劇情簡介(文本)
(2)人物:代表從事電影行業(yè)的人。
- 屬性:姓名(字符串),出生日期(日期),出生地點(diǎn)(字符串),傳記(文本),圖片(URL)
(3)類型:代表一種電影類型。
- 屬性:名稱(字符串),描述(文本)
(4)工作室:代表電影制作工作室。
- 屬性:名稱(字符串)、總部(字符串)、成立(日期)、描述(文本)、圖片(URL)
(5)獎(jiǎng)項(xiàng):表示授予電影的獎(jiǎng)項(xiàng)。
- 屬性:名稱(字符串),類別(字符串),年份(日期),收件人(人物或電影)
構(gòu)建代碼圖
首先,克隆FalkorDB代碼圖存儲(chǔ)庫。
Plain Text
git clone https://github.com/FalkorDB/code-graph.git
運(yùn)行FalkorDB。
Plain Text
docker run -p 6379:6379 -it --rm falkordb/falkordb
將OpenAI API密鑰設(shè)置為環(huán)境變量。將需要它為知識(shí)圖譜生成密碼查詢,并回答與代碼圖相關(guān)的RAG問題。
Plain Text
export OPENAI_API_KEY=YOUR_OPENAI_API_KEY
啟動(dòng)FalkorDB代碼圖工具。
Plain Text
npm run dev
這將在http://localhost:3000/上啟動(dòng)一個(gè)服務(wù)器。可以輸入任何存儲(chǔ)庫的GitHub URL,它將生成代碼圖。
還可以在側(cè)邊欄中詢問有關(guān)代碼圖的問題,它將以自然語言回答。在瀏覽編程框架復(fù)雜而龐大的代碼庫時(shí),這個(gè)功能非常有用。
未來的改進(jìn)
代碼圖有很大的改進(jìn)空間,特別是在加強(qiáng)與各種開發(fā)工具和平臺(tái)的集成方面。一個(gè)關(guān)鍵方面在于確保實(shí)時(shí)更新,使代碼圖與代碼庫中的變化保持同步。另一個(gè)重要的開發(fā)領(lǐng)域是擴(kuò)大支持的編程語言范圍,使代碼圖更加通用,并適用于不同的開發(fā)環(huán)境。此外,利用機(jī)器學(xué)習(xí)進(jìn)行預(yù)測分析和代碼推薦,在進(jìn)一步提高代碼圖的實(shí)用性和有效性方面具有巨大的潛力。
這些改進(jìn)可以幫助開發(fā)人員更全面地了解他們的代碼庫,使他們能夠進(jìn)行更徹底的代碼分析,并最終提高整體代碼質(zhì)量。
原文標(biāo)題:Enhancing Code Analysis With Code Graphs,作者:Balaji Dhamodharan