颠覆软件开发:我们与AI动力编码、测试及ChatGPT的旅程

由Swagata Acharyya和Pawan Kumar提供

在本文中,我已经解释了OpenAI的ChatGPT如何改变了我们团队的Android和iOS应用程序开发过程,增强了代码审查功能,实现了代码转换,自动化数据类生成和测试编写,简化了例行任务,同时强调了需要人工监督和命令的精度。

当我们团队还在走向现代化的Android和iOS应用程序开发过程的旅程时,我们没有预料到像OpenAI的ChatGPT这样的语言模型会在其中发挥任何作用。然而,我们现在打破了软件开发的传统界限,并将人工智能整合到我们的日常编程例程中。猜猜怎么着?它已经改变了游戏规则。

首次相遇:代码审查

在任何开发团队中,代码审核都是日常工作的重要方面。我们相互审核代码并确保编写的代码在一天结束时提高应用程序的整体代码质量。然而,由于时间限制以及工程师们忙于自己的工作,所谓的专门代码审核经常被用来得出赞成或LGTM的结论,存在可能会被忽略和未探索的改进。

这是一个问题,我们尝试了许多方法来尽早捕捉问题。我们正在寻找一些能够与我们的开发人员合作的东西,告诉他们如何使代码更好。所以有一天我们想尝试一下AI。编写了一个简单的Python代码,它读取一个满目的源代码目录并发送到OpenAI的GPT 3.5 Turbo来进行审查。通过几次提示的实验,它准备好了。AI开始审查代码,并提供详细的可行性输入,这可以使代码更好。

ChatGPT中文站
AI-aided code review

GPT-3.5涡轮发动机不仅凸显了我们缺失的分号或不匹配的括号,还深入挖掘了我们代码的逻辑、架构和灵魂。就像一位经验丰富的开发者,它进行了精明的观察,捕捉问题并在我们的工作到达人工评审员之前提出改进建议。就像拥有一组额外的一丝不苟、不知疲倦的眼睛,简化我们的开发过程,使我们的代码变得更好。

回顾文件的一个结果如下所示。这是精美地完成,并且经过仔细的处理。在某些情况下,它甚至还提供了优化后的代码(您需要修改提示符才能获取)。

Review for NetworkClient.kt: 

1. In line 3-6, the JSON parser configuration is hardcoded in the class.
This can be extracted out into a separate configuration class, which can be
reused across the application.

2. In line 9-21, the HttpClient is defined as a getter function, which can be a potential performance bottleneck as it creates a new instance
of the client on every invocation.
This can be corrected by making it a lazy variable, which would create the HttpClient instance only when it is first accessed.

3. In line 30, the GlobalScope.launch is used to launch a coroutine, which is not recommended as it can cause memory leaks.
Instead, it should be replaced with a coroutine scope that is limited to the lifetime of the request.

4. In line 35, the result.body() is called twice, which can be avoided by storing the response body in a variable and using it in both places.

5. In line 40-44, the logic for handling 401 errors and refreshing the token is not clear.
It can be improved by extracting it into a separate function and providing a clearer error message.

6. In line 49-55, the catch block is catching a broad Exception and providing a generic error message.
This can be improved by catching specific exceptions and providing more meaningful error messages.

7. In line 56, the client.close() is called outside the coroutine, which can cause issues with the request lifecycle.
It should be moved inside the coroutine to ensure that it is only called when the request is completed.

打破语言障碍:代码生成

ChatGPT,我们的新团队成员,不仅限于代码审查。接下来,它承担了代码生成的任务。我们过去会为Android(使用Kotlin)和iOS(使用Swift)分别编写相同的逻辑代码。然后有一天,我们想到了一个问题:为什么不试着让ChatGPT来编写代码呢?我们已经用Kotlin或Swift编写了代码。这只是一种转换。试试又有什么损失呢?

在第一个实验中,我们使用 Kotlin 完全编写了一个功能,然后将代码粘贴到 ChatGPT 中(当然没有敏感信息),并要求它为相同的逻辑生成 Swift 代码。这是很出色的。写成的代码在几秒钟内就能完成,而这可能需要超过一周的开发工作。

ChatGPT 使我们免受这种重复性工作的困扰。它采用了我们的 Kotlin 代码,并通过快速(意在双关语!)的转换返回了优美编写、经过优化的 Swift 代码。经过简短的人工审查和微小的调整后,我们能够将生成的 AI 代码引入我们的代码库中。这简直是魔法般的。

分类行为:生成数据分类

