我使用 Mac mini M4、32GB 統一記憶體,測試本機模型能否透過 Ollama 搭配 Codex,完成讀檔、改程式與執行測試。不過,模型能回答程式問題,只完成了連線驗證;真正可用的 Coding Agent,還要把工具呼叫轉成檔案變更,並通過獨立檢查。這個差別,直接影響本機模型能否省下開發時間。

Mac mini M4、32GB 統一記憶體的既有實測顯示:Gemma 4 E4B 在 Codex 的改檔任務受阻,12B-MLX 完成了最小工具任務,26B 則透過替代寫檔方式完成函式實作。同一顆 E4B 改接 Pi 後,也通過了相同函式的測試。因此,選擇本機 Agent 應看模型、工具介面與任務範圍是否合適,不能只按參數量決定。

Codex CLI 是什麼

Codex CLI 是 OpenAI 開發、在終端機使用的 Coding Agent。它會整理專案內容與需求,讓模型決定讀取哪些檔案、如何修改程式,以及是否執行測試;工具則在設定的權限範圍內操作電腦。本文的 Codex 指這套 CLI 程式,和提供推論的模型分開看待。

Ollama 與本機模型的分工

Ollama 負責下載、載入模型並提供 API;Gemma 4 是 Google DeepMind 的模型系列,負責理解需求和產生回應。把 Codex 連到 Ollama,等於沿用 Coding Agent 的工作流程,將推論交給本機模型。這適合希望掌握推論位置、已有可用硬體,且願意自行驗收程式的開發者。尚未裝好 Ollama,可參考 Ollama 入門教學

Codex 負責工具執行,Ollama 載入 Gemma 4 並提供模型推論,兩者透過請求與回應協作
推論交給本機模型,檔案操作仍由 Agent 管理。

工具回合會來回多次:Codex 送出需求與工具描述,Ollama 回傳模型提出的工具呼叫,Codex 執行後再把結果交給模型。某一輪工具名稱或格式不符合要求,整個任務就可能停在「說明做法」,沒有留下可用檔案。

人向 Codex Agent 提供需求與限制,Agent 與經 Ollama 推論的 Gemma 4 往返上下文、工具結果與工具呼叫,再向人回報成果
人設定目標並驗收,Agent 在授權範圍內執行工具。

Mac mini 實測能完成哪些工作

本文的本機運行環境是 Mac mini M4、32GB 統一記憶體,M4 採 10 核心 CPU,系統為當時的 macOS 26.6.2。Codex CLI 在這台 Mac 上執行,本機模型由 Ollama 載入;32GB 記憶體也要供 macOS 與其他程式共用,不能全部當成模型的可用容量。

下表整理這台 Mac 在 2026 年 8 月 29 日至 9 月 3 日的本機工具測試紀錄。E4B-MLX、26B 與 9 月 3 日的 12B 工具測試使用 Ollama 0.33.2;較早的 E4B 函式題紀錄則為 0.32.14 組合。Codex CLI 為 0.144.6,Pi 為 0.84.4。表中的 context 是模型每次可處理的內容容量。它們是不同日期、模型與任務條件的結果,不是同條件速度排名,也不是新版軟體的可靠度保證

組合與實際 context任務驗收結果
E4B/Codex,32K、64K實作 normalizeUsername()32K 提早結束;64K 工具格式受阻,外部測試均為 0/6
E4B-MLX/Codex,64K相同函式修改題嘗試錯誤工具形式,未正確改檔,外部測試 0/6
12B-MLX/Codex,原生 Responses、96K建立並執行 FizzBuzz完成工具回合,外部核對 1–20 輸出正確
26B/Codex,64K相同函式修改題改用 shell 寫檔後,外部測試 6/6
E4B/Pi,64K相同函式修改題僅修改指定檔案,外部測試 6/6

函式修改題要求讀取 README 與既有六項 Node.js 測試,只能修改 src/normalizeUsername.js,禁止安裝套件或更動測試。FizzBuzz 則是建立 Python 檔、執行並核對輸出的小任務,涉及的專案理解較少;12B 通過這題,不能拿來證明它在函式修改題優於 E4B。

