程式設計師與其他行業有個很大不同 —— 這行很多極有價值的資料都是開源的。
這意味著你只要肯學,就能變強。
很多同學都知道學原始碼的重要性,但由於如下2個原因,很少有人能堅持啃下一些優秀的原始碼:
原始碼難懂
這裏的難懂,除了核心功能本身程式碼複雜外,還有個因素 —— 附加功能的程式碼會干擾我們學習核心功能的程式碼。
學起來沒意義
功利地講,一些與工作息息相關的庫的原始碼(比如React
、Vue
)學完後尚且可以在簡歷中體現。
但大部分庫的原始碼,學完就完了。
即使你照著原始碼寫一個一摸一樣的庫出來,也沒有實際意義,因為不會有其他人用。
對於“缺少意義的事”,動力自然沒那麼足了。
綜上兩個因素,難學 + 沒意義,能堅持下來的人自然就少了。
本文將向你介紹一種全新的原始碼學習方式,能夠巧妙突破以上兩個卡點,讓你輕鬆、有意義感的學原始碼。
兩個核心理念
這種原始碼學習方式包含兩個核心理念:
AI驅動:我們先讓AI完整理解原始碼,再讓AI作為老師教我們學原始碼,完美突破難學的卡點
語言轉換:有了AI的加持,我們可以學習不會的語言編寫的原始碼
舉個例子,你只會JS
,但可以選一個Rust寫的庫作為學習目標。
這樣做有兩個好處:
有大量優秀的庫是用你不熟悉的語言寫的,如果只侷限在會的語言寫的庫,會錯失很多開源寶藏
照著目標語言寫一個你會的語言實現的同功能庫是有實際意義的,因為可能還沒有人用你會的語言實現過這個庫
準備工作
我們需要藉助兩個工具的幫助:
Cursor
Code2Prompt
Cursor是什麼
Cursor
是一款AI驅動的IDE,由於他是在VSCode
基礎上魔改的,所以如果你之前用的是VSCode
,可以一鍵遷移配置。
截止24.9.18,Cursor
提供了15天試用,試用到期後換個新郵箱就能繼續試用。
如果你用的GMail
,甚至不用換郵箱,修改郵箱別名即可。
PS:可能有同學覺得白嫖不好,但Cursor團隊留下這麼明顯的“漏洞”,可能也是爲了推高DAU,進而推高估值
Cursor
本身只是工具,核心的AI輔助功能還得交給具體的大模型實現。
本文介紹的原始碼學習法需要用到Claude-3.5-sonnet-200k
模型,他不僅有優秀的程式碼理解能力,更重要的是,上下文最大支援200k。
極限工況下,他能一次性理解“包含大概1.6w行程式碼的專案”。
當然,越接近上下文上限,理解能力衰減越快。經過我的測試,程式碼量9k行以內的專案比較合適。
Code2Prompt是什麼
雖然Cursor
預設會為專案啟用RAG
,也就是說,你對專案中任何程式碼進行提問時,Cursor
都會將與程式碼相關的內容加入提示詞中。
這能讓AI的回答更有針對性,顯得更懂專案。
但這種方式的底層依賴分詞,如果分詞效果不佳,對AI最終回答的質量影響很大。
舉個例子,下面的程式碼是個完整的函式呼叫:
const embeddings = new OllamaEmbeddings({ model: "mxbai-embed-large", baseUrl: "http://localhost:11434", });
如果分詞成了兩個document
:
// document1 const embeddings = new OllamaEmbeddings({ model: "mxbai-embed-large",
與
// document2 baseUrl: "http://localhost:11434", });
那麼,當提問與OllamaEmbeddings
相關的內容時,document2
就不會作為相關上下文出現在提示詞中,AI就不知道baseUrl
的存在。
但顯然,baseUrl
是與OllamaEmbeddings
有關的。
所以,要讓AI理解專案,最好的方式是 —— 在token
限制內,儘可能將如下資訊都給到AI:
專案的背景(README.md)、工程資訊(package.json)
目錄結構
每個檔案對應的程式碼
可以使用Code2Prompt這個庫實現上述功能。
這是個Rust
寫的庫,可以透過cargo
安裝:
cargo install code2prompt
使用方式也很簡單:
code2prompt 專案路徑
執行命令後,上述提到的資訊就會被複制到剪貼簿。
舉個例子,我對code2prompt
專案倉庫執行上述命令後得到的提示詞中,目錄結構部分如下:
包含code2prompt
專案完整資訊的提示詞只有3k行,完全可以被Claude-200k
理解。
接下來,我作為不會Rust的人,展示下如何學習code2prompt
(Rust
寫的)原始碼,並最終輸出一個node
版本的code2prompt
。
實踐 —— 基礎部分
首先,我們執行如下命令獲得包含code2prompt專案完整資訊的提示詞:
code2prompt code2prompt專案所在路徑
這裏你可以選任何“程式碼量符合標準”的專案
接下來,在Cursor
中,按Shift + cmd + L
開啟AI側邊欄,選擇Long Context Chat
模式,這會使用200k的Claude3.5
模型。
將上述3k行的提示詞輸入後,Cursor
嘗試理解專案:
從Cursor
的回覆中我們可以大概知道專案的實現原理並區分核心功能與附加功能。
比如,可以明顯看出如下幾個功能是附加功能:
結果包含
git diff
資訊計算結果的token數量
支援不同輸出形式(剪貼簿、檔案)
支援新增行號
當剔除這些附加功能後,我們可以讓Cursor
用我們熟悉的語言建立專案並實現核心功能。
相比原始的code2prompt
專案,當前Cursor
生成的專案:
使用我熟悉的
Node
,而不是Rust
編寫剔除了附加功能,只保留核心功能,程式碼一目瞭然
到這一步,學原始碼已經很簡單了,但還能更直觀一點 —— 我們可以讓Cursor
根據flowchart DSL
規範,根據程式碼邏輯生成流程圖:
flowchart.js
是一款輕量的流程圖應用,可以將flowchart DSL
渲染為流程圖。
以code2prompt
舉例,Cursor
生成的DSL
資料如下(你不需要理解這個資料,大概感受下他的格式就行):
st=>start: Start e=>end: End op_parse_args=>operation: Parse command line arguments (program.parse()) cond_path=>condition: Valid path provided? op_traverse=>operation: Traverse directory (traverseDirectory()) op_git_diff=>operation: Get Git diff (getGitDiff()) cond_diff=>condition: --diff option? op_prepare_data=>operation: Prepare template data op_render=>operation: Render template (renderTemplate()) cond_output=>condition: -o option? op_write_file=>operation: Write to file (fs.writeFile()) op_console_log=>operation: Log to console (console.log()) op_count_tokens=>operation: Count tokens (countTokens()) cond_tokens=>condition: --tokens option? op_log_tokens=>operation: Log token count (console.log()) st->op_parse_args->cond_path cond_path(yes)->op_traverse cond_path(no)->e op_traverse->cond_diff cond_diff(yes)->op_git_diff->op_prepare_data cond_diff(no)->op_prepare_data op_prepare_data->op_render->cond_output cond_output(yes)->op_write_file->cond_tokens cond_output(no)->op_console_log->cond_tokens cond_tokens(yes)->op_count_tokens->op_log_tokens->e cond_tokens(no)->e
在flowchart視覺化網站貼上上述DSL
,可以得到如下流程圖:
透過流程圖,你可以清晰知道核心功能是如何實現的(精確到方法呼叫)。
當了解核心功能的實現原理後,你可以嘗試執行程式碼,程式碼大機率無法一次跑通。
這時候只需要將報錯資訊提供給Cursor
,他就會修改程式碼嘗試幫你解決問題。
這一過程也能進一步加深你對原始碼的理解。
實踐 —— 進階部分
如果你不滿足於只瞭解“核心功能是如何實現的”,接下來還有很多玩法,比如:
在AI幫助下,繼續實現附加功能(比如計算結果的token數量)
將語言由
JS
改為TS
讓AI為你生成測試用例
同樣,以上改動不一定能一次跑通,反覆修正的過程也是加深學習的好方法。
總結
本文介紹了一種原始碼學習方法,適合總程式碼量低於9k行的專案。
具體步驟包括:
用
Code2Prompt
將專案重要資訊彙總為一條提示詞在
Cursor
中使用Claude3.5-200k
處理提示詞讓AI幫你分析專案的核心功能、附加功能
讓AI幫你重新實現核心功能,並生成核心功能流程圖
根據程式碼和流程圖學習專案工作原理
進階部分:在AI幫助下,補足、增強專案
最終,你不僅學會了專案原始碼,還收穫一個獨屬於你的專案。
雖然當前這種方式只能用來學習9k行程式碼內的專案,但是:
對於程式碼量超標的專案,可以按功能拆分,用該方法先分析子功能,農村包圍城市
這種方式對MonoRepo
形式的大專案尤其適用。
未來大模型的推理能力、上下文大小會持續提高
所以,這會是一種長期有效,且越來越有效的原始碼學習方式。