2026/09/10

AI Coding 的成本問題:與其追求最強模型,不如找到夠用的模型

AI Coding 發展到現在,大家已經不太需要討論「AI 能不能寫程式」,真正開始影響實際使用策略的問題,反而是成本。但要比較不同 Coding Model 的成本並不容易,單純比較每百萬 Token 的價格沒有太大意義,因為不同模型完成同一個任務時,使用的 Token 數量、執行時間、成功率與需要人工介入的程度都不同。真正有價值的比較方式,是讓不同模型執行同一個足夠複雜的工程任務,再比較最後的結果。

DHH 最近在 Lex Fridman Podcast 分享了一個很有意思的案例。他讓 AI 將 Python 的終端文字特效程式庫 TerminalTextEffects 重寫成 Rust。這不是單純要求產生一份功能類似的實作,而是需要維持原本的行為與輸出,並透過測試驗證相容性。後續他又讓不同模型嘗試相同任務,結果如下。

模型 結果 完成時間 成本
Fable 成功 約 45 分鐘 約 US$550
GPT-Sol 成功 約 1.5 小時 約 US$46
Grok 4.6 成功 約 1.5 小時 約 US$55
DeepSeek V4 Pro 成功 約 2.5~2.75 小時 約 US$23
GPT-Luna 失敗
DeepSeek V4 Flash 失敗

Fable 是其中最快完成任務的模型,大約 45 分鐘就完成,但成本接近 US$550。GPT-Sol 與 Grok 4.6 大約需要一倍的時間,成本卻只有 Fable 的十分之一左右。DeepSeek V4 Pro 更進一步把成本降低到約 US$23,代價則是執行時間增加到兩個半小時以上。

如果這是一個需要工程師坐在螢幕前等待結果的互動式任務,45 分鐘與兩個半小時的差異可能很重要。但如果它是一個可以非同步執行的 Agent Task,甚至是在 CI/CD Pipeline 裡面執行,時間的重要性就可能大幅降低。此時多花兩個小時換取二十倍以上的成本差異,很可能是一筆合理的交易。

Token 價格不是最重要的成本指標

這組測試還帶出另一個很重要的問題:GPT-Luna 與 DeepSeek V4 Flash 都屬於成本較低的模型,但最後沒有成功完成任務。因此只比較模型的 Input Token 與 Output Token 單價,其實很容易得到錯誤的結論。對工程工作而言,更值得關注的指標應該是:

Cost per Successful Task

假設模型 A 執行一次只需要 US$5,但成功率只有 30%,而模型 B 一次需要 US$30,卻幾乎可以穩定完成工作,那麼模型 B 很可能才是實際成本較低的選擇。而且這裡甚至還沒有把工程師的時間算進去。一個 Agent 執行兩個小時,中間完全不需要人工介入,最後產生可以直接 Review 的 Pull Request,與另一個只需要 30 分鐘,但工程師必須不斷修正方向、補 Context、重新執行的 Agent,兩者的實際成本完全不同。

因此更完整的成本模型至少應該包含:模型使用成本、成功率、執行時間與人工介入成本。這些因素加在一起,才比較接近真正的 AI Coding 成本。

Coding Model 可能存在能力門檻

這個案例也讓我重新思考「輕模型」與「高階模型」之間的差異。我們很容易把模型能力想像成線性的關係,例如最強模型是 100 分,中階模型 90 分,輕模型 80 分。如果只是一般的文字處理工作,這種理解可能還算合理,但 Agent Coding 不一定如此。

在長時間、多步驟的工程任務中,模型需要持續理解 Context、規劃下一步、修改程式、執行測試、分析錯誤,再根據結果修正自己的做法。其中任何一個環節持續出錯,都可能導致整個任務無法收斂。因此它比較像存在一道 能力門檻:模型只要超過這個門檻,就可能有能力自行完成整個任務;但如果低於這個門檻,結果不一定只是「慢一點」或「品質差一點」,而可能是根本做不完。

這也是為什麼便宜模型不一定真的便宜。如果一個模型的 Token 成本只有另一個模型的一半,但它無法完成任務,那麼它的 Cost per Successful Task 並不是另一個模型的一半,而是沒有意義。因此選擇 Coding Model 時,我現在更在意的問題不是:

哪一個模型最強?

而是:

哪一個模型是剛好跨過這個任務能力門檻的最低成本選擇?

最強模型不一定是最合理的預設模型

DHH 的測試中,Fable 的結果其實非常好。它最快完成任務,而且如果把這件事情交給一個不熟悉 Rust 的工程師自行研究、實作與驗證,US$550 未必算昂貴。所以這個案例並不能簡單解讀成「Fable 太貴,不值得使用」。

真正值得注意的是另一件事:Fable 值得 US$550,不代表每個任務都需要 Fable。如果 GPT-Sol 花約 US$46 也能完成相同任務,而我並不在乎多等待 45 分鐘,那麼在這個特定情境下,Sol 就可能是更合理的選擇。

