
剛開始接觸 Coding agent,容易以為「套件裝好了」就等於「已經能幫我寫程式」。實際操作時,終端機、登入方式、API 供應商與檔案權限各有自己的設定。少理解其中一環,就可能在已經看到版本號之後,仍然不知道為什麼任務停住。
這篇把第一次使用的過程拆成十一個部分。我們先準備 Windows 的命令列環境,再以 Crazyrouter 為具體例子,把 Codex CLI 接到自選的 API 服務,最後做一個可以親手驗收的 HTML 練習。每一段都保留操作原因,不只留下一串指令。
選用這個例子的重點,是練習如何把本機開發工具和 API 設定分開管理。你可以維持 Codex 的工作方式,同時清楚知道請求交給哪個服務、使用哪一個模型、憑證從哪裡讀取。這些能力往後更換工具時也用得上。
本文採 PowerShell 加 npm 的導入方式。已完成的步驟不用重做;尚未驗證的帳號能力也不會被當成既有成果。跟著執行時,以自己的回應、檔案與畫面判斷是否通過。
Codex CLI 負責接收需求,並在允許的範圍內處理本機專案。Crazyrouter 在這次練習中提供 API 的連線入口。兩者透過設定串起來,但本機操作權限與遠端帳戶並不因此變成同一件事。
| 名稱 | 初學者可以先這樣理解 | 本次用途 |
|---|---|---|
| PowerShell | 用文字與 Windows 溝通的視窗 | 安裝、查詢與切換資料夾 |
| Node.js | 執行 JavaScript 的環境 | 使用 npm 安裝工具 |
| npm | 套件管理器 | 取得 Codex CLI |
| Codex CLI | 在終端機內使用的程式開發助理 | 理解任務、處理專案 |
| Crazyrouter | 此處採用的外部 API 服務 | 設定請求目的地與服務商憑證 |
| API Key | 屬於自己帳戶的通行憑證 | 讓服務辨識請求來源 |
| config.toml | CLI 的設定檔 | 指定模型及 provider |
CLI 是 Command Line Interface 的縮寫。安裝之後不一定會出現桌面圖示,從終端機呼叫程式是正常用法。
這裡也先分清費用與權限來源:ChatGPT 的訂閱、OpenAI API 的帳戶與 Crazyrouter 的帳戶各自管理。瀏覽器登入成功,不代表任何一個外部 API 都會承認這個登入;有一把 Key,也必須用在對應的服務。
不熟悉的名詞可以在用到時再回來看。先記住「本機命令、遠端連線、檔案操作」三個層次,就足以協助你判斷錯誤發生的位置。
從開始功能表搜尋 PowerShell。若平常使用 Windows Terminal,選 PowerShell 分頁即可。不要先把所有視窗都設成系統管理員;特定安裝或沙箱程序需要額外權限時,再閱讀它的要求。
畫面中以 PS 開頭、後面帶著路徑與 > 的字串,叫做提示符。它表示現在的工作位置,並告訴你程式正在等輸入。複製教學指令時,不要連提示符一起貼上。
一開始先一行一行做。例如執行 node --version,等結果回來,再查 npm。若把兩行黏成 ...versionnpm...,PowerShell 只會收到一個不存在的內容,不會替你猜測原本想分成幾次操作。
遇到包含 if 與大括號的區塊時,則需要保持完整。後面的備份範例就是這種情況:可以一次貼上整塊,但不要缺少結尾括號。
通常可使用 Ctrl + V,不行時試試右鍵或 Ctrl + Shift + V。出現 >> 多半表示前一段輸入還沒結束,可能漏了引號。按 Ctrl + C 取消,再重新貼上即可,不需要因此重開電腦。
剛接觸命令列時,可以把一次操作記成三件事:貼上什麼、畫面回了什麼、是否回到提示符。不是每段輸出都在要求你繼續輸入;像版本編號就是完成結果。遇到安裝程式仍在下載,先讓目前命令結束,再輸入下一行,避免把準備工作和後續檢查混在一起。
Windows 安裝的命令列套件可能附有不同啟動檔。PowerShell 自動選到 .ps1 時,執行原則可能把它攔下。本文明確指定 npm.cmd 和 codex.cmd,先排除啟動檔選擇的差異。
這個做法不會要求你把整個系統的指令碼限制關掉。若裝置由公司或學校管理,仍然按照管理規範處理。
等到 Codex 的對話畫面開啟後,輸入位置的意思也會改變。自然語言任務應交給 Codex;Windows 指令則在退出對話、回到 PowerShell 提示符後執行。
node --version
npm.cmd --version
兩行都印出版本就可以往下走。教學準備時的環境曾回報 Node.js v24.21.0 與 npm 11.19.0,這是環境紀錄,不是每個人必須使用的固定版本。
如果 Windows 說找不到 node,先想兩種可能:還沒安裝,或者目前的終端機沒有拿到新的 PATH。這時候還沒有向 Crazyrouter 發送請求,不必修改模型或 Key。

