ChatGPT 正在殺死編程里的樂趣
多年以來,編程一直是我生命最重要的快樂來源之一,我從沒細(xì)想過這份快樂能伴隨我多久。但就在幾天前,在觀摩了 ChatGPT 替我編寫一個(gè) Python 程序的全過程后,我突然有種強(qiáng)烈的感覺:不遠(yuǎn)的將來,人們能從編程中獲得的樂趣可能會(huì)逐漸消失。
換句話說,ChatGPT 正在緩慢地“殺死”編程里的樂趣。在解釋這個(gè)觀點(diǎn)之前,讓我先帶你簡(jiǎn)單回顧一下:ChatGPT 到底幫我寫了個(gè)什么程序。
用 ChatGPT 編寫程序
先簡(jiǎn)單介紹一下 ChatGPT。ChatGPT 是人工智能公司 OpenAI 在 2022 年 11 月份推出的基于 GPT 自然語言生成模型的聊天機(jī)器人。它功能強(qiáng)大,能輕松完成許多在人類眼中非常復(fù)雜的任務(wù),比方說:根據(jù)你描述的需求寫一個(gè)可運(yùn)行的程序。
前天晚上十一點(diǎn)左右,我正坐在床上刷手機(jī),突然想起一個(gè)給路由器用的工具腳本,已經(jīng)拖延了幾個(gè)月都沒動(dòng)工。既然自己不愿寫,不如這次試試讓 ChatGPT 來幫我完成。
這個(gè)工具的需求簡(jiǎn)述如下:
接收一個(gè) URL 地址作為參數(shù),將該 URL 里的域名,以及該 URL 所返回的頁面里的所有域名,一并轉(zhuǎn)換成 dnsmasq 服務(wù)的配置條目,寫入到 /etc/dnsmasq.conf 文件中(需要考慮重復(fù)寫入)。
為了讓 ChatGPT 寫代碼,我需要用自然語言清楚描述程序的用途和大概的執(zhí)行流程,這個(gè)過程花了我 5 分鐘左右。
需求描述如下:
Write a Python program, it accepts an URL address url from command line input, the program extract the domain name from url and stores it in a variable called src_domain, then it starts to request the given URL address and parse the response as HTML, it should find out all valid domain names in the response and stores them in a set called secondary_domains. Now print the src_domain and secondary_domains to inform user.
Let's start to update dnsmasq's config file, combile src_domain and secondary_domains into a big set called domains. Iterate over domains...(之后的內(nèi)容省略)
將它發(fā)給 ChatGPT 后,我瞬間就收到了回復(fù):一長(zhǎng)串 Python 代碼。
圖:ChatGPT 聊天界面
其中一部分摘錄如下:
def main():
# ...
# Extract the source and secondary domains from the HTML response
src_domains = {src_domain}
secondary_domains = extract_domains(html)
domains = src_domains | secondary_domains
domains = sorted(list(domains))
# Create the configuration entries for each domain
domain_configs = create_domain_configs(domains)
# Write the configuration entries to the dnsmasq config file
dnsmasq_conf_path = '/etc/dnsmasq.conf'
write_config_to_file(domain_configs, dnsmasq_conf_path)
# ...
客觀來說,ChatGPT 給我的代碼結(jié)構(gòu)清晰、注釋準(zhǔn)確、函數(shù)和變量命名恰當(dāng),整體有模有樣。我將其保存在本地,準(zhǔn)備執(zhí)行。不過令人意外的是,第一次執(zhí)行失敗了。
一陣排查后,我發(fā)現(xiàn)代碼中至少存在 3 個(gè) Bug:
- bytes 和 str 類型兼容性問題
- 用 'a' 模式(追加)打開了文件,無法讀取內(nèi)容
- 在循環(huán)內(nèi)調(diào)用了 .read() 方法讀取文件,但文件游標(biāo)不會(huì)重置,因此只有第一次才讀到了完整內(nèi)容
這些 bug 在 Python 中很常見,因此改起來并不麻煩。將它們通通搞定后,程序終于可以正常運(yùn)行了。經(jīng)過簡(jiǎn)單的測(cè)試和驗(yàn)證,我發(fā)現(xiàn)它完美實(shí)現(xiàn)了我要的功能。
之后我算了一筆時(shí)間賬。從開始描述需求到調(diào)通整個(gè)程序,我一共花了 10 分鐘左右。也就是說,在不到半個(gè)番茄鐘的時(shí)間內(nèi),我成功借助 ChatGPT 把腦海中的想法變成了 88 行可運(yùn)行的 Python 代碼。
不夸張的說,當(dāng)晚我失眠了。半夜四點(diǎn),我從床上坐起來,腦海中一直重復(fù)著一些問題:“我以后應(yīng)該如何編程?向計(jì)算機(jī)描述需求,由計(jì)算機(jī)完成,還是自己打開 IDE 直接上手?在許多年以后,人們還需要編程嗎?我們現(xiàn)在到底是為何在編程?”
從這些問題開始一路發(fā)散,我突然想到:“樂趣”一直是驅(qū)動(dòng)我們編程的一個(gè)重要推動(dòng)力。具體來說,編程帶給我們的樂趣可被大致分為兩類,而目前的情況是:ChatGPT 正迅速吞噬其中很重要的那一類。
編程里的兩類樂趣
“創(chuàng)造使人快樂”——這個(gè)特點(diǎn)可能數(shù)萬年前就刻在了人類基因里。編程就是一種創(chuàng)造性工作。人們通過編寫代碼,一步一個(gè)腳印實(shí)現(xiàn)自己想要的東西,這個(gè)過程讓人心情愉悅。這種愉悅和“建造一所房子”、“制作一件工具”所產(chǎn)生的愉悅類似,都是在人類創(chuàng)造事物時(shí)自然產(chǎn)生。
而藏在編程這件事里的樂趣,大致可分為兩類,它們分別來自于編程中的兩大環(huán)節(jié),一個(gè)是“規(guī)劃與設(shè)計(jì)”,另一個(gè)是“解決小謎題”。
1. “規(guī)劃與設(shè)計(jì)”
在開發(fā)軟件項(xiàng)目時(shí),當(dāng)我們從用戶那接到一個(gè)需求后,第一件要做的事情就是“規(guī)劃與設(shè)計(jì)”。在這個(gè)環(huán)節(jié),我們需要先理解用戶需求,隨后在頭腦中完成一些“大”的決策,比如:
- 如何利用項(xiàng)目中的業(yè)務(wù)模型與術(shù)語,翻譯這個(gè)用戶需求。
- 分析該需求將給項(xiàng)目中的每一層帶來哪些改動(dòng)。
- 在實(shí)現(xiàn)時(shí),哪些部分需要考慮擴(kuò)展性,哪些部分不需要。
- 如何處理與之相關(guān)的舊代碼,合并、改寫還是擴(kuò)展?
- ……
一言以蔽之,在“規(guī)劃與設(shè)計(jì)”環(huán)節(jié),我們考慮的核心問題是:“如何在滿足用戶需求的同時(shí),讓項(xiàng)目質(zhì)量在長(zhǎng)期維度上保持健康?!?nbsp;個(gè)中要訣,在于將軟件的整體復(fù)雜度維持在一個(gè)合理范圍內(nèi),不要過度增長(zhǎng)。
2. “解決小謎題”
完成“規(guī)劃與設(shè)計(jì)”后,下個(gè)環(huán)節(jié)是“解決小謎題”。該環(huán)節(jié)的目標(biāo),是將“規(guī)劃與設(shè)計(jì)”里的每個(gè)“大決策”,分解為一個(gè)又一個(gè)的“小謎題”,隨后逐個(gè)擊破。
舉個(gè)例子,“給用戶注冊(cè)接口增加密碼強(qiáng)度校驗(yàn)”這個(gè)需求,可能會(huì)被拆解為以下這些小謎題:
- 如何從請(qǐng)求中讀取用戶輸入的密碼?
- 如何校驗(yàn)密碼必須包含至少 1 個(gè)特殊符號(hào)、1 個(gè)大寫字母?
- 如何獲取用戶之前的舊密碼,并判斷是否和新密碼相等?
- ……
一旦所有謎題被明確后,下一步就是編寫代碼解決它們。有許多技巧和工具能幫你能更流暢、更快速的解決每個(gè)謎題,比如說:實(shí)踐 TDD(測(cè)試驅(qū)動(dòng)開發(fā))、查文檔或求助于搜索引擎,等等。但它們之中沒有一個(gè)能和 ChatGPT 相提并論。
ChatGPT 帶來的變化
自人類發(fā)明計(jì)算機(jī)的第一天起,程序員就在完全依靠自己的頭腦完成以上兩個(gè)環(huán)節(jié)的工作。
但有了 ChatGPT 后,你會(huì)發(fā)現(xiàn),一旦“規(guī)劃與設(shè)計(jì)”部分已經(jīng)被搞定,那么剩下的工作:解決一個(gè)又一個(gè)的小謎題,其實(shí)已不再需要人們親自編寫代碼了——只要將需求丟給 ChatGPT 就行。
因?yàn)榭v使某個(gè)需求復(fù)雜無比,一旦它被拆解為許多獨(dú)立的小謎題后,每個(gè)謎題所涉及的抽象概念與邏輯關(guān)系都會(huì)大幅減少。這就意味著,你根本不需要花費(fèi)多少工夫,就能將它清晰地描述給 ChatGPT,由它完成代碼的編寫。
第一眼看上去,你是不是覺得這對(duì)程序員有好處?因?yàn)檫@么做能極大提升我們的工作效率呀!但在認(rèn)真思考過這件事后,我發(fā)現(xiàn)它在提升效率的同時(shí),也可能會(huì)帶來另一個(gè)嚴(yán)重的問題:當(dāng)每個(gè)人不再需要親自動(dòng)手解決那些小謎題后,編程的樂趣會(huì)消失一大半。
為什么這么說?讓我用一個(gè)我很喜歡的電子游戲《Hades》來做個(gè)類比。
以《Hades》來類比編程
《Hades》是由 Supergiant Games 開發(fā)的一款以希臘神話為背景的動(dòng)作游戲。在游戲中,你操作冥界王子扎格列歐斯逃離冥界。
圖:Hades 游戲封面
《Hades》的核心游戲體驗(yàn)由兩部分構(gòu)成:“實(shí)時(shí)戰(zhàn)斗”與“能力構(gòu)建”。
“實(shí)時(shí)戰(zhàn)斗”部分很好解釋,游戲包含多種可供選擇的武器,比如:冥府之刃(單手劍)、永恒之矛、索心弓等。每次游玩前,玩家可以選擇其中一把。為了獲得最好的獎(jiǎng)勵(lì),你需要熟練使用各種武器、躲避每一次攻擊,用精湛的操作擊敗每一個(gè)敵人。
“能力構(gòu)建”則是《Hades》的另一個(gè)極具特色的游戲機(jī)制?!禜ades》是一款 Rogue-like 游戲,玩家每次游玩的所有關(guān)卡都是隨機(jī)生成,每開始一次新游戲,主角的能力值都會(huì)被重置。當(dāng)你操作角色,闖過一個(gè)小關(guān)卡后,地圖上會(huì)隨機(jī)出現(xiàn)兩道通往下一個(gè)關(guān)卡的門,每道門上標(biāo)注著你能拿到的獎(jiǎng)勵(lì)。你需要在這兩道門之間做出選擇。
圖:選擇下一道門
游戲中的獎(jiǎng)勵(lì)五花八門,它們包括:增加生命值上限、增加大量金幣以及最重要的一種角色能力增強(qiáng)——來自不同奧林匹斯神靈的“祝?!?。這些“祝福”,有的會(huì)增強(qiáng)角色攻擊力,有的會(huì)給普通攻擊增加反彈效果,有的會(huì)提升你的沖刺距離,還有的則會(huì)直接升級(jí)你的武器,給其增加新的酷炫動(dòng)作。
圖:選擇“祝?!?/span>
《Hades》這款游戲引人入勝的原因,在于它完美融合了“實(shí)時(shí)戰(zhàn)斗”與“能力構(gòu)建”兩部分內(nèi)容。游戲發(fā)售后,數(shù)以百萬計(jì)的玩家(包括我)沉浸其中。我們潛心研究武器和“祝福”的每種組合,在選擇下一個(gè)獎(jiǎng)勵(lì)時(shí)絞盡腦汁,沉迷于操作主角用極富技巧性的戰(zhàn)斗將每位敵人轟殺至渣。
現(xiàn)在,請(qǐng)想象在另一個(gè)平行世界中,《Hades》的開發(fā)組發(fā)布了《Hades》游戲,但在這個(gè)時(shí)間線的《Hades》里,玩家不再需要親手操作冥界王子解決每場(chǎng)戰(zhàn)斗,而是只需要在每次游玩前負(fù)責(zé)以下這些事:
- 挑選一把武器
- 選擇能力加成
- 選擇下一道門(獎(jiǎng)勵(lì))
- 選擇眾神的“祝?!?/li>
- 選擇每場(chǎng)戰(zhàn)斗的策略,比如:優(yōu)先投彈攻擊還是莽進(jìn)敵人堆
總而言之,在這個(gè)游戲中,玩家不再需要練習(xí)如何操作索心弓射出蓄力一擊,如何使用永恒之矛的沖刺攻擊高效擊殺敵人。玩家要做的所有事情,就是在每個(gè)關(guān)鍵節(jié)點(diǎn)做出分析和指示,然后觀察 AI 完成所有戰(zhàn)斗,坐享最終的獎(jiǎng)勵(lì)。
你覺得這樣的《Hades》游戲,還像之前一樣那么有趣嗎?
一款注重經(jīng)營(yíng)與策略,完全去除了動(dòng)作要素的《Hades》游戲,這就是我認(rèn)為 ChatGPT 可能會(huì)將“編程”最終變成的樣子。
關(guān)于 ChatGPT 的一些疑問
假如到目前為止,你還沒有真正使用過 ChatGPT,那么相信你一定會(huì)有一些疑問。
ChatGPT 寫的代碼真有那么好嗎?
平心而論,ChatGPT 寫的代碼并沒有那么完美,相比許多經(jīng)驗(yàn)豐富的程序員仍有不小的差距。就像我在之前所描述的,ChatGPT 寫的代碼可能并不能直接運(yùn)行,有著一些細(xì)小的 Bug。
但 ChatGPT 的另一個(gè)強(qiáng)大之處,在于你總是可以通過對(duì)話的方式,不斷要求它改進(jìn)代碼。比如我在編寫工具腳本時(shí),就這樣要求過它:
- 請(qǐng)將代碼按指責(zé)封裝為不同的函數(shù),主函數(shù)的名稱為 main
- 請(qǐng)不要使用任何第三庫(kù)完成 HTTP 請(qǐng)求
從結(jié)果看來,ChatGPT 似乎已經(jīng)可以完美理解我的請(qǐng)求,瞬間就給出了修正后的代碼,這一點(diǎn)足以給我留下深刻的印象。
不用 ChatGPT 不就完事了?
讀完前面的所有內(nèi)容,也許你有句話一直在心里憋著,不吐不快:“既然作者你覺得用 ChatGPT 寫代碼沒啥樂趣,那么你不用不就完了,廢話這么多干啥?”關(guān)于這點(diǎn),請(qǐng)你考慮以下這個(gè)場(chǎng)景。
你在編寫一個(gè)函數(shù),試圖將某個(gè)嵌套數(shù)據(jù)類型進(jìn)行扁平化展開,現(xiàn)在有兩種做法擺在你的面前:
- 完全靠自己手工完成函數(shù)和對(duì)應(yīng)的單測(cè)代碼,花費(fèi) 20 分鐘
- 梳理思緒,描述需求,發(fā)給 ChatGPT,將它寫的代碼(以及測(cè)試用例)略作調(diào)整,直接使用,花費(fèi) 5 分鐘
你會(huì)選哪一種?不知道你的選擇是啥,但我目前正處于一種懷疑第一種做法的必要性的狀態(tài)中。
寫在最后
親愛的讀者朋友,我承認(rèn),本文標(biāo)題里的“殺死編程里的樂趣”實(shí)在有些危言聳聽。ChatGPT 當(dāng)然無法抹殺編程中的所有樂趣。但是,在你看過我使用 ChatGPT 的經(jīng)歷后,我希望你能停下敲打鍵盤的手,思考一下:在這個(gè) AI 迅猛發(fā)展的大浪潮中,編程這項(xiàng)只有幾十年歷史的智力行為究竟會(huì)如何變化,而這些變化會(huì)將我們帶向何處?
最后,雖然 ChatGPT 給了我一份質(zhì)量可比肩(部分)人類的 Python 代碼,但我并不認(rèn)為它會(huì)在短時(shí)間內(nèi)消滅編程,讓程序員這個(gè)職業(yè)成為歷史。里面的核心原因在于:“規(guī)劃與設(shè)計(jì)”部分短期內(nèi)無法由機(jī)器代勞。
但不會(huì)消滅編程,并不等同于 ChatGPT 不會(huì)改變?nèi)藗兊木幊塘?xí)慣。我認(rèn)為它已經(jīng)開始在調(diào)整人們從編程中獲取樂趣的方式了——如果不是直接抹除的話。
也許,那份以經(jīng)營(yíng)與策略為核心,完全去除了動(dòng)作要素的《Hades》游戲已經(jīng)在路上了。祝我們未來玩得開心。
我的博客: https://www.piglei.com/