這也是我自己使用 AI Coding 工具後越來越明顯的感受:很多工作並不需要最強模型。如果一個中階模型已經可以穩定、完整地完成任務,那麼繼續往上使用更昂貴的 Frontier Model,得到的可能只是速度提升或成功率從 95% 提升到 99%。這些提升當然有價值,但它們是否值得數倍甚至十倍的成本,取決於任務本身。高階模型真正有價值的地方,應該是用在那些只有它才能穩定跨過能力門檻的任務,而不是成為所有工作的固定預設。

Model Routing 不只是依照任務大小選模型

這個案例另外一個值得注意的地方,是後續模型執行任務時,並不是完全從零開始。前面的高階模型已經產生了相當完整的 Plan,後續模型可以基於既有規劃繼續執行。這讓 Model Routing 有了另一種可能。一般談到 Model Routing,最直覺的做法通常是:

簡單問題交給便宜模型,困難問題交給昂貴模型

但在 Coding Agent 裡,其實可以切得更細:同一個任務的不同階段,也可以使用不同模型。例如 Planning 階段需要理解大量 Context、辨識風險、建立 Architecture 與拆解工作,這個階段可以交給能力最強的模型。當 Plan 已經足夠清楚之後,大量 Implementation 工作可能不再需要同等級的推理能力,此時就可以交給成本較低的模型執行。完成之後,再使用另一個模型進行 Code Review 或 Security Review。一個可能的 Workflow 會變成:

  • Planning → 高階模型
  • Implementation → 中階模型
  • Testing / Fix → 中階模型
  • Code Review → 不同供應商的高階模型
  • Security Review → 適合安全分析的模型
  • Documentation → 輕模型

這比從 Session 開始到結束始終使用同一個 Frontier Model,更接近工程上的最佳化問題。如果一個昂貴模型最擅長的是理解複雜需求與建立正確的執行方向,就沒有必要繼續支付相同價格,讓它完成數百次相對機械性的 Code Modification。反過來說,如果 Planning 本身就是最容易讓 Agent 走錯方向的階段,也沒有必要為了節省 Token 成本,而讓能力不足的模型花大量時間自行探索。Model Routing 真正的價值,不只是「選便宜模型」,而是把昂貴模型的能力用在最值得花錢的地方。

找到模型的能力邊界,比追求單一最強模型更重要

要做好 Model Routing,前提是透過大量練習與實驗,逐漸找出每個模型的能力邊界;選對執行者,和選對任務一樣重要。我目前的分工是:Claude 專門處理純 Coding,Codex 用於 Coding、蒐集資訊與撰文,Gemini 則負責其餘各種雜事。

Gemini 的使用額度相對充裕,可以放心使用最新模型;Claude 和 Codex 我則以中階模型為主,分別使用 Sonnet 5 High 與 Terra Medium。這樣的配置下,每一家都能專注處理自己擅長的事情。即使我是使用最便宜的方案,Weekly Limit 也還沒有低於 70% 過。

網路上常見有人批評模型「很笨」。Context Engineering 是否做好,當然會影響結果,但另一個常被忽略的問題是:是否選對模型,也是否把任務交給了它具備的能力範圍。以我的經驗來說,Gemini 處理 Google 相關工作時,準確度「必定」高於另外兩家。這是經過多次實驗後得到的結論:同樣的 Prompt,無論是操作 Kubernetes 或 GCE,Gemini 幾乎都能一次到位;即使把 Gemini 的產出餵給 Claude 與 Codex,它們也會認為 Gemini 的考量更全面。

目前三大模型供應商確實沒有任何一家可以通吃所有工作。與其執著於單一模型的總體排名,更實際的做法是理解各自的長處、持續驗證它們的邊界,然後把合適的工作交給合適的模型。

AI Coding 開始變成工程最佳化問題

過去大家很習慣問:

現在最強的 Coding Model 是哪一個?

這個問題當然還是有意義,但隨著模型能力逐漸跨過許多日常工程任務的最低門檻,它的重要性可能會慢慢下降。接下來真正值得解決的問題可能會變成:

這個 Workflow 的每一個 Stage,應該 Route 到哪一個 Model?

而且長期來看,這甚至不應該由工程師手動決定。Agent Orchestrator 可以根據任務複雜度、Context 長度、歷史成功率、預估 Token 消耗、時間限制與模型價格,自動選擇最適合的模型。當模型執行失敗時,再升級到下一個能力等級,例如:

輕模型 → 中階模型 → Frontier Model

甚至 Planning 與 Review 可以直接使用 Frontier Model,而中間大量 Implementation 自動 Route 到成本較低的模型。到了這個階段,我們最佳化的就不再是單一 Prompt,也不只是單一模型,而是整個 AI Software Development Pipeline。

DHH 這次測試最值得注意的地方,因此不只是 Fable 花了 US$550,而 DeepSeek 只需要 US$23。它真正呈現的是一件更有意思的事情:

AI Coding 不需要永遠使用最強的模型,而是應該為每一個工作階段找到「能力足夠,而且成本最低」的模型

最強模型應該處理只有它能穩定完成的事情。剩下的工作,交給已經足夠好的模型。當 AI Coding 開始大量進入真正的工程流程後,我認為這會比單純追逐「目前 Coding Benchmark 第一名是誰」重要得多。