圖一:這是本機命令搜尋問題,先處理安裝位置。
到 Node.js 官方下載頁,選擇 LTS、Windows,以及電腦實際使用的架構。Windows「設定 → 系統 → 關於」可查 x64 或 ARM64。
下載副檔名為 .msi 的安裝程式。頁面上如果顯示 Docker 範例,那是另一種部署方式;這次直接安裝到 Windows,不需要先學容器或照做容器指令。
跟著精靈完成安裝,保留 npm 與 PATH 整合項目。原生模組編譯工具是另一類開發需求,對這個基本練習而言不必額外勾選。也不需要為了模仿別人的截圖任意改安裝目錄。
舊程式不一定會即時取得新環境。完成安裝後退出 PowerShell,再開新的視窗;若終端機附在編輯器裡,必要時把編輯器也關掉重開。

圖二:版本數字只供辨識,npm 是否可用仍要另外查詢。
重做前面的兩條檢查。如果仍失敗,再確認安裝是否完成及 PATH 是否含有 Node.js 目錄。一次只處理這個層次,比同時換網路、改登入與刪設定更容易追蹤結果。
npm.cmd install -g @openai/codex@latest
codex.cmd --version
codex.cmd --help
請先等第一個區塊完成,再進行版本與說明查詢。-g 代表把它作為 npm 全域工具提供,讓不同專案可以呼叫;不是指每次執行都要管理員身分。latest 是套件的發行標籤,之後可能指向不同版本。
看到 codex-cli 與版本數字,表示這個命令能啟動。本機準備過程曾顯示 0.158.0,但驗收時以你自己的結果為準。這一步沒有證明 API 已連上,也沒有測試模型額度。
安裝過程中的英文提示先讀內容,不要看到 WARN 就認定全部失敗。真正的排查線索通常是下載、權限或套件相關的錯誤,以及後續版本命令能不能完成。
先開新視窗,再查:
Get-Command codex.cmd -ErrorAction SilentlyContinue
npm.cmd config get prefix
第一行有結果時可以看到啟動檔路徑;第二行會顯示 npm 的全域目錄。用檔案總管開啟該處,查看是否存在 codex.cmd。
檔案存在但命令搜尋不到,優先檢查使用者 Path;檔案也不存在,就回去看安裝紀錄。需要加入 Path 時,加入的是資料夾,不是那個 .cmd 檔案本身。既有項目請保留,不能整欄覆寫。
儲存後再次開啟終端機。若曾使用不同方式裝過多份 Codex,還要核對目前執行的是哪一份,避免更新完卻一直啟動舊位置。
這個資料夾也可以當成自己的練習紀錄。第一次只放網頁,之後才逐步增加檔案;每次都先知道目前有哪些內容。若資料夾中已有以前的作品,不要因為名稱叫 demo 就當成可以隨意覆蓋。讓工具動手之前,先說清楚哪個檔案可以修改,是往後處理正式專案也用得上的習慣。
先把操作範圍畫清楚,再讓工具開始工作:
$projectDir = Join-Path $env:USERPROFILE 'CodexProjects\crazyrouter-demo'
New-Item -ItemType Directory -Path $projectDir -Force | Out-Null
Set-Location -LiteralPath $projectDir
Get-Location
$env:USERPROFILE 會使用目前使用者的家目錄,不用自行把帳號名稱寫進教學指令。建立與切換是兩個步驟,最後由 Get-Location 確認目前位置。
crazyrouter-demo 是方便辨識的名稱,沒有特殊功能。光是資料夾名字含有服務商名稱,不會幫你完成 API 設定。
第一次練習先不要放入公司專案、憑證檔或私人資料。等到小任務完成,再按照需求調整能讀取與能寫入的範圍。這樣你比較容易看懂每次授權的影響。
接下來先保留這個 PowerShell 視窗,因為示範會把 Key 設為目前行程的環境變數。另開一個視窗不一定有相同值;新手常在這裡以為設定失效,其實只是換了行程。
| 手上的存取方式 | 對應作法 | 要分開理解的部分 |
|---|---|---|
| ChatGPT 帳號 | 瀏覽器登入 | 帳號及工作區是否具有使用權 |
| OpenAI API Key | 官方 API 認證 | API 的權限與計費 |
| Crazyrouter API Key | 自訂 provider | 服務地址、模型與該服務的憑證 |
若使用官方登入,可以在 PowerShell 執行 codex.cmd login,並用 codex.cmd login status 看狀態。裝置碼方式 codex.cmd login --device-auth 需要帳號或管理者允許;它不是繞過地區或服務資格限制的方法。
以下以第三條為主。把 Crazyrouter 當作 API 連線案例,能練習在不改變本機專案操作方式的前提下,明確管理模型請求的目的地。這種區分比把 Key 貼進任何看起來像登入的欄位更可靠。
由 Crazyrouter 控制台建立個人使用的 API Token,並確認帳戶權限。需要辨識操作入口時,可查 Crazyrouter 文件。文章裡的示意文字不能代替你自己的有效 Key。
為了與官方憑證分開,這裡使用獨立名稱 CRAZYROUTER_API_KEY:
$crazySecret = Read-Host 'Crazyrouter API Key' -AsSecureString
$env:CRAZYROUTER_API_KEY = [System.Net.NetworkCredential]::new('', $crazySecret).Password
$crazySecret.Dispose()
Remove-Variable crazySecret
[bool]$env:CRAZYROUTER_API_KEY
輸入過程不直接顯示明文。末尾出現 True 只代表此行程有資料,不代表服務端已認可,也不代表可用額度。此例未做永久寫入,之後關閉視窗時,新視窗需要重新準備環境。
這裡刻意不在標題或步驟裡指定某個永遠可用的模型名稱。供應商的可選項目與帳戶權限可能調整,教學截圖也可能比你的操作時間早。比對自己的清單雖然多一個動作,卻能避免把顯示名稱、舊別名與真正的 API 識別字混為一談。清單查詢本身若失敗,先處理該回應,不要隨便填一個名字繼續。
$crazyBase = 'https://api.crazyrouter.com/v1'
$crazyHeaders = @{ Authorization = "Bearer $env:CRAZYROUTER_API_KEY" }
$crazyModels = Invoke-RestMethod -Method Get -Uri "$crazyBase/models" -Headers $crazyHeaders
$crazyModels.data | Select-Object -ExpandProperty id
$crazyModel = Read-Host 'Model ID'
先查看 /v1/models 的回傳,再選擇有權限且適用於 Codex/Responses 工作流程的模型。在 Model ID 提示處輸入完整標識,保留原本大小寫及其他字元。
不是所有清單項目都適合這個練習。圖像、音訊等模型即使可見,也不能因此推定可用於編程代理。模型列得出來只是第一項證據,下一節仍要呼叫實際請求。
$codexConfigDir = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $env:USERPROFILE '.codex' }
New-Item -ItemType Directory -Path $codexConfigDir -Force | Out-Null
$codexConfigFile = Join-Path $codexConfigDir 'config.toml'
if (Test-Path -LiteralPath $codexConfigFile) {
$backupFile = $codexConfigFile + '.' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '.bak'
Copy-Item -LiteralPath $codexConfigFile -Destination $backupFile
}
notepad.exe $codexConfigFile
這個區塊會參考 CODEX_HOME,並在已有設定時留下時間戳記備份。首次沒有檔案時,記事本可能詢問是否新增。已有其他設定的讀者要合併必要欄位,不是把整份內容丟掉。
model = "MODEL_ID_FROM_YOUR_ACCOUNT"
model_provider = "crazyrouter"
[model_providers.crazyrouter]
name = "Crazyrouter"
base_url = "https://api.crazyrouter.com/v1"
env_key = "CRAZYROUTER_API_KEY"
wire_api = "responses"
requires_openai_auth = false
請務必把 MODEL_ID_FROM_YOUR_ACCOUNT 換成剛才查到並選定的 ID;它是占位說明,不是模型名稱。model、model_provider 是最上層欄位,應放在各個方括號表格之前。遇到已存在的同名欄位就修改,不能重複貼出兩張相同的 provider 表格。
API 路徑不放 UTM,也不填成官網首頁。儲存後確認是 config.toml,不是 config.toml.txt。若舊會話還開著,先結束,再從設定過變數的視窗重新啟動。
另外,PowerShell 裡的模型變數與記事本中的模型欄位不會自動連動。你在清單中改選另一個 ID 時,兩邊都要核對。可以在不包含密鑰的個人筆記中寫下本次選擇,避免測試用一個模型、CLI 又用另一個,最後把不同結果當成同一組設定的表現。
連上 API 與允許工具碰本機檔案是不同的決定。初次啟動遇到信任目錄或 Windows 沙箱設定時,先對照路徑,不要只記住別人按第幾個選項。

