借助生成式AI進行更智能的API審查

借助生成式AI進行更智能的API審查的圖1

本文翻譯自:Smarter API Reviews With Gen AI

原文作者:Qt Group軟件工程師Daniel Smith

隨著生成式AI的興起,各企業(yè)正試圖探索如何在其環(huán)境中實施,以提升流程的效率。或許最佳切入點是尋找流程中的現(xiàn)有痛點,然后思考AI如何應對這些問題。(本篇博文由真人撰寫)

借助生成式AI進行更智能的API審查的圖2

Dall-E 3圖像生成提示語:一臺設計時尚的未來智能機器人坐在電腦前,分析屏幕上代碼的差異。機器人外觀友好、平易近人,屏幕展示了帶有高亮部分的復雜代碼。周圍環(huán)境暗示這是一個現(xiàn)代化的高科技辦公空間。

歷史背景

Qt Project的一個主要痛點歷來是在版本發(fā)布前按時完成API審查。API的增加和改動對Qt框架的使用方式有重大影響,并且對已有API的改動經(jīng)常會破壞用戶的系統(tǒng)兼容性,所以這些變更必須在加入最終發(fā)布版本之前仔細審查。為Qt添加新功能通常意味著引入新的API,我們希望未來這些新API能夠為用戶提供良好的設計和穩(wěn)定的使用體驗。然而有時現(xiàn)有的API免不了發(fā)生變更,我們也需要確保這些變更是經(jīng)過深思熟慮的,而且除了變更外,沒有其他替代方案能夠避免破壞兼容性。

這種做法雖然多年來行之有效,但在一些重要API更改初步合并后,卻因為在發(fā)布審查時需要撤回或在最終發(fā)布前進行重大修改,而導致發(fā)布日期多次延誤。為了縮短API變更實施與最終發(fā)布準備之間的時間差,我們希望在周期的早期階段進行API變更審查。但該如何實現(xiàn)呢?

最初的討論主要集中在簡單地為任何頭文件變動打上標簽以供人工審查,但這樣的解決方案太過繁縟。反而會導致工作量增加。但是,如果我們可以讓AI承擔一部分初步的代碼分析任務,至少可以用它來判斷某個改動是否“重大”,這樣會不會更好呢?

什么是GPT?

GPT,即“生成式預訓練模型”(Generative Pretrained Transformer),是一個能“理解”數(shù)據(jù)之間關系的復雜數(shù)學模型。在使用您可能熟悉的ChatGPT這類工具時,該模型通過語言數(shù)據(jù)進行了訓練,創(chuàng)建了一個模型來描述語言中的詞匯如何相互關聯(lián)。通過研究書籍、文檔、博文、錄音轉寫等中的數(shù)十億個詞匯,該模型能夠理解一個詞匯如何根據(jù)不同的上下文與另一個詞匯相關聯(lián)。通過這種方式,它也能理解新的輸入并逐詞生成輸出,形成類似我們聊天時的回應。當它為輸出生成一個新詞時,它會回顧上下文并生成句子中接下來最可能出現(xiàn)的詞。

如今,市面上有很多LLM(Large Language Model,大型語言模型),而OpenAI的GPT-4模型就是其中之一。到目前為止,GPT已經(jīng)經(jīng)歷了四次重大迭代,每一次都在功能、記憶力和理解力方面超越了之前的模型。

盡管GPT通常來說是用于理解人類語言,但它實際上只是一個模型,也可以被訓練用來理解如代碼等其他類型數(shù)據(jù)間的關系。這意味著我們可以與它討論某段代碼,并要求它進行分析,或是通過往復對話來幫助我們自己更好地理解代碼。

API審查的現(xiàn)狀

自去年12月中旬以來,我們一直在運行一個概念驗證機器人,監(jiān)控提交到codereview.qt-project.org的更改,并通過GPT-4進行diff(代碼差異)分析。由于生成式AI不會自行作出反應,它必須根據(jù)提示語來生成輸出。提示語可以包含指令、請求、上下文信息等。以下是我們用于API審查的提示語,以及提供的一段原始代碼更改差異:

(摘要)“任務:對公共頭文件中的更改進行分類,判定它們是否對API的行為和使用具有重大影響。其他說明:對公共頭文件中‘private:’部分的更改并非重大;對平臺插件的更改,有時通過文件路徑標識,也是不重要的;僅限空格的更改也非重大變更;……”

除了需要結合一些后端方法以便強行讓GPT提供相關響應之外,GPT-4的表現(xiàn)一般來說是可靠的。在大約一個月的運行時間中,超過230個更改被標記為“需要API審查”,每個更改都會接收到一個簡要分析,解釋了哪些變更對公共API的使用和操作有顯著影響。

新增API的示例

在本示例中,QRemoteObjectHost增加了新的功能。