來源

2026/09/08

模型變強後,初始 Markdown 的重點:從規則清單轉為可驗證的工作地圖

近來「重寫 initial Markdown」的討論,來自新一代模型在理解任務、規劃多步驟工作、使用工具與從錯誤中恢復方面的明顯進步。模型能承接更大的工作單位,也能依檔案、指令與文件自行補齊更多執行細節;人的工作重心因此逐漸從逐步指揮,轉向提供正確的專案脈絡、清楚的邊界與可驗證的成果定義。

早期的 coding agent 與模型較容易遺漏限制、選錯工具、過早宣告完成,或在長任務中失去進度。因此,團隊常將大量「第一步做什麼、第二步做什麼」、「永遠使用某種格式」和舊問題的補丁集中寫進 system prompt、AGENTS.mdCLAUDE.md。這些規則曾是提高穩定性的實用方法,但累積後會讓真正重要的專案知識、任務目標與驗收條件被埋在細節裡,也提高每次模型升級後重新校正的成本。

現在需要調整的原因,是把能力較強的模型放進更好的工作環境:initial Markdown 提供一份短而清楚的工作地圖,版本化文件提供可追溯的 source of truth,測試與檢查則提供成果證據。這種設計讓模型保有判斷與執行空間,同時讓專案的安全、品質與可維護性有明確依據。

1. 用短入口檔建立共同工作語言

AGENTS.mdCLAUDE.md 或其他 initial Markdown 承擔四件事:說明專案目標、標出任務邊界、列出常用指令,以及指向重要文件。入口檔維持精煉,agent 才能在每次工作時抓住真正重要的訊號。

OpenAI 的實務做法是將短版 AGENTS.md 當作知識地圖,而不是百科全書;它連到架構、產品規格、執行計畫與品質文件。這種 progressive disclosure 讓 agent 先理解方向,再依任務載入所需細節。

2. 將專案知識做成可查找的 source of truth

把架構、資料模型、API contract、runbook、既有決策與產品規格放在 repo 內、可版本控制且可搜尋的文件。initial Markdown 只需告訴 agent:哪一種問題該讀哪一份資料,以及資料的權威來源在哪裡。

高品質 context 的目標不是「越少越好」,而是「用最少的高訊號資訊,完整描述預期行為」。因此,關鍵限制應保留在入口檔;細節則放在 agent 可即時找到的文件,而不是藏在聊天紀錄或人的記憶中。

3. 把完成標準寫成可驗證的證據

模型能規劃與執行,但專案對「完成」的定義需要明確提供。將驗收轉成可觀察、可重跑的證據:

  • 單元測試、整合測試、E2E 與視覺比對
  • lint、型別檢查、schema/API contract 驗證
  • migration dry-run、release checklist 與 smoke test
  • 實際執行的命令、結果,以及未驗證項目的風險說明

這些品質機制比 prompt 措辭更能跨模型沿用。OpenAI 以文件的連結、更新狀態與結構化程度建立機械檢查;Anthropic 的長任務實驗則以 feature list、進度檔、Git 與端到端測試,讓每一個 session 都能接續並驗證前一段工作。

4. 為自主工作提供清楚授權與安全界線

長時間任務要順暢,agent 需要知道哪些事已獲授權、哪些事需要等待確認。把授權寫成具體的工作契約:

類別 建議授權方式
任務範圍內、可復原的本機變更 直接執行,完成後附上 diff 與驗證結果。
發現的旁支問題 記錄在總結或 backlog,保留給後續獨立處理。
刪除資料、部署、改權限、對外發送、金錢操作 明列需取得確認的門檻與負責人。
多 session 工作 每次留下進度、決策、下一步、已驗證與待驗證項目。

這讓 agent 在低風險工作保持節奏,同時在高影響操作前留下足夠的人工控制點。

5. 以任務評測決定規則與 Effort

Effort、模型版本、工具可用性與任務類型都會影響成果。最可靠的做法是建立一組 5–10 個真實且代表性的任務,為每個任務記錄:

  • 成功率與驗收結果
  • 耗時與 token/費用
  • 越界修改、回歸與人工介入次數
  • 使用的模型、Effort、工具與 initial Markdown 版本

先保存現況作為 baseline;每次調整一組規則後,重跑相同任務。保留能穩定改善失敗模式的規則,並把可重用的專案知識移到 source of truth。安全、法規與資料保護要求則作為穩定的必要條件持續維護。

一份可直接採用的最小初始檔

# Agent working agreement

## Goal and scope
- 本次任務的功能範圍、允許修改的模組,以及不在範圍內的事項。

## Non-negotiables
- 對外發送、部署、刪除資料、改權限與金錢操作,依既定核准流程處理。
- 使用既有 migration、logging、error-handling 與測試慣例。

## Find the source of truth
- 架構:docs/architecture/index.md
- 資料契約:docs/contracts/
- 執行與驗收:docs/runbooks/verification.md
- 進行中的計畫:docs/exec-plans/active/

## Definition of done
- 完成需求範圍內的變更,並將旁支問題列入後續事項。
- 跑與變更相符的檢查,回報實際命令與結果。
- 清楚列出未驗證項目、原因與風險。