圖三:模型標籤與版本是畫面範例,實際選項以目前安裝顯示為準。
只問一段 HTML 概念,不需要允許修改檔案;等到要建立頁面,再確認寫入 index.html 的操作。給一個清楚的工作範圍,比一開始開放整個磁碟更容易理解。
如果命令看不懂,可以請 Codex 解釋它會讀寫什麼、為什麼需要執行,以及是否有不影響其他檔案的方法。為了省事關閉所有限制,不應成為教學步驟。
需要額外管理員權限的沙箱初始化也要閱讀說明。組織管理的電腦若有政策限制,依原有規定處理,不用反覆嘗試不明提權指令。
之後即使模型正常回覆,仍可能因工作目錄或權限而無法存檔。這時應查本機寫入範圍,不必立刻重建 API Token。
保留第六節設定的變數,在同一 PowerShell 進行最小測試。這會產生真實使用量,依帳戶的服務規則計算:
$crazyPayload = @{
model = $crazyModel
input = 'Reply with OK.'
stream = $false
} | ConvertTo-Json -Depth 6
$crazyResponse = Invoke-RestMethod -Method Post -Uri "$crazyBase/responses" -Headers $crazyHeaders -ContentType 'application/json' -Body $crazyPayload
$crazyResponse | Select-Object id, status, error
$crazyResponse.output | ConvertTo-Json -Depth 8
請求路徑是 /v1/responses,模型取自 $crazyModel,內容只要求回覆 OK。看回應 ID、status、error 與實際輸出,不要把 HTTP 沒報錯當成業務成功。
若回傳結構與顯示方式不同,先對照當時的文件,保留可用的 request/response ID。能讀模型列表、卻不能完成生成,是兩種不同結果;兩者都應如實記錄。
Set-Location -LiteralPath $projectDir
codex.cmd
可以先說:「請用一句繁體中文解釋 HTML,不要讀寫檔案,也不要執行命令。」有回答後再看目前的 provider 和模型,確認不是留在另一個帳號或其他設定。
直接 HTTP 測試成功,不代表 CLI 已讀取相同設定。出現缺少變數、401、403 或用量提示時,先完成這一關,再加上檔案操作。
請在目前練習資料夾建立 index.html。
頁面標題為「我的第一張學習卡」,顯示一句「開始認識 Codex」。
放置「顯示筆記」按鈕,點擊後出現「我會檢查自己的 HTML 成果」。
CSS 和 JavaScript 都寫在此檔案,不使用外部圖片、字型或框架。
不要安裝套件、不要額外連網,也不要修改其他檔案。
完成後說明真正保存的位置及檢查方式。
若無法寫入,請明確指出限制,不要以對話裡的程式碼代替已完成檔案。
這個任務沒有資料庫,也不需要開發伺服器,所以初學者可以專心看懂輸入與輸出的關係。遇到授權提示,核對目標就是練習資料夾內的這個檔案。
退出對話回到 PowerShell,可使用 /quit 或實際介面提供的結束方法。接著:
Test-Path .\index.html
Start-Process .\index.html
先確認 True 再執行開啟命令。瀏覽器裡應該有標題、按鈕和正確的點擊結果。只有聊天有程式碼,並不表示已存檔;只有檔案存在,也不表示互動符合需求。
若按鈕沒有反應,回報時描述「看得到哪個按鈕、點擊後有沒有新文字」,會比只說不能用更清楚。請工具針對同一個檔案修正,再重新整理瀏覽器。也要查看位址列,避免開著昨天的另一份練習網頁,卻以為剛才的修改完全沒生效。
這裡不要求你立刻讀懂全部 JavaScript。先學會把自己的需求拆成能觀察的結果:檔案有沒有出現、畫面是否正確、互動有沒有符合指定內容。等這些都能親自確認,再慢慢閱讀程式碼與修改細節,學習的每一步就有清楚的依據。
一般情況使用者設定在家目錄的 .codex\config.toml;CODEX_HOME 可以改變位置。provider 與認證項目要放在使用者層級,不能以為寫進任何專案的同名檔案就能替換它。
備份是保留回頭路。想恢復時先退出會話,核對備份與目前內容,只還原自己動過的部分。不要把刪除 auth.json、清空整個資料夾當成第一個排錯動作。
| 設定項 | 它決定什麼 | 常見注意點 |
|---|---|---|
model |
呼叫哪個模型 ID | 名稱要取自帳戶資訊並經過呼叫 |
model_provider |
使用哪張供應商表格 | 要與 crazyrouter 表格名稱一致 |
name |
顯示名稱 | 顯示文字不會改變路由 |
base_url |
API 基礎路徑 | 本例已含 /v1,不要重複拼接 |
env_key |
從何處取得 Key | 值是變數名稱,不是秘密本體 |
wire_api |
使用的協定 | 按 Responses 路線設定 |
requires_openai_auth |
是否使用 OpenAI 認證 | 本例使用服務商變數,設定 false |
若把最後一項改成 true,Codex 會使用 OpenAI 認證並忽略 env_key。從兩篇不同文章各複製一半設定,很容易出現「看起來都有填,實際認證來源卻不對」的狀況。
Crazyrouter 是這次示範的接入對象,但模型能力仍需逐一驗證。支援 Chat Completions 不能直接推定支援 Codex 所需的 Responses、串流與工具操作。列表可見也不是完整成功的替代證據。
之後如果按服務方建議換入口,CLI 的 base_url 與測試腳本的 $crazyBase 應一致。不要在 A 位址測出結果,再用 B 位址啟動工具,最後把差異歸因於同一套設定。
例如,你可以記錄「今天能查模型,短請求仍被拒絕」,或「短請求通過,但儲存檔案需要額外確認」。這不是失敗的流水帳,而是在替下一次練習標出起點。沒有通過的項目先保留空白,不用為了讓清單看起來完整而把它打勾,更不能把預期結果當成真正取得的結果。
記下日期、CLI 版本、模型 ID,以及最近通過的是哪一個檢查項。密鑰不要寫在紀錄裡。下次表現不同,有這些資訊才能比較是本機版本改變,還是帳戶、模型渠道或服務回應不同。
準備求助時,優先提供經過遮蔽的錯誤類型、呼叫時間與回應 ID。這些通常比整個設定資料夾更有診斷價值,也不必暴露私人程式碼。
調整參數時一次只動一個,使用同一段短提示重測。確認基本連線後再恢復較長的任務。這樣既保留了接入方式的可重現性,也避免因為無目的重試而無法理解結果。
| 錯誤現象 | 優先檢查 |
|---|---|
| node 找不到 | 安裝完成與 PATH 是否更新 |
| npm.ps1 不允許執行 | 啟動檔選擇與原則 |
| Codex 命令不存在 | 全域工具目錄與實際檔案 |
| 下載逾時 | registry、網路及代理 |
| 環境變數缺少 | 變數名稱與目前視窗 |
| 401 | 憑證發行方、有效性與目標服務 |
| 403 | 錯誤本文、權限或提供地區 |
| 404 | API 路徑及模型標識 |
| 429 | 頻率限制、額度或相關帳戶狀態 |
| TOML 解析失敗 | 重複項目、英文引號和表格位置 |
先用本文的 .cmd 形式確認。若可以執行,就先沿用,不必為了一次安裝放寬所有指令碼權限。管理裝置上的限制由管理單位處理。
npm.cmd config get registry
先看目前來源。公司內部 registry 可能有用途,不能直接覆寫。下載的網路路線也不等於模型 API 的連線路線,修改其中一個不保證修復另一個,更不要直接關掉憑證驗證。
[bool]$env:CRAZYROUTER_API_KEY
設定檔只是指定從哪個變數讀取,並不會自行建立內容。檢查名稱是否完全一致,以及你是否換了 PowerShell 視窗。存在性檢查不用公開秘密值。
先看目的網域與回應說明。錯誤地址是可能原因之一,帳戶或地區限制也是另外的原因。不能只憑狀態碼就說改某個欄位一定能解決。
PowerShell 使用 $env:USERPROFILE,而不是 %USERPROFILE%;cd /d 也不是本篇使用的寫法。保持 Set-Location,有空白的路徑保留引號。
npm.cmd install -g @openai/codex@latest
codex.cmd --version
Get-Command codex* -All
升級後檢查命令位置,別讓不同來源的安裝混在一起。平常開新專案只需切換目錄,不需要每次重裝套件。
確認任務有要求存檔,再檢查寫入範圍和工作路徑。檔案可能根本沒產生,也可能位於另一個目錄。以 Test-Path 的結果與瀏覽器行為驗收,而非只看完成文字。
截圖可以先裁切到命令與錯誤附近,再確認沒有終端機上方殘留的私人資訊。錯誤本文若含服務的請求編號,可另外抄進自己的紀錄,方便向服務端查詢。不要直接分享整份設定備份,因為裡面可能包含與這次練習無關的帳號資料或私人專案位置。
命令、版本、錯誤與前一個成功步驟都很重要。API Key、設備碼、電子郵件及無關私人路徑應先遮蔽。一次只改一項設定,回覆他人時才說得清楚做過哪些調整。
檢查時可以分兩次走:先看環境與接入,再看畫面與操作。前一組是為了知道請求如何從自己的電腦送出,後一組則是確認工具真正完成了使用者的需求。即使兩組之間有一步尚未通過,前面的成果也不用全盤推翻;保留記錄,從停止的位置繼續即可。
若隔天回來發現又缺少環境變數,先想起本次刻意使用暫時設定,而不是直接判斷安裝壞掉。重新輸入自己有效的憑證、確認模型與目前目錄後,再做短請求。若只是把網頁移到另一個資料夾,則先看檔案路徑,不必改 API 位址。把這些情境分開,才不會遇到任何變化都重裝全部工具。
練習的最後也可以試著用自己的話回答三個問題:目前的 Key 由哪個服務發行、模型名稱是從哪裡取得、哪個動作證明檔案真的保存了。如果能說明這些,就已經掌握這次接入的主要關係。即使往後介面按鈕換了位置,也能根據原理重新找到對應設定,而不必完全依賴截圖。
每一次擴充功能前,都保留一個可工作的檔案版本。這份練習作品很小,用自己的方式備份即可;等開始接觸多檔案專案時,再加入版本控制。先建立能比較修改前後結果的習慣,會讓工具協作更容易理解。
走完這些步驟,接入就不只是背下一份設定。你會知道從本機到 API,再回到檔案成果的每一個判斷點。之後把 Crazyrouter 的示例延伸到自己的專案時,仍可沿用相同的驗收方式。
練習可以慢慢增加功能,但先讓每次修改都有能親自確認的結果。這比一次要求完整大型應用,再對著大量錯誤猜測原因,更有助於建立開發工具的使用習慣。
延伸閱讀:Codex 官方文件。