12B 成功的範圍

9 月 3 日的 12B-MLX 以實際 96K context 直連 Ollama 原生 /v1/responses,完成建立、執行與核對 fizzbuzz.py,最後回覆 TASK_OK。外部驗證也確認輸出正確。期間可用記憶體最低觀測值約 57%,swap 維持約 1.44MB;完成後已卸載模型。

在這次直連之前,12B 曾透過 API 轉換代理 LiteLLM 在 32K 完成相同類型的最小任務,所以不能寫成「96K 才能成功」。不過,同樣經過代理的 96K 較長任務出現逾時與串流錯誤。這組結果可作為小範圍工具流程的起點,尚不足以支持整個專案的自動開發。

26B 改檔成功仍有代價

26B 在函式題同樣遇到 unsupported call: apply_patch,但它改用 exec_command 呼叫 shell 寫入唯一允許的檔案,約 304 秒完成,模型內外的測試都通過 6/6。成功來自錯誤恢復,並不表示 apply_patch 相容性已修好。

這次 26B 測試曾獲准採用單次專屬的 5% 可用記憶體停止線,實際最低觀測值為 24%,既有 swap 約 3.84GB 且沒有增加。這項例外不是一般使用建議;對 32GB Mac,26B 加長 context 已缺少充足餘裕,不宜僅因一次成功便列為日常預設。

31B 的程式表現與設備需求

Gemma 4 31B 在另一組線上推論環境中,透過 API 轉換代理連接 Codex,完成了文字統計、CSV 銷售彙整與日誌彙整三個 Python CLI 任務。每題各自隔離、上限 300 秒,三題均完成改檔與執行,事後另行驗證的 13 項測試全數通過。這顯示 31B 在這組設定下能完成有明確規格的小型程式工作,但不代表長任務或大型專案已經可靠。

不過,先前的本機生成測量顯示,31B 在 Mac mini M4 32GB 上速度很慢,需要反覆等待模型回應的開發工作不容易維持流暢。若要把 31B 作為日常 Coding Agent,較實際的選擇是使用運算效能更高、記憶體容量與頻寬更充足的設備,或改用支援該模型的線上平台。上述三題的成功紀錄採用線上推論,不能當成這台 Mac 執行 31B 的速度或完成時間;本機速度也會隨量化、context 與軟體版本改變。

Ollama 如何連接 Codex

以下以 macOS、既有 12B-MLX 測試組合示範。需要先安裝 Ollama、Git,以及可用的 Node.js/npm;MLX tag 用於 Apple Silicon。模型 tag、權重內容與 CLI 行為會隨版本更新,實際安裝應核對當下文件。本文實測數據均取自前述日期的紀錄。

安裝 CLI 與選擇入口

Codex CLI 可透過 npm 安裝。模型尚未存在時才需下載;已經下載則以 ollama list 確認名稱即可。下載大小、模型載入占用與整台電腦的記憶體壓力是不同數值,不能互相替代。

npm install -g @openai/codex

# 查看已下載模型
ollama list

# 尚未下載時才執行
ollama pull gemma4:12b-mlx

Ollama 官方整合文件 提供 ollama launch codex 作為快速入口,會準備專用 profile 與模型目錄;只想建立設定可加 --config。手動選擇本機 provider 則使用 --oss--local-provider ollama。以下是兩種替代入口,擇一使用;launch 路徑是官方用法,本篇既有實測使用手動連線。

# 由 Ollama 設定並啟動,選擇本機模型
ollama launch codex

# 或手動選擇本機 provider 與模型
codex --oss --local-provider ollama \
  -m gemma4:12b-mlx --sandbox read-only

Context 應以 Ollama 實際載入值為準

Context 是模型一次可處理的上下文容量,包含系統指令、工具描述、專案內容和回覆空間。Ollama 的 context 文件 建議 coding tools 使用至少 64K;歷史 Codex 函式題的首輪輸入約有 3.1 萬 tokens,即使待改的函式很短,前置內容仍占去不少容量。這個輸入量只代表該次測試,不是每次 Codex 的固定成本。