讓 agent 協助重作 initial Markdown

將 agent 納入 initial Markdown 的重作流程,能以目前的 repository、工具與評測結果產出更貼近專案的候選稿。Anthropic 公開提到會用 prompt improver 調整 CLAUDE.md;OpenAI 也以週期性的「doc-gardening」agent 掃描過時文件並提出修正。交付物採用可 review 的候選稿:保留團隊規範,將可發現的專案知識移到文件索引,把品質要求連到可執行檢查。

可直接交給 agent 的 prompt:

請審閱此 repository 的 AGENTS.md/CLAUDE.md 與相關文件,為新一代 coding agent
產生一份 initial Markdown 候選稿。

目標:讓入口檔成為短而高訊號的工作地圖;它必須保留專案事實、不可跨越的安全與
權限界線、常用指令、source-of-truth 索引,以及可驗證的 Definition of Done。

請依序完成:
1. 只讀分析目前 instructions、目錄結構、CI、測試、文件與近期變更。
2. 將每一條現有內容分類為:保留、合併、移至文件、轉為機械檢查、或淘汰;說明理由。
3. 將安全、法規、權限、對外操作與團隊既定規範列為不可自動刪除項目。
4. 產生 `AGENTS.proposed.md`,不要覆寫原檔,也不要修改程式或設定。
5. 提供與原檔的摘要 diff、需人工確認的決策,以及 5–10 個代表性任務的評測計畫。

完成條件:候選稿能指出各種任務的權威資料位置,定義相符的驗收方式,並將可機械化
的規則連到測試、lint、CI 或腳本。

審閱候選稿時,優先確認三件事:專案或組織要求是否完整保留、每個文件連結是否可到達、以及代表性任務的結果是否優於原版。通過後再以 commit 或 pull request 合併;後續可根據真實失敗與 review feedback 繼續迭代。

持續演進的工作方式

  1. 以真實任務測試目前的 initial Markdown。
  2. 透過 ablation(移除/還原)找出真正影響品質的規則。
  3. 將穩定的專案知識版本化,並從入口檔提供清楚索引。
  4. 將重複出現的品質問題轉為測試、lint、checklist 或工具契約。
  5. 在模型、工具或權限機制改版後,重新跑代表性評測。

初始 Markdown 最終是一份讓 agent 能可靠工作的起點:它提供方向、邊界、知識入口與驗收標準;專案則以版本化文件與可執行檢查,持續累積可被下一代模型繼承的能力。

參考資料

2026/05/11

How to configure the MCP service for popular AI models

這篇整理 4 個終端型 AI 工具目前支援的 MCP 設定方式:

  • Google Gemini CLI
  • OpenAI Codex CLI
  • Claude Code
  • GitHub Copilot CLI

本文假設專案目錄是 /code/chan

範例都以 minhlucvan/agent-browser-mcp 為例,目標設定如下:

{
  "mcp": {
    "servers": {
      "agent-browser": {
        "command": "npx",
        "args": ["agent-browser-mcp"]
      }
    }
  }
}

先決條件

  • 已安裝 Node.js,讓 npx 可用
  • 以下範例以 macOS/Linux 路徑表示

1. Google Gemini CLI

Gemini CLI 支援:

  • 全域設定:~/.gemini/settings.json
  • 專案設定:/code/chan/.gemini/settings.json
  • 指令管理:gemini mcp add/remove/enable/disable/list

專案目錄設定

在專案根目錄建立或編輯 /code/chan/.gemini/settings.json

