標籤: Ollama

  • Claude Code 換腦記:雲端便宜但要未雨綢繆,5 萬內路徑

    重點摘要

    • Claude Code 是「身體」(agent loop、tool use、MCP),模型是「腦子」,claude-code-router(ccswitch)是「神經接口」,把腦子接上身體。
    • 雲端 LLM 現在真的便宜:DeepSeek V3.2 每百萬 token USD 0.28/0.42,SWE-bench Verified 72-74%,夠用 80% 場景。不需要為了省錢買硬體
    • 但 Anthropic 改價、限額、ToS 變動隨時可能 — 未雨綢繆有必要,可是不要花過頭。5 萬內買「合理保險」夠了。
    • 10 萬內 3 條路徑:0 元全雲端(屁股電腦 + cheap API)、3 萬二手 GPU5 萬 RTX 5070 Ti。20+ 萬路徑(RTX 5090 + Mac Studio Ultra)完全不必要。
    • 腦子可以換,工具不能綁架你 — 也不要綁架你家庭預算。

    為什麼要換腦:Claude Code 框架真好用,但要有「萬一」準備

    Claude Code 提供的是身體 + 技能:agent loop、tool use、Bash 執行、MCP server 接入、檔案編輯、git 操作、subagent 派遣。這套框架成熟、穩定、文件齊。問題只有一個:底層腦子綁死在 Anthropic API

    講真的,2026 年雲端 LLM 費用真的便宜。Claude Max USD 100/月、DeepSeek V3.2 一百萬 token 不到 USD 0.5,單看價格就是時代最佳。多數人現階段「為了省錢花 20 萬買 RTX 5090」算式根本算不過來:5 萬月 API 成本 × 80 個月 = 6 年半才回本,而 6 年半後 RTX 7090 都出來了。

    「便宜」不等於「無風險」。Anthropic 可以隨時改價、限額、deprecate model、改 ToS、加區域限制、政策性下架。「便宜」是現在的事實,「能用」是對方願意的事實。未雨綢繆 = 確保「對方變心」的那天不會讓我停工

    這篇講的是合理保險:用 5 萬內的預算建立 fallback,不是為了省錢、不是為了完全自主、不是為了跑分追 frontier。只是讓你睡得安穩

    神經接口:claude-code-router 是什麼,怎麼把腦子接上身體

    claude-code-router(社群稱 ccswitch)是一個 proxy gateway,綁在 localhost:3456。Claude Code 原本打到 Anthropic API 的請求,router 攔截下來、轉換格式、路由到你指定的後端(OpenRouter / DeepSeek / Ollama / Gemini / Volcengine / SiliconFlow)。[GitHub: musistudio/claude-code-router]

    核心能力 3 個:

    • Transformer:把 Anthropic API request schema 轉換成 OpenAI / Ollama 格式,模型不用知道對方是誰
    • 動態切換:聊天中用 /model 指令切後端,不重啟
    • 路由策略:根據 task 類型自動派模型(重任務 → Claude Opus、background → DeepSeek、本地 → Qwen3-Coder)

    實際省錢幅度:[Cut Claude Code Bill 90%] 給的數字是 50-90%,看路由邏輯激進程度。但對保留 Claude Max 訂閱的人,router 真正的價值不是省錢,是削峰 — 把 subagent / background 派出去,Claude Max 的 weekly quota 留給真正需要 Opus 的任務,永不撞 lockout

    腦子替換的 3 種劑量

    劑量 A:全雲端腦(0 元入場)⭐ 我推這個

    router 把全部請求(或除主對話外的全部)丟到便宜 cloud API(DeepSeek V3.2 / Qwen3-Coder API)。本機完全不用裝模型,連 Ollama 都不裝。屁股電腦完美參與 — 它只負責跑 Claude Code 跟 router 本身,推理在雲端。

    適合:多數人。除非你有商業機密 / air-gapped 需求,沒理由花硬體錢。

    劑量 B:半雲半本地

    本地裝中型模型(Qwen3-Coder-30B-A3B 或 Gemma 3 12B)跑 background / 重複性任務,雲端跑重活。需要至少一張 12-16GB VRAM 的 GPU。

    適合:日常 coding 主力 + 想壓 API bill 到極致 + 願意花 3-5 萬硬體錢做「保險」。

    劑量 C:全本地腦(本文不推)

    本地跑 Kimi K2.6(1T MoE)或 DeepSeek V3.2(671B),完全不打雲端。但需要 Mac Studio M4 Ultra 256GB(NT$ 35 萬起)。對 99% 開發者而言不划算 — 不在本文 5 萬內預算範圍

    5 萬內的 3 條路徑(具體 part list)

    路徑 1:NT$ 0(全雲端 + 屁股電腦)

    項目 內容 成本
    機器 手邊任何能跑 Node 20 的機器(屁股電腦 / Mini PC / 舊筆電都行) NT$ 0
    claude-code-router npm install -g @musistudio/claude-code-router 免費
    DeepSeek API 帳號 platform.deepseek.com 註冊,買 USD 5 預付 NT$ 150 起
    月用量(中度開發者) DeepSeek V3.2 USD 0.28/M input, USD 0.42/M output NT$ 500-3,000

    這條路最被低估。多數人以為「本地模型」=「沒網路也能跑」,但實際 90% 場景你有網路,DeepSeek API 比自己跑本地 30B 還快還準。0 硬體成本 + 月 USD 5-15 = 跟 Claude 訂閱比省 70-90%,而且性能 80% 場景夠用。

    路徑 2:NT$ 1.5 萬(二手 GPU 試水溫)

    Part 規格 NT$
    二手 RTX 3060 12GB PTT / 露天 / 蝦皮二手 8,000-10,000
    PSU 升級到 650W 確保 GPU 供電 3,000
    機殼 / 風扇 散熱 1,500
    合計 ~15,000

    可跑:Qwen3-Coder-Next(3B active,記憶體吃 ~6GB)、Gemma 3 12B Q4、DeepSeek-R1-Distill-Qwen-14B Q4。40-60 tokens/sec,互動體驗已過 30 t/s 的「跟 cloud 無感」門檻。[Best GPU for Local LLMs 2026]

    適合:「想玩本地但不想砸大錢」。1.5 萬投資 = 大約 30 個月 DeepSeek API 用量,只在你**確實會用本地** + 想實驗的前提下划算。

    路徑 3:NT$ 5 萬(RTX 5070 Ti 16GB 改現有桌機)⭐ 認真做本地的甜蜜點

    Part 規格 NT$
    RTX 5070 Ti 16GB(新) 2026 最佳 CP 值 LLM 卡 28,000-32,000
    PSU 850W 5070 Ti 需 750W+ 5,000
    RAM 加到 64GB DDR4 / DDR5 雙通道 6,000
    NVMe 2TB 模型 / GGUF 存放 5,000
    合計 ~48,000

    可跑:Qwen3-Coder-30B-A3B(MoE,VRAM 吃 ~14GB),80-120 t/s 飛快。已能應付日常主力 coding,Claude API 退到 background 角色(複雜重構 / 跨檔分析才用)。

    適合:真的認真做本地化 + 有現有桌機可以裝顯卡 + 5 萬預算的人。這條路在 2026 中是「合理保險」最高 CP 值的點。

    為什麼不砸 20+ 萬?算給你看

    很多「玩 LLM」社群推的是 RTX 5090(NT$ 12-15 萬)或 Mac Studio M4 Ultra 256GB(NT$ 35 萬+)。對 99% 開發者而言,這算式根本算不過來

    配置 硬體投入 月省 (vs Claude USD 100) 回本年數 折舊風險
    路徑 1(全雲端) NT$ 0 USD 80-95 立刻省
    路徑 2(NT$ 1.5 萬) NT$ 15,000 USD 80-90 5-6 個月 低(二手 3060 殘值高)
    路徑 3(NT$ 5 萬) NT$ 48,000 USD 80-100 14-16 個月 中(2 年後 RTX 6070 上市)
    RTX 5090 機(NT$ 23 萬) NT$ 230,000 USD 100(只是不付訂閱) 76 個月 / 6.3 年
    Mac Studio M4 Ultra(NT$ 40 萬) NT$ 400,000 USD 100 133 個月 / 11 年 超高

    RTX 5090 機 6.3 年才回本,但 6 年後 RTX 8090 都出來了,你的 5090 殘值剩 30%。Mac Studio Ultra 11 年回本,11 年後 Apple Silicon 已經換了 4 代。

    「未雨綢繆」≠「為了不可能發生的事過度準備」。Anthropic 真的明天倒了,你也能在 5 萬路徑下半天內切到本地 — 那才是「合理保險」。砸 20 萬給「我擔心 Anthropic 變心」,是恐懼定價,不是工程。

    4 個本地腦子怎麼選(為什麼不一定要追 frontier)

    模型 Release 規模 SWE-bench 適合誰
    Qwen3-Coder-Next 2026/02 80B MoE / 3B active SOTA local 5 萬路徑首選 ⭐
    Kimi K2.6 2026/04/20 1T MoE SWE-Bench Pro 58.6% 贏 Opus 4.6 需 Mac Studio Ultra,不在本文範圍
    DeepSeek V3.2 2026/Q1 671B MoE SWE-bench Verified 72-74% 用 API 最划算(自己跑要 256GB RAM)
    Gemma 4 2026/04 多 size Apache 2.0 純開源、小機器友善(路徑 2 OK)

    來源:[Qwen3-Coder GitHub][Kimi K2.6 完整指南][DeepSeek 完整指南][Gemma releases]

    關鍵判斷:不要追 frontier。Kimi K2.6 跑分贏 Opus 4.6 沒錯,但要 256GB RAM 的 Mac Studio Ultra 才跑得動 = 40 萬硬體。對 5 萬內預算而言,Qwen3-Coder-30B-A3B(30B 規模、3B active MoE,16GB VRAM 就跑得起)已經滿足 80% 場景。剩下 20% 的硬任務丟回 Claude 用 router 解決

    ccswitch 路由策略:哪個腦子接什麼活

    1. Heavy(複雜重構、跨檔架構分析、安全 review)→ Claude Opus 4.7(API 或 Max 訂閱)
    2. Medium(一般 coding、debug、寫 test)→ DeepSeek V3.2(API)或 Qwen3-Coder-30B(本地,僅路徑 3)
    3. Light(格式整理、改 typo、寫 commit message、跑 lint)→ 本地 Gemma 3 12B(路徑 3)或最便宜 cloud(DeepSeek background tier)
    4. Background(自動產生 README、批次重命名、log 摘要)→ 本地小模型或 DeepSeek,跑多久都不心疼

    router config 範例:

    {
      "providers": {
        "claude": { "type": "anthropic", "apiKey": "$ANTHROPIC_KEY" },
        "deepseek": { "type": "openai", "baseUrl": "https://api.deepseek.com" },
        "qwen-local": { "type": "ollama", "baseUrl": "http://localhost:11434" }
      },
      "routes": [
        { "match": { "complexity": "heavy" }, "provider": "claude", "model": "claude-opus-4-7" },
        { "match": { "complexity": "medium" }, "provider": "deepseek", "model": "deepseek-chat" },
        { "match": { "complexity": "light" }, "provider": "qwen-local", "model": "qwen3-coder:30b" }
      ]
    }

    實際省下來的成本:[Claude Code Router 完整 2026 指南] 給的數字是月 API bill 從 USD 200 降到 USD 30-50。如果你保留 Claude Max 訂閱,把 subagent / background 路由出去,可以避免撞 weekly quota lockout,實質效益就是 「有效用量翻 2 倍」

    屁股電腦改造案例:32GB RAM + Ryzen 7 4700U 怎麼玩

    我自己手上的 Mini PC:AMD Ryzen 7 4700U(8 cores)、32GB RAM、無獨立 GPU、Linux Mint。前面查過所有資料,這台機器在 2026 的真實處境是:

    • ❌ 30B+ 模型完全跑不動(無 GPU + RAM 不夠)
    • ⚠️ 7B Q4 可跑但 ~3-5 t/s,慢到不能互動
    • ✅ Gemma 3 1B-4B 可跑但太弱,agent 任務跑不完

    結論:路徑 1(全雲端)最 fit 我的場景:

    1. 裝 claude-code-router(5 分鐘)
    2. 申請 DeepSeek API(10 分鐘,USD 5 預付)
    3. router config 把 medium / light 全部 route 到 DeepSeek V3.2
    4. Heavy 留給 Claude(Max 訂閱 或 API pay-per-token)
    5. Mini PC 繼續扛 Claude Code + router process,VRAM 無關緊要

    月成本估:USD 15-30(NT$ 500-1,000)。跟新組 RTX 5070 Ti 桌機(NT$ 5 萬)比,4-8 年才回本。所以路徑 1 是我目前最 fit 的路徑 — 不是因為我堅持本地化,是因為「本地化」對我來說是未來的選項,不是現在的剛需。

    真話:不要為了「本地化迷思」花錢,但也不要裸奔

    很多人買 RTX 5090 是為了「資料安全 / 不依賴雲端 / 終究有一天用得到」。實際統計:

    • 「資料安全」→ 99% 場景你的 code 在 GitHub public repo / company 內部 repo,傳給 DeepSeek 沒比較危險
    • 「不依賴雲端」→ 你每天還是上 Stack Overflow、Google 搜文檔,雲端依賴沒消失
    • 「終究會用」→ 通常買了之後跑兩週就放著積灰塵,1 年後折舊損失 30%+

    真正該本地化的場景:商業機密、air-gapped 環境、隱私法規(GDPR / HIPAA)。個人 / 中小團隊 dev workflow 不在這個 list 內

    但「不要過度準備」≠「不準備」。裝 router 是免費的,就算現在全部 route 給 Anthropic,哪天它變心,你只要改 config 就能切。5 分鐘的事,沒理由不做。這才是真正的「未雨綢繆」:架構靈活、邊際成本接近 0,而不是花 20 萬買「萬一」。

    結尾:腦子可以換,工具不能綁架你 — 也不要綁架你家庭預算

    claude-code-router 的真正價值不在「省錢」,是主權。Anthropic 改價、改 ToS、deprecate model,你不用跟著它的節奏走。換腦只是動作,背後是 ownership 的姿勢:你選你信任的模型、你決定路由邏輯、你不被任何單一廠商綁架

    具體建議按你場景:

    • 偶爾用 / 屁股電腦 / 預算 0:路徑 1(全雲端 + DeepSeek API + 5 分鐘 router setup)
    • 想玩本地但不確定會不會堅持:路徑 2(NT$ 1.5 萬二手 RTX 3060)
    • 真認真做本地化 + 有現有桌機:路徑 3(NT$ 5 萬 RTX 5070 Ti)
    • RTX 5090 / Mac Studio Ultra(20+ 萬):除非有商業機密 / air-gapped 需求,否則 6-11 年回本算式不划算,不推

    不為了「本地化迷思」花錢。留錢給你該花的地方 — 可能是更好的螢幕、更好的椅子、家人的長照、孩子的教育、未來的不確定性。Claude Code 是工具,換腦只是技術選擇,你才是 own 自己工作流的人 — 也是 own 自己家庭預算的人

  • Claude Code 訂閱 6/15 拆分:一個 Max 用戶的 evidence-based 評估與本地化反轉

    重點摘要

    • Anthropic 在 2026/6/15 把 Claude 訂閱拆兩半:互動式(終端機 Claude Code、IDE、claude.ai)維持訂閱補貼價,**程式化(Agent SDK、claude -p、GitHub Actions、第三方包裝)移到獨立 metered credit pool**,按 API 全價算。
    • 對「個人坐下來打字 + 派 Agent Team」這種使用方式,**影響幾乎是零**;真正會被打到的是把訂閱接到 Python 程式跑 24 小時 agent army 的套利型用法。
    • 但「字面合法、精神鑽縫」的灰色地帶會持續存在 — Anthropic 隨時可以用 fair use 條款補洞,你不會收到通知。**真正的應對是把 LLM 從 service 變 commodity**:本地優先 + cloud burst 的 gateway 架構。
    • 2026/5 當下的本地 stack 已經追平 frontier:Qwen 3.6-27B 在 agentic coding 上達到「半年前 400B 級」水準,DeepSeek V4-Flash 用 MoE 把 1M context reasoning 壓到 33GB 量化版可跑。**Claude API 從 default 降級成 escape hatch**。

    2026 年 5 月中,Anthropic 連續宣布三波 Claude Code 政策變動。5/6 把 5 小時池額度直接 ×2、Pro/Max 取消尖峰時段;5/13 週池額度 +50%(到 7/13 結束的補貼期);最關鍵的是 5/14 預告、6/15 生效的「訂閱拆分」政策 — 把程式化用量從訂閱補貼池移到獨立 metered credit pool。

    這篇文章是我作為一個 Claude Max 訂閱用戶,用 21 個 transcript 實際 audit + 政策原文交叉比對的 evidence-based 評估。涵蓋:三波變動的精確時間軸、Anthropic 拆分的真實業務動機、不同使用模式落到新政策的具體影響、灰色地帶與真實風險,以及用 Qwen 3.6 + DeepSeek V4 反轉成「本地優先」工作架構的可執行路線。

    三波政策變動的精確時間軸

    2026/5/6 — 5 小時池 ×2、尖峰取消。Claude Code 五小時池對 Pro / Max / Team / 企業版直接加倍。Pro / Max 取消「peak hours」限制。Claude API 的 Tier 1 input tokens 上限 +1500%、output tokens +900%。背景是 Anthropic 跟 SpaceX 簽算力協議,Colossus 1 設施提供 300MW 額外容量、超過 220,000 NVIDIA GPU。

    2026/5/13 — 週池 +50%(臨時加碼到 7/13)。週限額提升 50%,適用於 Pro / Max / Team / Enterprise。這是限定期加碼,7/13 之後會回到原本水準(除非 Anthropic 再續延)。業界解讀是 Anthropic 對抗 OpenAI Codex 搶 agent 市場的動作。

    2026/6/15 — 訂閱拆兩池(真正的結構變動)。訂閱使用從這天起分成兩個池子:

    使用方式 6/15 後歸屬 計費邏輯
    終端機 / IDE 內互動式 Claude Code互動池(訂閱)不變
    claude.ai 網頁 / 桌面 / 手機互動池(訂閱)不變
    Claude Cowork互動池(訂閱)不變
    claude -p 無頭模式Agent SDK Credit Pool按 API 全價
    Claude Code GitHub ActionsAgent SDK Credit Pool按 API 全價
    Claude Agent SDK(Python/TS)Agent SDK Credit Pool按 API 全價
    第三方包裝(OpenClaw / Conductor / Zed / Jean)Agent SDK Credit Pool按 API 全價

    SDK Credit Pool 額度按訂閱方案分配:Pro $20、Max 5x $100、Max 20x $200,Team Standard $20/seat、Team Premium $100/seat。額度不滾存,每月歸零。耗盡後可選擇 enable overage(繼續按 API 全價收費)或 disable overage(請求被 reject)。

    Anthropic 為什麼要拆?

    訂閱政策本來是「個人吃到飽」設計。Anthropic 賭你打字慢、思考慢,$20 一個月吃不爆等值的 API token 量。這個賭注在「個人開發者用 Claude 寫 code」場景下成立 — 一個人類一天寫不了 10 萬行的對話。

    但 Claude Agent SDK + 第三方包裝(OpenClaw、Conductor、Zed、Jean)讓人可以把 $20 訂閱接到自己寫的 Python 程式,24 小時不停跑 agent army,實際 token 量遠超過 $20 等值。等於把吃到飽 buffet 整個載走轉賣 — 訂閱被當成「便宜 API」用於 production 流量。

    Anthropic 沒禁這條路,只是把它改成獨立 metered 預算 — 「載走轉賣」要另外算錢,「個人坐下來吃」不動。順便擋住 OpenAI Codex 用低價搶 agent 市場,也保住 unit economics 才有錢付 SpaceX 那 300MW 算力擴張的帳。

    實際使用模式 audit:21 個 transcript 看出什麼

    政策評估不能憑印象,要有實際使用 evidence。我盤點過去 28 天的 Claude 使用情況:

    • 21 個 transcript / 13 個唯一日期:不是每天用,平均一週 3-4 天
    • 互動式為主:全部 transcript 都是終端機 Claude Code session,不是 SDK / API 程式化呼叫
    • ccbot Telegram bridge:bridging interactive session,不是獨立 inference
    • 5 個 claude-harness-* hook:全是 SessionStart / PostToolUse / PreCompact 注入,在 session 內運行
    • claude-limited cgroup wrapper:也是互動 session 內
    • Agent Team 18-25 並行:從 interactive session 用 Agent tool 派
    • /loop, /schedule, GitHub Actions, 第三方包裝:全沒有
    • crontab 11 條:全是 stock data 收集(analyst / TDCC / 機構投資人),完全不叫 Claude
    • 唯一例外:某個內部 LLM 評估 harness 有一條 subprocess.run(["claude", "-p", ...])

    把這份 audit 對照 6/15 政策表格,結果出奇地簡單:21 個 transcript 裡有 20 條繼續走訂閱池,只有 1 個 evaluation harness 那條 claude -p 會搬到 SDK Credit Pool

    政策真正落到「典型重度使用者」頭上的點

    對於從終端機 / IDE 互動式使用 Claude Code、用 Agent tool 派 subagent、寫 brain / skill / memory 系統的人 — 也就是 Anthropic 設計訂閱時瞄準的客群 — 6/15 變動實質影響趨近於零

    真正被打到的只有四類具體模式:

    1. claude -p 串進 shell pipeline 或 CI/CD:每次 invocation 從訂閱池移到 SDK Credit Pool
    2. 用 Agent SDK 寫的 Python / TypeScript 程式:無頭運行的 production agent,完全脫離訂閱
    3. Claude Code GitHub Actions:CI/CD 整合在 workflow 內呼叫 Claude
    4. 第三方包裝:OpenClaw、Conductor、Zed、Jean 這些把 Claude 訂閱接成 IDE 後端的工具

    如果你已經習慣「人在前面打字,Claude 在後面派 agent 跑」的工作模式,這個政策變動就是 一個不會發生的事件

    灰色地帶:cycle + Agent Team 字面合法但精神鑽縫

    但有一種模式介於兩者之間,Anthropic 官方文件沒明寫:從 interactive session 派出大量 Agent Team,搭配 /loop 或 hook-based cycle 讓 session 自動延續

    技術上這完全合法。6/15 政策字面只點四個對象:claude -p、Agent SDK、GitHub Actions、第三方包裝。「cycle + 大量 Agent Team + 自動啟動循環」如果全部跑在 interactive Claude Code session 裡(用 Agent tool 派、用 /loop 接同 session、用 hook 觸發),技術上會被歸到互動池。

    但這顯然是「字面 vs 精神」的縫。Anthropic 拆這條政策的精神,就是要擋「沒人盯每一回合的大量自動化」 — 第三方分析給出的啟發式是:「if a Claude session runs without a human watching each turn, it is almost certainly moving to the new credit pool」。從這個精神判讀,大規模並行 Agent Team + 自動 cycle 精神上根本就是 programmatic,只是技術上沒被點名。

    兩個現實風險

    風險一:這個縫不會永遠在。Anthropic 看到統計上的 outlier 用戶(Max 訂閱跑出 Tier 4 API 等級的 token 量),下一輪政策補刀的機率不低。半年後可能變「subagent 從 interactive 派也算 programmatic」、或「同 session 自動 cycle 超過 N 次轉計費池」。歷史上 Anthropic 對訂閱濫用模式都是先觀察後動手 — 5/14 這次拆分本身就是這個 pattern 的證據。

    風險二:Fair use 抽象條款隨時可以動你。Terms of Service 寫的「abuse / excessive use」沒精確定義,他們覺得單帳號太誇張就可以單獨 throttle 你帳號,不需要先改政策、不需要事前通知。被點到的人通常只看到「Claude 突然變慢 / 限額變嚴 / 某些 tool 失效」,不會收到正式告知信。

    精確版說法:「字面合法、精神鑽縫、風險押在 Anthropic 不回頭補洞」。在他們補洞之前你賺,補了之後可能在毫無預警的下次續訂看到 SDK credit 開始扣 — 或更早,某一天突然發現自己被限流。

    反轉戰略:從 service 用戶變成 commodity operator

    真正的應對不是「擠到最後一秒用爆」,是 把工作系統的依賴從 Claude 拆出來,讓 LLM 變成可替換的 commodity。這個轉變的本質是反轉預設值:

    層級 現在(service 模式) 反轉後(commodity 模式)
    日常 code / reasoningClaude 預設,本地 fallback本地預設,Claude API 偶爾 burst
    Agent TeamClaude 的 Agent tool本地 orchestrator + 多 model 異質並行
    超長 contextClaude APIQwen 3.6 / DeepSeek V4 / Gemini 三家擇優
    A 級 PII / 客戶名 / 合約本地 7B(品質不夠)本地 70B 級,品質可用且不上雲
    vendor lock-in 風險Anthropic 政策變動 = 工作系統危機改 gateway config 而已

    架構的關鍵是 gateway 抽象層:用 LiteLLM 或自己寫一個薄 wrapper,讓所有 code 對外只看到一個介面 llm.complete(prompt, model_tier="cheap|standard|premium")。底下接什麼模型是 config,不是 code。Claude 政策再變、Anthropic 真的把帳號限流、OpenRouter 出新便宜模型 — 改一個 config 全部換完,所有專案不動。

    2026/5 最新 open weights stack:本地能跑什麼

    2026 中的 open weights 市場已經到「local 27B ≈ 半年前的 frontier closed」階段。對於配備獨顯 + 100GB+ RAM 的工作站,實際可選的本地 stack:

    Qwen 3.6 系列(2026/3-4 發布)

    • Qwen 3.6-27B(dense)— flagship 級 agentic coding,Q4 約 14GB VRAM。官方宣稱超越上一代 Qwen 3.5-397B-A17B,即「27B 在 2026 ≈ 半年前 400B 的水準」
    • Qwen 3.6-35B-A3B(MoE,35B 總參數 / 3B 啟動)— Q4 約 18GB。MoE 設計每次只算 3B 參數所以很快,適合並行 Agent Team
    • Qwen 3.6 Plus / Max-Preview — closed weights API only。Plus 在 Terminal-Bench 2.0 已贏 Claude 4.5 Opus(61.6 vs 59.3),SWE-bench Verified 還小輸(78.8 vs 80.9)。1M context、reasoning 預設。當 cloud burst 比 Anthropic API 更划算

    DeepSeek V4(2026/4/24 發布)

    • V4-Flash:284B 總參數 / 13B 啟動 MoE,完整模型需 ~170GB VRAM,重度量化壓到 33GB VRAM 可跑(2× RTX 4090 或 1× RTX 6000 Ada)
    • V4-Pro:1.6T 總 / 49B 啟動 — 100GB RAM 跑不了,跳過
    • 1M context native,hybrid attention(CSA + HCA)推理 FLOPs 比 V3.2 省 73%
    • 這是「反思 / 跨領域類比」的本地頂配

    Llama 3.3 70B 與其他

    Llama 3.3 70B ecosystem 最大,Q4 約 35GB。不再是 2026 中的首選,但作為「異質 diversity」角色仍有意義 — 同一 task 給不同 model 看,異質訓練資料能產生 outlier insight,單一 model 並行做不到。

    100GB+ RAM 機器的實際配置

    100GB 對 Qwen 3.6 系列來說是過剩配置。所以這台機器的設計目標不是「能跑大 model」,是「多 model 並行讓 Agent Team 有真實 diversity」:

    常駐 hot 在記憶體(同時 load):
    ├── Qwen 3.6-27B  → 主力 code / 對話       (~14GB)
    ├── Qwen 3.6-35B-A3B → 快速 Agent Team 主體 (~18GB,MoE 跑很快)
    ├── DeepSeek V4-Flash 量化版 → reasoning 深度  (~33GB)
    └── Qwen 3.6-7B 之類 → 路由 / 簡單分類     (~5GB)
    總計 ~70GB,留 30GB 給 vLLM cache + OS + agent 並行 context
    
    按需 load(cold,需要時起):
    ├── Llama 3.3 70B Q4 → 異質 diversity 用    (~35GB)
    └── 其他特殊微調 model

    Cloud burst 的新排序

    在 2026 中的市場狀態下,Anthropic API 不再是首選 burst 選項。新排序建議:

    1. Qwen 3.6 Plus API(阿里雲)— 主 burst。超長 context + 一般複雜任務。價格約 Claude Sonnet 的 1/3,Terminal-Bench 已贏 Claude 4.5 Opus
    2. Gemini API(Google)— multimodal / OCR / 大文件處理
    3. DeepSeek V4-Flash API — reasoning 硬 case 沒本地版時的備援
    4. Claude API — 只有「Anthropic 那條 reasoning 風格特別合用」的 edge case 才開,從 default burst 降級成偶爾用一下的特殊風味

    架構全景圖

    把上面所有層拼在一張圖上:應用層 → LiteLLM gateway 路由 → 本地 vLLM(95% 流量)+ Cloud burst(5%)→ 底層 model-agnostic 的 brain / skill / memory data layer。

    APPLICATION LAYER
    Aider · Open WebUI · Custom Agent Orchestrator(walsin/teams 通用化)
    OpenAI-compatible API
    LITELLM GATEWAY
    routing rule = config,不是 code
    task tier backend
    code / chatLOCAL Qwen 3.6-27B
    Agent TeamLOCAL Qwen 3.6-35B-A3B(MoE,快)
    reasoningLOCAL DeepSeek V4-Flash(量化)
    routingLOCAL Qwen 3.6-7B(輕量分流)
    超長 contextCLOUD Qwen 3.6 Plus API(1M ctx)
    multimodalCLOUD Gemini API
    edge reasoningCLOUD DeepSeek V4-Flash API
    特殊風味CLOUD Anthropic API(escape hatch,不是 default)
    LOCAL(~95% 流量)
    vLLM on 100GB+ RAM + GPU
    HOT(同時 load):
    • Qwen 3.6-27B — 14GB
    • Qwen 3.6-35B-A3B(MoE)— 18GB
    • DeepSeek V4-Flash 量化 — 33GB
    • Qwen 3.6-7B 路由 — 5GB
    合計 ~70GB,留 30GB 給 vLLM cache + agent 並行 context
    COLD(按需 load):
    • Llama 3.3 70B — 異質 diversity
    • 特殊 fine-tune
    CLOUD BURST(~5% 流量)
    按 token 計費,非訂閱
    • Qwen 3.6 Plus — 阿里雲(主 burst)
    • Gemini API — Google
    • DeepSeek V4-Flash API
    • Anthropic API — 偶爾用 only
    用途:
    • 超長 context (>32K)
    • 圖片 / OCR
    • 本地解不出來的硬 case
    A 級 PII 絕不出現在這層
    DATA / MEMORY LAYER (model-agnostic,完全不動)
    Brain.md · Skill.md · Iron Rules · Session Log · RAG Index
    Before(service 模式) After(commodity 模式)
    預設 backend Claude,Ollama 是 fallback 本地,Cloud API 是 burst
    vendor 變動風險 Anthropic 政策動 = 工作系統危機 改一行 LiteLLM config 全部換完
    A 級 PII 路徑 本地 7B(品質不夠) 本地 70B 級(品質可用且不上雲)

    這張圖的核心訊息:所有 vendor 都在 gateway 後面,application code 完全不知道下面是誰。Claude 政策再變、Anthropic 真的把帳號限流、阿里雲漲價、Gemini 改 API — 改一個 routing config 全部換完,brain / skill / memory data layer 一行不動。

    軟體 stack 建議

    • vLLM — inference server,提供 OpenAI-compatible API。Code 對外就是 OpenAI 格式,model 可以隨時換
    • LiteLLM — gateway 抽象層。前面接所有 backend(本地 vLLM + Anthropic API + Gemini + Kiro)。Code 只認 LiteLLM,backend 換不換無感
    • Open WebUI 或 Aider — 取代 Claude Code 對話介面的 interactive REPL
    • 自家 agent orchestrator — 不要依賴 Claude 的 Agent tool,自己寫 multi-process 派發。pattern 可以參考開源的 CrewAI、AutoGen,或像我自己有的 ABC 三級分流 evaluation harness 通用化

    過渡期(現在到 6/15)該做的事

    1. 建立 baseline metric:從今天開始每天結束前記錄 claude /usage 截圖或 log 到檔案。沒 baseline,出事時你連「被砍多少」都判斷不出來
    2. 盤點所有 claude -p 用法:grep -rn "claude -p" ~/ 找出來。每一條都是 6/15 後會從訂閱池搬家的成本點
    3. 後備模型 stack cheat sheet:寫一份 1 頁文件「如果 Claude 突然不能用,brainstorming 切去 X、code review 切去 Y、daily 工作切去 Z」。不要等出事才想去哪找
    4. Agent Team 預設規模降到 6-8:18-25 改成「報備使用」。這同時對抗 token 燒速、降低被點為 outlier 的機率,順便逼自己思考「真的需要這麼多視角嗎」
    5. 5/20 到 7/13 是補貼期:互動池 +50% 週限額。這 8 週是 Agent Team 衝刺 / 大規模 refactor 最划算時段

    真的被限流了怎麼辦

    先診斷不要先動作。連 Anthropic console 看是哪一條被扣 — credit pool 被扣 vs 互動池速率變慢是兩個完全不同問題,處理方法不一樣。

    立刻把 hot path 切到備援。Agent Team 規模直接砍半、evaluation 暫停或全切非 Claude 後端、日常工作切 Ollama 本地 + Gemini 雲混合。這幾個動作 1 小時內要能做完,不是出事當下才開始研究。

    正式申訴 + 評估升 Max 20x。如果你判斷被誤分類(明明是 interactive 被當 programmatic),開 ticket 跟 Anthropic 講。同時評估:接下來工作密度有沒有可能升 Max 20x,把 $200/月 credit 當成「事故緩衝」不是「正常用量」。

    結語:訂閱不是 token 額度,是時間窗

    最重要的觀念修正:你訂閱 $100/月給你的不是「token 額度」,是「Anthropic 暫時容忍你這種重度用法的時間窗」。這個窗會關。準備的本質是「窗關了我有沒有別條路」,不是「擠到最後一秒用爆」。

    反轉成本地優先 + cloud burst 的真正好處,不是省那 $100/月,是 把 LLM 從 service 變成 commodity。你不再是 Anthropic 的 user、Google 的 user、阿里雲的 user,你是一個有自己 stack 的 operator。任何一家政策變、漲價、限流、倒閉,你都只需要改一個 config。

    對 2026 中要進企業環境推 LLM 的人來說,這個論述也是直接合規上的加分 — 集團真實場景就是要 A 級 PII 不上雲、不能綁單一 vendor、不能讓核心評估綁在個人帳號上。本地優先架構直接符合這三條,不需要為了合規綁手綁腳。

    Anthropic 6/15 拆分對「個人坐下來用」這群人是非事件。但它送出的訊號很清楚:訂閱補貼的時代正在收窄,LLM 市場往真實計費走。早一步做反轉的人,不是因為政策才動 — 是因為看到方向,提早把脆弱性拿掉。

  • 腦子系統 7-prompt 驗證篇:routing 跟 sanitize 真的會做事嗎

    這篇要解決一個很具體的問題:企業要把 LLM 接進工作流,但客戶資料不能上雲、員工資料要脫敏後才能上雲、純技術問題可以直接上雲——誰來判斷哪條 prompt 屬於哪一級,以及這套判斷可不可信。本文記錄了從 v1 到 v8 兩天 8 個 commit 的完整驗證過程:做一個本地 LLM 驗證 harness,12 條 prompt 跑 routing + sanitize + worker 三階段,驗到 routing 12/12、worker reasoning 9/12,順手抓到兩個沒人警告過的漏洞——ccbot 反客為主、以及本地 LLM 在 response 裡 verbatim 複述原 PII / API key 的二次洩漏。

    重點摘要

    • 做什麼:本地 LLM 驗證 harness,把 prompt 分 ABC 三級(A 客戶/PII → 本地、B 內部代號 → 脫敏後上雲、C 純技術 → 直接上雲),12 條 prompt 跑完整 pipeline 驗證
    • 怎麼做:三階段 pipeline——judge 用本地 LLM 分級 → sanitize regex 替換敏感詞 → worker 真做事;每條 prompt 加 expected_keywords,response 比對 ≥30% hit 算過關
    • 為什麼:routing 是 defense in depth 第一層門禁,沒人擋的話客戶名直接被當技術問題上雲;本地 judge 必要,因為 A 級資料連「分類」這個動作都不能上雲
    • Prompt vs 本地 model:15 顆 model × 12 prompt 跑出來——size 不是 axis,prompt-stability 才是;thinking model + Ollama JSON 架構級不相容,全 0/12;-nothink 後綴騙人;qwen3-nothink + qwen2.5:7b 兩顆滿分
    • ccbot 意外:在 ccbot Telegram session 內叫 CC 跑驗證,子 claude -p 寫的 PostgreSQL 健檢稿漏進父 ccbot 視窗,反客為主蓋掉用戶的方法論討論。修法是雙保險:stdio 隔離 + 環境偵測 short-circuit
    • v8 補洞 + 新發現:4 個 hole 全修(routing 11/12 → 12/12、cross_team CLI baseline 建立、judge 改 qwen2.5:7b 跟 worker 交叉、forbidden_keywords 抓反向洩漏);新發現「routing 對 ≠ worker 不洩漏」——qwen3-nothink 本地 worker 會在 response 裡 verbatim 寫回原 PII / API key,留 v9 用「output 也跑 sanitize」對稱性原則修

    一、在做什麼:給 LLM 工作流加一道「資料分級」前門

    企業導入 LLM 第一個踩到的雷是資料治理。同樣是「請幫忙處理一下」,客戶投訴不能跟 OpenAI 講、員工 review 可以脫敏後問,但純技術問題(Kafka rebalance 怎麼解)直接打雲端 API 最快。沒有分級機制,要嘛全本地(成本爆炸 + 質量差)、要嘛全雲端(資料外洩 + 法遵爆炸)。

    所以這套 harness 的工作目標只有一個:每條 prompt 進來自動分級,並驗證這個分級正確、後續處理也對。三層定義:

    級別 特徵 處理方式 範例
    A 真實客戶名 / PII / credentials 本地 LLM 處理,連分類都不上雲 「客戶 A123456789 反映…」
    B 內部代號 / 員工名 sanitize 替換成 placeholder 再上雲 「[employee_alice] 寫的 5 個模組…」
    C 純技術 / 公開知識 直接上雲,可派 Kiro / Claude Code 並行 「Kafka consumer rebalance 怎麼解?」

    驗證集 12 條 prompt(prompts.py:PROMPTS_V7_ABC):7 條 happy path 覆蓋 A/B/C × team/cross 笛卡兒角落,5 條 adversarial 壓邊界(PII override、ambiguous team、camouflage api key、隱式 cross_tool、嵌套客戶名)。

    二、怎麼做:三階段 pipeline + keyword eval

    2.1 三階段 pipeline

    prompt → [Stage 1: Judge]    分 ABC 級 + need_team + cross_tool
           → [Stage 2: Sanitize] B 級替換內部代號為 placeholder
           → [Stage 3: Worker]   按級別分派
                                  A → worker_local_real (Ollama 本地推理)
                                  B → kiro CLI (sanitize 後)
                                  C → kiro CLI 直接打
                                  C+team → ThreadPoolExecutor 並行
                                  C+team+cross → Kiro × N + Claude × M 混編

    2.2 Judge 用本地 LLM(Ollama)

    Judge 是整個 harness 最關鍵的一層——它判斷一條 prompt 屬於哪一級,只要它判錯,defense 整個垮。所以 judge 必須:

    • 本地跑:不能把 prompt 送雲端去問「這條 prompt 含 PII 嗎」——因為光送過去就洩了
    • 強制 JSON 輸出:Ollama format=json,規範回傳 {"level": "A", "need_team": false, "cross_tool": false}
    • System prompt 含 few-shot:純規則對小模型沒用,要附 4 個 input/output 對偶範例(覆蓋 A/B/C × team/cross 角落),模型才會把規則當回事

    2.3 Sanitize 用 regex(6 類 pattern)

    # sanitize.py 簡化示意
    PATTERNS = [
        (r'\[client_\w+\]',     '[CLIENT_REDACTED]'),    # 客戶代號
        (r'\[employee_\w+\]',   '[EMPLOYEE_REDACTED]'),  # 員工名
        (r'\[internal_\w+\]',   '[INTERNAL_REDACTED]'),  # 內部代號
        (r'sk-[A-Za-z0-9_-]+',  '[api_key]'),            # API key
        (r'\b\d{3}-\d{3,4}-\d{4}\b', '[phone]'),         # 台灣手機
        (r'\b[A-Z]\d{9}\b',     '[tw_id]'),              # 台灣身分證
    ]

    sanitize 是 B 級的本分,但也是 A 級的補強——judge 萬一漏判 A 級成 C 級,sanitize 還能擋一刀(token 不會流出去)。defense in depth 兩層獨立。

    2.4 Worker 真做事 + keyword eval

    v3-v6 的 worker 全是 stub:worker_local_skip() 回字面字串「[A 級本地處理] 會 spawn…」、worker_kiro() 回「OK 收到」。意思是滿分等於通過 routing 考卷,不等於這個系統會幹活。v7 把 worker 改真:

    • worker_local_real:HTTP 打 http://localhost:11434/api/chat,用 qwen3-nothink 真推理
    • worker_kiro:subprocess kiro-cli chat,抓最後 3000 字當 response
    • worker_cross_team:ThreadPoolExecutor 真並行,3 facet 派 Kiro + 1 facet 派 Claude,結果合併

    每條 prompt 加 expected_keywords 列表,response 比對 ≥30% hit 才算 reasoning_passedall_correct = routing_correct AND reasoning_passed——兩條軸都對才算這條 prompt 真的成功。

    三、為什麼用這個方法

    四個設計選擇,每個都有對應的失敗情境:

    設計 替代方案 為什麼選這個
    本地 LLM 當 judge 雲端 LLM 判定 + 留 audit log A 級資料連「請判斷這條算什麼級」這個動作都不能傳出去——光問就洩
    judge + sanitize 兩層 只用 LLM judge,信任它分對 defense in depth:judge 失誤時 sanitize 兜底,兩層獨立失誤率相乘
    expected_keywords ≥30% hit 人工標 ground-truth + 拿 LLM 評分 v3-v6 沒有自動評分,worker 全是 stub 也驗不出來;30% 拍腦袋,但有比沒有強
    12 條 prompt(7 + 5 adv) 100 條 ground-truth 大集 驗證集大不一定強——關鍵是覆蓋角落 case + 30% adversarial。沒 adversarial 的 benchmark 會給你錯覺,gemma2:2b 看 happy path 5/5 完美,加 adversarial 立刻崩到 0/7

    四、Prompt 跟本地模型的測試情況

    這節是整篇技術重點——15 顆本地 model × 12 prompt 跑出來的對照,直接決定 production 配置。

    4.1 完整對照表

    Tier Model Size All correct Avg latency 用途
    1 滿分 qwen3-nothink:latest 2.5GB 12/12 7.4s PRIMARY
    1 滿分 qwen2.5:7b 4.7GB 12/12 11.8s FALLBACK
    2 qwen2.5:3b 1.9GB 9/12 7.4s LATENCY
    3 qwen2.5:0.5b 397MB 7/12 4.9s ⚡ EXTREME
    4 跨家族 phi3.5、llama3.2:3b、gemma2:2b 1.6-3.8GB 6/12 5.7-9.6s marginal
    5 全死 qwen3:4b/14b、qwen3.5:4b/9b、qwen35-9b-nothink、gemma4:e4b 2.5-9.6GB 0/12 14-104s REJECT
    5 OOM llama3.3:latest 42GB 0/12 HTTP 500 REJECT

    4.2 四條歸納

    1. Size 不是 axis,prompt-stability 才是。0.5b → 3b → 7b 一條乾淨單調曲線(7→9→12),但 7b vs 14b thinking 完全反向(12 vs 0)。size 跟 accuracy 沒有單調關係,真正分水嶺是「對 prompt 變動穩不穩」。
    2. Thinking model + Ollama JSON 架構級不相容。6 顆 thinking model 加 few-shot 仍然 0/12 → 不是調 prompt 能救,是模型走 reasoning chain 時把 num_predict budget 燒在 <think> tag,還沒輸出 JSON 就被截斷。
    3. -nothink 後綴騙人qwen35-9b-nothink:latest 仍然 0/12,跟其他 thinking model 同表現,後綴只是 Ollama tag 名稱不是真正關了 thinking。新 model 必須跑 30 秒 smoke test 才知道。
    4. VRAM 跌出 → 災難。size > ~7GB 在 16GB RAM 機器上會丟出 GPU,qwen3:14b 41s/call、gemma4:e4b 104s/call。可用上限約等於「VRAM – 1.5GB」。

    4.3 Few-shot 是怎麼救活跨家族 small instruct 的

    v3 一開始觀察到 phi3.5 / llama3.2:3b / gemma2:2b 全死在 level——3 個不同家族同時死在同一個地方,本能歸因到「small instruct safety bias」。後來重新驗,把 system prompt 從純規則改成「規則 + 4 個範例」(few-shot in system prompt),結果:

    Model 純規則 + few-shot Δ
    qwen3-nothink:latest10/1212/12+2
    qwen2.5:7b5/1212/12+7
    phi3.5:latest1/126/12+5
    llama3.2:3b2/126/12+4
    gemma2:2b5/126/12+1

    真實結論:純規則對小模型是可忽略的 boilerplate;規則 + 範例才會被當成必須對齊的 anchor。所以 size 不是 axis 這件事的另一半是:prompt 工程裡「有沒有 grounding example」才是真 axis。

    4.4 新模型來時怎麼判斷能不能用

    不要每顆都跑全套 30 分鐘。把 trait 抽出來變 5 步驟 checklist(tools/check_new_model.py):

    1. Stage 0 30 秒 smoke:輸出 {"ok":true} → 失敗直接淘汰,不跑下去
    2. Stage 1 看 model card:base/pretrained 跳過,要 instruct/chat 標籤
    3. Stage 2 12-prompt full suite:< 7/12 reject、7-11 marginal、12/12 production candidate
    4. Stage 3 n=3 一致性:同一條 prompt 跑三次 level 都一致才算穩
    5. Stage 4 PII adversarial:5 條藏 PII 進技術句,要 100% 抓 A 級

    五、結論被推翻三次:差異在哪

    整個工作從 v1 到 v8 兩天 8 commits 推翻三次結論又補了一輪洞。差異:

    版本 當時主張 後來被翻成
    v3(overnight benchmark) 「只有 qwen3-nothink 唯一可用,7B+ qwen2.5 危險會洩客戶資料,size 不是 axis」 v4 翻盤:7B+ qwen 都行,危險是 prompt 沒範例造成,fallback 三層全有
    v4(few-shot breakthrough) 「qwen3-nothink 12/12 滿分,prompt-stability 是真 axis」 v5 戳破:12/12 是 routing 滿分,worker 一次都沒真做事
    v7(end-to-end + ccbot fix) 「routing 對不等於 worker 對等,worker reasoning 9/12 才是真實水準」 v8 部分修正:routing 12/12 完成,但又翻出新軸——worker output 自己會 echo PII
    v8(holes fixed + PII echo) 「sanitize 前置 + judge 交叉 + forbidden_keywords + cross_team baseline 4 個 hole 補完」 新發現:routing 對不等於不洩漏——本地 LLM 自己會 verbatim 複述 PII,留 v9 補 worker output sanitize

    四次推翻的共同 pattern:結論被翻不是因為跑得不夠,是因為跑的東西不夠多軸。v3 只看 routing,v4 只看 routing+prompt 變動,v7 把 worker reasoning 拉進來,v8 加 forbidden_keywords 才看到 worker 自己會洩漏。每多一個軸就翻一次,翻到沒得翻為止

    六、ccbot 反客為主意外

    6.1 症狀

    用戶在 ccbot Telegram session 跟 CC(Claude Code)討論 v7 方法論,中途叫 CC 跑驗證。下一秒 ccbot 視窗開始印一篇完整的 PostgreSQL 健檢文:pg_dump --schema-only、SchemaSpy、postgres_autodoc、obj_description(attrelid, attnum)pg_settings WHERE source <> 'default'pgbackrest info + patronictl list、SchemaSpy + dbdocs.io + Atlas…

    用戶看了打字框問:「明明在討論方法論,結果你突然 PRINT 一篇 PGSQL,反客為主?」

    6.2 追根因

    對照前一次 v7 跑(run_v7_20260504_123811)的 02_pipeline_v7.json,prompt 07 cross_teamdocumentation facet 輸出**字面跟用戶 ccbot 看到的內容一字不差**。所以那段 PGSQL 不是父 CC 自己生成,是子 claude -p 為驗證集 prompt 07 documentation facet 寫的稿——但它怎麼漏到父 ccbot TG 訊息流?

    v7 既有 workers.pytmpfile + start_new_session + stdin=DEVNULL fix 註解寫:「avoids deadlocking parent session’s stdin/stdout」。但這只擋了「子進程跟父 CC 之間的 stdio 競爭」(deadlock 來源),沒擋住:

    1. claude -p 寫的 PG 稿 → tmpfile
    2. 父 orchestrator 讀 tmpfile,塞進 worker_cross_team result 的 response 欄位
    3. 父 orchestrator 把整個 result 印到 stdout / 回給呼叫端
    4. 父 CC 看到 stdout,覺得「我跑完了,把結果報告給用戶」→ 印到 ccbot TG
    5. 用戶眼睛裡:剛剛還在討論方法論,下一秒視窗變成 PG 健檢手冊

    L1 防線(stdio 隔離)解的是 stdio 競爭,沒解 output 內容被 relay。要加 L2 防線。

    6.3 修法雙保險

    先找 ccbot session 的可靠 marker:

    $ env | grep -i ccbot
    MEMORY_PRESSURE_WATCH=/sys/fs/cgroup/user.slice/user-1000.slice/
      [email protected]/app.slice/ccbot.service/memory.pressure

    ccbot.service systemd cgroup 會 set MEMORY_PRESSURE_WATCH,任何子進程都繼承——包括 ccbot fork 出來的 CC、CC fork 出來的 orchestrator、orchestrator fork 出來的 claude -p。完美 marker。修法:

    def _running_inside_ccbot() -> bool:
        """Override:
          WALSIN_FORCE_CC_WORKER=1  -> force enable
          WALSIN_FORCE_CC_WORKER=0  -> force disable
        """
        override = os.environ.get("WALSIN_FORCE_CC_WORKER")
        if override == "1": return False
        if override == "0": return True
        return "ccbot" in os.environ.get("MEMORY_PRESSURE_WATCH", "")
    
    
    def worker_claude(prompt, timeout=120):
        if _running_inside_ccbot():
            return {"tool": "claude",
                    "response": "[SKIPPED: running inside ccbot — "
                                "`claude -p` output would leak into parent TG. "
                                "Set WALSIN_FORCE_CC_WORKER=1 to override.]",
                    "latency_ms": 0, "exit_code": 0, "skipped": True}
        # ... 原本的 Popen + tmpfile 邏輯

    6.4 驗證:fix 有用且沒破壞 cross_team 可驗證性

    修完跑 prompt 07 cross_team 的 4 個 facet:

    facet tool skipped latency 證據
    securitykiroFalse12911ms真 PG security 答案
    testingkiroFalse8466ms真 PG testing 答案
    performanceclaudeTrue0ms[SKIPPED: ...]
    documentationclaudeTrue0ms[SKIPPED: ...]

    沒漏 PG 內容。reasoning_passed=True(62.5% hit)——kiro 兩個 facet 已經自然涵蓋足夠 PostgreSQL 關鍵字(pg_statreplicabackupWALindex),L2 防線 short-circuit 沒破壞 cross_team 可驗證性。

    注意這個 trade-off:L2 防線只在 ccbot 內生效。獨立 CLI 跑 WALSIN_FORCE_CC_WORKER=1 python3 orchestrator_v7.py 會放行 claude -p,完整 4 facet 都實跑——這才是「真要驗 cross_team 跨工具質量」的 baseline。本次跑因為在 ccbot 內,只算「ccbot 安全模式驗證」,完整 cross_team 留 v8 在獨立環境補。

    七、v8 補洞 + 抓到 v7 看不到的新漏洞

    v7 結尾留了 5 個洞,本輪一次解 4 個,順手抓到一個 v7 完全看不到的新類別漏洞。

    7.1 4 個 hole 修法

    # Hole 修法 驗證
    1 🔴#12 API key routing failsanitize.has_a_level_pii() 前置 gate,regex 命中強制 level=Arouting 11/12 → 12/12
    2 🔴cross_team CLI baseline 沒驗WALSIN_FORCE_CC_WORKER=1 讓 claude facet 真 fork(L1 stdio fix 還在兜底)#07 reasoning 62% → 88%
    3 🟡judge / PRIMARY 同一顆 qwen3-nothinkJUDGE_MODEL = "qwen2.5:7b",跟 worker 兩個世代交叉獨立性建立 ✅
    4 🟡30% 閾值沒抓反向洩漏每條 prompt 加 forbidden_keywords + per-prompt pass_threshold立刻紅了 #11 + #12 ⚠️

    7.2 v7 vs v8 跑分對比

    指標 v7 v8
    Routing correct11/1212/12
    Reasoning passed9/129/12
    ALL correct9/129/12

    ALL 沒變的原因:routing 多修對 1 條(#12)、reasoning 多失敗 1 條(#11 被 forbidden_keywords 抓到 PII leak)→ 互相抵消。但這個抵消是好事:v8 多抓的那個 fail 是真實 production 問題,v7 的「pass」是因為沒檢查所以沒看到。

    7.3 新發現:worker PII echo(routing 對 ≠ 不洩漏)

    forbidden_keywords 後,#11 + #12 立刻紅:

    [11_adv_tw_pii] level=A -> local_real (111691ms) reasoning=0.375
      hits=['log', 'session', '排查']
      LEAK=['A123456789', '0912-345-678'] x
    
    [12_adv_api_key] level=A -> local_real (115094ms) reasoning=0.125
      hits=['401']
      LEAK=['sk-test-abc123def456ghi789jkl'] x

    兩條都是 routing 對(level=A,本地處理),worker 也走對,但 worker 寫的 200 字 response 整段把原 PII / API key verbatim 重複出來。qwen3-nothink 在排查方向裡寫了類似「客戶 A123456789 反映…」「token sk-test-… 看起來像…」這種句子。

    意義:routing 的 A 級保護是「prompt 不上雲」,但 worker 寫出來的 response 還是會被印 log、塞 ccbot relay、走 webhook 給下游 → 從第二條路洩出去。Defense in depth 的第三層(worker 自我審查)還沒做。

    v7 為什麼看不到:v7 reasoning eval 只看正向 expected_keywords(該寫什麼),沒有反向 forbidden_keywords(絕對不能寫什麼)。回應只要寫對技術方向就 pass,模型有沒有複述 PII 完全不檢查。

    修法路徑(留 v9):defense in depth 第三層——對稱性原則,input 過 sanitize,output 也要過 sanitize。實作:worker_local_real() 在 return 前把 response 也送進 sanitize(),有 PII pattern 命中就替換成 placeholder。即使 LLM 複述 PII,輸出層也會擋。

    7.4 v9 還沒補完的 5 個洞(誠實清單)

    1. 🔴 worker PII echo(本輪新發現,留 v9 用「output sanitize」對稱性原則修)
    2. 🟡 #04 5 模組 review reasoning fail(kiro 沒程式碼可看就拒答,是 prompt 設計問題不是 worker)
    3. 🟡 30% threshold 仍未個別 calibrate(per-prompt 機制已支援,但實際每條的 threshold 沒個別調過)
    4. 🟢 跨家族 12/12 樣本不足(mistral-7b / yi-1.5 沒下載)
    5. 🟢 judge p99 latency(qwen2.5:7b 平均 8s,#01 偶發 56s,看是不是 cold start)

    給跟著做的人三條提醒

    1. Routing 滿分不要爽到忘了驗 worker。v3-v6 routing 滿分但 worker 全是 stub,直到 v7 加 expected_keywords 才看到 9/12 真實水準。reasoning eval 不必很完美(30% 閾值就有用),但有比沒有強得多
    2. 在 LLM agent 內 fork 同類 LLM,環境隔離不能只靠 stdio。要 env-marker double-gate(L1 stdio + L2 環境偵測 short-circuit),否則子寫的稿會回流到父的對話視窗。任何「Claude Code fork Claude Code」「ChatGPT plugin call ChatGPT」這種設計都要警惕。
    3. -nothink 後綴騙人,size 不是 axisqwen35-9b-nothink:latest 跟其他 thinking model 同樣 0/12。新 model 來請跑 tools/check_new_model.py 30 秒 smoke + 12-prompt full,不要看 model card 標籤就決定收進候選池。
    4. 對稱性原則:input 過 sanitize,output 也要過 sanitize。即使 routing 100% 對、prompt 沒上雲,本地 LLM 自己會 verbatim 複述 PII / API key 在 response 裡——response 一旦被印 log、寄 ticket、走 webhook 就二次洩漏。Reasoning eval 必須加 forbidden_keywords 反向檢查,worker return 前也要再過一次 sanitize。

    原始素材

    更新時間:2026-05-04 14:30(整合 v1 → v7 兩天 7 commits 重新編排)

  • 腦子系統小白指南:10 步驟從零做到完整 AI 工作流

    重點摘要(TL;DR)

    • 前 9 篇是給做過的人看的設計 / 實作 / 修補。本篇是給「沒做過、想做到那樣」的人 — 10 步驟從零到 v2.3 完整工作流。
    • 10 步驟:裝 CC → 寫 CLAUDE.md → 開始 brain → spawn 1 agent → Agent Team 並行 → 行動端 → 加分級 → Gateway → Ollama → 完整 v2.3。每一步都能單獨用,合起來變成完整體系。
    • 不需要一次做完。每一步停下來都能用,不會卡死。Step 1-3 是 1 週體感巨變,Step 4-6 是 Agent Team 開花,Step 7-10 是資安升級。
    • 不是寫程式 tutorial,是工作流改造指南。每一步都跟你怎麼做事的方式有關 — brain 改你「怎麼累積知識」、Agent Team 改你「怎麼處理複雜任務」、Gateway 改你「怎麼處理敏感資料」。
    • 本文是腦子系統第 10 篇 / 入門篇。前 9 篇連結在文末。

    誰該讀這篇

    • 有寫 code / 用 terminal 經驗,但沒系統性用過 AI 工作流
    • 看過前面 9 篇覺得有道理,但不知道從哪開始
    • 想做出完整 AI 工作流(腦子 + Agent Team + 跨平台 + 資安),不只是聊天用 ChatGPT
    • 願意花 1-3 個月漸進改造,不追求一週搞定

    不該讀這篇:完全沒寫過 code、沒用過 terminal — 那需要先補基礎(git / shell / markdown)。

    終點長什麼樣(預覽)

    10 步驟全部做完後,你的日常工作流會變成:

    你 (Claude Code) — 設了 ANTHROPIC_BASE_URL → Gateway
       ├─ 普通 prompt → Gateway 看分級 → cloud / 地端 自動路由
       ├─ Spawn Agent Team(7 個 opus 並行)→ 每個 agent 走 Gateway,獨立分級
       ├─ 寫到敏感字 → 自動切地端,cloud 流量歸零
       └─ 行動端透過 ccbot / Telegram → 同樣經 Gateway
    
    旁邊 brain 系統(~/.claude/projects/.../memory/)
       ├─ 全域規則 CLAUDE.md(自動載)
       ├─ 領域 brain markdown(LLM 看了知道踩過什麼坑)
       └─ 每個 brain 有 sensitivity_level: A/B/C
           └─ Gateway 自動同步字典做路由
    

    實際感受:

    • 寫 code 比以前快 3-5 倍(LLM 看過你 brain 不會犯重複錯)
    • 複雜任務不用親自跑,7 個 agent 平行做,你 review 結果
    • 不再擔心客戶資料貼進 ChatGPT(地端自動接管)
    • 離開電腦也能繼續(手機 LINE / Telegram → ccbot → 你的工作流)

    10 步驟總覽

    Step 做什麼 時間 階段體感
    1裝 Claude Code(或 Cursor / Continue)30 分鐘能跟 LLM 對話寫 code
    2寫第一份 CLAUDE.md(規則層)30 分鐘LLM 開始遵守你的習慣
    3建立 brain markdown(知識層)1 週累積不再講同樣的話兩次
    4Spawn 1 個 agent(Agent Team 入門)1 小時學會把工作 delegate
    5多 agent 並行(Agent Team 進階)1 小時同時跑 7 個任務
    6行動端通訊(ccbot / 官方 channel)1 小時手機也能繼續工作流
    7加 sensitivity_level 分級(資安 1)30 分鐘brain 開始分敏感度
    8裝 Gateway(資安 2)30 分鐘prompt 自動分流
    9加 Ollama 地端(資安 3)1 小時A 級資料永不上雲
    10完整 v2.3(B 級脫敏 + tests)半天production-ready

    關鍵:不要連續做完。Step 1-3 做完跑 1-2 週,習慣後再做 4-6,習慣後再做 7-10。跳級會崩潰

    Step 1:裝 Claude Code

    Claude Code(以下簡稱 CC)是 Anthropic 官方的 terminal AI coding 工具。也可選 Cursor、Continue、OpenCode 等替代品 — 概念一樣,本文以 CC 示範。

    # macOS / Linux,需要 Node 18+
    npm install -g @anthropic-ai/claude-code
    
    # 登入(用 Anthropic 帳號 OAuth 或 API key)
    claude
    
    # 在某個專案資料夾跑
    cd ~/your-project
    claude

    其他工具的安裝請查官方 docs:Claude Code Quickstart / Cursor / Continue / OpenCode

    第一個 prompt 試試:

    $ claude
    > 看一下這個專案的 README,告訴我是做什麼的

    能讀檔、回應 — 你已經在 step 1。跑幾天感受 LLM 怎麼讀你的 codebase

    Step 2:寫第一份 CLAUDE.md(規則層)

    CC 會自動讀你 home 目錄下的 ~/.claude/CLAUDE.md(全域規則)+ 專案根目錄的 ./CLAUDE.md(專案特定)。這就是「腦子」第一層。

    # 寫第一份(全域)
    mkdir -p ~/.claude
    cat > ~/.claude/CLAUDE.md << 'EOF'
    # 全域規則
    
    ## 我的習慣
    - 一律用繁體中文回應
    - code 不寫超過必要的註解
    - commit message 用 feat: / fix: / docs: prefix
    
    ## 我的環境
    - macOS / Linux mini PC
    - Python 3.12 / Node 20
    
    ## 不要做的事
    - 不要主動 git commit(等我說才 commit)
    - 不要安裝 dev dependency 沒問過
    EOF

    馬上感受差別:重啟 CC,再問同樣問題,LLM 已經會用中文回 + 不會自作主張 commit。這就是規則層的價值 — 你不用每次重複講

    原則:條目少而精,3-10 條最好。寫 30 條沒人記得住(包括 LLM)。

    Step 3:開始寫 brain markdown(知識層)

    規則是「你想要什麼」。Brain 是「你踩過什麼坑」。

    mkdir -p ~/.claude/projects/your-project/memory/brain

    第一份 brain 範例(假設你寫過 Kafka 踩過坑):

    cat > ~/.claude/projects/your-project/memory/brain/kafka.md << 'EOF'
    ---
    name: kafka
    type: technical
    ---
    # Kafka 我踩過的坑
    
    ## consumer rebalance 一直跑
    - 症狀:consumer group 每隔幾分鐘 rebalance,訊息處理停頓 30 秒
    - 原因:max.poll.interval.ms 預設 5 分鐘,業務邏輯處理超過會觸發
    - 解法:max.poll.interval.ms 拉到 15 分鐘 + 業務邏輯拆 batch
    
    ## 訊息順序錯亂
    - 同一個 partition 才保證順序
    - 多 partition 一定要設 partition key(預設 hash key)
    EOF

    更新 CLAUDE.md 引用 brain:

    echo "
    ## Domain Brain
    - [Kafka](projects/your-project/memory/brain/kafka.md)
    " >> ~/.claude/CLAUDE.md

    累積策略(關鍵):每次踩坑後 5 分鐘寫進對應 brain。不要等月底整理一次 — 那永遠不會發生。

    1 週後感受:LLM 開始知道「Kafka 你不會犯哪些錯」「OSGi 你踩過哪些雷」。同樣 prompt 一個月前要解釋 5 分鐘,現在 LLM 直接 hit brain 給對的答案

    Step 4:Spawn 一個 agent(Agent Team 入門)

    到這步你已經會用 LLM 寫 code + 累積 brain。下一個跨越:讓 LLM 派出小弟做事

    CC 內建 Agent tool。在 CC 裡:

    > 派一個 agent 看 ~/myproject/src/ 底下所有 .py 檔,
      找出沒寫 type hint 的函式,列清單給我

    CC 會 spawn 一個 sub-agent,sub-agent 自己跑 grep / read,跑完回報。你不用看那 100 個檔

    啟發點:任何「我想做但要花 1-2 小時看資料的事」都可以 delegate。你變成 manager,不是 doer

    Step 5:多 agent 並行(Agent Team 進階)

    真正威力:並行 spawn 多個 agent

    > 同時派 7 個 agent:
       1. agent A: review 我新寫的 OAuth 模組安全
       2. agent B: 看 .github/workflows 有沒有 CI 改進空間
       3. agent C: 找 README 跟實際 code 不一致的地方
       4. agent D: 算這個 codebase 的 test coverage
       5. agent E: 看 dependencies 有沒有過期
       6. agent F: 列所有 TODO 註解
       7. agent G: 找硬編碼的密碼 / token
    
    7 個並行,2 分鐘後給我一份 dashboard

    CC 會用 Agent tool 並行 spawn 7 個,各自獨立 context、各自查資料、回報。這是傳統工作流不可能做到的

    記憶體規則:LLM 推理在 cloud,本機跑的是 CC sub-agent process 本身。粗估每個 opus agent ~1 GB / sonnet ~600 MB / haiku ~400 MB,7 個 opus 並行 ~7 GB,先 free -h 確認 available 夠 +2 GB buffer。16 GB 機器跑得動但要關掉其他大耗 RAM 程式,32 GB 比較舒服。
    真正吃 RAM 的是本地 LLM:Step 9 的 Ollama 跑 14b 模型要 ~10 GB,跟 sub-agent process 加起來才是負載 — 16 GB 機器若同時跑 7 個 opus agent + Ollama 14b 會 swap 重災,建議改 7b 級模型或升級到 32 GB+。

    Step 6:行動端通訊(ccbot / 官方 channel)

    到這步你已經是 desktop power user。下一步:離開電腦也能繼續工作流

    兩個選項:

    • 官方 channel(2026/3 Anthropic 推出):MCP server 接 Telegram / Discord / iMessage,設定簡單。官方文件
    • ccbot(six-ddc/ccbot):Telegram 接 tmux,decouple from SDK,1 個 Telegram topic = 1 個 tmux window = 1 個 CC session

    ccbot 安裝:依官方 README(因為安裝方式可能更新)— https://github.com/six-ddc/ccbot。流程大致是:

    1. 去 Telegram @BotFather 申請 bot token + 開 Threaded Mode
    2. 依 README 用 uv tool installpipx install 裝 ccbot
    3. TELEGRAM_BOT_TOKEN + ALLOWED_USERS 環境變數
    4. 裝 hook 讓 CC tmux session 自動連 Telegram

    官方 channel 安裝(2026/3 Anthropic 推出):依 Claude Code Channels 官方文件,設定更簡單,但只支援 Anthropic 官方 endpoint。

    感受:通勤路上想到 bug,Telegram 一句話 → ccbot → 桌機 CC 開始跑 → 你下車回家結果已在。
    (ccbot 限 Telegram;若用 LINE,需自己寫 LINE bot bridge,或改用官方 channel 接 iMessage / Discord)

    Step 7:加 sensitivity_level 分級(資安第 1 道)

    到這步你 brain 累積了不少。但有些 brain 含敏感資訊(客戶名、家裡網路、內部專案代號)。一旦 LLM 走 cloud,這些就送出去了。

    第一道防線:brain frontmatter 標 sensitivity_level

    # brain/kafka.md(技術知識,公開可用)
    ---
    name: kafka
    type: technical
    sensitivity_level: C   # 純技術,可上 cloud
    ---
    
    # brain/client_alpha_oncall.md(客戶資料)
    ---
    name: client_alpha_oncall
    type: business_incident
    sensitivity_level: A   # A 級,絕對不上 cloud
    ---

    分級原則:

    • A 級:洩漏會出事(客戶名 / 家裡 IP / 個資 / 合約 / 配方)
    • B 級:能脫敏後送 cloud(內部 process 名 / 員工名)
    • C 級:純技術 / 開源 / 公開知識

    這步看起來只是改 frontmatter,但 讓你開始用「分級」眼光看資訊,為下一步 Gateway 鋪路。

    (Step 8 後回來做)從 brain 自動同步到 Gateway 字典

    等 Step 8 把 Gateway clone 下來後,回頭做這個同步,讓 brain 跟 Gateway 用一份字典:

    # 從所有 A 級 brain 抽 placeholder(例 [client_xxx] / [project_xxx])
    grep -h "sensitivity_level: A" -A 100 ~/.claude/projects/*/memory/brain/*.md \
      | grep -oP '\[client_\w+\]|\[project_\w+\]|\[employee_\w+\]' \
      | sort -u > ~/walsin-gateway/A_keywords.txt
    
    # 改 gateway_v2_cc.py 的 A_KEYWORDS list 從檔案 load:
    #   A_KEYWORDS = open(os.path.expanduser("~/walsin-gateway/A_keywords.txt")).read().splitlines()
    # 取代原本 hardcoded 的 ["[client_alpha]", ...]

    核心想法:一個 sensitivity_level 欄位,brain 跟 Gateway 兩邊都用 — 不用手動維護兩套字典。

    Step 8:裝 Gateway(資安第 2 道)

    分級標好了,但 LLM 不會自動知道。需要 Gateway 在「prompt 命中 A 級字典」時把 LLM 流量切到地端。

    用我寫的 v2.3 版(674 行 FastAPI):

    # clone Gist
    gh gist clone c82c51ae2a73bfe640dec5b61e5a542a walsin-gateway
    cd walsin-gateway
    
    # 裝套件
    pip install --user fastapi uvicorn httpx tiktoken
    
    # (若已做 Step 7 字典同步)Gateway 自動讀 ~/walsin-gateway/A_keywords.txt
    # (還沒做)先用 gateway_v2_cc.py 預設的字典,跑通後再回頭做 Step 7 同步
    
    # 啟動(必設 MASTER_KEY,用 export 不能用 inline env)
    export MASTER_KEY=sk-$(openssl rand -hex 16)
    echo "記下這把 key,別 commit、別寫進 tracked .env: $MASTER_KEY"
    
    # 啟動 Gateway 背景跑
    python3 gateway_v2_cc.py &
    
    # CC 切過去
    export ANTHROPIC_BASE_URL=http://localhost:4000
    export ANTHROPIC_AUTH_TOKEN=$MASTER_KEY

    從此你 prompt 命中字典 → 自動切地端。但這時還沒裝 Ollama,只是 Gateway 就位。完整體驗看 Step 9。

    ⚠️ 安全提醒(必看):Gateway 預設 bind 0.0.0.0(所有網卡),若你跑在筆電或公共 wifi,別人掃到 port 4000 就能試你的 master key,把 Gateway 當公網 proxy 借走你的 Anthropic API 額度。本機開發必須鎖回 127.0.0.1:編 gateway_v2_cc.py 末段的 uvicorn.run(...),把 host="0.0.0.0" 改成 host="127.0.0.1"。公網部署需 reverse proxy + TLS + 第二層 auth,不在本指南範圍。

    Step 9:加 Ollama 地端(資安第 3 道)

    # 裝 Ollama
    curl -fsSL https://ollama.com/install.sh | sh
    
    # 拉模型(看你硬體)
    ollama pull qwen3:14b      # 14B,中等強度,16GB RAM 跑得動
    ollama pull qwen3:1.7b     # 輕量,當 fail-safe

    到這步,完整路由生效:

    • 你寫「客戶 X 的訂單問題」→ Gateway 命中 A 級 → Ollama 14b 處理 → 不出本機
    • 你寫「Kafka rebalance 怎麼解」→ Gateway 沒命中 → cloud Claude → 全速 Opus 4.7

    實際感受:95% 工作跟原本一樣爽,只有 5% 命中字典的會慢一點 — 但那些任務本來就不該上雲。

    Step 10:完整 v2.3(B 級脫敏 + tests)

    v2.3 額外有:

    • B 級脫敏 fallback:中等敏感資料,地端壞了能脫敏後送 cloud(B 級走 cloud 時 response 帶 X-Gateway-Sanitized: 1 header)
    • Auth 防 substring 攻擊:secrets.compare_digest 精確比對
    • SSE byte-stream 直通:streaming 不變形
    • 24 個 pytest:跑 pytest test_gateway.py -v 全綠才上線
    • benchmark_runner.py:多模型對比 runner
    • demo_record.sh:asciinema 60 秒 demo 自動化

    跑 pytest 的前提:

    pip install --user pytest pytest-asyncio
    cd ~/walsin-gateway
    # sk-test-secret 是 test fixture 預設值;真實使用換成 openssl rand -hex 16 產生的 key
    MASTER_KEY=sk-test-secret python3 -m pytest test_gateway.py -v
    # 應看到 24 passed

    到這步你的工作流是 production-ready 的。能拿給公司 IT 看,有立場提內部 PoC

    不同階段你會得到什麼(別跳級)

    完成 Step 你的 superpower 建議停留
    1-3LLM 認得你的習慣 + 不再重複講同樣的話2 週
    4-5manager 模式 — delegate 而不是 do2 週
    6脫離桌機,工作流跟著你走1 週
    7-9敏感資料 + AI 生產力可同時擁有2 週
    10production-ready,可推給公司穩定使用

    最常見的失敗模式:跳級。沒寫過 brain 就裝 Gateway → 字典空的,Gateway 沒用;沒玩過 Agent Team 就跑 7 個 agent → 機器 OOM 崩潰。每階段穩了再下一階段

    跟前 9 篇對應

    本篇 Step 對應九部曲深入閱讀
    1-3 規則 + brain第 1 篇 (Why) + 第 2 篇 (How)
    4-5 Agent Team第 4 篇 (Tools) Harness 段
    6 行動端第 4 篇 (Tools) 的 ccbot / 官方 channel 段
    7 分級第 7 篇 (ISO) A/B/C 分級
    8-9 Gateway + 地端第 9 篇 (Proof) 完整 v2.3
    10 完整 production所有篇章 + Gist 完整 code

    踩坑警告(過來人提醒)

    • 不要先看 9 篇藍圖再開始 — 會被嚇到動彈不得。先做 Step 1-3,有感再看藍圖
    • 不要追求完美 brain — 寫得醜但有資訊比寫得漂亮但沒人看好
    • 不要 spawn 太多 agent — 機器 RAM 16GB 跑 7 個 opus 會 OOM,先 free -h 確認
    • 不要把 Iron Rules 寫 30 條 — 沒人記得住,3-10 條最好
    • 不要 Step 8 Gateway 上線就斷網 — 沒設 ANTHROPIC_API_KEY 時 fallback 地端,但本來工作流可能有依賴 cloud 的習慣,慢慢適應
    • 不要假裝 Agent Team 取代 review — agent 出的東西還是要看,他們是 fast doer 不是 quality gate

    結語:不要追求一週搞定

    10 步驟看似可以一週做完,但每一步的「習慣養成」需要時間

    Step 3 累積 brain 你會經歷「寫了 5 個又懶了」「再撿起來」「逐漸變成反射」。沒這 3 週適應期,Step 4 派 agent 你會不知道讓他做什麼。

    Step 5 並行 agent 你會經歷「派 7 個但 review 不過來」,然後學會「派 3 個但每個任務切清楚」。這也是要時間。

    這篇文章是地圖,不是腳本。照走 1 個月,你會擁有跟前 9 篇文章作者一樣的工作流。再走 3 個月,你會發展出自己的版本,可能比這個更好。

    這就是「我可以怎麼做到現在這樣」的答案。10 步驟,1-3 個月,從零到 v2.3

    延伸閱讀:腦子系統 10 篇

  • 腦子系統實證篇:本地 Gateway 完整實作版(v2.3,674 行真能接 CC)

    重點摘要(TL;DR)

    • 前 8 篇是藍圖。本篇是實作真實版:在 Mini PC(無 GPU、32GB RAM、Ryzen 7)用 364 行 FastAPI 跑通搬離方法論,真能接 Claude Code。
    • 核心邏輯:Gateway 看 prompt 內容,命中 A 級字典 → 地端最強模型(14b);其他 → cloud Claude(若有 API key)或 fallback 地端。
    • 關鍵設計原則(別搞錯):A 級資料用地端最強模型,不是最弱。敏感資料因為更重要,需要更可靠的回答。小模型只能當分類器或 fail-safe。
    • 真接 CC 的關鍵:用 Anthropic 原生 /v1/messages endpoint,不是 OpenAI 的 /v1/chat/completions,並做完整翻譯層(request / response / tool use / SSE)。
    • Harness 三 agent 永遠走 cloud(地端跑不動三 agent 並行 + long context),只是輸入經 Gateway 強脫敏 — 這是搬離後最關鍵的工作流保護。
    • 本文是腦子系統九部曲實證篇。前八篇:Why / How / Scale / Tools / ERP / Self-Service / ISO / Execution

    一、為什麼寫這篇 — 從藍圖到實作真實版

    前 8 篇腦子系統累積了大量「應該怎樣」的論述:Why / How / Scale / Tools / ERP / Self-Service / ISO / Execution。對真正要動手的人,這些都還是紙上的東西

    本篇是分水嶺 — 用一台 Mini PC(沒 GPU,32GB RAM,Ryzen 7 4700U,2020 年款)跑通可以真的接 Claude Code 的搬離 Gateway,證明:

    • 不需要 GPU,純 CPU 也能 host gateway logic
    • 不需要 LiteLLM / Portkey 等大框架,純 Python 364 行搞定
    • 不需要 ANTHROPIC_API_KEY 也能跑(有 fallback 模式)
    • CC + Agent Team + Harness 工作流不變,只改 BASE_URL

    二、5 條設計原則(別搞錯)

    原則 1:A 級資料地端,不可協商

    A 級的定義是「送出去會出事」 — 客戶機密、財報、製程 know-how。這個層級不能因為 cloud 模型強就送出。地端是底線。

    原則 2:A 級用地端最強模型,不是最弱

    這條最容易搞錯。直覺是「敏感資料 = 風險高 = 用小模型」,但 logic 應該倒過來:敏感資料因為更重要,需要更可靠的回答

    情境 地端模型選擇 理由
    A 級主處理 地端最強(14b / 32b / 80B-A3B) 資料越敏感,回答越要可靠
    分級判斷器 小模型(0.5b / 1.7b)or regex 分類本身不需要強能力
    Fail-safe 容錯 小模型保守路由 寧可路由保守不要錯放

    原則 3:路由邏輯走字典 + regex,不靠 LLM

    分級判斷不該交給 LLM(慢、不確定、可被 prompt injection 騙)。改用字典 + regex,毫秒級完成,可審計。

    原則 4:Anthropic 原生 endpoint(/v1/messages),不是 OpenAI 的 /v1/chat/completions

    CC 用 Anthropic Messages API,你 Gateway 必須 expose /v1/messages,不是 OpenAI 的 endpoint。並且做完整 Anthropic ↔ OpenAI 翻譯(因為地端 Ollama 用 OpenAI compatible 格式)。

    原則 5:沒 API key 也能跑(fallback 地端)

    Gateway 設計成:有 ANTHROPIC_API_KEY 就 C 級走真 cloud Claude;沒有就 fallback 走地端。讓你能純地端先驗證 logic,再加 cloud

    2.1 雙維度決策表(敏感度 × 可用性)— 別搞混

    fallback 不只看「cloud 有沒有 key」,還要看「資料能不能上 cloud」。雙維度決策才完整:

    分級 主路由 Fallback 關鍵保護
    A 級 地端最強(14b/32b/80B) 沒 fallback — 地端跑不動 = 等 / 改題目 即使有 cloud key 也不走 cloud
    B 級 地端優先 地端不可用 → 脫敏後 cloud 能脫敏才 fallback,不能脫敏寧願報錯
    C 級 cloud 優先 沒 key → 地端 純技術問題,無敏感度

    常見誤解:有 cloud key 就什麼都走 cloud。錯。A 級即使有 key 也不該走 cloud — 因為「資料外洩風險 > 模型能力差異」。Gateway 的職責就是替你擋住這個誘惑:你 prompt 命中 A 級字典,Gateway 不問你「要不要送 cloud」,直接路由到地端。

    本版實作狀態:A 級 + C 級已實作完整;B 級的「地端優先 + cloud fallback + 脫敏」是 TODO,本版 B 級 keyword 命中時邏輯等同 A 級(全地端)。完整 B 級實作見最末「待補的東西」章節。

    三、364 行 Gateway 完整實作

    結構:

    gateway.py(364 行)
    ├─ Classifier              (~30 行)— 抽 messages 文字 + 字典命中
    ├─ Anthropic→OpenAI Req    (~80 行)— system / messages / tool_use / tool_result 翻譯
    ├─ OpenAI→Anthropic Resp   (~40 行)— content blocks / stop_reason / usage
    ├─ SSE Streaming           (~40 行)— 6 種 Anthropic 事件 from OpenAI delta
    ├─ Backend Forwarders      (~80 行)— Ollama / Anthropic 雙路 forward + fallback
    └─ Main Endpoint           (~30 行)— /v1/messages,分類後派到對應 forward

    3.1 核心邏輯(主要 dispatcher)

    @app.post("/v1/messages")
    async def messages(request: Request):
        auth = request.headers.get("authorization", "")
        if MASTER_KEY not in auth and not ANTHROPIC_API_KEY:
            raise HTTPException(401, "bad master key")
    
        body = await request.json()
        original_model = body.get("model", "claude-opus-4-7")
        decision, keyword = classify(body.get("messages", []), body.get("system"))
    
        if decision == "A":
            log.warning(f"[A-LEVEL] 命中 '{keyword}' → 地端 {MODEL_A_LEVEL}")
            return await forward_to_ollama(body, MODEL_A_LEVEL, original_model)
        else:
            log.info(f"[C-LEVEL] → cloud {original_model}" if ANTHROPIC_API_KEY else f"[C-LEVEL] no key → local fallback")
            return await forward_to_anthropic(body, request, original_model)

    3.2 Anthropic ↔ OpenAI 翻譯的 4 個關鍵點

    # 1. Anthropic system 是 top-level → OpenAI 是 system message
    sys = body.get("system")
    if isinstance(sys, str):
        openai_messages.append({"role": "system", "content": sys})
    
    # 2. Anthropic tool_use 是 content block → OpenAI 是 message 上的 tool_calls
    if btype == "tool_use":
        tool_calls.append({
            "id": block["id"],
            "type": "function",
            "function": {"name": block["name"],
                         "arguments": json.dumps(block["input"])}
        })
    
    # 3. Anthropic tool_result 在 user message 內 → OpenAI 是 role:tool 獨立 message
    if btype == "tool_result":
        openai_messages.append({
            "role": "tool",
            "tool_call_id": block["tool_use_id"],
            "content": str(result_content)
        })
    
    # 4. SSE 翻譯:OpenAI delta 累積 → Anthropic 6 種事件
    #    message_start → content_block_start → content_block_delta(每個 token)
    #    → content_block_stop → message_delta(stop_reason)→ message_stop

    3.3 Forwarder(雙路 + fallback)

    async def forward_to_ollama(body, target_model, original_model):
        """A 級 → 翻譯成 OpenAI format,forward to Ollama 地端強模型。"""
        openai_body = anthropic_to_openai_request(body, target_model)
        is_stream = openai_body.get("stream", False)
        if is_stream:
            return StreamingResponse(stream_anthropic_from_openai(...))
        async with httpx.AsyncClient(timeout=600) as client:
            r = await client.post(f"{OLLAMA_URL}/v1/chat/completions", json=openai_body)
        return JSONResponse(openai_to_anthropic_response(r.json(), original_model))
    
    
    async def forward_to_anthropic(body, request, original_model):
        """C 級 → 直接 proxy 到 api.anthropic.com,沒 key 就 fallback 地端。"""
        if not ANTHROPIC_API_KEY:
            return await forward_to_ollama(body, ANTHROPIC_FALLBACK_MODEL, original_model)
        headers = {"x-api-key": ANTHROPIC_API_KEY, "anthropic-version": "2023-06-01"}
        if body.get("stream"):
            # SSE 直接透傳(Anthropic format,不用翻譯)
            return StreamingResponse(...)
        async with httpx.AsyncClient(timeout=600) as client:
            r = await client.post("https://api.anthropic.com/v1/messages", json=body, headers=headers)
        return JSONResponse(r.json())

    v2.3 完整 Gist(674 行 gateway + 24 個 pytest + benchmark + demo + README,5 個檔案):
    👉 https://gist.github.com/tm731531/c82c51ae2a73bfe640dec5b61e5a542a

    Gist 含 README + 5 步驟啟動 + 測試 curl 範例 + 已知限制。clone 下來改字典即可用。

    3.1 v2 → v2.1 changelog(review 後修)

    v2 上 Gist 後又收到 review,點出 3 個有實際影響的 bug,其中 1 個是安全問題。**全修了**:

    • 🔴 Bug 1(安全):Auth 邏輯反了 — 原本「沒設 cloud key 才檢查 master_key」意思是「接了 cloud 反而不檢查」,任何人能燒你 quota。修法:無條件檢查 master_key,並兼容 x-api-key + Authorization: Bearer 兩種 header。實測 no-key/wrong-key 都回 401
    • 🔴 Bug 2(功能):Streaming 模式 tool use 完全不工作 — 原本 stream_anthropic_from_openai 只翻譯 text delta,沒處理 delta.tool_calls。CC 的 Read/Edit/Bash 都是 tool use → A 級 + streaming 時 CC 卡住。修法:加 tool_calls delta 累積邏輯,追蹤 tool_call_index → our_block_index mapping,送 content_block_start (tool_use) + input_json_delta 事件序列。約 +60 行
    • 🟡 Bug 3:streaming 模式 stop_reason 寫死成 end_turn,即使 OpenAI 端因 max_tokens 截斷或 tool_calls 收尾也誤標。修法:streaming 過程累積最後 finish_reason,結束時用真實值映射(stop→end_turn / length→max_tokens / tool_calls→tool_use)
    • + 結構改進:content blocks 改 lazy open(只在真有內容時送 content_block_start),text 跟 tool 可正確交錯;dead import 清掉;docstring 改寫(原版誤稱用 sse-starlette)

    從 v1(80 行,描述跟 code 矛盾) → v2(364 行,文字宣稱) → v2 Gist(394 行,實際存在但 3 bug) → v2.1(502 行,bug 修完)。三天四個版本,每一輪 review 都點出真實問題。這個迭代過程本身就是 brain 系統「review-driven development」的最佳示範

    四、CC + Agent Team + Harness 三件事的協作

    4.1 CC 接 Gateway(0 行 code 改動)

    # Terminal 設環境變數
    export ANTHROPIC_BASE_URL=http://localhost:4000
    export ANTHROPIC_AUTH_TOKEN=sk-walsin-test
    
    # 跑 CC 跟原本一樣
    claude

    CC 完全不知道後面接的是 Gateway。所有 prompt 自動經分類 → 路由。

    4.2 Agent Team 走 Gateway(子進程繼承 BASE_URL)

    你在 CC 裡 spawn 7 個 opus agent 並行 — 每個 sub-agent 共用同一個 BASE_URL(從父 process 繼承)。Gateway 對每個 agent 的 prompt 獨立分類:

    你 (CC main)
    ├─ Agent 1 (opus): "review 這份 SAP API 設計"  → C 級 → cloud Claude
    ├─ Agent 2 (opus): "找 [client_alpha] 客訴 case" → A 級 → 地端 14b
    ├─ Agent 3 (opus): "寫 Kafka consumer"          → C 級 → cloud Claude
    ├─ Agent 4 (opus): "看 [project_xxx] 的合約"    → A 級 → 地端 14b
    ├─ Agent 5-7 (opus): 其他 C 級任務              → cloud Claude

    大多數 Agent Team 任務不命中 A 級字典,99% 體感跟原本一樣。少數命中的會走地端,慢一點但隔離。

    4.3 Harness 三 agent — 永遠走 cloud(關鍵保護)

    Anthropic 2026/3 發布的三 agent harness(Planner / Generator / Evaluator)是給 cloud 設計的。地端 80B-A3B 跑三 agent 並行 = GPU 排隊,根本跑不動。

    正解:Harness 永遠走 cloud,但輸入經 Gateway 強脫敏

    用戶: "幫我 refactor [project_xxx] 的支付模組"
        ↓
    Gateway 偵測 [project_xxx](A 級字典)
        ↓
    若強脫敏成功 → "幫我 refactor [PROJECT] 的支付模組" → cloud Claude(三 agent)
    若無法脫敏 → 整個任務改地端 14b sequential 跑(慢但安全)
        ↓
    Planner: 拆 task → Generator: 寫 code → Evaluator: 檢查
        ↓
    結果經 Gateway 回到用戶

    Harness 的價值在 long context + 複雜 reasoning,地端在這兩點本就弱。硬搬就是自虐。脫敏走 cloud 才是對的策略。

    4.4 三件事的協作全景

    你 (CC main session, ANTHROPIC_BASE_URL=gateway)
        │
        ├─ 普通 prompt → Gateway → 路由 → 對應 backend
        │
        ├─ Spawn Agent Team(7 個 opus 並行)
        │   ├─ 每個 sub-agent 繼承 BASE_URL
        │   ├─ Gateway 對每個 prompt 獨立分類
        │   └─ A 級走地端 14b,C 級走 cloud Claude
        │
        └─ Spawn Harness(Planner / Generator / Evaluator)
            ├─ 三 agent 共用 BASE_URL
            ├─ Gateway 強制路由全 cloud(脫敏後)
            └─ 因為地端跑不動三 agent 並行

    五、Brain 系統整合(sensitivity_level frontmatter)

    你的 brain markdown 系統(~/.claude/projects/.../memory/)是搬離的核心資產。整合方式:

    5.1 brain frontmatter 加分級欄位

    # 一般 brain(C 級,可上 cloud)
    ---
    name: kafka_consumer_pattern
    type: technical
    sensitivity_level: C
    ---
    Kafka consumer 群組 rebalance 機制...
    
    # 敏感 brain(A 級,只地端 + 強模型)
    ---
    name: client_alpha_oncall_pattern
    type: business_incident
    sensitivity_level: A
    applies_to: [bu_xxx]
    ---
    [client_alpha] 客訴流程,聯絡窗口...

    5.2 build.sh 編譯時依分級過濾

    #!/bin/bash
    # 編譯雙版本 CLAUDE.md
    
    # Cloud-bound CLAUDE.md(沒 A 級)
    find brain/ -name "*.md" \
      | xargs grep -L "sensitivity_level: A" \
      | xargs cat > .claude/CLAUDE.md.cloud
    
    # Local-bound CLAUDE.md(全部,A 級也進)
    cat brain/**/*.md > .claude/CLAUDE.md.local
    
    # Gateway 看員工任務目標選對應 CLAUDE.md

    5.3 brain 的 A 級關鍵字自動同步到 Gateway 字典

    # 從所有 A 級 brain 抽出 client name / project code 等
    grep -h "sensitivity_level: A" -A 20 brain/**/*.md \
      | grep -oP '\[client_\w+\]|\[project_\w+\]' \
      | sort -u > /tmp/A_keywords.txt
    
    # Gateway 啟動時 load
    A_KEYWORDS = open("/tmp/A_keywords.txt").read().splitlines() + DEFAULT_A_KEYWORDS

    5.4 公開版 brain repo 自動過濾

    如果你的 brain 有公開版(教學分享 / 開源),build script 自動排除 sensitivity_level: A 條目,只發 B / C。不用手動審 brain 是否能公開

    這是brain 系統跟 Gateway 的接合點:你寫 brain 時標分級,Gateway 自動知道哪些字串該擋,公開版自動過濾。一個 frontmatter 欄位,三個地方用

    六、放大邏輯 — 個人 → 80 人 → 萬人

    面向 個人(本文實證) 80 人公司 萬人集團
    Gateway 實作 364 行 FastAPI LiteLLM Docker K8s HPA + Portkey
    A 級字典 3-10 個關鍵字 100 個 1000+ 自動同步 brain
    A 級 backend Ollama Qwen3:14b(CPU) Ollama Qwen3:32b(1x 4090) 中央 GPU H100 跑 80B-A3B + 區域副本
    C 級 backend cloud Claude(個人 API key)or fallback 地端 Anthropic Enterprise Anthropic Enterprise + Azure / Bedrock 多家
    脫敏 字典 + regex Microsoft Presidio + LLM 兜底
    認證 master key 員工 SSO SSO + Token Impersonation
    Audit log stdout SQLite / OpenSearch 三軌制 + WORM + HSM mapping
    治理 0 Working Group 三道防線
    時程 30-60 分鐘 2-3 個月 12 個月
    預算 0 ~30 萬 NTD 4000-6000 萬 NTD

    核心邏輯一模一樣(看 prompt → 字典分類 → 路由)。差的只是:

    • 規模(字典條數、並發、儲存)
    • 治理(Working Group、三道防線、ISO 認證)
    • 合規(SOX / J-SOX / 個資法 / GDPR)
    • 能力 backend(14b vs 80B-A3B)

    七、能力降級補償策略

    實際擔心:地端模型比 Claude Opus 4.7 弱,搬完會不會生產力崩?

    實話:會降,看你會不會用補償工具。具體 benchmark 沒跑(個人 mini PC 沒 GPU 跑不了 32B+ 對比),但業界經驗的補償清單:

    地端弱的地方 補償工具 效果
    Long context 弱 RAG (Chroma / Qdrant) + chunking context 不全進 LLM,只進 top-K
    Reasoning 弱 Chain-of-thought structured prompt 強制分步,單步難度降
    Tool use 不穩 function calling 限縮 5-10 個 tools 減少選擇,提升正確率
    並行 Agent 跑不動 改 sequential workflow 一個跑完再下一個
    跨檔 refactor 弱 限定 working set(≤ 5 檔) 降低 context
    Memory 弱 brain markdown 強制 inject 永遠帶 context

    而且這只用在 5% A 級任務,其他 95% 還是 cloud。整體生產力下降可控,具體百分比待 SWE-bench Lite 子集 + 真實工作流 case 量化

    八、5 步驟讓你今晚就跑起來

    1. 裝 Ollama + 拉模型:
      ollama pull qwen3:14b      # A 級主處理(地端最強)
      ollama pull qwen3:1.7b     # 可選,當分類器 fail-safe
    2. 裝 Python 套件:
      pip install --user fastapi uvicorn httpx
    3. 存 364 行 gateway.py(本文第三章 + 完整版見 GitHub Gist)
    4. 跑起來:
      # 沒 API key 也能跑(fallback 地端)
      python3 gateway.py &
      curl -s http://localhost:4000/health   # 確認 OK
      
      # 有 API key 完整版
      ANTHROPIC_API_KEY=sk-ant-... python3 gateway.py &
    5. CC 切過去:
      export ANTHROPIC_BASE_URL=http://localhost:4000
      export ANTHROPIC_AUTH_TOKEN=sk-walsin-test
      claude   # 跟原本一樣寫 code

    30-60 分鐘搞定。設定完後 99% 工作跟原本一樣,只有 prompt 命中 A 級字典時自動切地端。

    九、跑不起來時會看到什麼(失敗模式排查)

    Gist 證明能跑,失敗模式證明跑過。下面是實作過程實際踩過的 7 個錯誤:

    錯誤訊息 / 症狀 根本原因 排查指令
    connection reset by peer + log 完全空 Container 還在 init(LiteLLM 啟動慢 30s-1min),或 Python stdout buffering docker exec <container> ps auxf 看 PID 1 是否還在跑;加 PYTHONUNBUFFERED=1
    404 Not Found from CC Gateway 用 OpenAI /v1/chat/completions,CC 打 Anthropic /v1/messages 看 Gateway log 有沒有「POST /v1/messages」;改用本文 Anthropic 原生 endpoint
    httpx.ReadTimeout 在 forward_to_ollama Ollama 模型在 CPU 第一次 load 太慢(超過 timeout) ollama run <model> "warm" 先暖機;timeout 從 300 改 600
    OCI runtime exec failed: "curl" not found LiteLLM image 沒裝 curl,內部 health check 工具有限 用 host 端 curl 測 http://localhost:4000/health 不要 docker exec
    {"detail": "bad master key"} CC 設了 ANTHROPIC_AUTH_TOKEN 但 Gateway 沒 match echo $ANTHROPIC_AUTH_TOKEN 跟 Gateway 的 MASTER_KEY 對
    CC 卡住沒回應(streaming 不出來) SSE 翻譯漏了 message_stop 事件,client 等不到結束 Gateway log 看最後送出的 event;確認 6 種事件全送(message_startcontent_block_start/delta/stopmessage_deltamessage_stop)
    A 級 prompt 沒命中字典(看到走 C 級) 字典 keyword 是 case-sensitive 漏了 re.IGNORECASE,或字典裡沒這條 curl -s gateway.../health 看 keywords_count;echo $PROMPT | grep -i <keyword>

    十、Gist 上線前檢查清單(13 條)

    從文章第一版到本版踩過的所有雷,清單化:

    1. Authorization header 兩種格式都要兼容:CC 可能送 x-api-key: xxxAuthorization: Bearer xxx,Gateway 都要認
    2. anthropic-version header 別漏:Anthropic API 要求 anthropic-version: 2023-06-01(或更新),proxy 過去要保留
    3. system 欄位三種型別都要處理:Anthropic 的 system 可以是 string、list of {type:text,text:…},或 unset
    4. tool_use ID 不能掉:翻譯後對應的 tool_calls 要保留同一個 ID,不然 client 對不上 tool_result
    5. tool_result 在 user message 內,翻譯後要拆成獨立 role:tool message
    6. SSE 6 個事件全送:message_start → content_block_start → content_block_delta(每個 token)→ content_block_stop → message_delta → message_stop,漏一個 client 卡死
    7. SSE event 名稱要寫 event:,data: 兩行:不是只送 data,Anthropic SSE 格式有 event 名
    8. Ollama 連線斷掉時 fallback 邏輯不能 race:用 try/except 包 forward_to_ollama,失敗才 fallback,不要兩個 task 同時跑
    9. timeout 要設 600 秒以上:CPU 跑 14b 慢,300 秒會 timeout
    10. master_key 預設值不要外洩:Gist 上的 sk-walsin-test 是 placeholder,部署前換掉
    11. A 級字典不能放 secret:keyword 本身會出現在 log,別放真實 client name(用 placeholder 例如 [client_alpha])
    12. health endpoint 不檢查 master_key:不然 monitoring 工具會 401
    13. 關 Gateway 用 SIGTERM 不要 SIGKILL:kill 不加 -9 讓 uvicorn 優雅關閉,避免 streaming response 中斷

    十一、TODO 全部 close(v2.2 update)

    原本標的 4 個 TODO 全做完了,本版升 v2.2(620 行)。逐項說:

    原 TODO v2.2 處理 行數
    B 級「地端優先 + cloud fallback + 脫敏」 ✅ 完整實作:ollama_alive() 健康檢查 → 失敗 sanitize_anthropic_body() → fallback cloud;sanitize 沒命中拒絕(503) +90 行
    Benchmark benchmark_runner.py 獨立檔(258 行):跑 SWE-bench Lite 子集 + 自家 prompts × 多 model,輸出 markdown 報表。不打分,只跑數據(讓人類自己判斷,避免 premise drift) 258 行新檔
    Asciinema 60 秒 demo demo_record.sh:health → C 級 → A 級 → auth fail 4 個 step,可直接跑或 asciinema rec -c 包起來錄影 110 行新檔
    Token usage 真實計算 ✅ 用 tiktoken 估算累積 text + tool args,取代原本的 chunk count(嚴重低估) +20 行

    11.1 v2.1 → v2.2 主要新邏輯

    elif decision == "B":
        # v2.2 完整 B 級實作
        if await ollama_alive():
            return await forward_to_ollama(body, MODEL_B_LEVEL, original_model)
    
        # 地端死了,看能不能 fallback cloud
        if not (ANTHROPIC_API_KEY and B_LEVEL_CLOUD_FALLBACK):
            raise HTTPException(503, "B-level: local unavailable, cloud fallback disabled")
    
        sanitized_body, hit = sanitize_anthropic_body(body)
        if not hit:
            # 地端死 + 脫敏沒命中 = B 字典跟脫敏字典不一致,寧願報錯
            raise HTTPException(500, "B-level: local down + sanitization mismatch")
    
        return await forward_to_anthropic(sanitized_body, request, original_model)

    11.2 Sanitization 字典(v2.2 新增)

    SANITIZE_MAP = {
        r"\[internal_process\]": "[PROCESS]",
        r"\[vendor_quote\]": "[QUOTE]",
        r"\[employee_name\]": "[PERSON]",
        # 通用 PII patterns
        r"\b[\w.+-]+@[\w-]+\.[\w.-]+\b": "[EMAIL]",
        r"\b(?:\d{1,3}\.){3}\d{1,3}\b": "[IP]",
        r"\b\d{4}-\d{4}-\d{4}-\d{4}\b": "[CARD]",
    }

    實作策略:regex-based 簡單脫敏(快、可審計);生產環境建議升 Microsoft Presidio(NER + checksum + 多語言)。

    11.3 Benchmark Runner 跑法

    # 跑全部 prompts × 你已 pull 的 ollama 模型
    python3 benchmark_runner.py
    
    # 加 cloud Claude 對比(有 ANTHROPIC_API_KEY 才能)
    ANTHROPIC_API_KEY=sk-ant-... python3 benchmark_runner.py \
      --models qwen3:14b,qwen3:4b \
      --anthropic-models claude-opus-4-7
    
    # 只跑 SWE-bench Lite 子集
    python3 benchmark_runner.py --suite swe --output report.md

    跑出來是 markdown 報表,每 model × 每 prompt 的 latency / tokens / 截斷回應。故意不打分 — 因為「能力 = X%」這種宣稱本身就是 review 點過的 premise drift 風險。**跑數據給人看,人類自己判斷**,比 AI 講百分比有 integrity。

    11.4 Demo 錄影

    # 純跑(看 terminal output)
    bash demo_record.sh
    
    # 用 asciinema 錄影
    asciinema rec -c "bash demo_record.sh" walsin-demo.cast
    asciinema upload walsin-demo.cast   # (可選)上傳分享

    4 個 step:health check → C 級 prompt → A 級 prompt(命中字典)→ 沒帶 key 401。每一步都看到 x-gateway-decision + x-gateway-model headers。

    11.5 v2.2 → v2.3 self-review 後再清 7 個漏洞

    「考試不能邊改邊考」 — 我自己當最嚴格 reviewer 把 v2.2 從頭審一次,找到 7 個應修的(不是別人指出),全清:

    優先 問題 v2.3 修法
    🔴 P0 Auth substring match 漏洞 — MASTER_KEY not in auth 太寬,sk-test-extra 也通過 secrets.compare_digest 精確比對 + Bearer 解析
    🔴 P0 SSE 透傳格式錯 — aiter_lines + "\n" 會剝掉 \n\n event 結尾 aiter_bytes 直通,SSE 格式 byte-for-byte 完整
    🔴 P0 Sanitize 漏 tool_use input + tool_result content — 只處理 text block 改遞迴 _sanitize_value 處理任意巢狀 dict / list / str
    🟡 P1 MASTER_KEY 預設 hardcoded,生產環境壞習慣 沒設環境變數時 log warning,提示部署前必設
    🟡 P1 demo_record.sh 缺 pre-flight,gateway 沒啟動 script crash 開頭加 curl /health,失敗給友善提示 + 啟動指令
    🟡 P1 /health 沒回報 ollama 狀態,monitoring 不夠 ollama: alive/down + b_level_model + b_cloud_fallback 配置
    🟡 P1 B 級走 cloud(脫敏後)client 不知道 回應加 X-Gateway-Sanitized: 1 header,透明度

    11.6 24 個 pytest 全綠(v2.3 新)

    $ pip install --user pytest pytest-asyncio
    $ MASTER_KEY=sk-test-secret python3 -m pytest test_gateway.py -v
    
    test_gateway.py::TestClassify::test_C_level_default              PASSED
    test_gateway.py::TestClassify::test_A_level_keyword_match        PASSED
    test_gateway.py::TestClassify::test_A_level_in_system            PASSED
    test_gateway.py::TestClassify::test_A_level_in_list_content      PASSED
    test_gateway.py::TestClassify::test_B_level_match                PASSED
    test_gateway.py::TestClassify::test_A_takes_precedence_over_B    PASSED
    test_gateway.py::TestMasterKey::test_correct_bearer              PASSED
    test_gateway.py::TestMasterKey::test_correct_bare                PASSED
    test_gateway.py::TestMasterKey::test_empty                       PASSED
    test_gateway.py::TestMasterKey::test_wrong                       PASSED
    test_gateway.py::TestMasterKey::test_substring_extra_suffix_blocked  PASSED  ← v2.3 修
    test_gateway.py::TestMasterKey::test_substring_prefix_blocked    PASSED  ← v2.3 修
    test_gateway.py::TestMasterKey::test_lower_case_bearer           PASSED
    test_gateway.py::TestSanitization::test_string_email             PASSED
    test_gateway.py::TestSanitization::test_string_ip                PASSED
    test_gateway.py::TestSanitization::test_string_no_hit            PASSED
    test_gateway.py::TestSanitization::test_recursive_dict           PASSED
    test_gateway.py::TestSanitization::test_recursive_list           PASSED
    test_gateway.py::TestSanitization::test_anthropic_body_text_block            PASSED
    test_gateway.py::TestSanitization::test_anthropic_body_tool_use_input_v23    PASSED  ← v2.3 修
    test_gateway.py::TestSanitization::test_anthropic_body_tool_result_v23       PASSED  ← v2.3 修
    test_gateway.py::TestRequestTranslation::test_system_string_to_message       PASSED
    test_gateway.py::TestRequestTranslation::test_tool_use_to_tool_calls         PASSED
    test_gateway.py::TestRequestTranslation::test_tool_result_becomes_separate_message PASSED
    
    ============================== 24 passed in 0.61s ==============================

    4 個 v2.3 安全修正關鍵 test 全綠 — 證明 substring 攻擊擋下、tool_use input 真的會被 sanitize。

    11.7 真的還剩什麼不會做(誠實)

    • SWE-bench 完整跑數據:需要 GPU 跑 32B+,我這台 mini PC 不行。Runner 寫好了,你有 GPU 自己跑
    • 真錄 asciinema 公開連結:script 寫好(含 v2.3 pre-flight check),你自己 run + upload
    • Microsoft Presidio 升級:regex 已夠 demo,生產時換成 NER + checksum
    • httpx async mock 整合測試:現在的 24 個 unit test 涵蓋純函式,async stream 整合測試還沒寫

    策略:能在我環境做的全做,不能做的寫好工具讓你自己做。每一輪迭代都比上一輪誠實。

    十二、5 個學到的事(實作後)

    1. Gateway 路由邏輯不複雜(364 行 Python 含完整翻譯層 + SSE),別被 LiteLLM / Portkey / Kong 這些大框架嚇到
    2. CC 工作流不用改(只改 BASE_URL),搬離成本低於想像。但要真接 CC 必須做 Anthropic 原生 endpoint + 完整翻譯層
    3. A 級資料用地端最強,不是最弱。敏感資料因為更重要,需要更可靠回答 — 這條最容易搞反
    4. Mini PC 雖弱但能跑(CPU 跑 14b 約 1-3 tok/s,慢但能用),證明搬離方法論不需要先投資 GPU
    5. Harness 不該硬搬地端(三 agent 並行 + 長 context 是 cloud 的價值,脫敏走 cloud 才是對的)

    結語:從藍圖到可執行的搬離

    前 8 篇腦子系統告訴你「應該怎樣」。本篇告訴你「實際怎樣」。

    364 行 Python + Mini PC + Ollama + Claude Code = 搬離方法論的可執行實作。

    這不是教你「怎麼蓋萬人企業 AI 治理」 — 那是另外 8 篇的事。

    這是教你「怎麼今晚就在自己電腦上跑通搬離 logic」 — 證明你的方法論不只是紙上的。

    有了這個實作,你才有立場跟集團 IT 提 PoC,跟 CFO 提預算,跟法遵提合規。

    下一步:你的 mini PC 有沒有變慢?Agent Team 還能 spawn 嗎?Brain 還在嗎?都沒事 — 因為 Gateway 是個獨立 process,不影響任何沒設 BASE_URL 的工作流。你想停掉就 kill 一個 process,連配置都不用改。

    這就是搬離方法論的真實樣子:低風險、可逆、漸進、實作在前、規模在後

    延伸閱讀:腦子系統九部曲

  • 80人AI腦子系統實戰建置:從0到上線的16個步驟

    重點摘要(TL;DR)

    • 把 80 人 AI 腦子系統從 0 蓋起來,共 5 個 Phase、16 個 Step、約 16 週。本文逐步拆解每一步的目標、動作、產出、坑。
    • 每一步都用四維框架檢查:安全(不洩漏)、穩定(不掛)、累積(知識變資產)、好用(員工願意用)。任何一步如果四維都不過,就砍掉。
    • 核心心法:物理保證 > 規則約束、拉力 > 推力、先粗版再精修、安全在前但好用不能放最後
    • 順序很重要,不能跳步。例如沒有 Step 6(分級對應表)就做 Step 9(Gateway),Gateway 規則沒依據;沒有 Step 12(Curator)就累積知識,3 個月後變垃圾堆。
    • 本文是《80人公司的AI腦子系統:從個人腦擴展到全公司不洩密的工程設計》的實作續篇。前篇講為什麼,本篇講怎麼做。

    為什麼要從「順序」談起

    很多公司導入 AI 治理失敗,不是技術不行,是順序錯了。常見錯誤:

    • 先買 Gateway 軟體,再去定資料分級 → 規則沒依據,Gateway 變裝飾
    • 先請大家寫 brain markdown,沒有 Curator 制度 → 3 個月後變過期文件墳場
    • 先做華麗 Dashboard,沒有 audit log 來源 → KPI 是亂編的
    • 先全公司鋪開,沒先試點 → 第一週體驗不好,80 人對系統信任歸零,救不回來

    本文每個 Step 都標「為什麼是這個位置」,讓你看完知道哪些可以平行、哪些必須串行。

    四維檢查框架

    每個 Step 都要回答四個問題。如果一個 Step 四維都打不到 ≥1 分,就砍掉 — 是 nice-to-have,不是 must-have。

    維度 問題 具體判斷
    🔒 安全 這步降低洩漏面積嗎? A 級資料更不會出去?稽核能找到證據?
    🛡️ 穩定 這步可用性夠嗎? 壞了能降級?有災難回復?HA?
    📚 累積 這步留下了什麼長期資產? 員工離職還在?可審計?可移交?
    😊 好用 員工這步以後生活更好嗎? 少打字?少切視窗?少等待?少抱怨?

    Phase 0:基礎準備(W0–W2)

    不要先動程式碼。先把組織結構知識容器建好。

    Step 1 — 召集 Working Group(W0,3 天)

    • 目標:讓 5-7 人(準 CISO + 法務 + IT + 3-4 部門 senior + 老闆 sponsor)成為這套系統的第一批決策者
    • 動作:第一次會議 60 分鐘,議程:同步為什麼要做、確認名單、排定 Phase 0 清單會議、訂下兩週一次例會
    • 產出:一份 working group 章程文件、會議紀錄、共享日曆
    • 四維:🔒 ✅(分級權威來源)、🛡️ —、📚 ✅(決策歷史可追)、😊 ✅(員工知道有人扛責)
    • 常見坑:老闆不到場 → 後面拍板沒人敢動;法務一個人說了算 → 後面所有東西判 A 級

    Step 2 — 建立雙 Repo(W1,2 天)

    • 目標:把「公司腦」和「個人腦」變成兩個物理上分離的 git repo
    • 動作:在公司 GitHub Org 建 company-brain(private)、發給每位員工一份 personal-brain template(github classroom 或 cookiecutter)
    • 產出:兩個 repo + README 說明使用方式 + .gitignore 範本
    • 四維:🔒 ✅✅(個人腦永不 push 中央=物理保證)、🛡️ ✅(git 提供版本+回復)、📚 ✅(每筆變更有 PR)、😊 ✅(員工用熟悉的 git workflow)
    • 常見坑:個人腦放公司 GitHub 而不是員工自己的 → 隱私保證失效;沒有 .gitignore 擋掉 .env / 密碼檔 → 第一週就有人 commit 進去

    Step 3 — Iron Rules v0(W1-W2,1 週)

    • 目標:寫下 3-5 條全公司必守的紅線,變成 company-brain/global/CLAUDE.md
    • 動作:Working Group 開 1 次會議,每個人提 5 條,合併成 3-5 條全體共識
    • 範例:「禁止把客戶合約原文送雲端 LLM」「Bug log 進公司腦前必須脫敏」「所有 brain 修改必須走 PR」
    • 產出:CLAUDE.md v0 commit 進 company-brain/global/
    • 四維:🔒 ✅(底線設定)、🛡️ —、📚 ✅(規則進 git)、😊 ✅(規則少而清楚 > 50 條沒人記)
    • 常見坑:寫成 30 條 → 沒人記得住;寫太抽象(「做正確的事」)→ 不能執行

    Phase 1:同步機制(W3–W4)

    讓「腦子」能流到員工每個 AI 工具。不寫 Gateway,先解決 build & sync

    Step 4 — build.sh 中性編譯器(W3,3-5 天)

    • 目標:一個 script 把 markdown 編譯到所有 AI 工具的格式
    • 動作:寫 bash / Python script,輸入 company-brain/ + personal-brain/,輸出:
      • .claude/CLAUDE.md(Claude Code / Desktop)
      • .cursor/rules/*.mdc(Cursor)
      • .github/copilot-instructions.md(Copilot)
      • ~/chatgpt-system-prompt.md(ChatGPT 用 Custom GPT 貼用)
    • 關鍵設計:每個 brain 檔的 frontmatter 加 tools: [claude, cursor, copilot, gpt],編譯時依目標 model 過濾
    • 產出:可執行的 build.sh + 4-5 種工具的編譯範例
    • 四維:🔒 ✅(可依工具過濾敏感腦)、🛡️ ✅(編譯失敗有錯誤訊息)、📚 ✅(中性格式不被工具鎖死)、😊 ✅✅(員工不用學新格式)
    • 常見坑:編譯太久 → 員工不願意每天 build,設成 git pre-push hook 自動跑

    Step 5 — 種子部門試跑(W4,1 週)

    • 目標:挑 10-15 人的部門(通常是 RD)當第一批用戶,真實流量驗證 Phase 0+1
    • 動作:每天收 1 次回饋(短 Slack 頻道)、每週 1 次 30 分鐘 retro 會議、補 brain
    • milestone:第一週結束,company-brain 有 ≥10 筆 brain markdown(由種子用戶產出)
    • 四維:🔒 —、🛡️ ✅(早期發現問題)、📚 ✅(brain 種子)、😊 ✅(早期使用者教其他員工)
    • 常見坑:挑錯部門 → 行政部根本不寫 brain;挑太大部門 → 回饋處理不過來。挑用 AI 最多的小團隊

    Phase 2:分級與脫敏(W5–W8)

    這是整個系統的核心。沒這 Phase,後面 Gateway 全是空殼。

    Step 6 — 分級對應表 v0.1(W5-W6,2 週)

    • 目標:列出 50-100 種公司會接觸的資料類型,粗分 A/B/C
    • 動作:Working Group 兩次會議,每次 90 分鐘,一次處理 30 種
    • 產出:company-brain/global/data-classification.md 表格化,進 git 管理
    • 原則:不糾結邊界 → 先有 v0.1 → Phase 2 試點時精修
    • 四維:🔒 ✅✅✅(整套架構的權威來源)、🛡️ —、📚 ✅✅(可審計、可移交)、😊 —(員工目前還用不到,但是後續所有 UX 的基礎)
    • 常見坑:法務說「不確定就 A 級」→ 後續 Gateway 90% 流量被擋,系統失效。**邊界 case 預設 B 級**(脫敏後可送雲),不是 A 級

    Step 7 — 脫敏字典 v0(W7,5 天)

    • 目標:三份純文字字典,擋掉 80% 紅字
    • 動作:從 CRM / HR / 專案系統匯出
      • client_names.txt(客戶公司名 + 簡稱)
      • employee_names.txt(員工姓名 + 暱稱 + Slack ID)
      • project_codes.txt(內部專案代號、產品代號、合約格式 regex)
    • 產出:三份 .txt + 每月由 HR / PM 維護的責任分配
    • 進階(可選):接 Microsoft Presidio v2.2.362(2025/3 釋出,2026/5 仍是最新版)當第二層補強。Presidio 是開源 PII 脫敏框架,內建 NER + regex + checksum,支援多語言,還有 image redactor 處理 DICOM 醫療影像。字典擋已知字、Presidio 擋通用 PII(信用卡、身分證、地址等),兩層疊加。
    • 四維:🔒 ✅✅(一次擋掉 80% 洩漏)、🛡️ ✅(純文字,壞不掉)、📚 ✅(離職員工從字典移除有歷程)、😊 ✅(員工不用記哪些字是紅字)
    • 常見坑:字典放 git 中 → 字典本身就是敏感資料(客戶 list)。要放另一個 access-controlled repo,build.sh 用 SSH key 拉

    Step 8 — Pre-commit Hook + Browser Extension MVP(W8,1 週)

    • 目標:在員工提交 brain 時、貼資料到網頁版 LLM 時,第一道防線
    • 動作:
      • Pre-commit hook(.git/hooks/pre-commit):掃 staged 檔案,字典命中就 block commit
      • Browser Extension(Chrome/Edge):偵測 chat.openai.com / claude.ai 的 paste 事件,字典命中跳警告 + 自動替換
    • 產出:兩個工具 + 內部 IT 自助安裝頁
    • 四維:🔒 ✅✅(防呆,擋住 80% 「員工懶得開 IDE」場景)、🛡️ ✅(本地執行,不 break 工作流)、📚 —、😊 ✅(警告比阻擋友善)
    • 常見坑:Pre-commit 跑太慢(掃整個 repo) → 員工 git commit --no-verify 繞過。**只掃 staged diff**,< 1 秒

    Phase 3:Gateway 上線(W9–W16)

    這是工程量最大的 Phase。前面都做完才有意義。

    Step 9 — LLM Gateway 骨架(W9-W11,3 週)

    • 目標:用開源 AI Gateway 做基礎,偽裝 Anthropic / OpenAI API。2026 主流選擇:LiteLLM(unified API 到 100+ providers)、Portkey(內建 guardrails + PII redaction + observability)、Kong AI Gateway。企業常見組合是 LiteLLM 當 proxy + Portkey 做 observability
    • 動作:
      • 架 LiteLLM 在內網(Docker),或用 Portkey self-host
      • 第一版只做 proxy + audit log,不做分級
      • 讓種子部門切過來:ANTHROPIC_BASE_URL=https://company-llm.internal/v1
    • 產出:可用 Gateway + audit log 進 SIEM + 每日 throughput 報告
    • 四維:🔒 ✅(流量集中)、🛡️ ✅✅(HA + 健康檢查)、📚 ✅✅(全程 audit)、😊 ✅(員工只改一行設定)
    • 常見坑:沒做 HA,Gateway 掛 = 80 人不能工作。**第一天就要 HA**,或備用 endpoint 自動切換

    Step 10 — 三層漏斗實作(W12-W14,3 週)

    • 目標:在 Gateway 內加分級 + 路由邏輯
    • 動作:
      • Layer 1:Aho-Corasick 演算法搜字典(< 5ms)
      • Layer 2:fine-tune 小模型做分類(BERT、Qwen3 1.7B、Llama 3.2 3B 都可),0.1-0.3s
      • Layer 3:fail-safe 全部判 B 級走脫敏 + 雲端
    • 產出:三層命中率分布 dashboard
    • 四維:🔒 ✅✅✅(自動分級)、🛡️ ✅(每層獨立可降級)、📚 ✅(每筆分類有紀錄)、😊 ✅(員工無感)
    • 常見坑:一開始就追求 Layer 2 LLM 完美 → 永遠上不了線。**先 Layer 1 + Layer 3 兩層上線**,Layer 2 之後加

    Step 11 — 雙引擎接入(W15-W16,2 週)

    • 目標:把雲端 frontier 和本地頂級開源模型都接進 Gateway
    • 動作:
      • 雲端:簽 Anthropic Enterprise(Claude Opus 4.7)、Azure OpenAI(GPT-5.5)、AWS Bedrock(多家)、Google Vertex AI(Gemini 3.1 Pro)。要 DPA + zero data retention 條款。2026 主流是「routing by task type」:Opus 4.7 跑 multi-file coding、GPT-5.5 跑 terminal/browser、Gemini 3.1 Pro 跑 long-context research。
      • 本地:架 Ollama 或 vLLM(production 用 vLLM,2-4x 並發)+ Qwen3-Coder-Next(80B 總參 / 3B active,MoE,256K context)或 Qwen3.6,給 A 級任務專用。MoE 架構讓消費級 GPU 可跑。
      • Gateway 路由規則:A 級 → 本地、B 級 → 脫敏 + 雲端、C 級 → 直接雲端,並依任務型別選最適合的雲端模型。
    • 產出:完整雙引擎可用、第一張月度安全報告(攔了多少 A 級)
    • 四維:🔒 ✅✅✅(A 級永不出去)、🛡️ ✅(雲端掛了本地頂)、📚 ✅(成本/用量數據)、😊 ✅(員工拿到 frontier 能力)
    • 常見坑:用個人帳號的 Claude / GPT → ISO 27001 第三方供應商不過。**必須 Enterprise 合約有 DPA**,費用貴 30-50% 但這是硬門檻

    Phase 4:治理機制(W13+,與 Phase 3 並行)

    沒這個 Phase,brain 會在 6 個月內變垃圾堆。Gateway 蓋好但沒 KPI,3 個月後沒人知道有沒有效。

    Step 12 — Curator 制度(W13,2 週啟動)

    • 目標:每個 team 一個 Curator,有權合併 / 刪除 brain
    • 動作:
      • 挑選:每 team 一個 senior(自願 + 部門主管同意)
      • 授權:GitHub team admin 權限 + 每週 1 小時 review brain PR
      • 儀式:每季全公司「腦子健檢日」,半天清掃過時 brain
    • 產出:Curator list + review SLA(PR 5 個工作天內處理)
    • 四維:🔒 ✅(防止劣化)、🛡️ —、📚 ✅✅✅(知識保鮮)、😊 ✅(垃圾不會堆)
    • 常見坑:Curator 沒被分配時間 → 永遠不 review。**1 小時/週要正式排進 KPI**,不是「有空就做」

    Step 13 — KPI Dashboard(W14-W16,3 週)

    • 目標:把 North Star + 四象限 KPI 變成可看的 dashboard
    • 動作:
      • 串 Gateway audit log → Grafana / Metabase / 自寫
      • 串 firewall log → 偵測網頁版 LLM 流量
      • 串 git activity → 計算 brain 增長率
      • 每月例會看「3 個問題」:North Star、Top 3 繞過原因、安全收益
    • 產出:每月 dashboard + 月報自動產生
    • 四維:🔒 ✅(可量測)、🛡️ ✅(早期警告)、📚 ✅(歷史趨勢)、😊 ✅(高層願意持續投資)
    • 常見坑:做太多指標(20+)→ 沒人看。**只看 5-7 個**,北極星 + 四象限就夠

    Phase 5:長期演進(M5+,持續)

    系統上線後不是結束。三件事要持續做。

    Step 14 — ISO 對應與稽核準備(M5-M6)

    • 目標:把 Step 1-13 的產出對應到 ISO 27001 / 42001 控制措施
    • 動作:
      • 產出 iso-mapping.md:每條 ISO 控制措施 → 對應的 Step + 證據(git log / Gateway log / Dashboard)
      • 第一次內部稽核(找外部顧問跑一遍)
      • 修正稽核發現的 gap
    • 產出:ISO 對應表 + 稽核 readiness 報告
    • 四維:🔒 ✅✅(對外背書)、🛡️ ✅(壓力測試)、📚 ✅✅(合規資產)、😊 —(這 Phase 員工不會直接受益,但對外贏單時受益)
    • 常見坑:把稽核當一次性活動 → 證書到手就鬆懈,3 年後重審手忙腳亂。**Dashboard 要持續跑**,稽核資料 90% 自動產出

    Step 15 — 第二批工具支援(M5+)

    • 目標:涵蓋第一批沒處理的工具
    • 動作:
      • ChatGPT 透過 Custom GPT Action 串 Gateway HTTP API
      • 移動端 Claude / ChatGPT app(只能靠規則 + 教育,管不到)
      • n8n / Dify / 自建 workflow 接 Gateway
    • 四維:🔒 ✅(更多入口受控)、🛡️ —、📚 ✅、😊 ✅(更多員工享受到拉力)

    Step 16 — 過時知識淘汰機制(M6+)

    • 目標:防止 brain 累積成考古學遺址
    • 動作:
      • 每筆 brain 加 last_verified: 2026-05 frontmatter
      • 用量遙測:90 天無 reference 的 brain 自動標 stale: true
      • 每季 Curator 審 stale list,合併 / 刪除 / 更新
    • 四維:🔒 —、🛡️ ✅(防誤用過期知識)、📚 ✅✅(品質才是知識的本質)、😊 ✅(搜尋更準)

    16 Step 全景表

    Phase Step 時程 產出 主導
    0 基礎 1 Working Group W0 章程 + 例會 準 CISO
    0 基礎 2 雙 Repo W1 git repo x2 IT
    0 基礎 3 Iron Rules v0 W2 CLAUDE.md Working Group
    1 同步 4 build.sh W3 編譯器 RD
    1 同步 5 種子部門試跑 W4 ≥10 brain 部門主管
    2 分級 6 分級對應表 v0.1 W5-W6 A/B/C 表 Working Group
    2 分級 7 脫敏字典 v0 W7 三份 .txt HR + PM
    2 分級 8 Pre-commit + Browser Ext W8 兩個工具 RD
    3 Gateway 9 Gateway 骨架 W9-W11 LiteLLM 上線 RD
    3 Gateway 10 三層漏斗 W12-W14 分級+路由 RD
    3 Gateway 11 雙引擎接入 W15-W16 本地+雲端 RD + 法務(合約)
    4 治理 12 Curator 制度 W13+(並行) Curator list + SLA 部門主管
    4 治理 13 KPI Dashboard W14-W16 月報 準 CISO + RD
    5 演進 14 ISO 稽核準備 M5-M6 對應表 準 CISO
    5 演進 15 第二批工具 M5+ ChatGPT etc. RD
    5 演進 16 知識淘汰 M6+ stale 機制 Curator

    關鍵心法:這 16 步背後的設計原則

    1. 安全在前,但好用不能放最後

    Phase 0-2 都在做安全基礎設施,但每個 Step 的「好用」維度都要 ≥1 分。**安全是必要不充分,沒有好用的安全系統會被員工繞過,等於沒做**。Step 4 的 build.sh、Step 8 的 Browser Extension,都是「安全 + 好用」並重的範例。

    2. 物理保證 > 規則約束

    能用 git 結構保證的(Step 2 雙 Repo),不要靠政策文件。能用 Pre-commit hook 自動擋的(Step 8),不要靠員工自律。能用 Gateway 路由強制的(Step 11),不要靠規範。**規則會被忘記,結構不會**。

    3. 拉力 > 推力

    Step 11 雲端 frontier 接入是「拉力」核心 — 員工為什麼選 Gateway 不選網頁版?因為 Gateway 給他 frontier model + 公司腦自動注入 + 速度更快,**而且不用自己付費**。讓 Gateway 比網頁版好用,員工自然不繞過。

    4. 先粗版上線,真實流量精修

    Step 6 分級表 v0.1、Step 7 字典 v0、Step 9 Gateway 骨架都明確標 v0 / 骨架。**等想清楚才上線 = 永遠不上線**。Phase 2 試點 4-6 週收斂的速度,比關門想 6 個月快 10 倍。

    5. 治理機制與技術建設並行

    很多公司先蓋 Gateway 再想 Curator,結果 Gateway 上線 6 個月後 brain 變垃圾堆。Step 12 Curator 在 W13 啟動,**和 Step 13 KPI Dashboard 並行**,因為 brain 累積速度從 Phase 1 試點就開始,治理不能等。

    常見問題

    16 週太長,3 個月能上線嗎?

    可以,但要砍 Phase 3+4。「3 個月版」=Step 1-8 + 簡化版 Gateway(只做 proxy + audit log,不做分級),Phase 4 治理機制延後。**重點是先把基礎(雙 Repo + 分級表 + 脫敏字典 + 種子部門)立起來**,Gateway 可以 v0.5 上線、v1.0 慢慢迭代。

    16 步可以跳哪幾步?

    可跳:Step 8(Browser Ext)、Step 15(第二批工具)。 不可跳:Step 1(Working Group)、Step 6(分級表)、Step 12(Curator)— 跳了系統會壞。 可緩:Step 14(ISO 稽核)— 等系統穩定再啟動。

    一個人(全職)能撐多少?

    • Phase 0-2(8 週):一個人可獨立完成,主要是文件 + 字典 + 簡單 script
    • Phase 3 Gateway(8 週):**要 1.5-2 個 RD**,因為要做 HA + 規則層 + 雲/本地對接
    • Phase 4-5(持續):0.5 個 RD + 0.3 個 CISO 角色就能維護
    • **最低配置:1 個全職 RD + 1 個準 CISO 兼職,跑 4 個月**

    沒有 ISO 認證需求,還要做這套嗎?

    要,只是 Step 14 可以跳。這套架構即使不認證 ISO,**對「accumulating domain knowledge」「員工生產力」「資安基線」三件事**都有獨立價值。ISO 是副產品,不是目的。

    結語:安全 / 穩定 / 累積 / 好用,缺一不可

    大部分企業 AI 治理失敗,不是某一維崩了,是四維沒有平衡:

    • 只要安全 → 員工地下繞過 → 安全也沒了
    • 只要穩定 → 沒有治理 → 半年後變垃圾堆
    • 只要累積 → 沒有 Gateway → 客戶資料外流
    • 只要好用 → 沒有分級 → 一夕事故

    這 16 步的順序,就是「四維平衡的最小可行路徑」。每一步都至少打中兩維,串起來就是一個能跑、能審、能成長、員工願意用的系統。

    第 0 週要做的事只有一件:打開行事曆,把 Step 1 的 Working Group 第一次會議排進去。其他 15 步都會跟著動起來。

    延伸閱讀:《80人公司的AI腦子系統:從個人腦擴展到全公司不洩密的工程設計》 — 講為什麼這樣設計、雙引擎本地+雲、能管 vs 不能管的邊界、拉力哲學。本文是它的實作續篇。

    2026/5 技術棧時間戳

    本文 Step 9-11 涉及的具體工具版本以撰文時間為準:

    • Gateway:LiteLLM(open source)、Portkey(內建 guardrails + PII redaction + 1600+ LLM)、Kong AI Gateway。企業常見組合 LiteLLM + Portkey 雙搭。
    • 本地 LLM:Qwen3-Coder-Next(80B-A3B MoE,256K context)、Qwen3.6、Kimi K2.6、DeepSeek V4、Llama 3.3 70B。Ollama 為日常 default,production 並發推 vLLM V1。
    • 雲端 frontier:Claude Opus 4.7(2026/4)、GPT-5.5(2026/4)、Gemini 3.1 Pro、DeepSeek V4。各家擅長領域不同,「routing by task type」是 2026 主流架構。
    • PII 脫敏:Microsoft Presidio v2.2.362(2025/3 釋出,2026/5 仍是最新版),含 image redactor + DICOM 支援。
    • 合規認證:ISO/IEC 42001:2023(目前唯一可認證的 AI 管理系統標準)。Schellman、TÜV SÜD、BSI、DNV 都是合格認證機構。
  • 80人公司的AI腦子系統:從個人腦擴展到全公司不洩密的工程設計

    重點摘要(TL;DR)

    • 把個人「腦子系統」(CLAUDE.md + brain markdown + skills)擴展到 80 人公司,核心不是技術,是畫清楚「能管」和「不能管」的邊界
    • 架構=雙 Repo(公司腦+個人腦)+ LLM Gateway 中間人 + 雙引擎(本地 model + 雲端 frontier)。員工感受不到分級存在,系統默默路由。
    • 分級判斷用三層漏斗:regex 5ms 攔 90%、小型分類器 300ms 攔 9%、保守 fail-safe 1%。不要員工自選,他們不可能每次選。
    • 「拉力 > 推力」:讓 Gateway 比網頁版 ChatGPT 好用,員工自然不繞過。唯一最重要的 KPI 是「Gateway request 數 ÷ (Gateway + 偵測到的網頁版流量)」
    • 真正的雙贏:傳統 IT 做永遠改不完的 UI,客戶都嫌不好用。AI 時代轉做「給 AI 安全取資料的入口」,客戶用自己愛的 AI 工具,RD 回去做 ISO、審核、累積 domain knowledge。

    緣起:為什麼個人腦子系統撐不住 80 個人

    過去一年,我在自己的多台電腦之間累積了一套「腦子系統」。它由四件東西組成:全域規則(CLAUDE.md)、領域知識庫(brain markdown,例如 OSGi 踩坑、Kafka 注意事項、Shopee API 陷阱)、可重用的能力包(skills)、自動記憶(MEMORY.md + 各種 user/project/feedback 檔)。同步靠 git repo,個人用 100 分。

    但當需求變成「給一間 80 人公司用,讓所有人都能累積知識、快速成長、自行用 AI 開發小工具,並且不限定 Claude Code,可能員工 A 用 Claude、B 用 Cursor、C 用 ChatGPT」,個人架構幾乎所有環節都會崩。本文把整套放大設計鉅細靡遺寫下來,讓 RD 或 IT 主管可以直接拿去當藍圖。

    你以為的「腦子」其實是四層

    先把概念釐清。很多人講「AI 腦子」其實是把四件不同的東西黏在一起,擴展時要分開看待:

    內容 載體 擴展邏輯
    規則層 Iron Rules、語言、Git 流程、安全紅線 CLAUDE.md / .cursorrules 全公司一致,變動少,PR review 嚴管
    知識層 領域踩坑、API 陷阱、業務眉角 brain/*.md 分部門、分主題、有 curator 治理
    能力層 可重用 skill、自動化腳本、模板 skills/, plugins 員工貢獻 + PR + 用量遙測
    記憶層 個人偏好、進行中工作、context MEMORY.md / 個人 .md 永遠留個人,不上中央

    這四層的擴展方式不一樣。規則層是法律,知識層是百科,能力層是函式庫,記憶層是日記。設計時要分開,不能當一坨處理。

    擴展前必須先回答的三個問題

    不要直接跳進畫架構圖。先把這三題定義清楚,不同答案會走到完全不同的系統。

    Q1:「同時使用」是什麼意思?

    • (a) 員工各挑工具,讀同一份共用知識 ✅ 正確答案,可實作
    • (b) 同一任務同時派 Claude + GPT 工作 ❌ 反模式,幾乎沒實用場景

    Q2:員工貢獻知識的開放程度?

    實務建議:opt-out(預設進公司腦,標記私人才留個人),特別是 bug 經驗 — 踩過的坑是最有價值的共享資產。但 opt-out 強制要配「自動脫敏管道」,不然 raw bug log 一進公司腦就帶四種污染:客戶名、訂單 ID、同事名、合約號。

    Q3:資料敏感度怎麼分?

    分級 例子 處理方式
    A 紅 客戶合約、財務數字、員工個資、未公開合作案 嚴禁所有雲端 AI,只能本地 LLM
    B 黃 bug log、客戶踩坑、商務邏輯、process 設計 脫敏後可送雲端
    C 綠 純技術問題、開源元件、公開文件 直接送雲端 frontier model

    務實話:不要追求 100% 不洩漏,要追求「降低洩漏面積」。100% 在 80 人團隊中不存在,追下去會做出沒人用的合規劇場。

    架構藍圖:雙 Repo + LLM Gateway + 雙引擎

    ┌─ 公司腦 repo (private GitHub Org) ─────────────────┐
    │  global/    Iron Rules(PR + 2 reviewer 才能改)      │
    │  teams/                                              │
    │    backend/  brain/* skills/*                        │
    │    frontend/ ...                                     │
    │  shared/skills/  跨部門通用 skills                   │
    │  build/    編譯器:MD → 各工具格式                    │
    │  redact/   自動脫敏規則 + 字典                       │
    └──────────────────────────────────────────────────────┘
                  │ git pull (每天自動)
                  ↓
    ┌─ 員工本機 ─────────────────────────────────────────┐
    │  公司腦/  ← clone 自上面                            │
    │  個人腦/  ← 自己的另一個 repo,永遠不 push 中央       │
    │  build.sh 把兩者編譯到所有工具:                      │
    │   → .claude/CLAUDE.md  (Claude Code/Desktop)        │
    │   → .cursor/rules/     (Cursor)                     │
    │   → .github/copilot-instructions.md (Copilot)       │
    │   → ~/chatgpt-prompt.md (給 Custom GPT 貼用)        │
    └──────────────────────────────────────────────────────┘
                  │ HTTP / MCP
                  ↓
    ┌─ 公司內網 LLM Gateway ─────────────────────────────┐
    │  攔截 → 分級 → 脫敏 → 路由 → 串流回應                │
    │  本地 Ollama (A 級任務專用)                         │
    │  雲端 frontier (B/C 級脫敏後)                       │
    │  審計 log → SIEM                                    │
    └──────────────────────────────────────────────────────┘

    為什麼是「公司腦 + 個人腦」兩個 repo

    • 員工本機把兩個 repo clone 在一起,build.sh 編譯時個人腦覆寫公司腦(個人偏好優先)
    • 個人腦本機 commit,永遠不 push 到中央 — 這就是「自己選擇要不要上」的物理保證
    • 要分享某筆個人筆記時,員工自己 git mv 進公司腦發 PR
    • 「不上傳」變成預設物理行為,不是靠規則約束

    關鍵概念釐清:Brain ≠ Model

    很多人問「為什麼一定要雲?所有人都用本地 model 配腦子就好了啊?」這個直覺方向是對的,但前提是要把兩件事拆開:

    概念 是什麼 耗 GPU? 在哪
    Brain(腦子) Markdown 文件、規則、踩坑紀錄 ❌ 完全不耗 都本地(git repo)
    Model(推理引擎) LLM(Claude / Qwen / Llama) ✅ 很耗 看你選

    腦子永遠該全本地,這沒有爭議 — 它就是 markdown 檔。爭議只在 model 要不要本地。所以真正的問題是「為什麼推理引擎要用雲」。

    為什麼不能「全本地 model」— 三個誠實的事實

    1. 能力差距是真實的

    2026/5 現況:本地頂級開源這一年大幅追上 — Qwen3-Coder-Next(80B 總參 / 3B active,MoE 架構,256K native context)已能跟 Claude Code、Cline、OpenCode 等 coding agent 直接整合;Qwen3.6、Kimi K2.6、DeepSeek V4是 2026/4 的 open-weight 第一梯隊。MoE 架構讓 80B 總參只啟動 3B per token,消費級硬體加量化可跑。但跟 frontier 雲端(Claude Opus 4.7(2026/4)、GPT-5.5(2026/4)、Gemini 3.1 Pro、DeepSeek V4)比,在 long-context agentic、跨檔案 reasoning、tool orchestration 上還是差一個檔次。差距比一年前縮小很多,但沒抹平。

    2. 80 人「全本地」的硬體成本

    • 中央 inference server(8x A100 80GB):採購百萬人民幣級別 + 機房 + 維運,80 人並發要排隊
    • 每人一台 Mac Studio M3 Ultra 192GB:採購 44 萬美金,出差不能用
    • 對比 80 人用 Claude/GPT API:每人每月 $50-200 美金,年成本 5-20 萬美金
    • 雲端在中小公司階段便宜一個量級

    3. 強制全本地會把員工逼地下

    能力不夠 → 員工抱怨 → 私下偷貼資料到 ChatGPT。把人逼到地下,比讓他在地上用更糟。雲端 ≠ 資料變成 OpenAI 訓練資料,Enterprise 合約(Azure OpenAI / AWS Bedrock / Anthropic Enterprise)是另一回事。

    真正的答案:Local-first, Cloud-when-needed(雙引擎)

    員工的 prompt
        ↓
    ┌─ 本地閘門 (Qwen3-Coder-Next / Qwen3.6) ─────┐
    │  1. 偵測敏感度(A/B/C 級)                     │
    │  2. A 級:本地 model 直接處理,不出去           │
    │  3. B 級:自動脫敏後送雲端                     │
    │  4. C 級:直接送雲端                           │
    └──────────────────────────────────────────────┘
        ↓ (B / C 級才會到這)
    ┌─ 雲端 frontier model ────────────────────────┐
    │  Claude Opus 4.7 / GPT-5.5                  │
    │  Gemini 3.1 Pro / DeepSeek V4               │
    │  各家擅長領域不同,Gateway 依任務型別路由       │
    └──────────────────────────────────────────────┘

    這才是「資料安全」和「員工生產力」雙贏的解。全雲洩漏 A 級、全本地犧牲 B/C 級體驗,雙引擎才永續

    LLM Gateway:員工感受不到的中間人

    員工不可能每次手動選分級,要他們按 🟢🟡🔴 三天就沒人用了。正確做法是系統默默判,員工不感知。員工的 IDE / Claude Code / Cursor 不直接連雲端 API,改連公司內網的 Gateway:

    員工的設定只有一行:
    ANTHROPIC_BASE_URL=https://company-llm.internal/v1
    
    之後做什麼都不變。Cursor 還是 Cursor,Claude Code 還是 Claude Code。

    Gateway 的三個職責:

    職責 在做什麼 用什麼
    分級 判 A / B / C Regex + 本地小型 LLM 分類器
    脫敏 B 級資料抽掉客戶名/同事名/合約號 字典 + regex + 本地 LLM 補刀(Microsoft Presidio 可借力)
    路由 送本地還是送雲端 規則引擎

    三層漏斗:5ms 路由掉 90% 流量

    不是「每個 prompt 都過 LLM 判」,那會塞爆。是三層漏斗:

    1. Layer 1:Regex / 字典比對(< 5ms,攔 90%)
      • 含「大有建設」/「老王」/合約號格式 → 紅,本地
      • 純英文技術詞、無中文人名地名 → 綠,雲端
      • 命中就路由,不過 LLM
    2. Layer 2:小型分類器(0.1-0.3 秒,攔 9%)
      • 用 fine-tune 過的 BERT 或 1B-7B LLM 做專門分類
      • 不是 70B 判分級,是 1B 做分類
      • 100ms 級延遲,員工幾乎感受不到
    3. Layer 3:保守路由(fail-safe,1%)
      • 真模糊的 case,全部判 B 級 → 走脫敏 + 雲端
      • 寧可多脫敏,不要誤送:錯就錯在不便利,不要錯在洩漏

    實際員工體驗:問「這個 process 跑 NPE,客戶大有建設訂單 SO20260415 卡住」→ Gateway 5ms 偵測到「大有建設」「SO\d+」→ 自動改寫成「客戶 [CUSTOMER_A] 訂單 [ORDER_ID]」→ 路由到雲端 Claude → 員工完全不知道發生了什麼,只覺得 AI 答得很好。

    能管的世界 vs 不能管的世界

    追求 100% 覆蓋會害死系統。要清楚畫出邊界,每塊用對應措施:

    範疇 可管性 措施
    Claude Code / Cursor / Continue / Aider ✅ 可改 BASE_URL Gateway 嚴管
    Claude Desktop / 自寫 script / n8n ✅ 可改 endpoint Gateway 嚴管
    公司網路出站流量 ✅ Firewall force proxy Gateway 嚴管
    ChatGPT 網頁 / Claude.ai 網頁 ⚠️ Browser extension 半攔 即時 paste 脫敏 + 警告
    GitHub Copilot inline ❌ MS endpoint 不能改 規則 + 教育
    手機 app / 私人裝置 ❌ 物理上管不到 合約 + 信任 + 事後追溯

    核心心法:不假裝管得到不該管的東西。每塊都有對應措施,沒有「假裝有但實際沒有」的灰區。資安部門能說明、員工能理解、出事能追責。

    「拉力 > 推力」的設計哲學

    對「不能管的世界」,訴諸三層(從硬到軟):

    Layer 1: 用「拉力」把人留在 Gateway 裡(最重要)

    讓 Gateway 比網頁版好用,員工自然不繞過:

    • Gateway 自動注入公司腦(員工不用每次貼 context)
    • Gateway 連 frontier 雲(Claude Opus 4.7、GPT-5.5、Gemini 3.1 Pro、DeepSeek V4),員工不用自己付費,還能依任務路由到最強模型
    • Gateway 整合公司 codebase RAG,網頁版做不到
    • Gateway 串流速度比網頁版快(內網直連)

    這是設計哲學的轉換:不是「禁止你用 X」,而是「Y 比 X 好用」。員工是理性人,會選好用的。80 人裡會有 70 人自動留在 Gateway,不用任何 enforcement。

    Layer 2: Browser Extension(半受控的中間地帶)

    • 偵測員工開啟 chat.openai.com / claude.ai / gemini.google.com
    • input 框 paste 時即時 regex 脫敏
    • 大量 paste(>500 字)跳警告:「這段內含 X 個敏感字,已自動替換 Y 個」
    • 不阻擋、不上報,只做防呆 condom

    Layer 3: 規則 + 教育 + 事後追溯

    • 明確紅字 list 寫進員工守則
    • 每季資安訓練(講具體案例)
    • DLP 遙測不阻擋只記 log,事後可追
    • 離職前 audit log 過一遍

    分級對應表怎麼從 0 開始建

    這是組織問題不是技術問題。沒有這張表,所有 Gateway 規則都是空的。

    誰主導

    • 準 CISO 角色(IT 主管 + 法務 + 老闆都接受的人)
    • 不要 IT 一個人定(太技術)
    • 不要法務一個人定(會把所有東西判 A 級,系統失效)
    • 不要部門主管各說各話

    Working Group(5-7 人)

    • 1 × 準 CISO(主導)
    • 1 × 法務(合規紅線)
    • 1 × IT 實作者(技術可行性)
    • 3-4 × 部門 senior(業務視角,挑會用 AI 的人)
    • 1 × 老闆 sponsor(拍板用,不參與每週會)

    四個 Phase(漸進式,不要追求一次到位)

    Phase 時間 目標
    Phase 0 1 週 列資料種類清單(50-100 種)
    Phase 1 2 週 粗分 A/B/C,先有 v0.1
    Phase 2 4-6 週 挑一部門試點,每週開會精修
    Phase 3 持續 全公司 + 月度 patch

    五個必避陷阱

    • ❌「不確定就 A 級」→ 系統失效,員工全跑網頁版
    • ❌ 追求 100% 完整才上線 → 永遠定不下來
    • ❌ 一次寫完不再動 → 6 個月後過時,員工不信任
    • ❌ 黑盒不公開 → 員工不知道為什麼被判 A 級
    • ❌ 法務一個人說了算 → 變成沒人用的合規劇場

    核心原則:先有粗版上線,再用真實流量精修 > 想清楚再上線

    KPI:唯一最重要的數字

    North Star(唯一最重要)

    本月 Gateway request 數
    ÷
    (Gateway request 數 + 偵測到的網頁版 LLM 流量)

    公司網路 DNS / firewall log 看得到員工開了多少次 chat.openai.com / claude.ai / gemini.google.com(域名級,不看內容,沒有隱私問題)。這個比例 = 「員工選 Gateway 的比例」,目標6 個月內達 90%+。< 70% 代表 Gateway 拉力不夠,要查為什麼。

    四象限 Dashboard

    象限 指標 目標
    採用 月活用戶 / 全員 80%+
    替代 North Star 90%+
    體驗 Gateway p50 延遲 < 500ms
    體驗 月度 NPS(vs 網頁版) 4.0/5+
    健康 Layer 1 regex 命中率 > 85%
    健康 員工申訴誤判率 < 0.5%

    月度報告:三個問題就夠

    1. 「上個月 X% 員工選擇 Gateway over 網頁版」← North Star
    2. 「員工繞過 Gateway 的 Top 3 原因」← 下個月修哪邊
    3. 「Gateway 帶來的安全收益 + 成本」← 攔住多少 A 級洩漏、雲端費用變化

    第一個月 MVP 時程

    不要一次蓋大廟。Phase 0 砍到極簡,先讓 Claude Code + Cursor 用戶跑起來,驗證治理流程能不能撐 80 人,再擴展。

    交付
    W1 公司腦 repo + 3-5 條 Iron Rules + build.sh(支援 Claude Code & Cursor)
    W2 個人腦 repo template + 員工 onboarding 文件 + 第一場培訓
    W3 脫敏字典 v0(client_names.txt + employee_names.txt)+ pre-commit hook 擋紅字
    W4 Curator 制度上線(每 team 一個 + 每週 1 小時 review)

    Brain Server / ChatGPT 整合 / 本地 Ollama / 完整 Gateway → 全部砍到 Phase 1(第 2-4 個月)。樂觀估計:1 個全職工程師 3-4 個月做到可上線 Gateway。悲觀:6 個月 + 2 個工程師。

    結語:這是 AI 時代的雙贏

    傳統 IT 部門做了再美的 UI,客戶都會嫌不好用 — 這是 ERP 行業 30 年的詛咒。AI 時代的反轉是:不要再做永遠改不完的 UI 了,做「給 AI 安全取資料的入口」就好。客戶用自己愛的 AI 工具(ChatGPT、Claude、Cursor),透過你架的 Gateway 安全地取資料、做事情。

    這對 RD 是解放:

    • 不再被「客戶嫌頁面醜」「客戶嫌操作太多步」這類無底洞的 UI/UX 工單吃掉時間
    • 可以回去做真正有複利的工作:ISO 流程符合性、資安審核、業務邏輯正確性
    • 每一個 RD 寫的 brain markdown,都是公司 domain knowledge 的長期資產,不會因員工離職就消失
    • 新進員工從第一天就站在累積的 brain 上工作,onboarding 從 3 個月縮到 3 週

    對員工是賦能:每個人都能用自己最熟的 AI 工具,在公司架好的安全護欄內,自行開發小工具、解決自己的痛點。對公司是護城河:domain knowledge 從個人腦袋變成公司資產,可累積、可審計、可傳承。

    整套設計的核心心法只有四句:

    • 能管的嚴管,不能管的不假裝管
    • 拉力 > 推力,讓 Gateway 比網頁版好用
    • 員工不感知,系統默默路由
    • 先粗版上線,真實流量精修

    剩下的就是把 working group 召集起來,開第一次會。

    2026/5 技術參考時間戳

    本文涉及的具體模型版本、開源工具、ISO 標準以撰文時間為準,LLM 領域變化快,請以最新發布為主:

    • 雲端 frontier(2026/4 發布):Claude Opus 4.7、GPT-5.5、Gemini 3.1 Pro、DeepSeek V4。各家擅長領域不同,「routing by task type」已成為主流架構。
    • 本地頂級開源:Qwen3-Coder-Next(80B 總參 / 3B active,MoE,256K context)、Qwen3.6、Kimi K2.6、DeepSeek V4、Llama 3.3 70B。
    • 本地 LLM 平台:Ollama 仍是預設選擇,production 並發推 vLLM V1(2-4 倍吞吐)。
    • AI Gateway 開源工具:LiteLLM(unified API to 100+ providers)、Portkey(observability + guardrails + PII redaction)、Kong AI Gateway。2026 企業常見組合是 LiteLLM 當 proxy + Portkey 做 observability。
    • PII 脫敏:Microsoft Presidio v2.2.362(2025/3 釋出,2026/5 仍是最新版),含 image redactor 與 DICOM 醫療影像支援。
    • 合規標準:ISO/IEC 42001:2023(AI 管理系統,目前唯一可認證 AI 標準)、ISO 27001:2022、ISO 27701。Schellman、TÜV SÜD、BSI、DNV 都是合格認證機構。
  • 我該選哪個 AI 模型?從硬體到能力的白話判斷指南

    選 AI 模型不是看誰最厲害,而是看哪個「裝得進你的機器、會做你的工作、跟你脾氣合」。這篇用白話講清楚怎麼判斷,不需要工程背景就能讀懂。最後附上三種人的實際範例和一張機器等級對照表,讓你看完知道下一步該做什麼。

    重點摘要

    • AI 模型有四關:可不可用、裝不裝得下、擅不擅長、合不合作
    • 「總參數」決定要多少記憶體,「激活參數」決定跑多快 — 兩個不一樣
    • 32GB 記憶體的家用電腦能跑 30B 級的本地模型(壓縮後),別被 700B 的數字嚇到
    • 判斷模型擅長什麼,看 第三方榜單 + 自己跑題目,不要相信廠商海報
    • 不會微調、不寫程式的一般人:雲端 ChatGPT/Claude 比地端模型實用 10 倍

    為什麼這篇不是工程師專用

    很多 AI 模型介紹一上來就講 Transformer、MoE、量化、KV cache,看不懂的人乾脆直接問 ChatGPT 算了。但這樣你永遠不會知道:為什麼有時候 ChatGPT 答得不如另一個工具好?為什麼有人在自己電腦上跑 AI?那台主機要花多少錢?

    這篇用「買菜選菜」的角度切入。選模型就像選餐廳:有的店招牌大但你家附近沒有(雲端 vs 地端)、有的菜單大但你只吃其中三道(總參數 vs 激活參數)、有的師傅擅長熱炒但你想吃日料(文字強但圖片弱)。看懂這幾個對應,後面什麼術語都不會卡住你。

    第一步:先問自己這四個問題

    判斷一個模型「對你來說可不可用」,不是看它在排行榜第幾名,而是先答這四個問題:

    1. 我要它做什麼? — 寫文案、翻譯、寫程式、看 PDF、看圖,選的方向完全不同
    2. 我要在哪裡用? — 雲端服務 (ChatGPT 網站、Claude 網站) 還是裝在自己電腦 (地端)
    3. 我有多少預算? — 雲端是月費或按量計費,地端是一次性硬體投資
    4. 資料能不能上雲? — 病歷、客戶資料、未公開的營業資料,丟雲端要先看公司規範

    這四題答完之後,80% 的人會發現:地端模型不是給你的。雲端 ChatGPT/Claude/Gemini 月費 600-800 台幣,你買得到的「能力」遠超過你自己組一台機器跑 Llama 3。地端只有在「資料不能外流」、「想要客製化微調」、「想當興趣研究」這三種情況才划算。

    第二步:看模型「裝不裝得進」你的機器

    如果你決定走地端,這一關是硬門檻。模型有兩個關鍵數字,廠商常常混在一起講,你要會分:

    總參數 vs 激活參數

    名詞 白話解釋 決定什麼
    總參數 模型「整本書」有多厚 要多少記憶體裝它
    激活參數 每次思考翻幾頁 跑得快不快

    普通模型(像 Gemma 3、Llama 3)「整本翻完」才回答你 — 總參數 = 激活參數。MoE 模型(像 Mixtral、DeepSeek、Gemma 4)「只翻其中幾頁」 — 總參數遠大於激活參數,跑得快但還是要把整本書放進記憶體

    記憶體簡易公式

    用「壓縮過」(技術上叫 Q4 量化) 的模型,大致這樣估:

    • 模型體積 ≈ 總參數 ÷ 2 GB
    • 實際記憶體需求 ≈ 模型體積 + 2~4 GB(系統開銷 + 上下文)

    例子:Gemma 3 27B 模型 → 27 ÷ 2 ≈ 14 GB 模型 + 4 GB 開銷 = 18 GB 記憶體需求。一台 16GB 筆電裝不下,32GB 桌機剛好。

    第三步:看模型擅長什麼

    模型不是萬能。同樣 27B 大小,有的會寫程式但不會看圖,有的中文很爛但英文很強。怎麼判斷?

    看第三方榜單(快速篩選)

    你的需求 看哪個榜單分數 大概及格線
    寫文案、知識問答 MMLU-Pro >65 算強
    寫程式 LiveCodeBench、HumanEval LiveCodeBench >30 可用
    中文能力 C-Eval、CMMLU >70 算強
    看圖、讀 PDF MMMU、DocVQA MMMU >60 算強
    數學、邏輯 MATH、GPQA MATH >70 算強
    綜合(一般使用) LMArena Leaderboard 看 Elo 排名

    自己跑題目(最關鍵)

    榜單分數會作弊,你必須跑「自己工作會碰到的題目」。流程:

    1. 準備 20-30 題你實際工作會碰到的問題(不是從網路抄題目)
    2. 同樣的題目餵給 2~3 個候選模型
    3. 蒙著看答案、給分(別看是誰寫的)
    4. 看「一次到位率」、「中文是否流暢」、「會不會瞎掰」

    這比看任何排行榜都準。我之前在本地 AI 模型完整實測那篇就是用這個方法,五款模型結果完全不照 leaderboard 排名走。

    第四步:確認模型「合作說明書」

    同樣強的兩個模型,「會不會聽指令」差很多。這部分用戶最容易踩雷,要看四件事:

    • 支不支援系統指令(System Prompt) — 例如 Gemma 系列不支援系統指令,你只能塞在第一句話。Llama、Qwen、Claude 都支援。不知道這點會發現「怎麼叫它扮演什麼角色都沒效」。
    • 能不能呼叫工具(Function Calling / Tool Use) — 想做 AI Agent、自動查資料、操作 Excel,模型必須會「呼叫工具」。Claude、GPT、Qwen 強;Gemma 弱要靠土法煉鋼。
    • 能不能吃圖、吃 PDF — 多模態能力。Gemma 3 / GPT-4o / Claude 都吃圖;純文字模型(像 Llama 3 base)看不到圖。
    • 上下文(Context)能裝多少 — 4K 只能聊天、32K 可以吃一份合約、128K 可以吃一本書、1M 可以吃整個資料夾。看你的工作內容多長。

    三種人的實例:看完直接套

    實例一:上班族 Mary(行銷專員)

    需求:寫社群貼文、改履歷、翻譯英文信、整理會議紀錄。一台 8GB 筆電,沒在管什麼資料外流。

    判斷:

    • 地端?不要,8GB 連最小可用模型都裝不下
    • 能力需求:文字 + 中文,不需要寫程式
    • 預算:能接受月費 600-800 元

    建議:直接訂 ChatGPT Plus 或 Claude Pro。免費版偶爾用也夠,只是會在尖峰時段斷線。不要花一分錢買硬體,投資報酬率最差的選擇。

    實例二:工程師阿志(後端開發者)

    需求:寫程式、Code Review、技術文件查詢、自動化腳本。32GB 桌機,公司規定客戶資料不能上雲。

    判斷:

    • 分流:涉及客戶資料的問題用地端,公開資料用雲端
    • 地端能力:寫程式 → Qwen2.5-Coder-32B(壓縮後 ~20GB,塞得進)
    • 雲端:Claude Sonnet 寫程式最強,搭配 Cursor 或 Claude Code

    建議:Ollama 裝 Qwen2.5-Coder-32B 跑地端,Claude Pro 月費跑雲端。兩邊加起來月支出 ~800 元 + 一次性 0 元(用現有電腦)。

    實例三:創作者小凱(YouTuber + 部落客)

    需求:腳本撰寫、字幕翻譯、看 PDF 整理重點、看圖寫敘述、長影片轉文字稿。16GB 筆電 + 一張 RTX 4060(8GB VRAM)。

    判斷:

    • 多模態(吃圖)是剛需 → 模型必須支援
    • 16GB 筆電能跑 8B-12B 級的多模態小模型(像 Gemma 3 12B)
    • 長影片字稿要長 context → 32K 起跳

    建議:雲端為主(ChatGPT 或 Gemini 看圖最強),地端裝 Gemma 3 12B 當備援(網路斷或想離線時用)。腳本創意給雲端、批量字幕翻譯給地端省錢。

    機器等級對照表:你的硬體能跑到哪

    下表用 Q4 壓縮後的本地模型尺寸估算。「速度感受」是 CPU 推理(沒獨顯)的體感:

    機器等級 能跑的最大模型 速度感受 適合
    8GB RAM 筆電 放棄,直接走雲端 N/A Mary(上班族)
    16GB RAM 筆電 7B-12B 模型(Gemma 3 12B、Llama 3 8B) CPU 跑會卡,有獨顯才順 輕度離線備援
    32GB RAM 桌機 26B-32B 模型(Gemma 4 26B MoE、Qwen2.5-32B) MoE 模型可用,Dense 慢但能跑 阿志(開發者)
    64GB RAM 工作站 70B 模型(Llama 3.3 70B) CPU 很慢,要獨顯才實用 研究、實驗
    RTX 3090/4090 (24GB VRAM) 27B-32B 模型,速度飛起 流暢,接近 ChatGPT 體驗 認真做地端 AI 的甜蜜點
    2x RTX 4090 / A100 70B 模型流暢、Mixtral 等大 MoE 商用級 公司部署、付費服務

    關鍵原則:沒有獨立顯示卡的話,別買貴的桌機去跑大模型。CPU 推理 30B 級模型每秒只吐 2-5 個字,寫一封信要等三分鐘,用一次就會放棄。要嘛走雲端,要嘛投資一張二手 RTX 3090(約 2 萬台幣)。我之前測過 AMD 內顯 (iGPU) 跑 Gemma 4 也會踩坑,內顯不是省錢方案。

    最後:我該問自己的 7 個問題

    把這份清單存起來,下次有人推薦你「某某新模型超強」時,逐題核對一遍:

    1. 我用 AI 來解什麼具體問題?(模糊回答 = 還沒想清楚,先別買硬體)
    2. 這些問題,雲端的 ChatGPT/Claude 已經能解嗎?(能 → 直接訂閱,不要繞遠路)
    3. 我的資料能不能上雲?(不能 → 才考慮地端)
    4. 我的機器有多少記憶體和顯卡?(對照本文那張表)
    5. 這個模型在我關心的能力(寫程式 / 中文 / 看圖)分數怎樣?(看榜單再自己跑題)
    6. 這個模型的「合作說明書」有什麼坑?(系統指令、工具呼叫、上下文長度)
    7. 用一個月後,我真的有用嗎?(很多人裝完地端模型用三天就涼了,雲端訂閱反而沒浪費)

    結論一句話:普通人選雲端、有資料安全顧慮的選地端、想當興趣研究的選地端 + 雲端混用。買硬體之前,先把第 1、2、7 題答清楚,就會省下七成不必要的開銷。

  • gemma4:e4b 在 AMD Renoir iGPU Vulkan 輸出亂碼的完整排查

    重點摘要

    • gemma4:e4b 在 AMD Renoir iGPU(Vulkan)超過 30 層就輸出亂碼,低層數正常
    • 根本原因:RADV Vulkan shader compiler 的精度優化破壞 f16 運算順序,誤差隨層數滾雪球
    • iGPU 沒有獨立 VRAM,記憶體從系統 RAM 借,RAM 不足會讓模型載入循環崩潰
    • Mac Metal / 純 CPU 不受影響;GGML_VK_DISABLE_F16 等環境變數無法修復底層 compiler bug

    在本地端跑大型語言模型時,GPU 加速聽起來理所當然——更快嘛。但如果 GPU 算出來的答案是錯的,快有什麼用?這篇文章記錄了一次真實的踩坑:gemma4:e4b 在 AMD Renoir iGPU 上透過 Vulkan 跑出亂碼的完整排查過程,以及背後一層比一層深的技術原因。

    事件起因:模型跑得快,答案全錯

    測試環境是一台搭載 AMD Renoir APU 的 mini PC,透過 Ollama 跑 gemma4:e4b 模型。Ollama 偵測到 iGPU 後自動啟用 Vulkan 加速,把 42/43 層 offload 到 GPU。

    速度看起來不錯,約 8 tok/s。但仔細看輸出內容,發現問題大了:

    • 問「什麼是 Kafka Consumer Group Rebalancing」→ 回答泰文的學習理論
    • 問 Python 日期解析函數 → 回答 JavaScript offsetTop 的用法
    • 問燈泡謎題 → 回答哲學框架

    模型完全沒理解問題,像是跑在另一個平行宇宙一樣。

    第一個坑:RAM 不足讓模型連載入都不穩定

    在問為什麼答案亂之前,先碰到一個更早的問題:模型根本載入不起來。第一次啟動時,Ollama 日誌出現了這個循環:

    16:35:53  offloaded 42/43 layers to GPU(模型開始載入)
    16:38:53  llm server not responding
    16:38:54  llm server loading model
    16:39:02  llm server not responding
    16:39:03  llm server loading model
    ...(反覆了將近 6 分鐘)
    16:42:28  llama runner started in 410.58 seconds(終於啟動)
    17:04:49  -- Boot --(機器直接重開機)

    當時系統狀況:OMS 全套服務正在運行,RAM 只剩 1.7 GiB 可用。停掉 OMS 釋放記憶體後重跑:

    llama runner started in 42.04 seconds

    差了 10 倍。問題不在模型,在記憶體。

    為什麼 iGPU 需要大量系統 RAM?

    AMD Renoir iGPU 沒有獨立顯存,它的記憶體架構分兩層:

    類型 來源 大小 特性
    UMA(Unified Memory) BIOS 開機時從系統 RAM 切出 2 GiB(此台設定) 固定預留,GPU 專用,穩定
    GTT(Graphics Translation Table) 從剩餘系統 RAM 動態借用 最多 ~6.8 GiB 依可用 RAM 決定,借不到就崩

    Ollama 顯示「8.8 GiB 可用 VRAM」= UMA(2 GiB)+ GTT 上限(~6.8 GiB)合計。

    跑 gemma4:e4b 需要 2.8 GiB GPU weights + 224 MB KV cache + 289 MB compute graph ≈ 3.3 GiB。流程是:

    1. 先用完 2 GiB UMA
    2. 再向 GTT 借 ~1.3 GiB 的系統 RAM 頁面
    3. GTT 的頁面必須來自空閒的系統 RAM

    OMS 開著只剩 1.7 GB 可用,GPU 借不到足夠的 GTT 頁面,runner 一直崩潰重試,才出現那個 6 分鐘的死循環。最後機器因為 OOM 直接 reboot。

    換句話說:iGPU 的「VRAM」是假的,它在跟你的程式搶同一塊系統 RAM。獨顯不會有這個問題,因為它有真正的 GDDR 記憶體。

    GPU 與 GPU 的差異:不是每顆都一樣精準

    解決了載入問題,答案還是亂的。這時才是 GPU 精度的核心問題。

    GPU API f16 硬體支援 ML 成熟度
    NVIDIA RTX CUDA 原生 Tensor Core,為 ML 設計
    Apple M 系列 Metal Neural Engine + Metal 緊密整合
    AMD RX 獨顯 ROCm / Vulkan 原生支援,ROCm 驗證過 中高
    AMD Renoir iGPU Vulkan(RADV) Vega 架構,遊戲導向,未針對 ML 驗證

    f16 規格一樣,為什麼結果不同?

    很多人的疑問:IEEE 754 fp16 是標準規格,大家都遵守,為什麼不同 GPU 算出來不一樣?

    因為規格只定義單一運算的結果,但沒有規定三件事:

    1. Denormal 數的處理方式:非常接近 0 的浮點數(小於 6×10⁻⁸)稱為 denormal。IEEE 標準要求保留精度處理,但 AMD Vega 架構預設會把這些數 flush to zero(FTZ)——直接歸零——以換取效能。NVIDIA 不做 FTZ。這在遊戲中完全沒影響,但 LLM attention 的 softmax 運算大量出現這個範圍的數值。
    2. 運算順序:浮點數不符合結合律(a + b) + c ≠ a + (b + c) 在 fp16 中是真的。Shader compiler 為了讓 GPU 並行效率最大化,會自由重排運算順序,這對遊戲結果沒有可見影響,但 LLM 的 attention 矩陣乘法有幾萬次浮點運算,順序一改,誤差模式就完全不同。
    3. FMA(Fused Multiply-Add)的使用時機a × b + c 可以分兩步算(兩次取整),也可以融合成一步(只取整一次,精度更高)。NVIDIA CUDA 強制所有路徑用 FMA。RADV 的 ACO shader compiler 根據優化情境決定,在某些 LLM 矩陣模式下選了非 FMA 路徑。

    這三個問題疊在一起,每一層的誤差模式都不同,而且誤差會被下一層當成合法輸入繼續放大。

    為什麼低層數正常、高層數亂碼?

    什麼是 Transformer 的「層」

    gemma4:e4b 是 Transformer 架構,共 43 層。每個 token 的生成,資料要依序流過全部 43 層,每一層的輸出是下一層的輸入:

    Token 輸入
      → Layer 1(基礎語法、token 特徵)
      → Layer 2 ~ 10(語法結構、基礎語意)
      → Layer 10 ~ 25(上下文理解、語意推理)
      → Layer 25 ~ 42(高階抽象、輸出生成)
      → 下一個 token

    當設定 num_gpu=N 時,前 N 層在 GPU 算,剩下的在 CPU 算

    誤差如何滾雪球

    Layer  1:正確值 2.000,Vulkan 算出 2.001 → 誤差 0.001(無感)
    Layer  5:誤差疊加,下層把這個「略偏的 2.005」當成正確輸入繼續算
    Layer 10:誤差影響語意方向判斷
    Layer 20:模型對問題的理解開始偏移
    Layer 30:完全脫離正確答案空間
    Layer 42:輸出隨機語言的 token,變成泰文或法文

    這就像傳話遊戲:每個人傳話都有一點偏差,傳到第 43 個人時,內容已經面目全非。

    為什麼簡單問題(1+1)還能過

    「1+1 等於幾」的答案空間極小——就算誤差很大,最終 token 機率分布仍然在「2」附近。但「請用 Python 寫一個函數處理三種日期格式」的答案空間是整個程式語言的 token 集合,一旦偏移,就隨機落到任何地方。這也是為什麼診斷時不能只用簡單問題測試,必須用複雜 prompt 才能暴露問題。

    診斷過程:二分法找臨界點

    for layers in 1 5 10 20 30 40 42; do
      echo -n "=== num_gpu=$layers === "
      curl -s http://localhost:11434/api/chat \
        -d "{\"model\":\"gemma4:e4b\",
             \"messages\":[{\"role\":\"user\",\"content\":\"1+1等於幾?\"}],
             \"stream\":false,
             \"options\":{\"num_gpu\":$layers,\"num_predict\":30}}" \
        | python3 -c "import json,sys; print(json.load(sys.stdin)['message']['content'])"
    done
    num_gpu 結果 狀態
    1 1+1 等於 2 ✅ 正確
    5 1+1 等於 2 ✅ 正確
    10 (空白) ⚠️ 不穩定
    20 簡單問題偶爾正確 ⚠️ 不穩定
    30 法文回應 ❌ 亂碼
    42 隨機英文片段 ❌ 亂碼

    嘗試修復:三種方案全部失敗,以及為什麼

    方案一:GGML_VK_DISABLE_F16=1

    理論上這個環境變數應該告訴 llama.cpp 在 Vulkan 路徑使用 f32 計算,避開 f16 精度問題。但沒有效果。原因在於 Vulkan 推論的整個管線分四層:

    1. llama.cpp         → 寫 GLSL compute shader 原始碼        ← 環境變數影響到這層
    2. glslang           → 編譯成 SPIR-V bytecode
    3. RADV / ACO        → 把 SPIR-V JIT 編譯成 AMD GCN 機器碼  ← 精度 bug 在這層
    4. AMD Vega 硬體     → 執行機器碼

    精度 bug 在第 3 層——RADV 的 ACO shader compiler 在把 SPIR-V 轉成 GCN ISA 時,對某些矩陣運算的指令做了重排或合併,這個行為由 RADV 自己決定,應用層的環境變數完全碰不到。就算第 1 層寫了 f32,RADV 也可能在編譯時把某些中間值降轉成 f16——這對遊戲是合法的效能優化,對 LLM 是致命的。

    方案二:OLLAMA_KV_CACHE_TYPE=f32

    只影響 KV cache 的儲存精度,不影響主要的矩陣乘法計算路徑。輸出直接變成旁遮普語。

    方案三:num_gpu=20 折衷

    1+1 這種極簡問題可以過,但稍微複雜的 prompt 仍然亂答。誤差臨界點比簡單測試顯示的還要低,不穩定。

    最終結論

    方案 速度 正確性 建議
    純 CPU(num_gpu=0) ~1 tok/s ✅ 正確 唯一可用方案
    Vulkan 全層(num_gpu=42) ~8 tok/s ❌ 亂碼 不可用
    Mac Metal(同款模型) ~8 tok/s ✅ 正確 最佳選擇

    快 8 倍但答案全錯,還不如 1 tok/s 的純 CPU。資料正確性永遠優先於速度。

    如果你也遇到類似問題:排查步驟

    1. 先確認系統有足夠空閒 RAM(至少要比模型大小多 2 GiB),不然連載入都會失敗或 OOM reboot
    2. num_gpu=0 跑純 CPU,確認模型本身答案正確
    3. 逐步增加 num_gpu(1 → 5 → 10 → 20 → …),用複雜問題測試(不要只用 1+1),找到亂碼的臨界層數
    4. 環境變數(GGML_VK_DISABLE_F16、OLLAMA_KV_CACHE_TYPE)對 RADV 底層 compiler bug 無效,不要在這裡浪費時間
    5. 若根本無法修,接受純 CPU 或換有 CUDA / Metal 支援的環境

    這不是 Ollama 的 bug,也不是模型的問題。是 AMD Renoir Vega iGPU + RADV Vulkan shader compiler 在 LLM 工作負載下的精度限制,加上 iGPU 共享系統 RAM 的架構特性,兩個問題同時踩到。

  • 本地 AI 模型完整實測:五款模型 × 兩台機器 × 三種設定,找出真正的上限

    重點摘要

    • Mini PC(Ryzen 7 4700U):gemma4:e4b 最快(1.45 tok/s),qwen3:14b 最完整(7/7 題全答);Bonsai 8B 因 AVX-512 需求完全無法使用
    • 換一台機器差多少?:同款 gemma4:e4b,MacBook Air M3 跑出 9.75 tok/s,是 Mini PC 的 6.7 倍;Q2 輸出從截斷 300 tokens 變成完整 2218 tokens
    • 開 Thinking 差多少?:速度幾乎不變(-6%),但 Q2 程式碼輸出 +65%,Q7 技術解釋 +124%,品質接近 GPT-3.5

    你想在本地跑 AI 模型,但不知道哪款模型值得裝?硬體夠不夠?開 Thinking 模式到底有沒有差?這篇文章用實際跑出來的數據回答這三個問題——五款模型 × 兩台機器 × 三種設定,全部實測,沒有廣告。

    測試環境分別是一台平價 Mini PC(Ryzen 7 4700U,16GB RAM,CPU-only)和 MacBook Air M3(24GB 統一記憶體)。七道測試題涵蓋:文字理解、Python 程式碼生成、SQL 查詢、TCP 技術解釋等真實使用情境。

    測試環境規格

    項目 Mini PC MacBook Air M3
    處理器 AMD Ryzen 7 4700U Apple M3
    記憶體 16GB DDR4(CPU-only) 24GB 統一記憶體
    顯示卡 AMD Vega 7 iGPU,僅 128MB VRAM(不可用) Apple GPU(共享統一記憶體)
    推論框架 Ollama + llama.cpp(CPU 模式) Ollama + llama.cpp(Metal)
    特殊限制 無 AVX-512,部分模型無法執行 無限制

    重點摘要表(先看這三張表)

    表 1:Mini PC 五款模型速度與完成度對比

    模型 平均速度 完成度 主要問題
    Bonsai 8B 0.001 tok/s 完全不可用 需要 AVX-512,CPU 不支援
    qwen3:4b 0.78 tok/s 5/7(部分截斷) Q2/Q5 在 300 token 限制下截斷或夾雜文字
    qwen3.5:9b 0.57 tok/s 5/7 Q6/Q7 需延長 timeout 至 1800s
    qwen3:14b 0.58 tok/s 7/7 全答 無截斷問題,但速度慢
    gemma4:e4b 1.45 tok/s 5/7(舊測試 600 上限) Q2/Q4 在 600 token 舊限制下截斷

    表 2:同款 gemma4:e4b,硬體差距

    指標 Mini PC(CPU) MacBook Air M3 差距
    平均速度 1.45 tok/s 9.75 tok/s 6.7×
    Q2 輸出長度 600 tokens(截斷) 2218 tokens(完整) 記憶體夠,才不截斷
    Q4 輸出長度 600 tokens(截斷) 1043 tokens(完整) SQL 查詢完整輸出
    最大 num_ctx 受 16GB 限制 65536+ 長文件處理能力天差地別

    表 3:Mac 上同款模型,三種設定對比

    設定 平均速度 Q2 輸出 Q7 輸出 適合場景
    Mini PC 舊測試(600 limit) 1.45 tok/s 截斷 309 tokens 快速查詢
    Mac think:false,無限制 9.75 tok/s 2218 tokens ✅ 442 tokens 日常程式碼
    Mac Thinking 開啟,無限制 9.16 tok/s(-6%) 3670 tokens ✅ 990 tokens 複雜推理、技術解釋

    第一層:Mini PC 上,哪個模型值得跑?

    在只有 CPU 推論的環境下,選模型就是在「速度」與「品質」之間做取捨。以下是完整的三維評估。

    Bonsai 8B:直接淘汰

    Bonsai 8B 的速度是 0.001 tok/s——不是很慢,是根本無法執行。原因是它的量化版本依賴 AVX-512 指令集,而 Ryzen 7 4700U 不支援 AVX-512(只有 AVX2)。llama.cpp 在這種情況下會退回軟體模擬,速度接近零。如果你的機器是 Intel 第 11 代以後或 AMD Zen 4 以後,才有機會跑 Bonsai 8B。

    qwen3:4b:最快但有截斷風險

    qwen3:4b 在 Q1~Q7 七個量化等級測試中,平均跑出 0.78 tok/s,是 CPU 上可用模型裡的最高速。但在 num_predict=300 的限制下,Q2(程式碼生成)和 Q5(格式輸出)出現截斷或夾雜不相關文字的問題。如果你只需要短問短答,qwen3:4b Q6 量化(約 21 元台幣月費 API 等級)是最划算的選擇。

    qwen3.5:9b vs qwen3:14b:9B 更快但 14B 更可靠

    qwen3.5:9b 平均 0.57 tok/s,但 Q6/Q7 題遇到了 timeout 問題——需要將請求超時設定延長到 1800 秒才能完成。原因是 9B 模型在複雜任務上思考時間較長,但預設 timeout 不夠。

    qwen3:14b 同樣 0.58 tok/s,卻跑出 7/7 完整答題率。它的 Q2 完整輸出 500 tokens、Q4 完整輸出 500 tokens,沒有截斷。代價是記憶體佔用更高,在 16GB 機器上跑 14B 模型時需要注意 KV Cache 可能 OOM(記憶體不足),建議設定 num_ctx 不超過 4096。

    gemma4:e4b:速度最快的完整模型

    gemma4:e4b 平均 1.45 tok/s,是所有可用模型中最快的,幾乎是 qwen3:14b 的 2.5 倍。在舊測試的 600 token 限制下,Q2 和 Q4 被截斷。但如果移除限制(num_predict=-1),這個問題就不存在——這正是下一層要說的。

    Mini PC 選模型建議:

    • 追求速度 → gemma4:e4b(1.45 tok/s,移除 token 限制)
    • 追求品質 → qwen3:14b(7/7 完整,0.58 tok/s)
    • 省記憶體 → qwen3:4b Q3/Q4(短任務夠用)
    • 不建議 → Bonsai 8B(AVX-512 門檻)、qwen3.5:9b(需調 timeout)

    第二層:同款模型,換台機器差多少?

    用同款 gemma4:e4b,在 Mini PC 和 MacBook Air M3 上各跑一輪,看看換硬體能得到什麼。

    速度差 6.7 倍,不只是快慢的問題

    Mini PC 平均 1.45 tok/s,Mac 平均 9.75 tok/s。這個差距背後的原因是架構:Mini PC 用 x86 CPU 做矩陣運算,效率遠低於 Apple Silicon 的 Neural Engine + 統一記憶體架構。M3 的統一記憶體讓 CPU 和 GPU 共享同一塊 24GB,模型權重可以直接放在 GPU 能讀取的記憶體,不需要搬移。

    記憶體夠,輸出才完整

    這是硬體差距最直接的體現:Q2 要求生成一個能解析多種日期格式的 Python 函式,Mini PC 在 600 token 限制下就截斷了(回答還在中途),而 Mac 無限制跑出 2218 tokens 的完整函式

    Q4 要求生成帶有 CTE 和 Window Function 的複雜 SQL,Mini PC 截斷,Mac 輸出完整 1043 tokens 含說明。這不是模型能力的差異,是記憶體和 KV Cache 空間的差異。

    24GB 統一記憶體的隱藏優勢:num_ctx 可拉到 65536+

    num_ctx 決定模型能「看到」的上下文長度。Mini PC 的 16GB RAM 在跑 gemma4:e4b 時,實際可用的 KV Cache 空間有限,num_ctx 設太高就 OOM。Mac 的 24GB 統一記憶體可以輕鬆設定 num_ctx=65536,意味著可以貼入整個程式碼檔案、長文件、對話紀錄,模型不會「忘記」前面說了什麼。這個差距在實際工作流中比速度差距更重要。

    第三層:同台機器,調設定差多少?

    在 MacBook Air M3 上,用同款 gemma4:e4b 比較三種設定:舊測試的 600 token 限制、無限制(think:false)、開啟 Thinking 模式。

    速度幾乎不變,但輸出長度和品質大幅提升

    think:false 無限制:平均 9.75 tok/s。Thinking 開啟無限制:平均 9.16 tok/s。速度只差 6%,但輸出品質差距大:

    • Q2(Python 程式碼):2218 tokens → 3670 tokens(+65%),Thinking 版本多了完整的邊界條件處理和說明文字
    • Q4(SQL 查詢):1043 tokens → 1413 tokens(+35%),多了欄位說明和效能備注
    • Q7(TCP 三次握手):442 tokens → 990 tokens(+124%),Thinking 版本多了為何需要三次的深層解釋

    Thinking 模式讓模型在回答前先「想」一遍,輸出的答案更完整、更有條理。對於技術問題、程式碼生成、複雜推理,這個設定幾乎是免費的品質提升。

    gemma4:e4b 全力展開:這就是本地 LLM 的真實上限

    以下展示 Thinking 模式在 Mac 上的實際輸出,讓你判斷品質是否符合你的需求。

    Q2 Thinking:完整的多格式日期解析函式

    問題:「寫一個 Python 函式,能解析 YYYY-MM-DD、YYY/MM/DD(民國年)、YYYYMMDD(8位)、YYYMMDD(7位民國年)四種格式。」

    Thinking 模式輸出 3670 tokens,以下是完整的函式程式碼:

    from datetime import datetime
    import re
    
    def parse_mixed_date_string(date_str: str) -> datetime:
        if not isinstance(date_str, str):
            raise TypeError("輸入必須是字串 (string) 格式。")
        date_str = date_str.strip()
    
        # 模式 A: YYYY-MM-DD
        if re.fullmatch(r'\d{4}-\d{2}-\d{2}', date_str):
            try:
                return datetime.strptime(date_str, "%Y-%m-%d")
            except ValueError:
                pass
    
        # 模式 B: YYY/MM/DD(含民國年)
        if re.search(r'[/]', date_str):
            parts = date_str.split('/')
            if len(parts) == 3:
                year, month, day = parts[0], parts[1], parts[2]
                try:
                    temp_date_str = f"{year.zfill(4)}-{month.zfill(2)}-{day.zfill(2)}"
                    return datetime.strptime(temp_date_str, "%Y-%m-%d")
                except ValueError:
                    pass
    
        # 模式 C: YYYYMMDD(8位)
        if re.fullmatch(r'\d{8}', date_str):
            try:
                return datetime.strptime(date_str, "%Y%m%d")
            except ValueError:
                pass
    
        # 模式 D: YYYMMDD(7位民國年)
        if re.fullmatch(r'\d{7}', date_str):
            try:
                year = date_str[:-4]
                month = date_str[-4:-2]
                day = date_str[-2:]
                temp_date_str = f"{year.zfill(4)}-{month}-{day}"
                return datetime.strptime(temp_date_str, "%Y-%m-%d")
            except ValueError:
                pass
    
        raise ValueError(f"無法識別或解析的日期格式:'{date_str}'")

    非 Thinking 模式在同題只輸出 2218 tokens,函式邏輯正確但缺少邊界案例說明和型別標注說明。Thinking 版本多的那 1452 tokens 全是有用的:錯誤處理說明、邊界條件討論、使用範例。

    Q4 Thinking:帶 CTE 和視窗函數的複雜 SQL

    問題:「找出每個城市近 30 天消費金額前三名的顧客,輸出城市、姓名、消費總額。」

    WITH RecentSpending AS (
        SELECT o.customer_id, SUM(o.amount) AS total_spending
        FROM orders o
        WHERE o.created_at >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
        GROUP BY o.customer_id
    ),
    RankedCustomers AS (
        SELECT c.name, c.city, rs.total_spending,
            RANK() OVER (PARTITION BY c.city ORDER BY rs.total_spending DESC) as city_rank
        FROM RecentSpending rs
        JOIN customers c ON rs.customer_id = c.id
    )
    SELECT city, name, total_spending
    FROM RankedCustomers
    WHERE city_rank <= 3
    ORDER BY city, city_rank;

    Thinking 版本(1413 tokens)在 SQL 後面額外附上了欄位說明對照表、RANK vs DENSE_RANK 的差異說明、以及在資料量大時建議加索引的備注。這種「自動補充說明」的行為,在程式碼審查或教學場景特別有用。

    Q7 Thinking:TCP 三次握手的技術解釋

    問題:「解釋 TCP 三次握手的過程,並說明為什麼需要三次而不是兩次。」

    Thinking 模式的回答(節錄,990 tokens):

    TCP 三次握手是在兩台設備開始傳輸實際資料之前,建立穩定可靠連線的過程:

    1. Client → Server (SYN):「我想連線,序列號從 X 開始」
    2. Server → Client (SYN-ACK):「我收到了,我也準備好,序列號從 Y 開始」
    3. Client → Server (ACK):「我收到你的確認,正式連線」

    為何需要三次而不是兩次:三次握手確保雙方的「發送能力」和「接收能力」都得到驗證。第三次 ACK 讓客戶端確認成功收到伺服器的肯定回應,確保雙方對初始序列號達成共識。若只有兩次,Server 無法確認 Client 是否真的收到了 SYN-ACK,可能導致半開連線(half-open connection)堆積。

    非 Thinking 模式(442 tokens)的回答只覆蓋了步驟本身,沒有解釋半開連線問題。Thinking 版本的 990 tokens 多出了協議設計的「為什麼」。

    技術踩坑筆記

    坑 1:AVX-512 問題不是模型 bug,是 CPU 選錯了

    Bonsai 8B 需要 AVX-512,AMD Ryzen 4000 系列(Zen 2 架構)不支援。解法:換用 AVX2 相容的量化版本,或換到支援 AVX-512 的 CPU(Intel 11th Gen+、AMD Zen 4+)。在買 Mini PC 跑本地 LLM 之前,先確認 CPU 指令集支援情況。

    坑 2:num_predict=300 在 CPU 機器上是陷阱

    設 num_predict=300 看起來是「省時間」,但會讓程式碼生成等長輸出任務的測試結果完全失效。正確做法是設 num_predict=-1(無限制),然後觀察模型自然停止的位置。如果真的需要截斷,至少設到 1000 以上再做程式碼類測試。

    坑 3:qwen3.5:9b 的 timeout 問題

    qwen3.5:9b 在 Q6(長文生成)和 Q7(技術解釋)上,Ollama 預設的請求 timeout 不夠,導致連線中斷而不是模型輸出完成。解法:在呼叫 API 時設定 timeout 參數為 1800 秒,或在 Ollama 的環境變數中調整 OLLAMA_TIMEOUT。

    坑 4:KV Cache OOM 發生在 num_ctx 設太高時

    在 16GB 機器上跑 qwen3:14b,如果 num_ctx 設到 8192 以上,KV Cache 的記憶體需求會超過可用 RAM,導致 OOM 或系統卡死。建議 16GB RAM 跑 14B 模型時,num_ctx 不超過 4096;跑 4B 模型時,num_ctx 可以到 8192。

    坑 5:think:false 是必要的,否則輸出會混入思考過程

    qwen3 系列模型如果不設定 think:false,輸出會包含 <think> 標籤包裹的推理過程,混在正式答案裡,對程式解析造成困擾。在 Ollama API 呼叫時加上 "options": {"think": false},或使用 /set parameter think false。只有在你明確需要 Thinking 輸出時才開啟。

    坑 6:num_predict 是物理截斷,不是智慧壓縮

    很多人以為設 num_predict=600 會讓模型「給出精簡版本」,實際上不是。模型不知道 num_predict 這個參數的存在——它只是一個一個往下生成 token,到達上限時被外力硬切斷。結果是:程式碼寫到一半沒有結尾大括號、SQL 少了 WHERE 條件、解釋說到一半消失。

    這次測試的 Q2(日期解析函數)和 Q4(SQL 排名查詢)在 num_predict=300 時全數截斷就是這個原因。移除限制(num_predict=-1)之後,模型自然停止,輸出完整。

    坑 7:有些內容本質上無法壓縮到指定長度內

    假設你問模型「給我一份完整 Kafka 設定檔,限制 50 個 token 內」——這兩個要求本身就互相矛盾。一份能正常運作的 Kafka 設定檔,光是必要欄位就需要遠超 50 token。模型沒有辦法把磚頭塞進比磚頭小的洞。

    面對不可壓縮的內容,有三種做法:(1)直接移除 token 上限;(2)分步請求——先要最精簡模板,確認結構後再要完整版;(3)在 prompt 明確說「輸出必須完整可執行,不要省略任何欄位」,但前提是 token 上限本身要夠大。

    補充:不同模型怎麼面對衝突指令?

    這裡有個值得理解的差異:本地模型(Ollama + llama.cpp)的 token 限制來自 API 參數,是硬體截斷,模型本身完全不知道有這個限制存在。雲端模型(Claude、GPT-4 等)的「限制」則來自 prompt 文字指令,模型讀到這個指令後會嘗試推理你的真實意圖。

    情境 本地模型(Ollama) 雲端模型(Claude)
    限制來源 num_predict API 參數 prompt 文字指令
    遇到「50 token 內給完整設定檔」 不知道有衝突,第 50 個 token 硬截 判斷兩個要求互相矛盾,主動說明,給完整版
    答案冗長可縮短的情況 按字數截斷,不壓縮 推理目標,給出精簡版本
    答案本質不可壓縮 截斷,輸出殘缺內容 告知無法在限制內完整輸出,給出建議
    GPT / Gemini 回答為什麼那麼短? 不是 token 限制,是 System Prompt + RLHF 訓練偏好所致

    這個差異的實際意義是:在本地 LLM 環境下,token limit 是你唯一能控制輸出長度的工具,設太小就會截斷。雲端模型則更像是在和一個理解你意圖的人對話——你不需要精準計算 token,只需要把你真正想要的說清楚。

    進階應用:讓本地 LLM 記住對話上下文

    本地 LLM 的 API 呼叫預設是無狀態的——每次送出的是獨立的單輪問答,模型不記得你上一題問了什麼。如果你想做多輪對話助理、程式碼審查工具、或任何需要「記住脈絡」的應用,就需要自己管理對話歷史。

    為什麼不能無限加長 messages?

    標準做法是把整段對話歷史塞進 messages 陣列一起送出。但對話越長,messages 陣列越大,最終超過 num_ctx 上限,前面的對話就會被硬截斷——模型在不知情的狀況下「失憶」,不會告訴你它看不到前面的內容。

    解法不是把 num_ctx 設更大(那只是延後問題),而是主動管理 messages 陣列:用摘要壓縮舊對話,只保留近期原文加上一段精簡的歷史摘要。

    三種管理策略比較

    方式 num_ctx 用量 記憶效果 適合場景
    無管理(全部塞) 持續增長,最終截斷 前期對話被硬切,模型不自知 短對話、單次任務
    Sliding Window(只保留近 N 輪) 固定 早期資訊完全消失 客服機器人、無需長記憶的助理
    摘要壓縮(推薦) 固定,摘要極短 保留關鍵結論、數字、決策 開發助理、長程任務、知識型問答

    摘要壓縮的運作方式

    核心思路是:用同一個本地模型來摘要自己的舊對話。超過門檻後,把早期輪次壓縮成一段文字,之後每次送出時帶著「摘要 + 近期原文」,而不是全部歷史。

    第 1-8 輪:原文保存在 messages[]
    
    第 9 輪觸發壓縮:
      old[1-5輪] → summarize() → "重點:xxx, yyy, zzz"
      messages 只留 [6-8輪原文] + 新問題
    
    第 9 輪實際送出的內容:
      system: "對話背景摘要:重點 xxx, yyy, zzz"
      user(6): ...  ai(6): ...
      user(7): ...  ai(7): ...
      user(8): ...  ai(8): ...
      user(9): 現在的問題

    完整 Python 實作(本地 Ollama 版)

    import json, urllib.request
    
    MAC_URL = "http://192.168.1.xxx:11434/api/chat"  # Mac 的 Ollama,Mini PC 不跑本地模型
    MODEL  = "gemma4:e4b"
    
    def call_model(messages, think=False):
        payload = {
            "model": MODEL,
            "messages": messages,
            "stream": False,
            "think": think,
            "options": {"num_ctx": 4096, "num_predict": -1}
        }
        data = json.dumps(payload).encode()
        req = urllib.request.Request(
            MAC_URL, data=data,
            headers={"Content-Type": "application/json"}
        )
        with urllib.request.urlopen(req, timeout=300) as r:
            return json.loads(r.read())["message"]["content"]
    
    def summarize(messages):
        """把舊對話丟給模型,壓縮成條列式重點"""
        history_text = "\n".join(
            f"{'User' if m['role'] == 'user' else 'AI'}: {m['content']}"
            for m in messages
        )
        prompt = f"""以下是一段對話記錄,請用條列式摘要最重要的資訊、結論、已確認的事實。
    保留具體數字、決策、技術細節。100字以內。
    
    對話:
    {history_text}
    
    摘要:"""
        return call_model([{"role": "user", "content": prompt}])
    
    class ChatSession:
        def __init__(self, keep_recent=4, compress_threshold=8):
            self.messages = []
            self.summary = ""               # 累積摘要
            self.keep_recent = keep_recent             # 保留最近幾輪原文
            self.compress_threshold = compress_threshold   # 超過幾輪就壓縮
    
        def chat(self, user_input):
            self.messages.append({"role": "user", "content": user_input})
    
            # 超過門檻 → 壓縮舊對話
            if len(self.messages) > self.compress_threshold:
                old = self.messages[:-self.keep_recent]
                new_summary = summarize(old)
    
                # 把舊摘要 + 新摘要合併
                self.summary = f"{self.summary}\n{new_summary}".strip()
                self.messages = self.messages[-self.keep_recent:]
                print(f"[已壓縮,摘要更新:{len(self.summary)} chars]")
    
            # 組合本次送出的 messages
            send_messages = []
            if self.summary:
                send_messages.append({
                    "role": "system",
                    "content": f"對話背景摘要(已發生的重點):\n{self.summary}"
                })
            send_messages.extend(self.messages)
    
            response = call_model(send_messages)
            self.messages.append({"role": "assistant", "content": response})
            return response
    
    # 使用方式
    if __name__ == "__main__":
        session = ChatSession(keep_recent=4, compress_threshold=8)
        while True:
            user = input("你:").strip()
            if user.lower() == "exit":
                break
            reply = session.chat(user)
            print(f"AI:{reply}")
            if session.summary:
                print(f"[背景摘要:{len(session.summary)} chars]")

    效能調優:摘要用小模型,回答用大模型

    摘要這個步驟本身也消耗一次推理呼叫。如果 Mac 上同時有快慢兩個模型,可以分工:快的模型做摘要,慢的(品質更好的)做正式回答:

    MAIN_MODEL    = "qwen3:14b"   # 回答主要問題,品質優先
    SUMMARY_MODEL = "qwen3:4b"   # 做摘要,速度優先(簡單任務夠用)
    
    def summarize(messages):
        # 使用小模型做摘要
        payload = {
            "model": SUMMARY_MODEL,
            ...
        }

    這樣摘要時間從數十秒縮短到幾秒,而主要對話品質不受影響。MacBook Air M3 速度夠快(9+ tok/s),用同一個模型做摘要也無妨。

    日常應用:把 Mac 當成你的私人 AI 主機

    gemma4:e4b 在 MacBook Air M3 上跑出 9+ tok/s,這個速度對互動式日常使用完全夠用——不是只能跑 benchmark,而是可以當成隨時待命的個人助理。重點是:所有資料留在本機,不送雲端,不計費。

    架構很簡單:Mini PC 負責發問和顯示,Mac 負責思考和回答。Mini PC 本身不跑模型,只是一個入口。

    你(Mini PC)→ 問題 → Mac gemma4 → 回答 → 你
    
    Mini PC:入口,不思考
    Mac:腦子,負責推理

    兩個最常用的場景

    場景一:快速摘要

    把一篇文章、一份 log、一段程式碼丟給 Mac,要它用幾句話說重點。不需要 Claude 等級的推理,gemma4 速度更快、更省錢(免費)。

    #!/usr/bin/env python3
    # summarize.py — 從 stdin 讀內容,打到 Mac gemma4 要摘要
    # 用法:cat article.txt | python3 summarize.py
    #       cat error.log   | python3 summarize.py --prompt "這份 log 的錯誤原因是什麼"
    
    import json, sys, urllib.request, argparse
    
    MAC_URL = "http://192.168.1.xxx:11434/api/chat"
    MODEL   = "gemma4:e4b"
    
    parser = argparse.ArgumentParser()
    parser.add_argument("--prompt", default="請用5句話以內摘要以下內容的重點:")
    args = parser.parse_args()
    
    content = sys.stdin.read().strip()
    if not content:
        print("ERROR: no input"); sys.exit(1)
    
    payload = {
        "model": MODEL,
        "messages": [{"role": "user", "content": f"{args.prompt}\n\n{content}"}],
        "stream": False, "think": False,
        "options": {"num_ctx": 8192, "num_predict": -1},
    }
    req = urllib.request.Request(
        MAC_URL, data=json.dumps(payload).encode(),
        headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req, timeout=300) as r:
        print(json.loads(r.read())["message"]["content"])
    # 使用範例
    cat ~/Downloads/article.txt   | python3 summarize.py
    cat /var/log/app.log          | python3 summarize.py --prompt "這份 log 有什麼異常?"
    git diff HEAD~5               | python3 summarize.py --prompt "這幾個 commit 改了什麼?"

    場景二:快速產程式驗證

    想驗證一個想法、寫一段臨時腳本、或確認某個 API 用法——不需要開 IDE,直接從命令列問 Mac,幾秒鐘拿到可以跑的程式碼片段。

    #!/usr/bin/env python3
    # ask.py — 命令列直接問 Mac,拿回程式碼或答案
    # 用法:python3 ask.py "寫一個 Python 函數,把 list 裡的重複元素移除但保留順序"
    #       python3 ask.py "用 curl 怎麼測試一個需要 Bearer token 的 API"
    
    import json, sys, urllib.request
    
    MAC_URL = "http://192.168.1.xxx:11434/api/chat"
    MODEL   = "gemma4:e4b"
    
    question = " ".join(sys.argv[1:])
    if not question:
        print("Usage: python3 ask.py \"your question\""); sys.exit(1)
    
    payload = {
        "model": MODEL,
        "messages": [{"role": "user", "content": question}],
        "stream": False, "think": False,
        "options": {"num_ctx": 4096, "num_predict": -1},
    }
    req = urllib.request.Request(
        MAC_URL, data=json.dumps(payload).encode(),
        headers={"Content-Type": "application/json"},
    )
    with urllib.request.urlopen(req, timeout=300) as r:
        print(json.loads(r.read())["message"]["content"])
    # 使用範例
    python3 ask.py "寫一個 bash script,每天早上備份 ~/Documents 到外接硬碟"
    python3 ask.py "Python requests 怎麼設定 retry 和 timeout"
    python3 ask.py "這個 SQL 有什麼問題:SELECT * FROM orders WHERE date > NOW() - 30"

    什麼時候還是要 Claude

    任務 Mac gemma4 Claude API
    文章/log 摘要 ✅ 夠用,免費
    快速程式片段 ✅ 夠用,快
    翻譯、改寫 ✅ 夠用
    私人資料(不想送雲端) ✅ 最佳選擇
    程式碼審查(跨檔案) ❌ 沒有 context
    複雜架構決策 ❌ 推理不足
    Agent Team 自動化開發 ⚡ 出草稿 ✅ 審查整合

    原則是:不需要記憶 codebase、不需要複雜推理的任務,都可以先試 Mac。速度快、免費、資料不出門。遇到 Mac 答不好的,再升到 Claude。

    進階應用二:Mini PC + Mac 混合架構,讓 Agent Team 更有效率

    角色定義(固定,不隨任務改變)
    
    Mini PC  → 純指揮中心:跑 Claude Code、管理 Agent Team、處理串接邏輯
               不跑任何本地模型,資源用在穩定性和協調上
    
    Mac      → 推理後端:跑 Ollama + gemma4:e4b
               只負責生成,不做決策
    
    Claude API → 審查 + 架構:程式碼審查、複雜邏輯、跨檔案推理
                 Mini PC 透過網路呼叫,不在本地
    
    規則:Mac 不在線 → fallback 給 Claude API,不是 Mini PC 自己跑

    當你用 Claude Code 的 Agent Team 跑自動化程式開發時,會面對一個現實問題:Claude API 的費用隨 token 用量線性增長,而很多任務其實不需要 Claude 的完整推理能力——DTO 生成、CRUD 樣板、SQL migration 這類結構性重複工作,本地的 gemma4:e4b 就能處理。

    解法是把 Mac 當成 Agent Team 的「草稿後端」:Claude Agent 負責架構決策和程式碼審查,Mac gemma4 負責產生第一版草稿,再由 Claude 驗證整合。

    架構分工

    任務類型 交給誰 原因
    DTO / model class Mac gemma4 結構固定,重複性高
    CRUD endpoints 樣板 Mac gemma4 Pattern 固定,不需要推理
    SQL migration Mac gemma4 有範本可循
    Unit test 骨架 Mac gemma4 快速產出結構,Claude 填邏輯
    複雜業務邏輯 Claude sonnet 需要跨檔案理解,Mac 沒有 context
    安全相關程式碼 Claude sonnet/opus 不可靠的輸出風險太高
    架構決策 / Code Review Claude opus 需要深度推理與判斷

    前置設定:讓 Mac 的 Ollama 對區網開放

    Ollama 預設只監聽本機。在 Mac 上把它開放給區網,Mini PC 才能連進來:

    # Mac 上執行(停掉 Ollama app 後)
    OLLAMA_HOST=0.0.0.0 ollama serve
    
    # 從 Mini PC 驗證是否連得到(換成 Mac 的區網 IP)
    curl http://192.168.1.xxx:11434/api/tags

    不想暴露 port 的話,用 SSH Tunnel:Mini PC 上執行 ssh -L 11435:localhost:11434 [email protected] -N,之後打 localhost:11435 就等於打 Mac 的 Ollama。

    工具腳本:mac_draft.py

    Agent 透過 Bash tool 呼叫這支腳本,傳入任務描述,拿回草稿程式碼。腳本會自動檢查 Mac 是否在線,不在線就回傳 exit code 1,讓 Agent 自行處理 fallback。

    #!/usr/bin/env python3
    """
    mac_draft.py — Call Mac's local gemma4 for code draft generation.
    
    Usage:
        python3 mac_draft.py "write a SQLAlchemy User model with id, name, email"
        python3 mac_draft.py --task "CRUD for User" --context "FastAPI, SQLAlchemy async"
    
    Exit codes:
        0 = success, draft printed to stdout
        1 = Mac unreachable → fallback: implement with Claude directly
        2 = model error
    """
    import json, sys, urllib.request, urllib.error, argparse
    
    MAC_HOST = "http://192.168.1.xxx:11434"   # 改成 Mac 的實際 IP
    MODEL    = "gemma4:e4b"
    TIMEOUT  = 600
    
    SYSTEM_PROMPT = """You are a code generation assistant. Output ONLY code —
    no explanations, no markdown fences, no comments unless essential.
    The output will be reviewed and integrated by another agent."""
    
    def check_reachable():
        try:
            with urllib.request.urlopen(f"{MAC_HOST}/api/tags", timeout=5):
                return True
        except Exception:
            return False
    
    def generate(task, context=""):
        prompt = f"Context: {context}\n\nTask: {task}" if context else task
        payload = {
            "model": MODEL,
            "messages": [
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user",   "content": prompt},
            ],
            "stream": False, "think": False,
            "options": {"num_ctx": 4096, "num_predict": -1},
        }
        data = json.dumps(payload).encode()
        req  = urllib.request.Request(
            f"{MAC_HOST}/api/chat", data=data,
            headers={"Content-Type": "application/json"},
        )
        with urllib.request.urlopen(req, timeout=TIMEOUT) as r:
            return json.loads(r.read())["message"]["content"]
    
    parser = argparse.ArgumentParser()
    parser.add_argument("task", nargs="?")
    parser.add_argument("--task", dest="task_flag")
    parser.add_argument("--context", default="")
    args = parser.parse_args()
    
    task = args.task or args.task_flag
    if not task:
        print("ERROR: no task provided", file=sys.stderr); sys.exit(1)
    
    if not check_reachable():
        print(f"MAC_UNREACHABLE: {MAC_HOST}. Fallback: implement with Claude.",
              file=sys.stderr); sys.exit(1)
    
    try:
        print(generate(task, args.context))
    except Exception as e:
        print(f"ERROR: {e}", file=sys.stderr); sys.exit(2)

    Agent 的實際使用流程

    # Agent (sonnet) 在 Bash tool 中這樣呼叫:
    
    # 1. 請 Mac 出草稿
    draft=$(python3 ~/llm-benchmark/scripts/mac_draft.py \
      --task "generate SQLAlchemy User model" \
      --context "PostgreSQL, async, Pydantic v2")
    
    # 2. 檢查是否成功
    if [ $? -ne 0 ]; then
      echo "Mac unavailable, implementing directly"
      # Claude 自己寫
    fi
    
    # 3. 草稿給 Claude 審查後整合進 codebase
    echo "$draft"  # Claude 讀到這裡,決定是否採用、修改哪裡

    告訴 Agents 這條規則:寫入 AGENTS.md

    Claude Code 的 Agent Team 每個 subagent 啟動時沒有對話歷史。規則要寫進 AGENTS.md,agent 才會在每次任務開始時讀到它。在專案的 AGENTS.md 加上這個區塊:

    ## Mac Draft Resource (Local LLM Offload)
    
    Mac (gemma4:e4b) is available as a fast code draft generator.
    Tool: python3 ~/llm-benchmark/scripts/mac_draft.py
    
    Use Mac draft BEFORE writing code yourself for:
    - DTO / model class boilerplate      ✅
    - CRUD endpoints (standard pattern)  ✅
    - SQL migration scripts              ✅
    - Unit test scaffolding              ✅
    
    Do NOT use Mac draft for:
    - Complex business logic             ❌ (no codebase context)
    - Security-sensitive code            ❌ (unreliable)
    - Cross-file refactoring             ❌ (no context)
    - Architecture decisions             ❌ (use opus)
    
    Workflow:
    1. Call mac_draft.py with task description
    2. exit code 1 (MAC_UNREACHABLE) → implement with Claude directly
    3. Review draft: check patterns, imports, logic, security
    4. Integrate into codebase
    
    Mac generates the shape. Claude ensures it fits.

    這樣每個 subagent 都會知道「遇到樣板類任務先叫 Mac 出草稿」,不需要每次重新交代規則。

    結論與推薦

    本次測試跨越三個維度,每層都有明確的答案:

    Mini PC + Mac 混合架構的定位

    Mini PC 的角色是指揮中心,不是推理引擎。它跑 Claude Code、管理 Agent Team、處理串接邏輯,資源用在穩定性和協調上。推理工作全部交給 Mac 的 gemma4:e4b。

    • 日常問答 / 摘要:Mini PC 發問 → Mac gemma4 回答,免費、快速、資料不出門
    • 草稿程式碼:Agent 呼叫 mac_draft.py → Mac 出草稿 → Claude 審查整合
    • 複雜推理 / 架構決策:直接用 Claude API,不走 Mac
    • Mac 不在線:fallback 給 Claude API,Mini PC 本身不需要跑任何模型

    如果你的情境是 Mini PC 獨立運作(沒有 Mac),模型選擇建議:gemma4:e4b 速度最快(1.45 tok/s)、qwen3:14b 完成度最高(7/7 全答)、qwen3:4b 最省記憶體。但這個架構的速度上限就是 CPU 推論,不如 Mac 的 Apple Silicon。

    MacBook Air M3 的最佳設定

    • 日常程式碼:think:false,num_predict=-1,9.75 tok/s,輸出完整
    • 複雜推理/技術解釋:Thinking 開啟,速度只慢 6%,品質提升明顯
    • 長文件處理:設定 num_ctx=65536,充分利用 24GB 統一記憶體

    本地 LLM 的真實上限在哪裡?

    gemma4:e4b 在 MacBook Air M3 + Thinking 模式下,輸出品質接近 GPT-3.5 的水準——在程式碼生成、SQL 查詢、技術解釋這些結構清晰的任務上。它不是 GPT-4,創意寫作和跨領域推理還是有差距,但對開發者的日常工作場景已經夠用。

    真正的瓶頸不是模型大小,而是硬體架構。同款模型在 Apple Silicon 上跑出的效果,在 x86 CPU 上根本發揮不出來。如果你認真考慮本地 LLM,MacBook Air M3 是目前性價比最高的入門選擇;Mini PC 路線則需要搭配 NVIDIA GPU(VRAM ≥ 8GB)才能真正發揮。