Codex 的 model_context_window 是客戶端預算,不等於 Ollama 已按相同容量載入模型。既有測試曾把前端設為 96K,runner 卻仍為 32K。判斷時應在模型載入後查看 ollama psCONTEXT 欄位。

歷史設定落差示意,Codex 預算設為 96K,但 Ollama 實際載入仍為 32K,需以 ollama ps 確認
前端容量設定不會自動保證服務端採用相同值。

要讓特定模型使用 96K,可在工作目錄建立名為 Modelfile 的純文字檔,內容如下。96K 在此為 98,304 tokens,是這次直連成功的設定,並非所有模型都必須照填;較大的 context 會增加記憶體需求。

FROM gemma4:12b-mlx
PARAMETER num_ctx 98304

在放置 Modelfile 的目錄執行下列指令,建立專用模型名稱。它重用既有權重,方便把這份 context 設定和原 tag 分開。

ollama create gemma4:12b-mlx-codex96k -f Modelfile

另一種方式是調整 Ollama App 的 context 設定,或以 OLLAMA_CONTEXT_LENGTH 啟動服務。若採後者,須先退出原本占用 11434 的 Ollama App/服務,再執行 OLLAMA_CONTEXT_LENGTH=98304 ollama serve;單純在另一個 shell 設環境變數,不會改變已啟動的服務。專用 tag 和服務預設擇一管理即可。

原生 Responses 的自訂 Profile

需要明確固定 endpoint 和模型時,可建立 ~/.codex/ollama-local.config.toml。以下把設定集中在同一個 profile,連到本機 Ollama 的 /v1,並使用 Responses 協定;不需要另外架設 Chat Completions 轉換代理。

model = "gemma4:12b-mlx-codex96k"
model_provider = "ollama_local"
model_context_window = 98304
sandbox_mode = "read-only"

[model_providers.ollama_local]
name = "Ollama local"
base_url = "http://127.0.0.1:11434/v1"
wire_api = "responses"

[model_providers.ollama_local.auth]
command = "/usr/bin/printf"
args = ["ollama"]

其中 ollama 是本機服務忽略的佔位驗證字串,不是 OpenAI API key。OpenAI 的進階設定文件 規定 command-backed auth 不應再混用 env_keyrequires_openai_auth。Profile 檔名與啟動參數要一致:

codex --profile ollama-local

以上依 2026 年 9 月 7 日文件整理,預設先使用唯讀權限;它保留歷史成功組合的 endpoint、模型 tag 與容量設定,但不是該次實作測試的逐字設定檔。實作測試使用可寫工作目錄,不能把下面的唯讀起步流程當成改檔能力驗證。

起步任務與結束檢查

第一次使用可從空白 Git 目錄開始,只交付單一讀取任務,例如「執行 pwd 並回報目前目錄,不修改檔案,也不執行其他指令」。這能檢查基本工具是否工作;要驗證改檔,之後仍需在可重建的副本裡另做有明確測試的任務。

TASK_DIR=$(mktemp -d /tmp/codex-ollama.XXXXXX)
cd "$TASK_DIR"
git init
codex --profile ollama-local

模型開始回應後,在另一個終端機查看載入狀態;使用結束先退出 Codex,再卸載該模型。PROCESSOR 欄能協助確認 GPU 使用情況,SIZE 則不等於完整統一記憶體占用。

# 工作期間查看實際 context
ollama ps

# 退出 Codex 後卸載
ollama stop gemma4:12b-mlx-codex96k
ollama ps

使用畫面與實際等待時間

下列保留先前依實測輸出整理的終端機示意圖,並非原始螢幕截圖。它們對應 8 月 29 日的 E4B、32K context 紀錄:Ollama client 為 0.32.14,當時沒有獨立確認 server/runtime 版本;Codex CLI 為 0.144.6。畫面中的警告與秒數屬於這次歷史環境。