{
  "mcpServers": {
    "agent-browser": {
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

全域設定

編輯 ~/.gemini/settings.json

{
  "mcpServers": {
    "agent-browser": {
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

用指令安裝

安裝到目前專案:

gemini mcp add -s project agent-browser npx agent-browser-mcp

安裝到全域:

gemini mcp add -s user agent-browser npx agent-browser-mcp

不進 TUI 列出 MCP

列出目前可用的 MCP server:

gemini mcp list

用指令移除

移除專案設定:

gemini mcp remove -s project agent-browser

移除全域設定:

gemini mcp remove -s user agent-browser

如果只是暫時停用,也可以用:

gemini mcp disable agent-browser
gemini mcp enable agent-browser

2. OpenAI Codex CLI

Codex 支援:

  • 全域設定:~/.codex/config.toml
  • 專案設定:/code/chan/.codex/config.toml
  • 指令管理:codex mcp add/remove/list/get/login/logout

要注意一點:目前 codex mcp add/remove 沒有 scope 參數,實務上比較適合管理全域設定。若你要做專案限定 MCP,直接編輯 /code/chan/.codex/config.toml 會比較明確。

專案目錄設定

在專案根目錄建立或編輯 /code/chan/.codex/config.toml

[mcp_servers.agent-browser]
command = "npx"
args = ["agent-browser-mcp"]

全域設定

編輯 ~/.codex/config.toml

[mcp_servers.agent-browser]
command = "npx"
args = ["agent-browser-mcp"]

用指令安裝

Codex CLI 目前最直接的做法是加到全域設定:

codex mcp add agent-browser -- npx agent-browser-mcp

不進 TUI 列出 MCP

列出目前已設定的 MCP server:

codex mcp list

用指令移除

codex mcp remove agent-browser

專案設定怎麼移除

如果你是手動寫在 /code/chan/.codex/config.toml,就把這段刪掉:

[mcp_servers.agent-browser]
command = "npx"
args = ["agent-browser-mcp"]

如果只是暫時不想用,也可以改成:

[mcp_servers.agent-browser]
command = "npx"
args = ["agent-browser-mcp"]
enabled = false

3. Claude Code

Claude Code 的 MCP scope 最完整,分成 3 種:

  • local:只對你自己、只在目前專案有效,存在 ~/.claude.json(巢狀於 projects.{專案路徑}.mcpServers
  • project:專案共享,存在專案根目錄 /code/chan/.mcp.json
  • user:全域,存在 ~/.claude.json(頂層 mcpServers

如果你這篇文章要區分「專案目錄設定」和「全域設定」,最適合介紹的是:

  • 專案設定:/code/chan/.mcp.json
  • 全域設定:~/.claude.json

專案目錄設定

在專案根目錄建立 /code/chan/.mcp.json

{
  "mcpServers": {
    "agent-browser": {
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

全域設定

編輯 ~/.claude.json,放在頂層 mcpServers

{
  "mcpServers": {
    "agent-browser": {
      "type": "stdio",
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

用指令安裝

安裝成專案共享設定:

claude mcp add --transport stdio --scope project agent-browser -- npx agent-browser-mcp

安裝成全域設定:

claude mcp add --transport stdio --scope user agent-browser -- npx agent-browser-mcp

如果你想做「只在這個專案對你自己有效」,可以用:

claude mcp add --transport stdio --scope local agent-browser -- npx agent-browser-mcp

不進 TUI 列出 MCP

列出目前可用的 MCP server:

claude mcp list

用指令移除

claude mcp remove agent-browser

如果你先前是用 --scope user--scope project 加的,移除時記得用同樣 scope:

claude mcp remove --scope user agent-browser
claude mcp remove --scope project agent-browser
claude mcp remove --scope local agent-browser

4. GitHub Copilot CLI

GitHub Copilot CLI 支援:

  • 全域設定:~/.copilot/mcp-config.json
  • 專案設定:/code/chan/.mcp.json/code/chan/.github/mcp.json
  • 指令管理:copilot mcp add/remove/list/get

要注意一點:目前 copilot mcp add/remove 是針對 user-level,也就是 ~/.copilot/mcp-config.json。專案層級通常要手動編輯 /code/chan/.mcp.json/code/chan/.github/mcp.json

專案目錄設定

可以在專案根目錄放 /code/chan/.mcp.json

{
  "mcpServers": {
    "agent-browser": {
      "type": "local",
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

或放在 /code/chan/.github/mcp.json,作為 repository-level 共享設定:

{
  "mcpServers": {
    "agent-browser": {
      "type": "local",
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

全域設定

編輯 ~/.copilot/mcp-config.json

{
  "mcpServers": {
    "agent-browser": {
      "type": "local",
      "command": "npx",
      "args": ["agent-browser-mcp"]
    }
  }
}

用指令安裝

Copilot CLI 的 mcp add 目前是寫入全域設定:

copilot mcp add agent-browser --type local -- npx agent-browser-mcp

不進 TUI 列出 MCP

列出目前已設定的 MCP server:

copilot mcp list

用指令移除

copilot mcp remove agent-browser

專案設定怎麼移除

如果是手動寫在 /code/chan/.mcp.json/code/chan/.github/mcp.json,就把 agent-browser 那段刪掉即可。

四套工具差異總結

工具 全域設定 專案設定 可用指令安裝到專案? 可用指令移除?
Gemini CLI ~/.gemini/settings.json /code/chan/.gemini/settings.json 可以,-s project 可以,gemini mcp remove -s project
OpenAI Codex CLI ~/.codex/config.toml /code/chan/.codex/config.toml 官方文件偏向手動編輯專案設定 可以移除 CLI 加上的全域設定
Claude Code ~/.claude.json /code/chan/.mcp.json 可以,--scope project 可以,claude mcp remove --scope project
GitHub Copilot CLI ~/.copilot/mcp-config.json /code/chan/.mcp.json/code/chan/.github/mcp.json user-level 可以;project-level 建議手動編輯 可以移除 user-level;project-level 手動刪除

參考資料

2026/04/23

How I Actually Use Claude Code, Gemini, Codex, and Copilot Together

本來就有在用 Google Gemini、GitHub Copilot、OpenAI Codex,最近為了研究一些東西也入手了 Claude Code。

老實說,Claude Code 燒 token 跟鬼一樣,所以如果要拿來做 coding 或 code review,強烈建議把內建的 LSP 功能打開。

直接用 /plugin 安裝幾個常用插件:

  • code-review
  • context7
  • skill-creator
  • php-lsp
  • pyright-lsp
  • typescript-lsp

LSP 設定

要讓這些 LSP plugin 正常運作,你本機還是要有對應的 language server:

npm i -g intelephense pyright typescript typescript-language-server

這一段其實是關鍵。

因為 LSP 提供的是「結構化程式資訊」(symbol、type、reference),不是單純把整份 code 丟給模型讀。

簡單講就是:

  • 沒有 LSP → 靠 token 硬吃整包 code
  • 有 LSP → 精準抓需要的 context

這會直接影響兩件事:

  • token 使用量
  • 回答準確度

Claude Code 的優勢

目前「內建 LSP connector」這件事,是 Claude Code 跟其他模型最大的實用差異。

你會很明顯感覺到:

  • context 更乾淨
  • hallucination 比較少
  • 大型專案比較撐得住

各家工具怎麼用(我的定位)

因為我自己有一套 agentic workflow,所以不太會去爭哪個模型最強,而是看它「適合做什麼」。

Claude Code

專門拿來 coding / deep code review

優點:

  • LSP 整合完整
  • 結構理解能力強

缺點:

  • token 消耗偏高

Google Gemini

基本上是萬用工具人

  • 跟 Google 生態整合很深
  • UI 我自己最喜歡
  • daily reset,沒有 weekly limit,用起來壓力小

我很多生活雜事都丟給它做。

另外裝了 code-review extension 之後,我實測:

👉 它的 /review 品質其實可以逼近 Claude Code(Sonnet)


OpenAI Codex

目前我的 coding 主力

有幾次經驗是:

  • Claude Sonnet 解不出來
  • 換 Opus 還是不行
  • Codex 直接解掉

不確定是不是剛好遇到所謂「降智期」,但整體體驗真的很順。

另外它的 image-2 也蠻驚艷的。


GitHub Copilot

本質是「model switch + 強 context engineering」

重點不在模型本身,而是:

  • IDE 整合超強
  • context 處理很聰明

所以我只要回到 IDE workflow,就會開 Copilot。


我目前的使用方式

我不會只用一個模型,而是讓它們各自做擅長的事。

例如寫文章:

  • 用 Gemini 查資料(準確、快)
  • 用 Codex 發散(寫得很順)
  • 用 Claude 收斂(結構整理、修正)

讓模型分工,其實比「找一個最強模型」還有效。


總結

我自己的結論很簡單:

沒有最強的模型,只有適不適合你 workflow 的工具

如果你願意花時間理解每個工具的設計哲學,再把它們組合起來用,體驗會差很多。

2026/03/01

Copilot CLI Dev Environment Bootstrapping

GitHub Copilot CLI 開發環境設置

在新機器上快速復原 Copilot CLI 工作環境的完整指南。


前置需求

確認以下工具已安裝:

工具 用途 安裝參考
pnpm Node.js 套件管理 請參考官方安裝頁面
PHP PHP 執行環境 依作業系統安裝
Node.js JS/TS 執行環境 建議透過 nvm 安裝
Python Python 執行環境 建議透過 uv 管理

1. LSP Server 安裝

PHP — intelephense

pnpm add -g intelephense

Node.js / TypeScript — typescript-language-server

pnpm add -g typescript-language-server typescript

Python — pyright

pnpm add -g pyright

2. LSP 設定檔

建立檔案 ~/.copilot/lsp-config.json(Windows:%USERPROFILE%\.copilot\lsp-config.json):

{
  "lspServers": {
    "intelephense": {
      "command": "intelephense",
      "args": ["--stdio"],
      "fileExtensions": {
        ".php": "php"
      }
    },
    "typescript": {
      "command": "typescript-language-server",
      "args": ["--stdio"],
      "fileExtensions": {
        ".js": "javascript",
        ".jsx": "javascriptreact",
        ".ts": "typescript",
        ".tsx": "typescriptreact",
        ".mjs": "javascript",
        ".cjs": "javascript"
      }
    },
    "pyright": {
      "command": "pyright-langserver",
      "args": ["--stdio"],
      "fileExtensions": {
        ".py": "python"
      }
    }
  }
}

3. MCP 設定

建立或更新 ~/.copilot/mcp.json(Windows:%USERPROFILE%\.copilot\mcp.json):

{
  "mcpServers": {
    "context7": {
      "tools": [
        "get-library-docs",
        "resolve-library-id"
      ],
      "type": "http",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}

context7 使用遠端 HTTP 模式,不需要本地安裝任何套件。


4. 驗證

啟動 Copilot CLI 後,執行以下指令確認設定生效:

/lsp    → 查看 LSP server 載入狀態
/mcp    → 查看 MCP server 連線狀態

快速腳本(一鍵安裝)

# 1. 安裝 LSP servers
pnpm add -g intelephense typescript-language-server typescript pyright

# 2. 建立設定目錄
mkdir -p ~/.copilot

# 3. 寫入 LSP 設定
cat > ~/.copilot/lsp-config.json << 'EOF'
{
  "lspServers": {
    "intelephense": {
      "command": "intelephense",
      "args": ["--stdio"],
      "fileExtensions": {
        ".php": "php"
      }
    },
    "typescript": {
      "command": "typescript-language-server",
      "args": ["--stdio"],
      "fileExtensions": {
        ".js": "javascript",
        ".jsx": "javascriptreact",
        ".ts": "typescript",
        ".tsx": "typescriptreact",
        ".mjs": "javascript",
        ".cjs": "javascript"
      }
    },
    "pyright": {
      "command": "pyright-langserver",
      "args": ["--stdio"],
      "fileExtensions": {
        ".py": "python"
      }
    }
  }
}
EOF

# 4. 寫入 MCP 設定
cat > ~/.copilot/mcp.json << 'EOF'
{
  "mcpServers": {
    "context7": {
      "tools": [
        "get-library-docs",
        "resolve-library-id"
      ],
      "type": "http",
      "url": "https://mcp.context7.com/mcp"
    }
  }
}
EOF

Windows 使用者:請將 ~/.copilot/ 替換為 %USERPROFILE%\.copilot\,並使用 PowerShell 執行對應命令。


Copilot CLI 自動設置 Prompt

在新環境啟動 Copilot CLI 後,貼上以下 prompt,讓 Copilot 自行查找最新做法並完成設置:

請幫我完成 Copilot CLI 的開發環境設置:

1. 我使用 pnpm 管理所有 LSP 套件。
   請全域安裝下列語言的 LSP server(自行查找目前主流推薦的套件名稱與安裝方式):
   - PHP
   - JavaScript / TypeScript
   - Python

2. 根據安裝結果,產生並寫入 ~/.copilot/lsp-config.json,
   設定每個 LSP server 的啟動指令與對應的副檔名。

3. 在 ~/.copilot/mcp.json 加入 context7 MCP server,
   使用官方建議的最新連線方式(HTTP remote 或本地安裝皆可,以官方文件為準)。

4. 完成後用 /lsp 和 /mcp 確認設定已正確載入,並回報結果。

2026/01/23

Why Daily Quotas Change the AI Coding Game

我目前訂閱的 AI 工具有 Gemini 跟 GitHub Copilot,Copilot 採用的是典型的低價入門策略,每月 10 鎂,實際上包含兩種不同性質的服務。

  • 第一種是能力相對較弱、但速度很快的輕量模型,可以無限次使用
  • 第二種是具備深度推理能力的 premium 模型,但有每月免費使用額度限制

只要有在實際做開發,要把 premium 的免費額度用完其實不難,而在 agentic workflow 逐漸成形的情境下,最大的痛點之一正是「成本不確定性」,你很難事前知道一次執行會消耗多少 token,也很難直覺換算這些 token 對應的實際成本,目前雖然已經出現一些用來量測與建議 prompt 的工具,但仍在早期探索階段,在這種前提下,只要有預算上限存在,每一次較大規模的 agent 執行,本質上都帶有不確定風險,而 Copilot 的 premium quota 又是 monthly reset,這會自然放大使用者的心理壓力,也正是在這個時候,Gemini Pro 的優勢開始變得非常明顯,即便一樣無法精確預測 token 的實際消耗方式,但 Gemini CLI 採用的是 daily reset 的配額模型,以我目前每天實際使用的情況來看,幾乎沒有遇過低於 50% 的狀態,隔天早上又會完整恢復。

這種配額機制會直接改變使用者的行為模式:

第一,你很清楚額度每天都會重置,反而會產生「今天不用就浪費掉」的心理,這和多數 monthly quota 服務的使用心態是完全相反的
第二,原本因為 Copilot 在 editor 或 IDE 內整合良好,加上有 LSP 支援,因此開發流程自然會以 Copilot 為主,畢竟少了 LSP,就等於更多純推理操作,也意味著更高的 token 消耗

但在 daily reset 的前提下,會開始出現一種心態轉變,既然每天都會歸零,那不如就讓它燒,於是實際開發行為的比重也開始慢慢轉移,從長期來看,這種使用模式的轉變,可能會讓 Google 在 coding 領域逐步侵蝕 Copilot 目前的優勢。

除了每一次實際使用本身都會回饋到模型品質的優化之外,GitHub 最核心的護城河,向來是它掌握了大量真實且高品質的程式碼 repository,但當你讓 Gemini 深度參與實際開發流程,完整讀取並理解你的 codebase,在「結構理解、模式學習與工作流程掌握」這個層級上,效果其實已經非常接近直接擁有該 repository 所能帶來的價值。

Copilot 當然也有 editor 與 IDE plugin,只是目前整體體驗仍偏陽春,一旦這一層補齊之後,Copilot 的差異化優勢到底還剩下什麼,其實就值得重新思考了,更何況目前越來越多標準正在浮現,像是 agent skills 這類抽象層的規範,Google 一開始看起來並沒有打算全面跟進,但後來的策略調整,其實也反映了現實壓力。

今年 Cloudflare 在 TBPN 的訪談中提到,Google 的資料訓練量約為 OpenAI 的 3.2 倍,也約為 Microsoft 與 Anthropic 的 4.8 倍,這裡不只是「量」的差距,更重要的是資料來源本身的結構性差異。

  • Android 裝置
  • Gmail
  • YouTube
  • Google Drive

這些並不是零散或單一用途的資料,而是高度貼近真實生活與工作流程的長期行為軌跡,近期 Apple 也開始在部分場景中採用 Gemini,即便在隱私層面不至於直接取得原始內容,但在實際系統運作與品質優化過程中,能夠接觸到的訊號密度,仍然是可以預期的,從這個角度來看,Google 在長期模型品質演進上的潛在優勢其實非常明顯。

我自己長期使用 Google 生態系,因此對這樣的發展並不排斥,但同時也希望市場不要走向單一壟斷,當初 OpenAI 問世時,讓 Google 罕見地拉起 Code Red,甚至合併了內部兩個 AI 研發部門,這才有了今天 Gemini 這個名字,也正是這種彼此拉扯的競爭關係,才讓整個 AI 發展速度被大幅推進,如果所有玩家都能持續往前推,也許哪一天,人類真的可以更接近馬斯克說的「不必為了生存而工作」的未來,這樣的世界,其實也不壞。

2025/12/27

Setting Up Trusted SSL for Laravel Sail and Docker Environments

平常在本機開發時對應的通常是 http,但如果某些特殊原因,想要使用 https 的話,沒有憑證會看到令人礙眼的警告內容,今天紀錄一下怎麼可以在本地使用自簽憑證讓討厭的 ssl 警告消失,有兩種我目前開發的常用情境:

  1. 用 docker 自架 php + nginx
  2. 使用 laravel sail

安裝使用 mkcert

1. 安裝 mkcert

我們使用 Scoop 作為 Windows 的套件管理工具,打開 PowerShell,執行以下指令:

scoop install mkcert

2. 建立本地 CA (憑證授權單位)

這一步最為關鍵,它會讓你的 Windows 系統信任由 mkcert 簽發的憑證:

mkcert -install

注意:若彈出安全性警告,請點擊「是」。

套用自簽憑證

自架範例

1. 專案結構

├── docker/
│   ├── conf.d/
│   │   └── default.conf  # Nginx 設定
│   └── ssl/              # 存放 mkcert 憑證
├── public/
│   └── index.php             # 測試檔案
└── compose.yml           # Docker 配置

2. 產生憑證

# 建立目錄
mkdir -p docker/nginx/ssl

# 使用 mkcert 生成針對 demo.test 的憑證
# 檔案會直接產生在 docker/nginx/ssl 內
cd docker/nginx/ssl
mkcert demo.test

3. default.conf 配置

server {
    listen 80;
    server_name demo.test;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;
    server_name demo.test;

    ssl_certificate /etc/nginx/ssl/demo.test.pem;
    ssl_certificate_key /etc/nginx/ssl/demo.test-key.pem;

    root /var/www/html/public;
    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
}

4. compose.yml

services:
  php:
    image: php:8.4-fpm
    volumes:
      - .:/var/www/html

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - .:/var/www/html
      - ./docker/conf.d:/etc/nginx/conf.d
      - ./docker/nginx/ssl:/etc/nginx/ssl
    depends_on:
      - php

sail 範例

1. 生成專屬憑證

切換到你的 Laravel 專案根目錄,建立存放憑證的資料夾並產生檔案:

mkdir -p docker/ssl
cd docker/ssl
mkcert demo.test

2. 配置 Docker 環境

我們將使用 Caddy 作為反向代理伺服器。
修改 docker-compose.yml
找到 services 區塊,加入 caddy 服務,並調整 laravel.test 的埠號對應:

services:
    laravel.test:
        # ... (其餘配置保持不變)
        ports:
            - '${VITE_PORT:-5173}:${VITE_PORT:-5173}' # 移除 80 埠映射,改由 Caddy 處理
        networks:
            - sail

    caddy:
        image: caddy:latest
        restart: unless-stopped
        ports:
            - "80:80"
            - "443:443"
        volumes:
            - ./Caddyfile:/etc/caddy/Caddyfile
            - ./docker/ssl:/etc/caddy/certs
            - sail-caddy-data:/data
            - sail-caddy-config:/config
        networks:
            - sail
        depends_on:
            - laravel.test

# 記得在最下方的 volumes 區塊新增
volumes:
    sail-caddy-data:
        driver: local
    sail-caddy-config:
        driver: local

3. 建立 Caddyfile

在專案根目錄建立 Caddyfile

demo.test {
    reverse_proxy laravel.test:80
    tls /etc/caddy/certs/demo.test.pem /etc/caddy/certs/demo.test-key.pem
}

4. 調整應用程式設定

1. 更新 .env

確保 Laravel 知道目前的通訊協定:

APP_URL=https://demo.test
2. 讓 Laravel 信任 Proxy

修改 bootstrap/app.php,讓 route() 函式能正確生成 https 連結:

->withMiddleware(function (Middleware $middleware) {
    $middleware->trustProxies(at: '*');
})
3. 配置 Vite (若有使用)

修改 vite.config.js 以支援 HMR (熱重載) 透過 HTTPS 運作:

import fs from 'fs';

export default defineConfig({
    server: {
        host: '0.0.0.0',
        hmr: { host: 'demo.test' },
        https: {
            key: fs.readFileSync('./docker/ssl/demo.test-key.pem'),
            cert: fs.readFileSync('./docker/ssl/demo.test.pem'),
        },
    },
    // ...
});