跳至內容

從零開始學 AI 工程(八):
Phase 0-8 Editor Setup

編輯器調好一次,每天省力。擴充套件怎麼裝、settings.json 每行在做什麼、Cursor 跟 VS Code 不一樣的地方,還有踩到的型別檢查設定差異。

本文作者是 AI 工程的初學者,正透過《AI Engineering from Scratch》課程自學,並全程搭配 AI 輔助:一步步照著課程開發者的進度動手執行,卡關時就向 AI 提問、請它引導。這篇文章,是把作者與 AI 互動的完整過程與學習歷程,先交由 AI 記錄、統整成初稿,再由作者親自逐段審視、修改、優化而成。AI 負責整理,最終判斷與文字由作者把關。

寫下它有兩個用意:替後來的讀者鋪一條能照著走的路徑,也幫作者自己複習、把學過的東西沉澱下來。

這篇怎麼讀

這篇跟系列其他文章一樣有三層:

  • 作者說了什麼:課程的原始指令、步驟、練習
  • 我問 AI 之後理解的背後道理:白話概念、類比、跟前面學過的東西怎麼接
  • 走到這裡才會知道的事:課程沒明說但實際會遇到的補充

每一個指令,都要問到懂為止,才往下走。

這一課導覽框

  • 課名:Phase 0 - Lesson 8 — Editor Setup
  • 類型:Build(動手做的課)
  • 目標:把編輯器從「打字的地方」調成「幫你抓錯、自動排版、能連遠端 GPU 的工作台」
  • 時間:課程標約 20 分鐘,我邊裝邊排錯大概花了 40 分鐘
  • Cursor 使用者:課程用 VS Code 示範,但 Cursor 是 VS Code 的 fork,擴充套件和設定格式相容。這篇會標出 Cursor 跟 VS Code 不一樣的地方
  • 完課驗證:擴充套件全裝好 + settings.json 設好 + Black format on save 生效 + 型別檢查有波浪線

這一課要解決的問題

課程開頭的說法:

You’ll spend thousands of hours inside your editor writing Python, running notebooks, debugging training loops, and SSH-ing into GPU boxes. A misconfigured editor turns every session into friction.

你會在編輯器裡花上幾千個小時寫 Python、跑 notebook、debug 訓練迴圈、SSH 進 GPU 機器。一個沒調好的編輯器,讓每次工作都多一層阻力。

編輯器調好要 20 分鐘。不調的話,每天多浪費 20 分鐘。


先看懂作者的地圖

課程把編輯器的設定想成五層,由下往上疊:

Editor Setup 五層堆疊

底層裝好,上面才有東西掛。第一層是編輯器本體,最上面是遠端開發。


步驟 1:安裝編輯器

課程推薦 VS Code,免費、跨平台、Jupyter 原生支援、擴充套件生態系大。我用的是 Cursor,它是 VS Code 的 fork,內建 AI 程式碼輔助。擴充套件和 settings.json 格式跟 VS Code 完全一樣,課程教的東西直接通用。

驗證安裝(在終端機跑):

# VS Code 用這個
code --version

# Cursor 用這個
cursor --version

如果 codecursor 指令找不到(Mac 上常見),打開編輯器 → Cmd+Shift+P → 搜尋 “Shell Command” → 選「Install ‘code’/‘cursor’ command in PATH」。


步驟 2:裝擴充套件

課程列了八個 AI 工程必要的擴充套件:

cursor --install-extension ms-python.python
cursor --install-extension ms-python.vscode-pylance
cursor --install-extension ms-toolsai.jupyter
cursor --install-extension eamodio.gitlens
cursor --install-extension ms-vscode-remote.remote-ssh
cursor --install-extension ms-python.debugpy
cursor --install-extension ms-python.black-formatter
cursor --install-extension charliermarsh.ruff

VS Code 使用者把 cursor 換成 code 就好。

這是全域安裝——裝一次,開任何專案都能用。跟前面學的 uv pip install(裝進特定 .venv)不同,擴充套件是裝進編輯器本體的。

每個擴充套件在做什麼:

擴充套件做什麼
Python讓編輯器認識 Python,偵測虛擬環境、跑程式、debug
Pylance自動補全、型別提示、抓 import 錯誤
Jupyter在編輯器裡直接跑 notebook,不用另開瀏覽器
GitLens看每一行是誰改的、什麼時候改的
Remote SSH連遠端 GPU 機器,像在本機一樣編輯遠端檔案
Debugpy一步一步追蹤 Python 程式碼
Black Formatter存檔時自動排版,程式碼風格永遠一致
Ruff快速 lint,幫你抓常見錯誤

實際跑的結果

八個裡面五個 Cursor 已經內建了(Python、Pylance、Jupyter、Remote SSH、Debugpy),只補裝了三個:GitLens、Black Formatter、Ruff。已經裝過的會顯示 is already installed,不會重複裝。

跑的時候會看到一堆 DeprecationWarning: The 'punycode' module is deprecated,這是 Cursor 內部用的 Node.js 模組版本比較舊,跟你無關,不用理它。


步驟 3:設定 settings.json

打開編輯器 → Cmd+Shift+P → 輸入 **“Open User Settings (JSON)”**(注意有 User 這個字,不要開成 defaultSettings.json,那個是唯讀的預設值)。

課程要你加的設定:

{
    "python.analysis.typeCheckingMode": "basic",
    "editor.formatOnSave": true,
    "editor.rulers": [88, 120],
    "notebook.output.scrolling": true,
    "files.autoSave": "afterDelay"
}

每個設定為什麼這樣選

"python.analysis.typeCheckingMode": "basic" — 預設是 "off",開到 "basic" 之後,你如果把一個字串丟進一個只吃數字的函式,還沒跑程式,編輯器就會畫波浪線告訴你。AI 工程常常在處理 tensor 的 shape,維度傳錯是最常見的 bug 之一。不開到 "strict" 是因為太嚴格,第三方套件的型別標注不完整,會噴一堆假警告。

"editor.formatOnSave": true — 預設是 false。開了之後,按 Cmd+S 存檔的瞬間,Black 自動幫你把程式碼排整齊。冒號後面補空格、等號兩邊補空格、縮排統一。你不用花任何腦力在格式上面。

"editor.rulers": [88, 120] — 在編輯器裡畫兩條淡淡的垂直線。88 是 Black 自動換行的位置,120 提醒你註解或 docstring 寫太長了。不會強制你什麼,純粹是視覺參考。

"notebook.output.scrolling": true — 預設是 false,notebook 的 cell 輸出有多長就顯示多長。訓練模型的時候一個 cell 可能印出幾千行 loss 數字,不開這個整個畫面會被撐爆。開了之後輸出區變成固定高度、可捲動的小視窗。

"files.autoSave": "afterDelay" — 預設是 "off"。你改了程式碼,跑的時候忘記存,結果跑的是上一版,debug 半天發現根本沒跑到新的。這個設定讓編輯器在你停止打字幾秒後自動存檔。

走到這裡才會知道的事:formatOnSave 會改你的 settings.json

"editor.formatOnSave": true 加進去之後,第一次按 Cmd+S 存 settings.json 的時候,編輯器會自動把你的 JSON 重新排版。例如 [88, 120] 可能被拆成兩行。這不是壞掉了,正是 format on save 在做它該做的事。


步驟 4:終端機整合

再加這幾個設定(Mac 用 zsh):

{
    "terminal.integrated.defaultProfile.osx": "zsh",
    "terminal.integrated.fontSize": 13,
    "terminal.integrated.scrollback": 10000
}

常用的終端機快捷鍵:

動作macOS
開關終端機Ctrl+`
新開一個終端機Ctrl+Shift+`
分割終端機Cmd+\

分割終端機在 AI 工程很實用:一邊跑訓練腳本,一邊看 GPU 使用狀況。


步驟 5:遠端開發(Remote SSH)

這步的概念是:將來要訓練大模型,本機跑不動,你會需要 SSH 連進雲端的 GPU 機器。Remote SSH 這個擴充套件讓你在編輯器裡直接打開遠端機器的資料夾,編輯檔案、跑終端機、debug,體驗跟在本機完全一樣。不用另外開 SSH 視窗用 vim 改檔案。

操作流程:Cmd+Shift+P → “Remote-SSH: Connect to Host” → 輸入 user@遠端IP

課程還教了怎麼設 SSH key 做免密碼登入,以及在 ~/.ssh/config 裡加設定讓連線只要選名字。