Codex 能提出修改,當時沒有改檔

題目要求檢查折扣函式:199 元打 85 折應為 169.15,但 Math.round() 會把結果取成整數。E4B 在 Codex 約 123 秒出現第一段回應,約 165 秒結束,指出問題並提出移除取整數操作的 diff。這是直接放在提示詞中的唯讀題,沒有工具呼叫,也沒有套用 diff。

依 8 月 29 日紀錄整理的 Codex OSS mode 使用畫面,E4B 回傳折扣函式的建議 diff,沒有修改檔案
依歷史輸出整理的示意圖,建議 diff 尚未套用。

這次畫面也出現 missing field models、fallback metadata 與 telemetry tag 警告,但最終仍有文字回覆。它們值得記錄,卻不能單憑警告推定模型完全不能使用,更不能據此認定後續改檔已成功。

Ollama 的生成速度不能代替 Agent 完成時間

相同日期,直接呼叫 Ollama API 的短題測量使用 32K context、thinking 關閉,生成上限為 192 tokens。單次冷啟動首字延遲 20.08 秒,其中載入約 19.31 秒;生成速度為 30.69 tokens/s,全程約 24.35 秒。這份 API 回答提出乘 100、取整再除 100 的候選修改,與 Codex 回傳的 diff 不同。

依 8 月 29 日 Ollama API 測量整理的 E4B 終端機示意圖,32K context、首字延遲 20.08 秒、生成速度 30.69 tokens/s
這是單次 API 測量,不能視為 Codex 的完成速度。

兩條路徑的提示內容、工具負擔與計時範圍不同,不宜把秒數相除就當成 Codex 的效能折損。後續 Ollama 更新後,單次 API 載入也曾變快,但檔案快取狀態不同,不能把差距全部歸因於版本。實際工作應記錄首段回應、整個任務時間與驗收結果;完整模型速度比較可參考 Gemma 4 全系列實測

工具錯誤與 Pi 替代方案

本機 Coding Agent 卡住時,增加 context 或換更大的模型不一定能解決問題。先判斷錯誤發生在工具名稱、串流轉換,還是任務收尾,能減少沒有方向的重試。

現象既有證據建議動作
工具名稱不受支援E4B 嘗試不符合 Codex 的工具形式,函式未改好核對模型與 Agent 的工具相容性,停止重複同一錯誤
串流事件中斷12B 經 LiteLLM 時出現 OutputTextDelta without active item先查 bridge 與 Responses 事件,不能直接歸因記憶體
程式存在但 Agent 逾時12B 文字統計題在 300 秒停止,外部四項測試通過分開記錄檔案品質與流程未完成,保留成果再檢查
回覆完成,檔案卻未修改E4B 有提早結束或錯誤回報的紀錄以檔案差異與外部測試判定,不依退出碼放行

原生直連減少轉換層,仍要核對工具格式

LiteLLM 是模型 API 代理,可在不同介面之間轉換請求。12B 的 96K 較長測試中,第一題建立文字統計 CLI 與四項測試,但 300 秒內未完成 Agent 回覆;第二題約 120 秒出現反覆串流事件錯誤,且沒有產生檔案,因此停止,第三題未執行。期間可用記憶體約 56–58%,沒有證據支持把這次故障歸因於記憶體不足。

後來的原生 Responses FizzBuzz 成功,提供了可省去這層轉換的路徑。不過,E4B 早先失敗的測試也有直連 Ollama,所以「改直連」只處理部分協定問題,沒有證明 E4B 的 Codex 工具格式已改善。Ollama 的 Responses 相容性本身也有範圍,例如文件目前不支援以 previous_response_id 保存服務端對話狀態。

E4B 搭配 Pi 的適用情境

Pi 是另一套終端機 Coding Agent,預設工具包括 readwriteeditbash。它與 Codex 的工具定義、提示與回合控制不同;同一顆 E4B 在 Pi 的 64K 函式修改題,完成指定檔案變更,外部驗證為 6/6,README、套件設定與測試檔均未改動。