diff --git a/.../qconnectionfactories.h b/.../qconnectionfactories.hindex b56a34f..7eabfd6 100644--- a/src/remoteobjects/qconnectionfactories.h+++ b/src/remoteobjects/qconnectionfactories.h@@ -18,7 +18,7 @@#include <QtNetwork/qabstractsocket.h>
#include <QtRemoteObjects/qtremoteobjectglobal.h>-+#include <QtRemoteObjects/qremoteobjectnode.h>
QT_BEGIN_NAMESPACE
@@ -116,6 +116,7 @@
Q_SIGNALS: void shouldReconnect(QtROClientIoDevice*);+ void setError(QRemoteObjectNode::ErrorCode);
protected: virtual void doDisconnectFromServer() = 0;
diff --git a/.../qremoteobjectnode.h b/.../qremoteobjectnode.hindex 18f75bc..13e2540 100644--- a/src/remoteobjects/qremoteobjectnode.h+++ b/src/remoteobjects/qremoteobjectnode.h@@ -6,6 +6,7 @@
#include <QtCore/qsharedpointer.h>#include <QtCore/qmetaobject.h>+#include <QtNetwork/qlocalserver.h>#include <QtRemoteObjects/qtremoteobjectglobal.h>#include <QtRemoteObjects/qremoteobjectregistry.h>#include <QtRemoteObjects/qremoteobjectdynamicreplica.h>
@@ -61,7 +62,8 @@ MissingObjectName, HostUrlInvalid, ProtocolMismatch,- ListenFailed+ ListenFailed,+ SocketAccessError }; Q_ENUM(ErrorCode)
@@ -181,6 +183,7 @@ ~QRemoteObjectHost() override; QUrl hostUrl() const override; bool setHostUrl(const QUrl &hostAddress, AllowedSchemas allowedSchemas=BuiltInSchemasOnly) override;+ static void setLocalServerOptions(QLocalServer::SocketOptions options);
Q_SIGNALS: void hostUrlChanged();

在輸入提示語后,GPT-4提供了以下對新增API的分析,并進行了很好的總結:

1. 在qconnectionfactories.h中添加了新的#include 指令,這可能會暴露以前在該頭文件中不可用的額外符號或類型。這一變更可能會影響那些包含此頭文件的用戶。

2. 在qconnectionfactories.h文件中添加setError(QRemoteObjectNode::ErrorCode)信號是一個重大變更。這代表了一個通過錯誤代碼發(fā)出錯誤信號的新API,這將影響API用戶處理錯誤狀態(tài)的方式。

3. 在qremoteobjectnode.h中的ErrorCode枚舉中新增了一個SocketAccessError枚舉值,這是一個重大變更。這增加了一個API用戶需要處理的新潛在錯誤狀態(tài)。

4. 在qremoteobjectnode.h中向QRemoteObjectHost類添加靜態(tài)void setLocalServerOptions(QLocalServer::SocketOptions options)函數(shù)是一個重大變更。它引入了一個新的API,用于設置本地服務器的選項,這將影響用戶配置QRemoteObjectHost實例的方式。

這些更改不僅會影響現(xiàn)有代碼的行為(如果它依賴以前的錯誤代碼或者沒有考慮到新的setError信號),還會影響開發(fā)者使用API的方式(通過提供新的方法和配置選項)。

在這種情況下,GPT能夠偵測到新的行為變化,并提醒開發(fā)者雖然這是一項新增功能,如果現(xiàn)有用戶的代碼還沒有準備好處理新信號,它有可能導致問題。這樣的警告可能有助于提醒審查者,在合并更改之前可能需要進行額外的審查,甚至需要在API文檔中添加注釋。

現(xiàn)有API更改示例

當在qvariantanimation.h中對現(xiàn)有API進行簡單更改時,機器人會看到這些內(nèi)容:

diff --git a/.../qvariantanimation.h b/.../qvariantanimation.hindex 640c057..4bdb971 100644--- a/src/corelib/animation/qvariantanimation.h+++ b/src/corelib/animation/qvariantanimation.h@@ -26,7 +26,7 @@BINDABLE bindableEasingCurve)
public:- typedef QPair<qreal, QVariant> KeyValue;+ using KeyValue = std::pair<qreal, QVariant>;typedef QList<KeyValue> KeyValues;
QVariantAnimation(QObject *parent = nullptr);

輸入提示語后,GPT-4提供了以下分析,可用于向審查者明確闡述所做更改的具體內(nèi)容:

在qvariantanimation.h中,KeyValue的定義從typedef更改為using聲明,這將基礎類型從QPair更改為std::pair,可能會影響API用戶與KeyValue實例的交互方式。

早期嘗試

生成式AI總是有些難以捉摸。正如之前所述,它會不斷地猜測下一個詞,一次又一次,直到認為應該停止為止。(你可以了解一下LLM的原理,確實令人困惑。)雖然GPT 3.5非常適合用來閑聊,但它經(jīng)常忘記你告訴它的內(nèi)容,也不太能很好地遵循指令。它還會受到“近因偏見”的影響,即在你的提示語中,靠后的詞被認為比前面的詞更重要。這帶來了一些問題,因為有些指令可能被忽略,或者更糟糕的是,生成輸出時可能完全未考慮某些變更的差異。這導致使用GPT 3.5進行分析時效果不夠理想。即便采取措施要求輸出更加一致、降低創(chuàng)造性,它仍然會不一致地忽略掉請求的整個部分,或者完全臆想出變更中新增或刪除了什么。