我目前用不到這步。 我的策略是 Cursor 在本機做開發和小實驗,需要 GPU 算力的時候上 Google Colab(免費的 T4 GPU)。Colab 是在瀏覽器裡操作,不走 SSH。等將來需要自己的 GPU 伺服器時再回來設。


替代編輯器

課程提了三個替代方案:

Cursor — 我在用的。VS Code 的 fork,內建 AI 程式碼生成。擴充套件和 settings.json 格式跟 VS Code 相容。

Windsurf — 另一個 AI-first 的 VS Code fork,同樣相容。

Vim/Neovim — 課程直接說:如果你現在還不會 Vim,不要現在學。學習曲線會跟學 AI 工程搶注意力。已經會的人才留在 Vim。


設定好之後的日常工作流

課程描述的 daily workflow:

  1. 打開專案資料夾(或 Remote SSH 連進遠端 GPU 機器)
  2. 寫 Python,有自動補全、型別提示、紅線即時抓錯
  3. 跑 Jupyter notebook,直接在編輯器裡跑
  4. 用內建終端機跑訓練腳本、uv pip install、監控 GPU
  5. 用 GitLens 看改了什麼,確認後再 commit

這裡的重點是:所有事情都在同一個視窗裡完成。不用在瀏覽器、終端機、編輯器之間切來切去。


關鍵術語

術語一般人怎麼說實際意思
LSP「自動補全引擎」Language Server Protocol,一套標準協定,讓編輯器跟語言伺服器溝通,取得型別資訊、補全建議、錯誤提示
Pylance「Python 外掛」微軟做的 Python 語言伺服器,底層用 Pyright 做型別檢查和 IntelliSense
Remote SSH「在伺服器上工作」擴充套件在遠端機器裝一個輕量伺服器,把畫面串流回本機的編輯器
Format on save「自動排版」每次存檔時跑 formatter(Black 或 Ruff),讓程式碼風格永遠一致

驗證設定

驗證 Black format on save

新建一個 .py 檔,貼一段故意寫得很醜的程式碼:

def add(a:int,b:int)->int:
    return a+b

Cmd+S 存檔。如果 Black 生效,冒號和箭頭旁邊會自動補上空格,變成:

def add(a: int, b: int) -> int:
    return a + b

驗證型別檢查

在同一個檔案加上:

result = add("hello", 3)

函式宣告要 int,你傳了 str。如果型別檢查生效,"hello" 底下會出現波浪線警告。


走到這裡才會知道的事

defaultSettings.json 不是你要的

Cmd+Shift+P 搜尋 settings 的時候,會看到兩個選項。**“Open User Settings (JSON)”** 才是你要改的那個。另一個 “Open Default Settings (JSON)” 是編輯器的出廠預設值,打開來有幾千行,而且是唯讀的,改不了。

Cursor 的型別檢查設定跟 VS Code 不一樣

課程教的 "python.analysis.typeCheckingMode": "basic" 在 Cursor 上不會生效。Cursor 內建的不是 Pylance,是 Basepyright(Pyright 的一個分支)。型別檢查的設定 key 要用:

"cursorpyright.analysis.typeCheckingMode": "basic"

原本的 python.analysis.typeCheckingMode 留著不影響(萬一以後用 VS Code 還能用),但 Cursor 認的是 cursorpyright. 開頭的版本。

Cursor 的 Black formatter 需要多一步

在 Cursor 裡,光開 "editor.formatOnSave": true 可能不會自動用 Black。要在 settings.json 裡明確指定 Python 的 formatter:

"[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter"
}

我最後的 settings.json 長這樣

{
    "window.autoDetectColorScheme": true,
    "python.analysis.typeCheckingMode": "basic",
    "cursorpyright.analysis.typeCheckingMode": "basic",
    "editor.formatOnSave": true,
    "editor.rulers": [88, 120],
    "notebook.output.scrolling": true,
    "files.autoSave": "afterDelay",
    "terminal.integrated.defaultProfile.osx": "zsh",
    "terminal.integrated.fontSize": 13,
    "terminal.integrated.scrollback": 10000,
    "[python]": {
        "editor.defaultFormatter": "ms-python.black-formatter"
    }
}