本文作者是 AI 工程的初學者,正透過《AI Engineering from Scratch》課程自學,並全程搭配 AI 輔助:一步步照著課程開發者的進度動手執行,卡關時就向 AI 提問、請它引導。這篇文章,是把作者與 AI 互動的完整過程與學習歷程,先交由 AI 記錄、統整成初稿,再由作者親自逐段審視、修改、優化而成。AI 負責整理,最終判斷與文字由作者把關。
寫下它有兩個用意:替後來的讀者鋪一條能照著走的路徑,也幫作者自己複習、把學過的東西沉澱下來。
這篇怎麼讀
學習的紀錄,每一步我都寫了三塊:
- 作者要我做什麼 — 原始指令
- 背後的道理 — 給零基礎的解釋
- 跟著走才會遇到的事 — 按著課程走、但作者沒明說的補充或是遺漏掉的步驟
每一個指令,我有不懂的,我都要問到懂為止,才往下走。
這一課導覽框
- 課名:Phase 0 · Lesson 1 — Dev Environment(開發環境)
- 目標:把 Python / Node.js / Rust(Julia 選配)四種語言的環境從零建好
- 時間:課程標 45 分鐘。我含理解時間花了好幾小時,但值得
- Mac 使用者最重要的一句:作者的 GPU 安裝指令帶
--index-url ...cu124,那是給 NVIDIA 的,Mac 千萬別照抄(見步驟 6)- 完課驗證:跑作者的
verify.py,7 個 core 檢查全 PASS 就算過
先看懂作者的地圖:一個環境有「四層」
作者在動手前先給了一張簡單的架構說明。 他說:一個 AI 開發環境有四層,像蓋房子一樣由下往上堆。
第 4 層 AI 函式庫 PyTorch、transformers ...
第 3 層 語言本身 Python 3.12、Node 22、Rust ...
第 2 層 套件管理器 uv、pnpm、cargo ...
第 1 層 系統底座 作業系統、shell、git、GPU 驅動 ...
關鍵在於: 每一層都靠它下面那層才裝得起來。
系統底座得先建置好,才能裝套件管理器;有了套件管理器,接著安裝程式語言;有了語言,才裝得了 AI 函式庫。
- Python — AI 核心(數學、模型)
- TypeScript / Node — 智能體、MCP 伺服器、網頁應用
- Rust — 效能吃緊的地方
- Julia — 數學特別重的課(選配)
每個語言都有自己的「管家組合」
每種語言都有兩位管家,一位管語言版本(幫你下載、安裝、切換不同版本),一位管套件(幫你安裝這個語言的第三方函式庫,像 Python 的 NumPy、Node 的 React)。
| 語言 | 管版本 | 管套件 |
|---|---|---|
| Python | uv | uv / pip |
| Node.js | fnm | pnpm / npm |
| Rust | rustup | cargo |
| Julia | juliaup | Pkg(Julia 內建) |
三個要記住的重點:
- Python 這邊 uv 一把抓兩件事(管版本 + 管套件)。這是它比傳統做法(pyenv 管版本、pip 管套件、venv 管虛擬環境各自為政)好用的原因,也是為什麼課程選它。
- Rust 這邊 cargo 是內建的——你裝好 Rust 之後 cargo 自動就在,不用另外裝。
- npm 和 pnpm 的差別:npm 是 Node 一裝好就附贈的原廠管家;pnpm 是社群做的、更快更省磁碟的替代品。你可以只用 npm,或裝了 pnpm 之後兩者並存。
看懂這張圖,後面每個步驟出現的工具(uv、fnm、rustup、cargo⋯⋯)就都對得上位置了。 坦白說,我這個技術小白啥都不懂,但大略理解看過去,先這樣,我相信日後會越來越熟悉的。
步驟 1:系統底座
作者給 Mac 使用者的指令:
xcode-select --install
brew install git curl wget
每行在做什麼
xcode-select --install:叫 Mac 內建的xcode-select這個工具,去下載並安裝開發者工具包(Command Line Tools)。這包裡就有 git、編譯器等基本工具。brew install git curl wget:叫 Homebrew(brew)幫你安裝git(版本控制)、curl(下載檔案)、wget(下載檔案的另一個工具)三樣。
為什麼這個指令我可以「直接」用?
我卡在 xcode-select --install 上:為什麼我不用先裝什麼,就能直接叫它?
原來 xcode-select 這個小工具是 Mac 出廠就內建的,它的工作只有一件事:
幫你把開發者工具包下載安裝進來。可以把它想成 Apple 預先埋好的一顆「種子」。
這裡藏著一個電腦世界的經典困境:你想裝工具,可是「安裝」這件事本身也需要一個工具。那第一個工具哪來的? 答案是作業系統預先放一顆種子讓你有起點,這叫 bootstrap(自舉)。整條鏈子長這樣:
內建的 xcode-select(種子)
→ 裝開發者工具(含 git、編譯器)
→ 裝 Homebrew(軟體管家)
→ 用 Homebrew 裝 git / curl / wget / ...
而 brew install git curl wget,就是用 Homebrew(Mac 的「軟體安裝管家」,指令叫 brew)去裝三個小工具。這也讓我第一次看懂指令的「文法」:
- 第一個字 = 你要叫的工具(
brew) - 後面接的 = 叫它做什麼(
install git curl wget)
走到這裡才會知道的事:別把三個系統的指令整塊貼
作者把 macOS、Ubuntu、Windows 三種系統的指令放在同一個區塊。我沒注意,整塊複製貼上,結果連 Ubuntu 那行 sudo apt ... 也被執行了,終端機跳出 Password: 跟我要密碼。apt 是 Linux 的指令,Mac 根本沒有——我等於叫了一個不存在的東西。
教訓:這種混多系統的指令,別整塊貼,只挑自己系統那幾行。
卡在 Password: 的話,按 Control + C 取消即可,安全。
步驟 2:Python(用 uv)
作者的指令:
curl -LsSf https://astral.sh/uv/install.sh | sh
uv python install 3.12
uv venv
source .venv/bin/activate # or .venv\Scripts\activate on Windows
uv pip install numpy matplotlib jupyter
裝完之後,作者要你跑這段 Python 驗證:
import sys
print(f"Python {sys.version}")
import numpy as np
print(f"NumPy {np.__version__}")
a = np.array([1, 2, 3])
print(f"Vector: {a}, dot product with itself: {np.dot(a, a)}")
每行在做什麼
curl -LsSf ... | sh:下載 uv 的安裝腳本,直接餵給sh執行(等於「一鍵安裝 uv」)。uv python install 3.12:叫 uv 幫你下載並安裝一份 Python 3.12。uv venv:在當前資料夾建一間乾淨的虛擬環境(資料夾名字.venv)。source .venv/bin/activate:走進那間虛擬環境(activate);走進去後打的python就是房間裡指定的版本。Windows 對應寫法是.venv\Scripts\activate。uv pip install numpy matplotlib jupyter:把三個常用套件裝進這間房間:numpy:數值運算與陣列matplotlib:畫圖表jupyter:互動式筆記本,之後上課會常用
- 驗證程式碼:印出 Python 版本、NumPy 版本,並用 NumPy 算一個小向量的點積(結果應為
14)。
這一步東西最多,我學到的也最多,拆成幾個小主題講。
curl | sh 是笨方法,uv 是聰明工具
第一行 curl ... | sh 在裝 uv。這裡我查明兩件事:
- 那根
|(管道) — 像一條輸送帶,把左邊的產出直接餵給右邊。curl下載一份安裝腳本,| sh把腳本交給系統立刻執行。 - 為什麼裝 uv 要curl、之後裝 Python 卻用
uv python install— 因為curl是個很笨的下載工具,不懂自己在裝什麼,只會抓檔案;而 uv 是專業、內建智慧的工具,裝 Python 本來就是它的本行。
所以邏輯是:第一次取得工具,用通用的笨方法(curl | sh)把它 bootstrap 出來;工具到手後,就改用它自己的聰明指令。 這跟步驟 1 的「先有種子」是同一個道理,只是換了一層。
(那串 -LsSf 其實是給 curl 的一組安全設定:下載失敗就別給、自動跟隨轉址、安靜但出錯要吭聲。它跟 fnm 用的 -fsSL 是同幾個字母、只是順序不同。順序不影響結果,大小寫才有差。)
venv 是一間隔離的房間(Python 原生工具)
uv venv 建的是一個 虛擬環境(venv),把它想成一個隔離的小房間。
分享一個我一開始混淆的重點:venv 是 Python 專屬的機制。 之後步驟 3 的 Node、步驟 4 的 Rust 都不用 venv,它們各自有別的隔離方式。 所以「venv」「虛擬環境」這個詞只會在 Python 語境下看到
其他語言怎麼做隔離:
| 語言 | 每個專案的隔離機制 | 要不要 activate |
| Python | .venv 資料夾(放專屬的 Python + 套件) | 要(source activate 走進房間) |
| Node.js | 每個專案自己的 node_modules 資料夾 | 不用(Node 在專案資料夾裡跑會自動找 node_modules) |
| Rust | Cargo.toml(清單)+ target/(編譯產物);套件全域快取但每個專案版本各自算 | 不用(cargo run 會照 Cargo.toml 解析) |
| Julia | Project.toml(用詞跟 Python 最像) | 要(Pkg.activate(".")) |
Python 需要你「走進房間」才啟用隔離;Node、Rust 靠「你人在專案資料夾裡」自動觸發;Julia 跟 Python 最像也要 activate。
為什麼要分房間:
- 專案 A 需要某套件的 1.0 版
- 專案 B 需要同一套件的 2.0 版
- 全裝在一起 → 兩個版本打架,永遠不能同時活
venv 讓每個專案關在自己房間、帶自己的家當,就不會互相污染。而 source .venv/bin/activate 是「走進房間」(術語叫 activate)。走進去後,行首會冒出一個 (...) 標記,提醒「我人在房間裡了」,這時候的 python 就是房間裡指定的版本。
為什麼 python3 給我的是舊版 3.9?
我裝了新版 Python,但一打 python3 --version 卻跳出舊的 3.9。
我馬上詢問AI,得到以下:
- 我電腦裡同時有好幾個 python 並存。
- 系統靠一份「找工具的順序名單」(叫
PATH)從上往下找、找到第一個就用。 - 剛好 Apple 內建那個 3.9 排在前面,就先被叫到。
換句話說,系統不會自動挑「最新的」,它只挑「名單上最前面找到的」。這跟後來看到的 shadowed(被遮住) 是同一件事:新版被舊版擋在後面。理解「並存 + 排隊」這個機制後,很多「我明明裝了、怎麼沒生效」的困惑都解開了。
走到這裡才會知道的事:驗證碼要先「進到 Python」才能跑
作者在這一步後給了上面提及的一小段驗證用的 Python 程式(import sys / print(...) / 用 numpy 算個小向量的點積),但他沒說:這段是 Python 的話,你必須先打 python 進到 Python 裡面,才能跑它。
我不知道,直接把它貼在終端機的 % 提示符後面——結果炸出一大片跟影像處理有關的亂碼。
後來才知道:終端機(shell)看到第一個字 import,去叫了一個同名、但完全不同的工具(Mac 上 ImageMagick 的截圖指令也叫 import),跟 Python 毫無關係。
這件事給了我一個很受用的程式原則:先搞清楚「現在在對誰講話」。
- 終端機的門牌是
%,它聽「shell 的話」(uv、cd、brew…) - Python 的門牌是
>>>,它才聽「Python 的話」(import、print…)
正確做法是三步:
- 打
python走進 Python(看到>>>) - 貼那段程式,執行
- 跑完打
exit()出來(回到%)
(順帶記兩個常用的:想「走出 venv 房間」是打 deactivate;想把兩句指令串起來、前一句成功才跑後一句用 &&——例如 uv venv && source .venv/bin/activate。)
這跟「走進 venv 房間」是同一種概念:先進到對的世界,裡面才聽得懂你的話。
還有兩件小事順帶記一下:
- 作者把
uv venv和source .venv/bin/activate上下排在一起,很容易誤以為是一句,其實是兩句獨立指令。 - Mac 上沒有叫
python(不帶 3)的指令,只有python3,所以python --version會找不到,這也正常。
步驟 3:Node.js(用 pnpm)
作者的指令:
curl -fsSL https://fnm.vercel.app/install | bash
fnm install 22
fnm use 22
npm install -g pnpm
node -e "console.log('Node', process.version)"
每行在做什麼
curl -fsSL ... | bash:下載 fnm 的安裝腳本,交給bash執行(等於「一鍵安裝 fnm」)。fnm install 22:叫 fnm 把 Node.js 22 這個大版本抓下來、放進倉庫。fnm use 22:切換成現在用 Node 22。(裝好 ≠ 正在用,是兩件事。)npm install -g pnpm:用 Node 22 附贈的npm全域安裝pnpm。-g= global(全域),意思是這台電腦到處都能用。
node -e "console.log('Node', process.version)":叫node直接執行雙引號裡的一小段 JS 印出版本。-e= execute(執行)。
這是「第二個語言世界」,而且和 Python 幾乎對稱
到這裡我意識到一個大轉折:前面在弄 Python,現在開始弄的是另一個語言世界(JavaScript / TypeScript),它跑起來要靠 Node.js。
最讓我學得快的,是發現 Node 世界的工具跟 Python 世界一一對應。我學的其實就是「同一個概念的 Node 版」:
| Python 世界 | Node 世界 | 在做什麼 |
|---|---|---|
| uv | fnm | 管語言版本 |
uv python install 3.12 | fnm install 22 | 裝某個版本 |
| pip | npm | 內建套件管理器 |
| uv(更快的替代品) | pnpm(更快的替代品) | 大家愛用的升級版 |
這三行指令各做一件事:
fnm install 22— 把 Node 22 下載進倉庫fnm use 22— 切換成現在用這台(「裝好」和「正在用」是兩回事,所以兩句都要打)npm install -g pnpm— 用剛切好的 Node 22 的 npm 把 pnpm 裝起來(-g= 全域)
最後 node -e "..." 是驗證。這裡有個好對比:同樣是「跑一段程式」,**Node 用 -e,Python 卻用 -c**。而且 node -e "..." 直接在 % 打就沒事。因為我是叫 shell「去執行 node」,再把那段 JS 當包裹交給它,講的是 shell 聽得懂的話。這跟前面赤裸貼 Python 會爆,剛好互為對照。
一個延伸觀念:flag 的意思屬於「工具」,不是跨工具通用
我在這步冒出一個問題:-e 是 node 專屬的嗎?我好像在別的地方也看過。追下去才懂——同一個字母,交給不同工具,意思完全不同:
node -e "..."→ node:執行這段 JavaScriptecho -e "..."→ echo:啟用特殊符號(完全不同的意思)[ -e 檔案 ]→ 判斷式:這個檔案存不存在- Python 則用
-c→ 執行程式碼字串(不是-e)
所以看到任何 -x,判讀訣竅永遠是先問「這是交給哪個工具的」,跟前面「先看在對誰講話」是同一種思維。
走到這裡才會知道的事:fnm 裝完,當下可能認不得它
fnm 裝完後,當下那個終端視窗可能還認不得它,馬上打 fnm install 22 有機會跳 command not found: fnm。這不是失敗,是「新工具剛報到、視窗的通訊錄還沒更新」。作者沒提這點。
解法:把終端視窗關掉重開一個(或照安裝訊息貼它給的那行設定),再繼續就好。
步驟 4:Rust
作者的指令:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustc --version
cargo --version
每行在做什麼
curl --proto '=https' --tlsv1.2 -sSf ... | sh:下載rustup(Rust 的版本管理器)的安裝腳本,交給sh執行。前面那串 flag 是額外的安全設定:--proto '=https':只允許https這種加密連線,不接受不安全的連線--tlsv1.2:要求至少 TLS 1.2 的加密版本-sSf:安靜下載、出錯要吭聲、下載失敗別交東西給 sh
rustc --version:印出 Rust 編譯器(rustc)的版本。cargo --version:印出 cargo 的版本;cargo 是 Rust 的套件與專案管家,地位等同 Python 的uv或 Node 的pnpm。
我這台之前已裝好,這步沒卡。
但我在後面的練習(練習 3 用 cargo 跑 Rust)真正搞懂了 Rust 和 Python / JS 的根本差別:編譯 vs 直譯。
先問一個問題:電腦到底看得懂什麼?
電腦的 CPU 其實只看得懂「機器話」,也就是一堆 0 和 1 的指令。但我們寫的程式碼(print("Hello") 那種)是給人看的文字,CPU 完全讀不懂。所以中間一定要有人把「人話」翻成「機器話」。
差別只在於:這個翻譯,是「事先一次翻好」還是「每次跑再現場翻」。這就分出了兩派。
編譯派:先翻成成品,之後直接讀
編譯語言(Rust、C)像先把整本書翻譯、印成成品,再給人讀:
- 你先「編譯」一次,把原始碼整份翻成 CPU 看得懂的執行檔。
- 之後每次要跑,CPU 直接讀那個執行檔,不用再翻,翻譯器等於下班走人了。
- 所以跑起來超快,適合效能吃緊的地方。代價是:改一行就得重新編譯,而且執行檔綁平台(Mac 編的不能直接丟到 Windows 跑)。
你在練習 3 打 cargo run 時,它其實偷偷做了兩件事:先編譯(把 Rust 原始碼翻成執行檔),再執行那個執行檔。這就是為什麼 Rust 比 Python 多一道手續。
直譯派:原始碼原封不動,每次現場翻
直譯語言(Python、JavaScript、Julia)像即席口譯:
- 原始碼保持原樣,不預先翻。
- 每次執行,都叫一個直譯器出來,一句一句現場翻譯 + 執行。
- 所以稍微慢一點(每跑一次都要重翻),而且跑之前要先裝好直譯器。但好處是:改一個字存檔就能直接再跑(不用等編譯),原始碼搬到別台電腦也能跑(只要那台有裝直譯器)。
這就是為什麼你 python -c "..."、node -e "..." 可以「直接跑原始碼」:背後有直譯器隨時待命。
一張表看懂差別
| 編譯派(Rust、C) | 直譯派(Python、JS) | |
|---|---|---|
| 什麼時候翻譯 | 事先一次翻完 | 每次執行、現場翻 |
| 跑起來的速度 | 快(直接讀成品) | 慢一點(邊翻邊跑) |
| 改一行之後 | 要重新編譯才能跑 | 存檔直接再跑 |
| 要帶什麼才能跑 | 只要執行檔 | 要裝好直譯器 |
| 換一台電腦 | 執行檔常要重編 | 原始碼搬過去就能跑 |
| 適合場景 | 效能吃緊、交付成品 | 快速嘗試、開發實驗 |
這跟 AI 有什麼關係?
這也解釋了為什麼 AI 世界兩派都用:研究、實驗階段要「改一個想法馬上看結果」,直譯的 Python 最舒服;但真正吃效能的核心(推論引擎、底層運算)就會用編譯的 Rust / C,把速度榨出來。這門課同時教兩種語言,理由就在這裡。
(老實說現實還有混血款,例如 Java 是「先編譯成半成品、再由直譯器跑」,還有所謂 JIT 即時編譯。但對現在的我來說,先把「事先翻好 vs 現場翻」這條主軸記牢就夠了,細節之後遇到再補。)
記住這個分野後,之後看到任何語言,我都能一眼判斷它是哪一派、為什麼行為長那樣。
步驟 5:Julia(選配)
作者的指令:
curl -fsSL https://install.julialang.org | sh
julia -e 'println("Julia ", VERSION)'
每行在做什麼
curl -fsSL ... | sh:一樣是「下載安裝腳本、餵給sh執行」的套路(跟 uv、fnm 同款)。julia -e 'println("Julia ", VERSION)':叫julia直接執行單引號裡的一小段 Julia 程式碼。-e= execute(跟 node 用同一個字母)println就是 Julia 的「印出來」(等同 Python 的print)- 用單引號是因為程式碼裡有雙引號,避免打架
Julia 是選配。純 AI 應用短期用不到,可先跳過(作者原話是「For math-heavy lessons where Julia shines」,數學課才用得到)。
步驟 6:GPU(有的話)
這步是 Mac 使用者一定要警覺的地方。作者原文的指令是:
# NVIDIA
nvidia-smi
# Install PyTorch with CUDA
uv pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu124
搭配這段 Python 驗證:
import torch
print(f"CUDA available: {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"GPU: {torch.cuda.get_device_name(0)}")
每行在做什麼
nvidia-smi:NVIDIA System Management Interface,用來檢查 NVIDIA 顯卡狀態。Mac 沒有這個工具,因為 Mac 沒 NVIDIA 卡。uv pip install torch torchvision torchaudio --index-url ...:從指定的來源(CUDA 12.4 專用)下載 PyTorch 系列三個套件。torch:PyTorch 主體,做張量運算與自動微分的核心torchvision:處理影像的配套函式庫torchaudio:處理音訊的配套函式庫--index-url ...cu124:不從預設來源抓,改從 PyTorch 官方的 CUDA 12.4 專屬倉庫抓
- Python 驗證那段:問
torch「你能用 CUDA 嗎?」,能的話印出 GPU 名字。
作者也貼心加了一句:
No GPU? No problem. Most lessons work on CPU. For training-heavy lessons, use Google Colab or cloud GPUs. (沒 GPU?沒問題。大部分課用 CPU 就能跑,重訓練上 Google Colab 或雲端 GPU 即可。)
走到這裡才會知道的事:Mac 不能照抄那行 CUDA 指令
那個 cu124 是 CUDA 12.4 專用,CUDA 是 NVIDIA 顯卡的技術。我是 Mac,沒有 NVIDIA 卡,這行不能照抄,照抄會裝錯甚至裝不起來。nvidia-smi 那行 Mac 也沒有(那是 NVIDIA 驅動內建的工具)。
Mac 的正確做法是去掉 --index-url 那段,用乾淨版讓它自動抓 Apple Silicon 的版本:
uv pip install torch torchvision torchaudio
驗證也要換一段。CUDA 在 Mac 上一定是 False(Mac 的宿命),要看的是 MPS(蘋果自家的 GPU 加速):
python -c "import torch; print('PyTorch', torch.__version__); print('MPS:', torch.backends.mps.is_available())"
看到 MPS: True,就代表我的 Mac 也能幫 AI 加速。Mac 用 MPS 代替 CUDA,這是整門課我最需要記住的一條「偏離課程」的調整。
步驟 7:驗證一切
作者最後給一支總驗證腳本:
python phases/00-setup-and-tooling/01-dev-environment/code/verify.py
每行在做什麼
python phases/00-.../verify.py:叫python去執行那個路徑下的verify.py腳本。- 這是相對路徑(從你目前站的位置往下走),所以要在課程專案的根資料夾打,不然
python會找不到檔案。
- 這是相對路徑(從你目前站的位置往下走),所以要在課程專案的根資料夾打,不然
我的結果是 7/7 core 全 PASS(Python、NumPy、Matplotlib、Jupyter、Git、Node、Rust),GPU 區塊則是兩個 FAIL。這兩個要分清楚:
- CUDA FAIL — Mac 上永遠如此,不是問題、也修不好,用 MPS 就好。
- PyTorch FAIL — 只是因為我這間新房間一開始只裝了 numpy / matplotlib / jupyter,還沒裝 torch。這正是下面練習 2 要補的。
腳本最後印出 You're ready. Start with Phase 1.,環境正式完工。
三個練習,我實際做了什麼
練習 1:跑驗證腳本、修好失敗項
7/7 core 已過。剩下的 PyTorch 由練習 2 補、CUDA 在 Mac 上不用修。
練習 2:為課程建 venv 並裝 PyTorch
venv 我早在步驟 2 就建好了(而且特地建在課程專案資料夾裡,讓程式碼和房間住同一棟樓,比建在家目錄整齊)。所以這題只剩「裝 torch」——照上面 Mac 的乾淨裝法,裝完看到 MPS: True 就成。
我順便想通一個策略問題:既然之後要用 Google Colab 的免費 GPU,本機還需要裝 torch 嗎? 需要。兩個角色不同,都要有:
- 本機(Mac + MPS) = 天天開的通勤車:寫扣、debug、小實驗,九成時間在這
- Colab(免費 GPU) = 偶爾出動的重裝備:大訓練才上去,而且它預裝好 torch
練習 3:四種語言各寫一個 Hello World
這題把「直譯 vs 編譯」變成手感:
python -c "print('Hello, world!')" # Python:直譯,直接跑
node -e "console.log('Hello, world!')" # JS:直譯,直接跑(注意是 -e,不是 -c)
# Rust:編譯語言,要先「蓋專案」再編譯執行
cargo new hello_rust && cd hello_rust && cargo run
julia -e 'println("Hello, world!")' # Julia:直譯(沒裝就跳過)
Rust 那行的三段在做什麼
cargo new hello_rust:叫 cargo 建一個叫hello_rust的新專案(會自動生一支現成的 Hello World)。cd hello_rust:走進這個新資料夾(cd= change directory)。cargo run:叫 cargo 編譯 + 執行這個專案,一步搞定。&&:把三個指令串起來的意思是「前一個成功了,才跑下一個」。任何一步失敗,後面就不會執行。
Rust 之所以多一道手續,正是因為它要先編譯。cargo new 還會自動幫你生一支現成的 Hello World(cargo 就是 Rust 的 uv / pnpm,又一次對稱)。
跑完想清理的話
cd ..
rm -rf hello_rust
cd ..:..是「上一層資料夾」的固定符號,這行等於「往上退一層」,退回課程專案資料夾。rm -rf hello_rust:刪除(remove)hello_rust這個資料夾。-r= 連同裡面所有東西一起刪、-f= 強制別問我。因為你人已經站在它的「樓上」,直接講名字就刪得到。
作者交付的兩個產物(Ship It)
這一課結尾,作者「出貨」了兩個東西:
verify.py— 一支驗證腳本,任何人都能跑來檢查自己的環境。prompt-env-check.md— 一段提示詞(不是腳本)。你把它整段貼給任何 AI,就能把它「變身」成一位「開發環境診斷醫生」:先判斷是哪一層壞了 → 要你貼出診斷指令的輸出 → 給你確切的修法,最後用verify.py驗證。
走到這裡才會知道的事:這份檔案的路徑會找錯
作者寫的 outputs/prompt-env-check.md 是相對於這一課的資料夾,實際位置在 phases/00-setup-and-tooling/01-dev-environment/outputs/,不是專案最外層那個空的 outputs。我一開始找錯地方,以為檔案不見了。
有意思的是,這份提示詞的三步流程,幾乎就是我這整堂課被幫忙的方式:先判斷哪一層、看真實輸出、給確切指令、再驗證。對怕 AI 幻覺的我來說,它其實是個好範本,強迫 AI 先看證據再修、最後還要驗證,正好壓低亂編的機率。
我學到了以下
裝完環境只是表面。回頭看,我真正帶走的是幾組可以遷移到任何地方的思考工具:
- 電腦只做你「說」的,不做你「想」的。 結果很怪時,先懷疑「我是不是有個字、一個位置打得跟我以為的不一樣」,而不是「電腦壞了」。
- 一切都是「工具 + 給它的指示」。 而指示(那些
-e、-g、-d)的意思,屬於「你交給哪個工具」,沒有跨工具共用的意思。 - 先看在對誰講話。 shell 的門牌是
%、Python 是>>>;同一個字(import)講給不同聽眾,意思天差地遠。 - bootstrap:先有種子,才長得出後面。 第一個工具用通用笨方法取得,之後改用它的聰明指令。四層地基就是這樣一層帶一層。
- 並存與排隊。 同名工具可以並存,系統靠
PATH順序決定用哪個;「裝了沒生效」多半是排隊順序問題,不是壞掉。 - 沒消息就是好消息。 終端機話少,指令做完通常安安靜靜就是成功;它只有出事才開口。
給未來的自己
這一課我最大的體會是:環境建置不是障礙,是第一堂真正的工程課。 那些讓人想跳過的「裝東西」,其實藏著整個學科怎麼運作的縮影:分層、bootstrap、隔離、排隊、對誰講話。認真把每個「為什麼」問到懂,比裝好幾個工具值錢得多。
還有一件事我想留給自己:卡住就停下來追問、要 AI 給我看真實輸出、自己想通了才往下。 這份踏實感,就是「我的環境」和「別人幫我弄好的環境」之間最大的差別。