作者 | Antirez? ? ? ? ?
首先我要明確,這篇文章并不旨在回顧大語言模型。顯而易見,2023 年對人工智能來說是不平凡的一年,再去強調這一點似乎沒有多大必要。這篇文章更多是作為一位程序員的個人體驗分享。
自從 ChatGPT 出現,再到使用本地運行的大語言模型,我就開始廣泛應用這項新技術。我的目標不僅僅是提高編碼效率,更重要的是,我不想在編程中那些無需過多精力投入的地方浪費時間。不愿意花費大量時間去查找某些專業且無趣的文檔,不想為了學習一些過于復雜且往往無需如此的 API 而勞心費力,也不想編寫那些幾小時后就會被我拋棄的臨時代碼。尤其是如今 Google 成了一個充斥著垃圾信息的海洋,我們只能在其中努力尋找那少數有用信息。
同時,我也不是編程領域的新手。我完全有能力在沒有任何輔助的情況下編寫代碼,而且我也常常這么做。隨著時間的推移,我越來越頻繁地借助大語言模型來編寫高級代碼,特別是 Python 代碼,而在 C 語言方面則相對少一些。在體驗大語言模型的過程中,我深刻認識到,應該在何時使用它們,以及何時它們的使用反而會拖慢我的步伐。我還了解到,大語言模型有點類似于維基百科和 YouTube 上琳瑯滿目的視頻課程:它們對那些有意愿、有能力和自律的人大有裨益,但對于其他人來說,幫助有限。我擔心,至少在初始階段,它們更多的是惠及那些本就占據優勢的人。 但我們還是一步一個腳印來吧!
全知全能還是鸚鵡學舌? ? 在機器學習新浪潮中,最讓人擔憂的是 AI 專家們難以接受自己知識的局限性。人類發明了神經網絡,更關鍵的是,還發明了一個自動優化神經網絡參數的算法。隨著硬件能力的提升,能夠訓練更大的模型,利用數據的統計知識(即先驗知識),通過不斷的嘗試和錯誤,逐漸找到了一些比其他架構更有效的模型設計。但不管怎樣,神經網絡本質上還是相當復雜且不透明的。
面對大語言模型一些新的無法解釋的能力,謹慎的科學家們反而低估了它們。許多人認為,大語言模型不過是稍微高級點的馬爾科夫鏈 (Markov chains),最多只能重復訓練集里有限變化的內容。然而,越來越多的證據表明,這種看法幾乎可能是大錯特錯的。 同時,很多吃瓜群眾過分夸大了大語言模型的能力,認為它們擁有現實中根本不存在的超自然力量。事實上,大語言模型最多只能在其訓練數據所代表的空間內進行插值,即使如此,它們的這一能力也已經相當驚人。真要是今天的大語言模型能夠在看過的所有代碼構成的空間內自如插值,它們即便不能創造真正的新穎事物,也足以取代 99% 的程序員。但現實情況要并沒有這么樂觀。大語言模型確實可以編寫一些它之前未曾見過的程序,展示出將不同思想的訓練數據融合的能力,但這種能力目前還有很大的限制,尤其是在需要細膩推理時,它們往往無法勝任。盡管如此,它們仍代表著從人工智能誕生至今的最偉大成就,這一點似乎無庸置疑。
無知卻博學 ? 確實,大語言模型大體上只能進行初級的推理,這些推理經常不準確,甚至會摻雜著一些關于不存在事實的幻覺。但它們卻擁有海量的知識。在編程領域,以及其他有高質量數據的領域,大語言模型就像是理解力有限卻知識淵博的人。如果要和這樣的伙伴進行結對編程(對我來說,結對編程本身就是個痛苦),可能會很糟糕:它們可能提出一些荒謬的想法,我們需要不斷斗爭才能貫徹我們自己的想法。但如果這個博學的傻瓜能夠聽從我們的指令,回答我們提出的所有問題,那一切都會變得不同。現有的大語言模型雖然不能引領我們超越已知的路徑,但如果我們想探索一個不熟悉的領域,它們往往能夠幫我們從一無所知到掌握足夠的知識來獨立前行。 在編程領域,直到二十或三十年前,這些能力可能還不太引人注目。
那時,你需要掌握幾種編程語言、經典算法以及那些基本的庫。其余的則依靠你自己的智慧、專業知識和設計能力。具備這些素質,你就能成為一名全能的專家級程序員。然而,隨著時間的推移,我們見證了框架、編程語言、各種庫的大量涌現。這種復雜性通常是不必要的,甚至無法自圓其說,但事實就是如此。在這樣的情況下,一個無所不知的“白癡”成了寶貴的盟友。 我來舉個例子:我對機器學習的實驗最初是用 Keras 進行的,持續了至少一年。后來因各種原因,我轉向了 PyTorch。我已經了解什么是嵌入(Embedding)或殘差網絡(Residual Networks, ResNets),但我并不想深入研究 PyTorch 的文檔(就像我學習 Keras 那樣,那時 ChatGPT 還不存在)。有了大語言模型,用 Torch 編寫 Python 代碼變得非常容易。我只需清楚地了解我想要構建的模型,并提出合適的問題。
應用案例 ? 我要討論的不是那些簡單的問題,比如“嘿,類 X 是如何執行 Y 操作的?”如果只是這些問題,那些對大語言模型保持懷疑態度的人可能就有理由了。但實際上,更復雜的模型能做的事情遠遠超出這些。幾年前,這些還被認為是不可思議的魔法。我可以這樣對 GPT4 下指令:看,這是我在 PyTorch 中實現的神經網絡模型。這里是我的數據批次。我想調整這些張量的大小,以便它們能與神經網絡輸入的要求相匹配,并且我希望以這種特別的方式展現它們。你能幫我寫出調整這些張量尺寸的代碼嗎?GPT4 幫我寫出了代碼,我接下來要做的,就是在 Python 命令行界面中測試這些張量是否真的符合我需要的大小,以及數據結構是否正確。 再舉一個例子。不久前,我需要為基于 ESP32 的設備開發一個藍牙低能耗 (BLE) 客戶端。經過研究后,我發現多平臺藍牙編程接口大都不好用。解決方法很簡單,就是用 Objective C 和 macOS 的原生 API 來編寫代碼。但這樣一來,我就面臨著兩個問題:一是學習 Objective C 中復雜的 BLE API,這些 API 充滿了我認為完全沒有必要的復雜設計(作為一個極簡主義者,這些設計與我所認為的“好設計”截然相反);二是回憶起怎樣使用 Objective C 編程。我上次使用 Objective C 編寫程序是十年前了,很多細節,比如事件循環、內存管理等,我都已經記不清了。 最后的結果就是這段代碼,雖然它看起來不是很美觀,但它完成了它的任務。我在極短的時間內就編寫完成了。否則根本不可能做到這一點。 https://github.com/antirez/freakwan/blob/main/osx-bte-cli/SerialBTE.m 這段代碼主要是通過在 ChatGPT 上復制粘貼我想實現但不太確定如何著手的功能來編寫的,因此最初它們并未能正確運行。
然后,大語言模型幫我指出了問題所在并告訴我如何解決。雖然大部分代碼不是由 LLM 直接編寫的,但它確實極大地加快了編程速度。不用 ChatGPT 我也能完成這個任務嗎?答案是肯定的,但更有趣的不僅是它節省了我很多時間:事實上,如果沒有 ChatGPT,我連嘗試的勇氣都沒有,因為那似乎并不值得。這一點至關重要。對于我的項目來說,編寫這樣一個不重要的程序的努力與其帶來的好處的比例本來是不劃算的。此外,這個過程產生了一個比程序本身更有用的副作用:為了這個項目,我對 linenoise(我用于行編輯的一個庫)進行了改造,使其可以在多路復用環境下運行。 這是另一個例子,更多地涉及到數據解釋而非代碼編寫。我打算用一個我在網上發現的卷積神經網絡 (Convolutional Neural Network) 設置一個 Python 腳本,但這個網絡缺乏詳細文檔。網絡的一大優勢是它采用了 ONNX (Open Neural Network Exchange) 格式,這使我能夠輕松地識別出網絡的輸入和輸出以及它們對應的名稱。我對這個卷積網絡了解的唯一一點是:它能識別圖像中的特定特征。但我不知道所需輸入圖像的格式和大小,更何況,網絡的輸出比我預想的要復雜得多(我原本以為它是一個二元分類器 (binary classifier),用于判斷觀察到的圖像是否正常或存在問題。
我原以為它只有兩個輸出,但實際上有數百個)。我首先把 ONNX 網絡的元數據輸出復制粘貼到 ChatGPT 中,并向助手闡述了我所知道的關于網絡的有限信息。ChatGPT 推測了輸入的組織方式,以及輸出可能是標準化后的框,用于指出圖像中潛在缺陷的部分,還有其他輸出表示這些缺陷的可能性。經過幾分鐘的交流,我得到了一個能進行網絡推斷的 Python 腳本,以及將起始圖像轉換為適合輸入的張量等必要代碼。讓我印象深刻的是,當 ChatGPT 觀察到測試圖像上的原始輸出值(基本上是邏輯單元 (logits))時,它終于“理解”了網絡的運作方式:一系列浮點數為識別輸出的確切細節和標準化提供了上下文,比如框是否居中或指定了左上角等細節。
一次性程序 ? 我曾經遇到過很多類似的情況,就像我之前敘述的那樣。但記錄這些并沒有太大意義,因為這些情況重復的故事基本相同。我的問題是,我需要迅速了解一些事情,特別是在大語言模型給出的回答可能是無稽之談時,我得能夠驗證這些信息的真實性。在這種情況下,我會利用大語言模型加快我的知識獲取速度。 但在其他情況下,我會讓大語言模型完全編寫代碼。舉個例子,當我需要編寫一個基本可以隨時丟棄的程序時。比如這個: 簡單語言模型示例程序 我需要可視化一個小型神經網絡學習過程中的損失曲線(loss curve)。
我向 GPT4 展示了 PyTorch 程序在學習過程中生成的 CSV 文件格式,然后我提出了一個需求:如果我在命令行中指定了多個 CSV 文件,我不想再看到同一實驗的訓練和驗證損失曲線,而是想比較不同實驗的驗證損失曲線。上面就是 GPT4 生成的結果,總共用了三十秒。 類似地,我需要一個程序來讀取 AirBnB 的 CSV 報告,并按月份和年份對我的公寓進行分組。接著,它會考慮清潔成本和每次預訂的夜晚數量,統計不同月份的平均租金價格。這個程序對我非常有用,但編寫它又極其無聊,因為過程中沒有什么新穎之處。因此,我把 CSV 文件的一部分復制粘貼到 GPT4 上,告訴大語言模型我要解決的問題。程序第一次嘗試就運行成功了,下面是完整的展示。
import pandas as pd pd.set_option('display.max_rows', None) df = pd.read_csv('listings.csv') reservations = df[df['Type'] == 'Reservation'] reservations['Start Date'] = pd.to_datetime(reservations['Start Date']) reservations['Year'] = reservations['Start Date'].dt.year reservations['Month'] = reservations['Start Date'].dt.month reservations['Nightly Rate'] = (reservations['Amount'] - reservations['Cleaning Fee']) / reservations['Nights'] all_listings = reservations['Listing'].unique() all_years = reservations['Year'].unique() all_months = range(1, 13) index = pd.MultiIndex.from_product([all_listings, all_years, all_months], names=['Listing', 'Year', 'Month']) all_data = pd.DataFrame(index=index).reset_index() merged_data = pd.merge(all_data, reservations, on=['Listing', 'Year', 'Month'], how='left') average_nightly_rates = merged_data.groupby(['Listing', 'Year', 'Month'])['Nightly Rate'].mean().fillna(0)要準確地理解如何對這些原本分散和無序的數據進行分組,需要一些簡單的邏輯推理。這不是大語言模型僅憑重復它所見過的語言模式就能簡單解決的問題。雖然 GPT4 在訓練中肯定觀察到了類似的程序,但幾乎可以肯定它沒有看到一個程序需要以我所要求的方式,在具有特定格式的 CSV 文件中對數據進行分組。這證明了(至少在我看來),大語言模型能夠在其訓練集中不同程序所勾勒的范圍內進行一定程度的創新和推理。 在我個人看來,編寫這類程序可能是對時間的不明智使用。一個大語言模型能替我完成這項工作,顯著提升了我編程的效率。這意味著,我能將精力集中在真正重要的事務上。
?
?
當事情不按計劃進行:系統編程的挑戰 ? 在大語言模型和編程領域,我取得了一定的成功。但是,當我使用 C 語言編寫程序時,我通常只把 LLM 作為一種更便捷的文檔工具。作為一名系統編程專家,我發現只有在 LLM 能進行復雜的推理分析時,它們才對我有實際用處。而在這方面,LLM 經常無法滿足期望。 讓我們看一個實驗例子: 試著概述一個高效、小型但完整的 C 語言實現的布隆過濾器(Bloom Filter)的要求,重點在于哈希(hashing)功能的關鍵要素。然后用優質的 C 語言編寫它。 另外,考慮到你的例子應該可以存儲 100,000 個元素,并且誤報概率不超過 5%。添加的元素是以空字符結尾的字符串。 以下是輸出結果:
?
?
#includeGPT4 所生成的布隆過濾器實現上并不算很出色。布隆過濾器應用廣泛,并不是什么稀奇古怪的數據結構。然而,要編寫一個合格的布隆過濾器,需要更高層次的抽象思維。比如,需要找到一種有效的方法,對同一個字符串進行多次哈希處理,同時確保這些哈希值相互之間的獨立性。 但是,如果你明確指示 GPT4 改進哈希函數,使之能產生多個互不相關的輸出,它提出的方案就顯得更加合理: ?#include #include #include #define N 100000 // Number of elements #define P 0.05 // False positive probability #define M (int)(-(N * log(P)) / (log(2) * log(2))) // Size of bit array #define K (int)(M / N * log(2)) // Number of hash functions unsigned char bitArray[M / 8 + 1]; void setBit(int n) { bitArray[n / 8] |= 1 << (n % 8); } int getBit(int n) { return bitArray[n / 8] & (1 << (n % 8)); } // Basic hash functions (for demonstration purposes) int hash1(char *str) { int hash = 5381; int c; while ((c = *str++)) hash = ((hash << 5) + hash) + c; return abs(hash % M); } int hash2(char *str) { unsigned long hash = 0; int c; while ((c = *str++)) hash = c + (hash << 6) + (hash << 16) - hash; return abs(hash % M); } void add(char *str) { setBit(hash1(str)); setBit(hash2(str)); // Add more hash functions if needed } int is_in(char *str) { return getBit(hash1(str)) && getBit(hash2(str)); // Check more hash functions if used } int main() { char *testStr = "testString"; add(testStr); if (is_in(testStr)) { printf("%s is probably in the set. ", testStr); } else { printf("%s is definitely not in the set. ", testStr); } return 0; }
unsigned int hash(const char* str, unsigned int hash_id) { unsigned int hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c + hash_id; } return hash % BF_SIZE; }? 如果 GPT4 能夠自行提出這種方案,它編寫的布隆過濾器將會有所不同,可能會使用單一的哈希函數一次性設置多個位。 GPT4 能夠獨立完成編寫合適且更通用哈希函數的任務。但在整個布隆過濾器的編寫過程中,它未能表現出足夠的推理能力。相反,它只是提供了兩種不同但相似的哈希函數,這種結果更像是從一篇關于布隆過濾器的低質量文章中看到的。 大語言模型在推理能力上的不足,加上可能缺乏高質量的相關資料,甚至還可能存在大量低質量的資料,共同造成了這種不盡人意的結果。
?
?
事實上,這并非個例。在算法或系統編程領域,我嘗試使用 LLM 的體驗通常都很差勁,哪怕在類似 Python 編程這樣的領域,LLM 表現出來的推理能力并不算高。 與此同時,GPT-4 不僅能反編譯它生成的函數(在另一個獨立會話中),還能精準地理解該函數的用途: https://chat.openai.com/share/f54b64d7-d19a-4be4-8f10-08553aa812f1 因此,認為 GPT-4 在系統編程領域無用的說法顯然是不恰當的。 有趣的是,這些情況下,小型與大型模型之間的差異顯著。來看看兩個本地模型的對比表現。 例如,Mistral 的專家模型 (MoE) Mixtral,對同樣的問題給出了以下回應: ?
?
?
unsigned int hash(const char* str, unsigned int hash_id) { unsigned int hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; } return hash + hash_id; }? 顯然,僅在最后加入 hash_id 是一個非常不佳的解決方案。Mixtral 對許多應用而言是一個優秀的模型,但對于大語言模型本就有限的推理能力來說,目前的規則顯然是:越大越好。 這是我與本地大型語言模型 deepseek-coder 的對話記錄。由于 RAM 有限,我只能將模型量化到 4 位來使用。盡管如此,作為一個擁有 340 億參數的龐大模型,它在這個問題上的推理能力似乎相當出色。以下是我用 llama.cpp 進行的聊天記錄:
?
?
我有一個哈希函數,它應該為相同的數據輸出 N 個不同的哈希。但是,我發現當我改變 hash_id 的值時,生成的哈希分布非常差:
?
?
unsigned int hash(const char* str, unsigned int hash_id) { unsigned int hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; } return hash + hash_id; }? 可能是我使用的加鹽策略不夠好?我該如何改進呢? [Deep-seek coder 的回復] 你的實現中可能存在的一個問題是,你只是簡單地在哈希的末尾添加了 hash_id。這可能會導致分布不均,尤其是當 hash_id 過大或分布不均時更為明顯。 考慮使用位運算來混合 hash_id。這里有一個使用異或 (XOR) 運算的例子: ?
unsigned int hash(const char* str, unsigned int hash_id) { unsigned int hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) ^ c + hash_id; // Using XOR to mix in the hash_id } return (hash ^ hash_id); // Mixing the hash_id one more time at the end }
?
?
這樣做可以比簡單添加更有效地分布 hash_id,從而使哈希分布更均勻。[省略……實際回復更詳盡] 在我的 MacBook M1 Max 上運行的這個模型表現得相當不錯。它成功地將求和和異或操作混合使用了。在這個案例中,模型得到了我提供的關于問題的線索的幫助,但最終是模型自己識別出了問題的真正所在,并提出了一個有效的解決方案。這樣的成就是任何書籍、文檔或 Google 搜索都無法達到的。不管你如何看待這個模型——無論是作為一個初級的、基于插值的結果,還是以其他方式——它確實展現了某種形式的推理能力。
在這個特定案例中,如果我們認為識別問題的根源和找到可能的解決方案是一種推理,那么它確實做到了這一點。但無論我們如何看待大語言模型,斷言它們對程序員無用是非常草率的。 然而,根據我過去幾個月的經驗,對于系統編程來說,如果你已是資深程序員,大語言模型往往無法提供令人滿意的解決方案。我來舉一個真實世界中的例子。我的最新項目,ggufflib,涉及到開發一個讀寫 GGUF 格式文件的庫,而這正是 llama.cpp 用來加載量化模型的格式。起初,為了弄懂量化編碼的工作原理(因為速度原因,每個量化比特都以特殊方式存儲),我試過使用 ChatGPT,但最后我選擇了對 llama.cpp 代碼進行逆向工程,這樣更加迅速。一個能夠有效協助系統程序員的大語言模型,在看到數據編碼的結構聲明和解碼函數后,應該能夠重建數據格式的文檔。雖然 llama.cpp 的功能足夠簡短,可以完全放入 GPT4 的上下文中,但它的輸出卻毫無用處。在這些情況下,我們還是得回歸傳統方式:紙筆在手,細讀代碼,尋找解碼器提取的比特在哪里注冊。 為了讓你更好地理解上述案例,如果你感興趣,可以嘗試一下。這里有一個來自 llama.cpp 實現的結構。 ?
?
?
// 6-bit quantization // weight is represented as x = a * q // 16 blocks of 16 elements each // Effectively 6.5625 bits per weight typedef struct { uint8_t ql[QK_K/2]; // quants, lower 4 bits uint8_t qh[QK_K/4]; // quants, upper 2 bits int8_t scales[QK_K/16]; // scales, quantized with 8 bits ggml_fp16_t d; // super-block scale } block_q6_K;? 然后是用于執行去量化的函數: ?
void dequantize_row_q6_K(const block_q6_K * restrict x, float * restrict y, int k) { assert(k % QK_K == 0); const int nb = k / QK_K; for (int i = 0; i < nb; i++) { const float d = GGML_FP16_TO_FP32(x[i].d); const uint8_t * restrict ql = x[i].ql; const uint8_t * restrict qh = x[i].qh; const int8_t * restrict sc = x[i].scales; for (int n = 0; n < QK_K; n += 128) { for (int l = 0; l < 32; ++l) { int is = l/16; const int8_t q1 = (int8_t)((ql[l + 0] & 0xF) | (((qh[l] >> 0) & 3) << 4)) - 32; const int8_t q2 = (int8_t)((ql[l + 32] & 0xF) | (((qh[l] >> 2) & 3) << 4)) - 32; const int8_t q3 = (int8_t)((ql[l + 0] >> 4) | (((qh[l] >> 4) & 3) << 4)) - 32; const int8_t q4 = (int8_t)((ql[l + 32] >> 4) | (((qh[l] >> 6) & 3) << 4)) - 32; y[l + 0] = d * sc[is + 0] * q1; y[l + 32] = d * sc[is + 2] * q2; y[l + 64] = d * sc[is + 4] * q3; y[l + 96] = d * sc[is + 6] * q4; } y += 128; ql += 64; qh += 32; sc += 8; } } }? 當我請求 GPT4 編寫關于使用格式的概述時,它難以清晰地說明“ql”中上下四位的數據塊是如何存儲的,這與權重位置有關。在撰寫這篇博客時,我還嘗試讓它編寫一個簡化版本的函數來展示數據的存儲方式(可能它難以用文字解釋,但可以通過代碼來表達)。然而,它生成的函數存在諸多問題,比如索引不正確,從 6 位到 8 位的符號擴展處理錯誤(僅僅是將其轉換為 uint8_t 類型),等等。 對了,這是我最終自己編寫的代碼: ?
} else if (tensor->type == GGUF_TYPE_Q6_K) { uint8_t *block = (uint8_t*)tensor->weights_data; uint64_t i = 0; // i-th weight to dequantize. while(i < tensor->num_weights) { float super_scale = from_half(*((uint16_t*)(block+128+64+16))); uint8_t *L = block; uint8_t *H = block+128; int8_t *scales = (int8_t*)block+128+64; for (int cluster = 0; cluster < 2; cluster++) { for (uint64_t j = 0; j < 128; j++) { f[i] = (super_scale * scales[j/16]) * ((int8_t) ((((L[j%64] >> (j/64*4)) & 0xF) | (((H[j%32] >> (j/32*2)) & 3) << 4)))-32); i++; if (i == tensor->num_weights) return f; } L += 64; H += 32; scales += 8; } block += 128+64+16+2; // Go to the next block. } }? 從上述函數中,我移除了這段代碼的核心貢獻:即長篇注釋,詳細記錄了 llama.cpp 中 Q6_K 編碼使用的確切格式。現在,如果 GPT 能夠幫我完成這一工作,那將非常有幫助。我相信這只是時間問題,因為這類任務在沒有技術突破的情況下也是可行的,只需適當的擴展即可。
?
?
重新審視編程工作 ? 不得不說,這是一個事實:現今的編程大多是在微調同樣的內容,只是形式略有變化。這種工作并不需要太高的推理能力。大語言模型在這方面表現出色,盡管它們的能力仍然受限于上下文長度。這個現象應該引起程序員的深思:真的值得去編寫這類程序嗎?雖然可以賺到不錯的收入,但如果大語言模型也能完成其中一部分工作,那么在未來五到十年,這可能并非最佳的職業發展方向。 再來看,大語言模型真的具備一定的推理能力,還是只是表面上的假象?有時候,它們似乎在進行推理,但這可能只是因為,像符號學家所說,使用的“符號”造成了一種實際上并不存在的意義錯覺。
足夠了解大語言模型的人會明白,事實并非如此:這些模型整合既有信息的能力,遠非簡單的詞匯重復。它們在預訓練期間的訓練主要是預測下一個 Token,這個過程迫使模型構建了一種抽象的模型。雖然這個模型可能脆弱、零散且不完美,但從我們觀察到的現象來看,它確實存在。在數學確定性存在疑問,且領域內頂尖專家意見分歧的情況下,相信自己的直覺似乎是明智之舉。
最后,今天還有什么理由不去使用大語言模型輔助編程呢? 正確地向大語言模型提問是一項關鍵技能。這項技能練習得越少,利用 AI 改善工作的能力就越弱。而且,無論是與大語言模型還是與人類交流,清晰描述問題同樣重要。溝通不暢是一個嚴重的障礙,很多程序員盡管在自己的專業領域很有能力,但在溝通上卻做得很糟糕。現在,連 Google 都變得不那么好用了,所以即便是將大語言模型作為一種壓縮文檔的方式來使用,也是個不錯的主意。至于我,我將繼續大量使用它們。我從來不喜歡去深究某個晦澀的通訊協議的細節,或者去理解由某些想要炫耀自己技術的人編寫的復雜庫方法。這些對我來說就像是"無用知識"。有了大語言模型,我就能免于這些困擾,每天都能感覺到它帶來的幫助。
審核編輯:黃飛
評論
查看更多