這次 Pi 執行於唯讀根檔案系統的 Docker 容器,只掛載拋棄式任務目錄,模型請求經過受限代理。這些限制是測試環境額外建立的,不是 Pi 預設提供的保護;Pi 官方說明它沿用啟動者的檔案、程序、網路與憑證權限。實際採用前可依 Pi 官方容器隔離文件 建立環境,不能把換 Agent 等同於自動獲得 sandbox。

對只能負擔 E4B、工作又能縮成單一函式與固定測試的情境,Pi 值得列為候選。這個判斷來自同題成功紀錄;工具介面較合適不代表所有專案更快或更準,仍須保留獨立驗收。

本機 Coding Agent 適合哪些工作

現階段較有價值的起點,是規格清楚、修改範圍小,而且能直接檢查對錯的工作。等待幾分鐘完成一次小修改是否值得,取決於後續檢查需要多少時間;若仍要重新讀取所有檔案、修正輸出與重做測試,省下的推論費用未必能抵銷維護成本。

  • 解釋函式、提出候選 diff:E4B 已有不需工具的成功紀錄,適合先確認理解與回覆是否可用。
  • 修改單一函式、產生小型腳本:先限制可寫檔案,準備模型無法修改的驗收測試。12B 的最小工具成功與 E4B+Pi 的函式成功,可作為各自組合的起點。
  • 跨多個檔案重構、安裝依賴與長任務:本文證據不足以保證可靠度,應另行評估,不能沿用 FizzBuzz 成功結論。
Agent 回覆完成後,仍須檢查檔案差異並執行獨立測試,才能確認改檔任務是否成功
驗收結果必須能由模型之外的程序重現。

需要改檔時,先建立 Git worktree 或副本,再把權限調整為 workspace-write;worktree 方便回復變更,本身不是作業系統隔離。任務結束後,另外執行 git status --shortgit diff 與原有測試,確認新增檔案、修改範圍和實際輸出。模型回覆「完成」或程序退出碼為 0,都不能取代這些證據。

32GB Mac 一次只保留一個高負載模型,還要觀察 memory_pressure -Qsysctl vm.swapusage。可用記憶體低於約 25%、swap 持續增加,或 GUI 開始延遲時應停止擴大工作並卸載模型;這是本文採用的保守操作線,不是硬體通用的精確故障門檻。模型存於外接 SSD,也無法消除統一記憶體與 I/O 壓力。

常見問答

使用前還需分清本機推論、帳戶計費與整個工具流程的網路行為。

Ollama 搭配 Codex 需要 ChatGPT 訂閱嗎?

本文選的是 Ollama 本機模型,推論不經 OpenAI 雲端模型,因此這條本機推論路徑不使用 ChatGPT 訂閱額度或 OpenAI API 計費。硬體、電力與自行維護仍有成本;若切換成雲端模型,則依該服務的方案與驗證方式處理。

接到 localhost 就代表全程離線嗎?

不能只看網址判斷。Ollama 也能轉接雲端模型;本文的 Gemma 4 本機 tag 才是在本機推論。官方提供 OLLAMA_NO_CLOUD=1 關閉 Ollama 雲端功能,修改後須重啟服務,但這不會同時封鎖 Codex 的 MCP、外掛或 shell 網路存取。需要離線工作時,還要檢查整個工具環境的網路權限。

一定要設成 96K context 嗎?

不一定。Ollama 對 coding tools 建議至少 64K,本文 96K 是特定直連測試使用的值。容量應同時配合模型上限、任務內容與記憶體餘裕;不能只增加 Codex 預算而不檢查 Ollama 的實際載入值。

Mac mini 32GB 應直接選 26B 嗎?

不建議僅依這次成功紀錄決定。26B 完成了受限的函式題,但當時可用記憶體最低約 24%,且仍需繞過工具錯誤。優先選擇能保留系統餘裕、並在預定小任務通過驗收的組合,比只追求較大的參數量更容易維持可用流程。

參考來源


Sponsored Links