借助生成式AI進行更智能的API審查的圖3

Dall-E 3提示語:一個自信的機器人在辦公室里,自豪地在白板上展示錯誤信息。這個機器人顯得自信滿滿,面帶微笑地用記號筆劃線標出錯誤的答案。這一幕略帶幽默,突顯了機器人對其錯誤答案的錯誤自信。環(huán)境是現(xiàn)代辦公室,白板上滿是方程式和文本,其中一些部分被明顯地標記為錯誤,但機器人似乎毫無察覺。

2023年11月,微軟推出了GPT 3.5的增強版,命名為3.5-instruct,顧名思義,這一版本是為了提高其遵循指令的能力。盡管這樣做有所改進,但模型仍然對實際改變的差異產(chǎn)生了錯誤的幻覺。

為了解決這些問題中的一些,嘗試了best-of-three模型,需要三次嘗試中的兩次同意變更的重要性才能采納結果。這至少提高了整體的準確性,但輸出仍然缺乏細節(jié),并且明顯由于沒有完全理解在軟件開發(fā)層面所做的改變而受到影響。

當GPT-4的成本降低后,即使是粗略的測試也顯示出了顯著改善的結果。GPT-4對其所讀內(nèi)容有更好的記憶力,并能對其作出決策背后的推理進行更清晰的說明。由于準確性更高,機器人被重新調(diào)整為單次配置,自那以后只需對提示語做一些小調(diào)整。

下一步及未來發(fā)展

AI并不是萬能的解決方案。即便它有這個潛力,那也與現(xiàn)在仍相去甚遠。與人類不同,它不知道自己實際在做什么,它只是通過選擇最可能的下一個詞來響應上下文提示語。這意味著,如果它在任何中間點上選擇錯誤,剩余的回復可能會走向錯誤的方向,產(chǎn)生一個充滿自信但非常錯誤的答案。我們可以采取一些措施來緩解這個問題,但這需要時間和成本。盡管當前一代的生成式AI存在不足,但我們已經(jīng)為減輕API審查的工作量打下了堅實的基礎。

下一步,我們希望探索更大的上下文以評估變更的重要性,包括在單次評估中包含多個文件,以便完全理解整個變更,而不是像目前這樣逐個文件進行評估。此外,我們希望未來的GPT迭代或相關LLM技術能夠提高準確率和遵循指令的能力。盡管GPT-4在這個用例上遠超GPT-3.5,但它仍然會不時犯錯、忽略上下文。

結論

通過在代碼合并時批量審查過渡到單次變更的審查,我們可以節(jié)省發(fā)布前緊急時期審查所需時間。新方法也為討論提供了更多背景,如此變更的必要性的討論可以一次到位。在我們傳統(tǒng)的審查流程中,一個相當復雜的腳本執(zhí)行了一堆硬編碼邏輯來排除不相關的代碼行,創(chuàng)建了一次性提交,集合了所有的API變更以供審查。雖然先前的方法能快速提供變更的概覽,但缺失了必要的上下文。另外,追蹤變更的源頭和討論其重要性也是一個耗時的過程。考慮到編寫變更與進行API審查之間可能會有相當一段時間的間隔,回憶每個變更背后的原因可能頗具挑戰(zhàn)性。

這個概念驗證版的API審查機器人只是幫助Qt項目的所有參與者更方便地做出貢獻,并更快地使變更得到關注的輔助工具。雖然到頭來每次變更仍需人工審核,我們?nèi)韵M@一新機器人能讓這一流程變得更加輕松。

深圳市優(yōu)飛迪科技有限公司成立于2010年,是一家專注于產(chǎn)品開發(fā)平臺解決方案與物聯(lián)網(wǎng)技術開發(fā)的國家級高新技術企業(yè)、專精特新中小企業(yè)。

十多年來,優(yōu)飛迪科技在數(shù)字孿生、工業(yè)軟件尤其仿真技術、物聯(lián)網(wǎng)技術開發(fā)等領域積累了豐富的經(jīng)驗,并在這些領域擁有數(shù)十項獨立自主的知識產(chǎn)權。同時,優(yōu)飛迪科技也與國際和國內(nèi)的主要頭部工業(yè)軟件廠商建立了戰(zhàn)略合作關系,能夠為客戶提供完整的產(chǎn)品開發(fā)平臺解決方案。

優(yōu)飛迪科技技術團隊實力雄厚,主要成員均來自于國內(nèi)外頂尖學府、并在相關領域有豐富的工作經(jīng)驗,能為客戶提供“全心U+端到端服務”。

借助生成式AI進行更智能的API審查的圖4

登錄后免費查看全文
立即登錄
App下載
技術鄰APP
工程師必備
  • 項目客服
  • 培訓客服
  • 平臺客服

TOP