API响应以其原始、无结构的形式,对于研究和建模数据类可能会带来很大的困扰。我们曾使用其他工具,但这些工具需要对JSON进行某种净化操作,然后才能被引入以创建数据类。这是非常烦人和耗时的事情,我们希望能够更快地完成这项工作。

我们在生成数据类方面又找到了ChatGPT这个盟友。只需简单地复制粘贴API响应,我们就立即获得了两个平台可立即使用的数据类。这种由人工智能驱动的类魔法极大地节省了我们的手工劳动力,使处理API响应变得轻而易举。

举个例子,

在ChatGPT中的提示:

create codable model and Kotlin Data class from below JSON using swift and Kotlin respectively

{"services":[{"label":"Money Transfer","icon":"https://raw.githubusercontent.com/someurl/P2P.png","order":45,"isNew":"false","serviceType":"Banking","cta":"P2P"},{"label":"Cardless Cash","icon":"https://raw.githubusercontent.com/someurl/CC.png","order":2,"isNew":"false","serviceType":"Banking","cta":"CC"}]}

输出:

import Foundation

// MARK: - Services
struct Services: Codable {
let services: [Service]
}

// MARK: - Service
struct Service: Codable {
let label: String
let icon: String
let order: Int
let isNew: String
let serviceType: String
let cta: String
}

同时,在Kotlin中

import com.google.gson.annotations.SerializedName

data class Services (
@SerializedName("services") val services : List<Service>
)

data class Service (
@SerializedName("label") val label : String,
@SerializedName("icon") val icon : String,
@SerializedName("order") val order : Int,
@SerializedName("isNew") val isNew : String,
@SerializedName("serviceType") val serviceType : String,
@SerializedName("cta") val cta : String
)

时间的考验:写作测试

单元测试和UI测试一直是我们开发过程中不可或缺的一部分,尽管有些费力。我们曾经花费数天时间为某个功能编写测试。在看到我们在ChatGPT的其他领域取得的成功后,就有一个问题浮现了:我们能否利用它的力量来编写测试呢?

输入ChatGPT,将撰写测试的几天时间缩短为几分钟。只需提供一个类或一个流程,瞬间就可以得到一组良好结构化的单元和UI测试。经过几次迭代和审核后,我们准备好了强大的测试来证明我们代码的可靠性。

轻松编写脚本:自动化脚本

而当涉及自动化我们的例行任务时,ChatGPT再次证明了其实力。从从GitLab生成开发者行动摘要到在多个仓库中创建发布分支,ChatGPT将繁琐的全天工作变成了一些快捷命令。我们新获得的生产率确实令人愉悦。

太美好了,难以置信?

然而,我们与ChatGPT的旅程并不是所有的彩虹和独角兽。这个AI有它的怪癖。有时,它产生让我们不知所措的输出。输入措辞的轻微变化可能会导致明显不同的输出。它不像人类一样“理解”我们的命令,有时会错过上下文或复杂性的要点。

但事实是,ChatGPT并不是用来取代我们开发人员的。它是为了帮助我们,让我们的生活更轻松,使我们的工作流程更加高效。尽管它的输出通常非常准确,但仍需要我们人类进行审核和验证。正是在这种共生伙伴关系中,我们找到了一种节奏,将AI的速度和效率与人类智慧的细致和上下文意识相结合。

ChatGPT中文站
Human and AI collaboration

虽然我们对我们已经取得的成就感到兴奋,但我们也明白向ChatGPT提供正确的数据至关重要。正如人们所说的“垃圾进,垃圾出”。因此,我们已经学会在提示中精确和详细,为AI提供最好的起点。而且,从IP的角度来看,在分享什么与ChatGPT以及我们自己保留产品的哪个部分之间需要有一个政策。这需要一些迭代和观察,但整个产品从AI中获益。

在一天结束的时候,我们是掌控者。我们仍然做出重要决策,解释AI的输出,并确保它们适用于我们特定的用例。这就像需要小心处理的超能力。是的,ChatGPT为我们节省了大量时间和精力,但它并没有降低我们角色的重要性;相反,它使我们能够专注于工作中真正的创造性和关键性方面。

收盘点

总之,我们与ChatGPT的冒险既让人兴奋,又让人开悟。我们了解到在正确的方法下,AI可以成为软件开发领域的强有力的同伴。它重塑了我们的流程,注入新的活力到我们的团队,并提高了我们的生产力。这只是个开始。我们对未来充满期待,迫不及待地想看到这个由AI驱动的革命能带我们走多远!

请在评论中告诉我,你如何在日常工作中使用AI。另外,如果你对我们编写的用于代码审阅的Python脚本感兴趣,请在评论中告诉我,我会与你分享GitHub的URL!

2023-10-20 17:01:53 AI中文站翻译自原文