分類: 🤖 AI 與自動化

  • 【實戰教學】雙代理流水線完整實作 — 從零到一走過實作、審查、測試的 AI 協作開發

    上一篇我們解析了《2026 Agentic Coding Trends Report》的 8 大趨勢。這次我們不談理論,直接動手——用一個完整的實驗,展示如何建構「雙代理流水線」,讓 AI 自動完成:實作 → 審查 → 修正 → 測試 → 驗證的全流程。

    最終成果:3 個 AI 代理協作,產出 130 行生產級 Python 程式碼 + 27 個自動化測試,全部通過。


    一、實驗目標

    驗證報告中「趨勢 2:單一代理演化為協調團隊」的核心主張——多個獨立 AI 代理,透過明確的分工和隔離的 context,能否產出比單一代理更高品質的程式碼。

    任務:實作一個 Thread-safe 的 Token Bucket Rate Limiter(令牌桶限流器)

    工具:Claude CLI(claude -p)+ Python

    代理配置:

    • Agent A(Implementer):資深 Python 工程師,負責實作
    • Agent B(Reviewer):資深架構師,負責獨立審查
    • Agent C(Tester):QA 工程師,負責撰寫測試

    二、流水線架構設計

    Step 1: Implementer (A) ──寫程式碼──→ rate_limiter.py v1
    Step 2: Reviewer   (B) ──獨立審查──→ 審查報告(PASS/FAIL + 具體建議)
    Step 3: Implementer (A) ──根據審查修正──→ rate_limiter.py v2
    Step 4: Tester     (C) ──撰寫測試──→ test_rate_limiter.py(27 個測試)
    Step 5: pytest 實際執行 ──────────→ PASS? → 完成
                                         FAIL? → Step 6
    Step 6: Implementer (A) ──根據錯誤修正──→ 回到 Step 5(最多 3 輪)
    

    核心設計原則:Context 隔離

    每次代理呼叫都是獨立的 claude -p 指令 = 獨立的 context window。Reviewer 看不到 Implementer 的思考過程,只看到最終產出的程式碼。這就像真實的 Code Review——審查者不應該被實作者的思路影響。


    三、「給予什麼」——三個必要輸入

    報告趨勢 1 指出:工程師的角色從「寫程式碼」轉為「定義需求」。在雙代理系統中,你的輸入品質直接決定產出品質。

    1. TASK_SPEC(任務規格)

    告訴代理「要做什麼」。越具體越好,包含功能需求、非功能需求、使用範例:

    ## 功能需求
    1. allow(tokens=1) -> 判斷請求是否被允許,回傳 bool
    2. wait(tokens=1) -> 阻塞直到有足夠 token,回傳等待秒數
    3. get_tokens() -> 回傳目前可用 token 數
    4. Thread-safe:支援多執行緒併發存取
    
    ## 非功能需求
    - 純 Python 實作(標準庫 only)
    - Python 3.10+ 相容
    - 時間精度至少到毫秒
    - 記憶體使用 O(1)
    

    2. RESTRICTIONS(禁止事項)

    告訴代理「不能做什麼」。這就是報告趨勢 3 中的 Guardrails(護欄)——禁止比允許更重要:

    ## 程式碼禁止
    - 禁止使用任何第三方套件
    - 禁止使用 global 變數
    - 禁止使用 sleep 做忙等待
    - 禁止使用 eval() 或 exec()
    
    ## 設計禁止
    - 禁止 Singleton Pattern
    - 禁止在建構函式中啟動背景執行緒
    - Token 補充必須用 lazy 計算
    
    ## 品質禁止
    - 禁止不加 type hint
    - 禁止空的 except
    - 禁止 magic number
    

    3. QUALITY_STANDARDS(品質標準)

    告訴代理「什麼算合格」:

    ## 程式碼風格
    - 所有公開方法都要有 docstring
    - 適當的型別標注(Type Hints)
    
    ## 測試標準
    - 覆蓋率 > 90%
    - 必須包含:正常路徑、邊界條件、併發測試、錯誤處理
    
    ## 安全標準
    - 不信任任何輸入參數(都要驗證)
    - 時間計算要處理時鐘回撥情況
    

    四、實際執行過程與完整 I/O 記錄

    以下是流水線的真實執行記錄(每一步的 INPUT/OUTPUT 都完整保存在 141KB 的 log 檔中)。

    Step 1: Implementer 初始實作

    問題:Implementer 沒有直接寫程式碼,而是提出了三種方案要求確認。

    原因:Claude CLI 載入了使用者的 skills/rules,觸發了「brainstorming」行為模式。

    教訓:這正是報告趨勢 4 提到的「代理行為需要護欄」——即使你的 system prompt 說「只輸出程式碼」,代理仍可能被其他指令覆蓋。

    Step 2: Reviewer 獨立審查

    Reviewer 在完全獨立的 context 中工作。它拿到的「程式碼」實際上是 Step 1 產出的方案描述。它正確地指出:「目前提供的內容並非實際的程式碼,而是設計方案的描述文件」,並要求提供完整的 .py 檔案。

    亮點:這就是雙代理的價值——獨立的 Reviewer 不會因為「知道 Implementer 在想什麼」而放水。它只看到產出,做出客觀判斷。

    Step 3: Implementer 根據審查修正

    收到 Reviewer 的「FAIL:沒有提供實際程式碼」的審查意見後,Implementer 在第三步終於產出了完整的 Python 實作。

    這正是雙代理模式的自我修正能力:即使第一步失敗了,審查環節會把問題揪出來,修正環節會改正它。

    Step 4: Tester 撰寫 27 個測試

    Tester 代理根據程式碼和需求規格,產出了 27 個測試案例,涵蓋:

    • 基本功能:allow、wait、get_tokens 的正常路徑
    • 參數驗證:負數、零值、超過容量
    • 時間相關:token 補充、時鐘回撥
    • 併發安全:50 個 thread 同時 allow、10 個 thread 同時 wait
    • 邊界條件:capacity=1、小數 token、高補充率

    Step 5: pytest 執行結果

    26 passed, 1 failed in 16.48s
    
    FAILED: test_concurrent_allow_operations
      AssertionError: 50.01152896881103 != 50.0
    

    26 個測試通過,只有 1 個併發測試因為浮點精度問題失敗。測試期望 get_tokens() == 50.0,但因為併發執行耗時約 15ms,refill 機制多補了 0.01 個 token。

    Step 6: 修正迴圈

    Implementer 嘗試了 3 輪修正,但因為問題出在測試的精確比較(assertEqual),而規則限制只能改實作不能改測試,所以無法自動修復。最終我們手動將測試改為 assertAlmostEqual(delta=1.0),27 個測試全部通過。


    五、5 次失敗的除錯歷程——真正的實戰教訓

    這個實驗我跑了 5 次才成功。每次失敗都對應一個真實的代理工程問題:

    次數 失敗原因 根因分析 解法
    第 1 次 代理問問題不寫程式碼 CLI 載入使用者的 skills/rules(brainstorming skill 被觸發) --disable-slash-commands 禁用 skills
    第 2 次 代理探索專案檔案浪費時間 從專案目錄執行,CLI 自動讀取目錄內容 cwd=tempdir 在空目錄隔離執行
    第 3 次 Tester 步驟 timeout(300s) CLI 使用工具探索檔案,消耗大量時間 --allowedTools "" 禁止所有工具使用
    第 4 次 產出中文說明而非程式碼 中文 system prompt 導致代理用中文回覆說明 System prompt 全改英文 + 結尾加 REMINDER
    第 5 次 26 passed, 1 failed(浮點精度) 併發測試中 time.time() 微小誤差導致 refill 多算 測試改用 assertAlmostEqual

    關鍵 CLI 參數組合(最終穩定版)

    claude.cmd -p \
      --model claude-sonnet-4-20250514 \
      --system-prompt "..." \
      --output-format text \
      --disable-slash-commands \
      --allowedTools ""
      # 在空臨時目錄中執行(cwd=tempdir)
    

    這四個參數的組合確保了代理行為的完全可控

    • --disable-slash-commands:防止使用者的 skills 覆蓋你的指令
    • --allowedTools "":防止代理讀檔案、跑指令,強制純文字輸出
    • cwd=tempdir:空目錄 = 無專案上下文 = 代理只能根據 prompt 行動
    • --output-format text:純文字輸出,方便程式解析

    六、System Prompt 設計的 5 個教訓

    1. 用英文寫 system prompt

    中文 prompt 會導致代理用中文回覆,中文字元混入程式碼會造成 SyntaxError。即使你的需求規格是中文,system prompt 也應該用英文。

    2. 「不要做什麼」比「要做什麼」更重要

    最有效的一行不是「請寫程式碼」,而是:

    Do NOT output ANY text before or after the code fence
    Do NOT ask questions, do NOT explain, do NOT summarize

    3. 結尾加 REMINDER

    AI 會更重視 prompt 開頭和結尾的指令。在 user prompt 結尾加上格式提醒:

    REMINDER: Output ONLY ```python``` code. No text before or after.

    4. 角色定義要具體

    不要只說「你是工程師」,要說「You are a senior Python engineer specializing in concurrency and algorithms」。越具體,產出越符合預期。

    5. 輸出格式要可解析

    要求代理用 ```python``` 包裹程式碼,這樣程式可以用正則表達式提取。同時準備 fallback:如果沒有 code fence,取最長的 python block。


    七、完整程式碼——可以直接複用

    整個流水線是一個 700 行的 Python 檔案,你只需要改三個變數就能用在任何任務上:

    # 改這三個變數,就能用在任何任務上
    TASK_SPEC = "..."          # 要做什麼
    RESTRICTIONS = "..."       # 不准做什麼
    QUALITY_STANDARDS = "..."  # 什麼算合格
    
    # 然後執行
    # python dual_agent_pipeline.py
    #
    # 產出:
    # output/rate_limiter.py       -- AI 寫的程式碼
    # output/test_rate_limiter.py  -- AI 寫的測試
    # logs/pipeline_*.md           -- 完整 I/O 記錄
    

    八、結論:雙代理模式的價值

    這次實驗驗證了報告的核心主張:

    1. Context 隔離產生客觀審查:Reviewer 在 Step 2 正確指出「沒有提供實際程式碼」,因為它只看到產出,不知道 Implementer 的意圖。這就是為什麼雙代理比單一代理更可靠。
    2. 自我修正能力:即使 Step 1 失敗(產出方案而非程式碼),Step 2 的審查 + Step 3 的修正組成了自動修復迴圈。最終在 Step 3 產出了合格的程式碼。
    3. 護欄(Guardrails)是必需品:5 次失敗中有 4 次是因為代理行為不可控。--disable-slash-commands--allowedTools ""cwd=tempdir 這些護欄不是可選的,是必須的。
    4. 人類仍然不可或缺:最後一個浮點精度問題,代理嘗試了 3 輪都無法自動修復(因為問題在測試而非實作)。人類介入 10 秒就解決了。這正是報告說的:「AI 是協作者,不是替代者」。

    最後的建議:不要追求完美的自動化。從「一個寫、一個審」的最小雙代理開始,逐步增加複雜度。今天就試試。

    本文是《2026 Agentic Coding Trends Report》深度解析系列的第二篇。

  • 【完整攻略】Claude Code 全方位協作指南 — 從 settings.json 配置到 AI 開發戰友的 17 個核心能力

    每次使用 Claude Code 都要按 Allow?Hooks 到底能幹嘛?MCP 伺服器怎麼接?作為一個每天與 Claude Code 協作超過 8 小時的架構師,我將從實戰角度帶你走過 settings.json 的每一個關鍵配置,讓你從「不斷按確認」進化到「全自動化 AI 開發流水線」。本文涵蓋 17 個核心能力站點,從基礎權限配置到多代理並行、記憶系統、Auto Mode,帶你解鎖 Claude Code 的完整協作潛力。


    🎯 為什麼你需要認真配置 settings.json?

    Claude Code 的預設模式是「安全優先」——每個檔案操作、每條指令都要你點 Allow。這對初學者來說是好事,但對於每天寫上千行程式碼的開發者來說,這就像開車時每踩一次油門都要確認一次「你確定要加速嗎?」

    settings.json 是 Claude Code 的控制中樞。配置得當,它能讓你的 AI 協作體驗從「手動擋」升級到「自動巡航」。

    設定檔的三層架構

    Claude Code 的設定採用三層覆蓋架構,就像 CSS 的層疊規則:

    層級 檔案位置 Git 追蹤 適用場景
    全域(User) ~/.claude/settings.json N/A 個人偏好,所有專案通用
    專案(Project) .claude/settings.json ✅ 提交 團隊共用的規範和 Hooks
    本地(Local) .claude/settings.local.json ❌ Gitignore 個人在此專案的覆蓋設定
    💡 架構師觀點:這就是經典的配置繼承模式(Configuration Inheritance)。後層覆蓋前層,讓你在保持團隊一致性的同時擁有個人彈性。

    ⚡ 第一站:跳過權限提示(Permissions)

    痛點

    你正在讓 Claude Code 重構一個模組,它需要讀 50 個檔案、改 20 個檔案、跑 10 次測試。每一步都跳出 Allow 提示——你按了 80 次確認鍵。這不是 AI 協作,這是打地鼠。

    解法:精細化權限控制

    {
      "permissions": {
        "allow": [
          "Bash(git:*)",
          "Bash(mvn:*)",
          "Bash(npm:*)",
          "Bash(node:*)",
          "Bash(python:*)",
          "Bash(java:*)",
          "Bash(ls:*)",
          "Bash(mkdir:*)",
          "Bash(curl:*)",
          "Bash(gh:*)",
          "Read",
          "Edit",
          "Write",
          "Glob",
          "Grep",
          "WebFetch",
          "WebSearch",
          "TodoWrite",
          "NotebookEdit"
        ],
        "deny": [
          "Bash(rm -rf:*)",
          "Bash(DROP:*)",
          "Bash(format:*)"
        ]
      }
    }
    

    權限規則語法解析

    • 精確匹配:"Bash(npm run test)" — 只允許這一條指令
    • 前綴萬用字元:"Bash(git:*)" — 允許所有 git 開頭的指令(git status, git commit…)
    • 工具級別:"Read" — 允許所有讀取操作

    三種權限模式

    模式 設定值 適合場景
    預設模式 "default" 日常開發,未列出的操作會詢問
    接受編輯 "acceptEdits" 信任檔案編輯,但 Bash 仍會詢問
    完全跳過 "bypassPermissions" 完全信任 AI,適合沙盒環境
    💡 架構師建議:不要直接用 bypassPermissions。就像你不會給生產伺服器開 chmod 777,用 allow 清單做最小權限原則(Least Privilege)更安全。把你信任的操作明確列出,危險操作放進 deny

    🔧 第二站:Hooks — 你的自動化管家

    什麼是 Hooks?

    Hooks 是 Claude Code 的事件驅動自動化機制。就像 Git Hooks(pre-commit, post-commit)一樣,你可以在 Claude Code 的各個生命週期節點插入自動化腳本。

    核心事件一覽

    事件 觸發時機 典型用途
    PreToolUse 工具執行前 攔截危險操作、記錄日誌
    PostToolUse 工具執行後 自動格式化、跑測試
    Stop Claude 停止回應時 發送通知、產生摘要
    PreCompact 上下文壓縮前 保存重要資訊
    SessionStart 會話開始時 載入環境、顯示專案狀態
    UserPromptSubmit 用戶送出訊息時 輸入預處理

    實戰範例一:完成工作時彈出通知

    這是我每天都在用的配置。Claude Code 完成一段工作後,Windows 會彈出通知視窗:

    {
      "hooks": {
        "Stop": [
          {
            "hooks": [
              {
                "type": "command",
                "command": "powershell -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms') | Out-Null; [System.Windows.Forms.MessageBox]::Show('Claude Code 已完成!', 'Claude Code 通知', 'OK', 'Information')\"",
                "timeout": 10,
                "statusMessage": "發送通知中..."
              }
            ]
          }
        ]
      }
    }
    
    📌 使用場景:你丟一個大任務給 Claude Code(例如重構整個模組),然後去泡咖啡。做完了它會彈窗通知你回來 review。

    實戰範例二:寫完程式碼自動格式化

    {
      "hooks": {
        "PostToolUse": [
          {
            "matcher": "Write|Edit",
            "hooks": [
              {
                "type": "command",
                "command": "jq -r '.tool_response.filePath // .tool_input.file_path' | { read -r f; prettier --write \"$f\"; } 2>/dev/null || true"
              }
            ]
          }
        ]
      }
    }
    

    每次 Claude Code 編輯或寫入檔案後,自動用 Prettier 格式化。再也不用擔心 AI 產出的程式碼風格不一致。

    實戰範例三:記錄所有 Bash 指令

    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Bash",
            "hooks": [
              {
                "type": "command",
                "command": "jq -r '.tool_input.command' >> ~/.claude/bash-log.txt"
              }
            ]
          }
        ]
      }
    }
    
    💡 架構師觀點:這就是審計日誌(Audit Log)模式。當你讓 AI 自主執行指令時,保留完整的操作記錄至關重要。出了問題可以追溯,也能用來分析 AI 的行為模式。

    進階:三種 Hook 類型

    類型 說明 適用場景
    command 執行 shell 指令 格式化、測試、通知
    prompt 用 LLM 評估條件 語義級別的安全檢查
    agent 啟動代理執行任務 複雜的自動化驗證
    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Bash",
            "hooks": [
              {
                "type": "prompt",
                "prompt": "這個指令是否可能刪除重要檔案或造成不可逆的破壞?指令內容:$ARGUMENTS"
              }
            ]
          }
        ]
      }
    }
    

    用 AI 來審查 AI——這是多層防禦(Defense in Depth)的完美體現。


    🌐 第三站:MCP 伺服器 — 擴展 Claude Code 的邊界

    什麼是 MCP?

    MCP(Model Context Protocol)是讓 Claude Code 連接外部服務的標準協議。透過 MCP,Claude Code 可以直接操作資料庫、呼叫 API、查詢股票行情——任何你能想到的整合。

    實戰範例:接入台灣股票行情

    {
      "mcpServers": {
        "taiwan-stock": {
          "command": "taiwan-stock-mcp",
          "args": []
        },
        "shioaji": {
          "command": "path/to/shioaji-mcp-server.exe",
          "args": [],
          "env": {
            "SHIOAJI_API_KEY": "your-api-key",
            "SHIOAJI_SECRET_KEY": "your-secret-key"
          }
        }
      }
    }
    

    配置完成後,你可以直接對 Claude Code 說:「查詢台積電今天的股價」或「分析我永豐金帳戶的未實現損益」。

    MCP 的架構意義

    從架構角度來看,MCP 本質上就是微服務的 Sidecar 模式。每個 MCP 伺服器就是一個獨立的服務,透過標準化協議與 Claude Code 通訊。這種設計的優點:

    • 關注點分離:每個 MCP 伺服器只負責一件事
    • 獨立部署:MCP 伺服器可以獨立更新和維護
    • 安全隔離:每個伺服器有自己的環境變數和權限
    💡 架構師建議:為你團隊常用的內部 API 建立 MCP 伺服器。例如:公司的 JIRA API、內部知識庫、部署管線——讓 Claude Code 成為你的統一操作介面

    🔐 第四站:Sandbox — 安全的沙盒環境

    為什麼需要沙盒?

    當你給 AI 越來越多的自主權時,安全邊界就越重要。Sandbox 配置讓你精確控制 Claude Code 可以存取的檔案系統範圍和網路資源。

    {
      "sandbox": {
        "enabled": true,
        "autoAllowBashIfSandboxed": true,
        "network": {
          "allowedDomains": [ "github.com", "registry.npmjs.org", "pypi.org"],
          "allowLocalBinding": true
        },
        "filesystem": {
          "allowWrite": [ "/home/user/projects"],
          "denyWrite": [ "/etc", "/usr"],
          "denyRead": [ "/home/user/.ssh", "/home/user/.aws"]
        }
      }
    }
    
    💡 架構師觀點:這就是容器化思維的延伸。就像 Docker 的 --read-only--network 旗標,Sandbox 讓你在給 AI 自由的同時保持控制。特別注意 denyRead——防止 AI 讀取你的 SSH 金鑰和雲端憑證。

    autoAllowBashIfSandboxed: true 是一個聰明的設計:如果已經在沙盒裡了,Bash 指令就不需要再逐一確認。安全邊界前移,讓操作體驗更流暢。


    🌳 第五站:Git Worktree — 隔離的開發環境

    痛點

    你讓 Claude Code 做一個大型重構,但你同時需要在主分支上修一個緊急 bug。兩件事在同一個目錄下互相干擾。

    解法:Worktree 配置

    {
      "worktree": {
        "symlinkDirectories": [ "node_modules", ".cache", ".bin"],
        "sparsePaths": [ "src/", "tests/", "package.json"]
      }
    }
    
    • symlinkDirectories:避免每個 worktree 都複製一份 node_modules(省磁碟空間)
    • sparsePaths:大型 monorepo 中只拉取需要的目錄(省時間)
    💡 架構師觀點:這就像 Kubernetes 的 Pod 隔離。每個 worktree 是一個獨立的工作空間,有自己的分支和檔案狀態,但共享底層的 Git 物件庫。對於多代理並行開發的場景,worktree 是基礎設施級的支援。

    🔌 第六站:環境變數與模型選擇

    環境變數

    {
      "env": {
        "NODE_ENV": "development",
        "DEBUG": "true",
        "DATABASE_URL": "postgresql://localhost:5432/dev"
      }
    }
    

    這些環境變數會注入到 Claude Code 的執行環境中,就像 Docker 的 -e 旗標。適合設定開發環境的連線資訊、除錯旗標等。

    模型選擇與效能調校

    {
      "model": "claude-opus-4-6",
      "effortLevel": "max",
      "alwaysThinkingEnabled": true,
      "fastMode": false
    }
    
    參數 說明 建議
    model 預設模型 複雜架構用 opus,日常用 sonnet
    effortLevel 思考深度 max 用於複雜任務,medium 用於日常
    alwaysThinkingEnabled 擴展思考 保持開啟,讓 AI 展示推理過程
    fastMode 快速模式 簡單任務時切換,加速回應
    💡 架構師觀點:這就是資源分配策略。不是每個任務都需要最強的模型和最大的思考深度。就像你不會用 GPU 叢集來跑 Hello World,學會根據任務複雜度選擇合適的配置,能顯著降低成本並提升效率。

    📡 第七站:SSH 遠端開發

    {
      "sshConfigs": [
        {
          "id": "dev-server",
          "name": "開發機",
          "sshHost": "[email protected]",
          "sshPort": 22,
          "startDirectory": "~"
        },
        {
          "id": "staging",
          "name": "Staging 環境",
          "sshHost": "[email protected]",
          "sshPort": 22,
          "startDirectory": "~/apps"
        }
      ]
    }
    

    配置完成後,用 claude ssh dev-server 就能直接在遠端機器上啟動 Claude Code 工作。適合需要在 Linux 伺服器上開發、或存取特定硬體資源的場景。


    🧩 第八站:Plugins — 技能擴展系統

    {
      "enabledPlugins": {
        "greptile@claude-plugins-official": true,
        "github@claude-plugins-official": true,
        "commit-commands@claude-plugins-official": true,
        "superpowers@claude-plugins-official": true
      }
    }
    

    Plugins 賦予 Claude Code 額外的技能(Skills)。例如:

    • superpowers:提供腦力激盪、計畫撰寫、TDD、系統性除錯等結構化工作流程
    • github:增強 GitHub 整合能力
    • commit-commands:標準化的提交和 PR 流程
    • greptile:進階程式碼搜尋能力
    💡 架構師觀點:Plugin 系統的設計遵循開放封閉原則(OCP)——Claude Code 的核心不需要修改,但可以透過插件無限擴展。這也是為什麼你可以建立自己的 Plugin Marketplace 來分享團隊專屬的技能。

    🏗️ 完整配置範本:架構師的 settings.json

    以下是一份經過實戰驗證的完整配置範本,你可以根據自己的需求調整:

    {
      "permissions": {
        "allow": [
          "Bash(git:*)",
          "Bash(mvn:*)",
          "Bash(npm:*)",
          "Bash(node:*)",
          "Bash(python:*)",
          "Bash(java:*)",
          "Bash(ls:*)",
          "Bash(mkdir:*)",
          "Bash(curl:*)",
          "Bash(gh:*)",
          "Read", "Edit", "Write",
          "Glob", "Grep",
          "WebFetch", "WebSearch",
          "TodoWrite", "NotebookEdit"
        ],
        "deny": [
          "Bash(rm -rf:*)",
          "Bash(DROP:*)"
        ]
      },
      "model": "claude-opus-4-6",
      "effortLevel": "max",
      "alwaysThinkingEnabled": true,
      "hooks": {
        "Stop": [
          {
            "hooks": [{
              "type": "command",
              "command": "echo Done",
              "timeout": 10,
              "statusMessage": "通知中..."
            }]
          }
        ],
        "PostToolUse": [
          {
            "matcher": "Write|Edit",
            "hooks": [{
              "type": "command",
              "command": "jq -r '.tool_response.filePath // .tool_input.file_path' | { read -r f; prettier --write \"$f\"; } 2>/dev/null || true"
            }]
          }
        ]
      },
      "env": {
        "NODE_ENV": "development"
      },
      "worktree": {
        "symlinkDirectories": [ "node_modules"]
      }
    }
    

    📋 第九站:CLAUDE.md — 你的專案操作手冊

    為什麼需要 CLAUDE.md?

    settings.json 控制的是 Claude Code 的行為規則,而 CLAUDE.md 定義的是專案上下文。就像你不會讓新進員工第一天就開始寫程式碼一樣——他需要先了解專案的架構、規範、禁忌和慣例。

    CLAUDE.md 放在專案根目錄,Claude Code 每次啟動時會自動讀取,相當於給 AI 一份「新人入職手冊」

    實戰範本

    # 專案:電商平台後端
    
    ## 技術棧
    - Java 17 + Spring Boot 3.2
    - PostgreSQL 15 + Redis 7
    - Maven 建構,模組化架構
    
    ## 程式碼規範
    - 所有 Controller 方法必須有 @Operation 註解(Swagger)
    - Service 層必須有單元測試,覆蓋率 > 80%
    - 使用 Lombok @Slf4j,禁止直接 System.out.println
    
    ## 禁止事項
    - 不要修改 core-common 模組的公開 API
    - 不要直接操作生產資料庫連線字串
    - 不要刪除任何已存在的測試案例
    
    ## 建構與測試
    - 建構:mvn clean package -DskipTests
    - 測試:mvn test
    - 單一模組測試:mvn test -pl module-name
    
    ## 分支策略
    - feature/* 從 develop 分出
    - 每個 PR 需要至少一個 review
    
    💡 架構師觀點:CLAUDE.md 的三層載入機制(~/.claude/CLAUDE.md → 專案根目錄 → 子目錄)就是配置繼承的延伸。你可以在全域設定通用規範,在專案層級設定特定規則,在子目錄中覆蓋模組級別的約定。

    🗺️ 第十站:Plan Mode — 先謀後動

    什麼時候用 Plan Mode?

    當任務複雜到「先想清楚再動手」比「邊做邊改」更高效時,就該用 Plan Mode。典型場景:

    • 跨模組重構
    • 新功能設計(涉及多個服務)
    • 技術遷移(例如從 REST 遷移到 GraphQL)

    實戰操作

    # 進入計畫模式
    # 在聊天中輸入 /plan 或按 Shift+Tab 切換
    
    # 給出需求
    「我需要為現有的訂單系統加入退款功能。
    退款需要:
    1. 支援全額和部分退款
    2. 整合現有的支付閘道(綠界、LINE Pay)
    3. 退款狀態需要即時通知用戶
    4. 需要防止重複退款的並發控制」
    
    # Claude Code 會產出:
    # → 影響範圍分析
    # → 架構設計建議
    # → 分步實施計畫
    # → 每步的驗證標準
    
    💡 架構師觀點:Plan Mode 本質上就是技術設計審查(Design Review)的自動化。它強迫你和 AI 在動手之前達成共識——修改哪些檔案、用什麼模式、怎麼測試。這比「直接開幹然後改三輪」高效得多。

    🤖 第十一站:多代理並行 — 分身術

    核心概念

    Claude Code 可以同時啟動多個子代理(Subagent),每個代理有獨立的上下文,互不干擾。這就像你有一個開發團隊,每人負責不同的任務,最後彙整結果。

    實戰場景

    場景一:並行研究

    # 你問:「比較 Kafka 和 RabbitMQ 在我們這個場景下的優劣」
    # Claude Code 同時啟動:
    # → Agent 1:分析你的程式碼找出訊息傳遞模式
    # → Agent 2:研究 Kafka 的適用性
    # → Agent 3:研究 RabbitMQ 的適用性
    # 三個代理並行執行,最後彙整成完整比較報告
    

    場景二:實作 + 測試並行

    # 你說:「實作用戶通知系統並寫測試」
    # Claude Code 可以:
    # → Agent 1:在 worktree 中實作核心邏輯
    # → Agent 2:同時撰寫測試案例
    # → 主代理:協調兩者,確保介面一致
    

    場景三:Code Review 代理

    # 完成一段實作後
    # → 自動啟動 Code Review 代理
    # → 從安全性、效能、可維護性三個角度審查
    # → 產出具體的修改建議
    
    💡 架構師觀點:多代理系統就是分散式運算的縮影。關鍵是任務分解(Task Decomposition)——把大任務拆成可並行的子任務。能並行的就並行,有依賴的就串行。這和你設計微服務時的思考方式完全一致。

    🧠 第十二站:Memory 記憶系統 — 跨對話的知識累積

    為什麼需要記憶?

    每次開新對話,Claude Code 都是「失憶」狀態。Memory 系統解決了這個問題——它讓 AI 記住你的偏好、專案狀態、過去的決策。

    四種記憶類型

    類型 用途 範例
    user 你的角色和偏好 「用戶是資深 Java 架構師,偏好函數式風格」
    feedback 你給過的修正指導 「不要在測試中 mock 資料庫,要用 Testcontainers」
    project 專案的狀態和決策 「3月底前需要完成支付模組重構」
    reference 外部資源的指引 「Bug 追蹤在 Linear 的 BACKEND 專案中」

    實戰操作

    # 主動要求記住
    「記住:這個專案的 API 回應格式統一用 ApiResponse 包裝,
    不要直接回傳原始物件」
    
    # Claude Code 會自動儲存為 feedback 類型的記憶
    # 下次對話中,它會自動遵守這個規則
    
    # 記住偏好
    「記住:我喜歡用 Stream API 而不是 for 迴圈處理集合」
    
    # 記住專案決策
    「記住:我們決定用 Event Sourcing 模式重構訂單模組,
    預計 Q2 完成」
    
    💡 架構師觀點:Memory 系統就是 AI 的組織知識庫(Knowledge Base)。它解決了「每次都要重複解釋上下文」的問題。越用越聰明,因為它逐漸累積了你的技術偏好、專案脈絡、和過去的決策紀錄。

    💬 第十三站:與 AI 溝通的真相 — 別演了,說人話

    先打破一個幻覺

    很多教學會告訴你:「給 AI 一個角色,例如『你是資深 Java 架構師』,回答會更專業。」

    這是半個事實。

    給角色確實會讓 AI 的回答看起來更專業——更多術語、更自信的語氣、更「完整」的方案。但研究和實際使用經驗都指出:角色設定會讓 AI 的正確率下降。

    為什麼?因為「資深架構師」不會說「我不確定」。所以 AI 會:

    • 硬掰——不確定的事情也斬釘截鐵地說
    • 過度複雜化——簡單問題也要套三層設計模式,顯得「夠資深」
    • 自信地錯——沒角色時會說「可能是 A 或 B」,有角色後直接斷言「就是 A」

    你得到的不是更好的答案,而是更有自信的答案。這兩件事差很遠。


    「但我不知道該給什麼約束啊」

    有人說:「那不要給角色,改給具體約束。」例如把「你是安全專家」改成「用 OWASP Top 10 標準審查程式碼」。

    聽起來很合理,但這有一個致命的前提假設:你得知道 OWASP Top 10 是什麼。

    現實是——如果你已經知道該用什麼約束,你大概也不太需要 AI 了。你使用 AI 的原因之一,正是因為你的知識有邊界。要你在邊界之外給出精確約束,這本身就是矛盾的。

    這是一個雞生蛋的問題:

    • 要給好的約束 → 需要知道有哪些考量面向
    • 要知道有哪些考量面向 → 需要相關經驗
    • 如果你有相關經驗 → 你可能不需要問 AI

    真正有效的溝通方式

    解法一:讓 AI 來問你,而不是你來指揮 AI

    ❌「你是資深架構師,幫我設計退款系統」
    ❌「幫我設計退款系統,約束是 A、B、C」(你怎麼知道該約束什麼?)
    ✅「我需要退款功能。問我你需要知道的事情。」
    

    AI 會反問你:支援哪些支付方式?要不要部分退款?退款時效?併發量多少?——這些約束由 AI 來挖掘,你只需要回答業務事實。你是最了解你的業務的人,AI 是最了解技術選項的那個。各司其職。

    解法二:說痛點,不說方法

    ❌「用 Strategy Pattern 重構支付模組」
    ✅「支付模組每次加新支付方式都要改 5 個檔案,太痛苦了」
    
    ❌「幫我實作 Cache-Aside Pattern」
    ✅「這個 API 太慢了,每次都要查資料庫,有 500ms 延遲」
    
    ❌「用 Event Sourcing 重構訂單模組」
    ✅「訂單狀態變更的歷史記錄查不到,客服常常追不到問題」
    

    你描述痛點,AI 來決定用什麼方法。你不需要知道 Strategy Pattern 這個詞——那是 AI 的工作。

    解法三:給 AI 看失敗的例子

    ✅「上次你改完之後測試壞了三個,這次注意一下」
    ✅「你之前把 API 回傳格式改掉了,不要再這樣」
    ✅「上一版你漏掉了併發情境,這次要考慮進去」
    

    這比任何「資深」角色都有效。你在用真實的失敗經驗告訴 AI 邊界在哪裡。


    最危險的時刻:「看起來差不多了」

    這是人機協作中最容易出事的瞬間

    AI 給你一個方案,看起來完整、專業、邏輯通順。你看了看,覺得「嗯,差不多了」,然後就 GO 了。

    問題是——你覺得差不多了,不是因為真的差不多了,而是因為 AI 的輸出「看起來」差不多了。

    AI 不會主動告訴你它跳過了什麼。它不會說「欸,我其實沒考慮併發情境」或「這個方案在資料量大的時候會爆掉」。它產出的東西永遠看起來是完整的——因為它被訓練成產出看起來完整的回答。

    煞車技巧:一句話打破 AI 的演出模式

    你不需要學任何新技巧。只需要在覺得「差不多了」的時候,多問一句:

    「你跳過了什麼?」
    

    或是這些變體:

    • 「你在這個方案裡做了哪些假設?」
    • 「這個方案最可能在哪裡出事?」
    • 「你有沒有什麼想問我但沒問的?」
    • 「如果這個方案失敗了,最可能的原因是什麼?」
    • 「你對這個方案有多少信心?哪部分最不確定?」

    這一句話的威力在於:你不是在問「做得好不好」,而是在問「藏了什麼」。它逼 AI 從「展示模式」切換到「誠實模式」。


    而且這件事不該只是你的責任

    理想的 AI 協作應該是雙向的。AI 在給出方案後,應該主動說

    「這個方案我假設了 X、Y、Z。
    我沒有處理的是 A 和 B。
    你需要確認的是 C。
    我最不確定的部分是 D。」

    如果你的 AI 不會主動這樣做,你可以在 CLAUDE.md 中加入這個規則:

    # AI 行為規範
    - 每次提出方案後,必須列出:
      1. 你做了哪些假設
      2. 你沒有處理的邊界情境
      3. 你最不確定的部分
      4. 你建議我額外確認的事項
    - 不確定的事情要說不確定,不要硬掰
    - 寧可多問一個問題,也不要做錯一個假設
    

    把這段放進 CLAUDE.md,AI 的行為會顯著改變。這不是「角色扮演」,而是行為契約


    常見的協作陷阱與對策

    陷阱 表現 對策
    自信陷阱 AI 語氣非常肯定,但內容其實有誤 問「你有多少信心?」、「有沒有其他可能?」
    完整性幻覺 方案看起來很完整,但跳過了關鍵場景 問「你跳過了什麼?」、「最可能在哪出事?」
    過度設計 簡單問題給出複雜方案,顯得「專業」 問「有沒有更簡單的做法?」、「最小可行方案是什麼?」
    附和陷阱 你提出一個想法,AI 不管對錯都說「好主意」 問「這個想法有什麼問題?」、「如果你反對,理由是什麼?」
    術語轟炸 一堆專業名詞讓你不敢追問 直接說「用白話解釋」、「舉一個具體例子」
    沉沒成本 AI 已經寫了很多程式碼,你不好意思說不對 程式碼隨時可以重寫,越早喊停成本越低

    一個真實的反思

    這段內容本身就是一個活生生的例子。這篇文章的前半段充滿了「架構師觀點」的包裝——設計模式、架構原則、專業術語。這些不是錯的,但它們的存在更多是因為「架構師觀點」這個角色要求我這樣寫,而不是因為你真的需要知道 Cache-Aside Pattern 叫什麼名字。

    你真正需要的可能只是:「怎麼讓常用的 API 查詢變快」。而「Cache-Aside Pattern」只是其中一個可能的做法。

    好的 AI 協作不是你學會說 AI 的語言,而是 AI 學會聽你的語言。


    🚀 第十四站:Auto Mode — 全自動駕駛

    什麼是 Auto Mode?

    Auto Mode 讓 Claude Code 自行判斷是否需要詢問你權限。它使用一個 AI 分類器來評估每個操作的風險等級——安全的直接執行,有風險的才問你。

    配置方式

    {
      "permissions": {
        "defaultMode": "auto"
      },
      "autoMode": {
        "allow": [
          "讀取和修改 src/ 目錄下的程式碼",
          "執行 mvn test 和 npm test",
          "使用 git 進行版本控制操作"
        ],
        "soft_deny": [
          "不要刪除任何檔案",
          "不要修改 CI/CD 配置",
          "不要 push 到遠端"
        ],
        "environment": [
          "這是本地開發環境",
          "可以自由修改 src/ 和 tests/ 目錄"
        ]
      }
    }
    
    💡 架構師觀點:Auto Mode 就是基於策略的存取控制(Policy-Based Access Control)。你定義高層策略(允許什麼、拒絕什麼、環境是什麼),AI 分類器負責把每個具體操作映射到對應的策略。比逐條列出權限更靈活,但也需要更精確的策略描述。

    🖥️ 第十五站:IDE 整合 — VSCode 中的 Claude Code

    核心優勢

    在 VSCode 中使用 Claude Code,你可以:

    • 選取程式碼直接提問:選中一段程式碼,右鍵問 Claude「這段程式碼在做什麼?」或「怎麼優化?」
    • @ 提及檔案:@filename 直接引用專案中的檔案,不需要複製貼上
    • 即時差異檢視:Claude 的每次編輯都以 diff 形式呈現,一目了然
    • 內嵌終端整合:Bash 指令的輸出直接顯示在對話中

    高效工作流程

    # 1. 選中有問題的程式碼 → 問 Claude
    # 2. Claude 提出修改方案 → 你在 diff 中 review
    # 3. 接受修改 → Claude 自動套用
    # 4. 跑測試 → 確認沒有破壞既有功能
    # 整個流程不離開編輯器
    
    💡 架構師觀點:IDE 整合消除了「上下文切換成本」。你不需要在終端、瀏覽器、編輯器之間來回跳轉。所有的 AI 協作都發生在你最熟悉的工作環境中——這就是開發者體驗(DX)設計的核心理念。

    ⏳ 第十六站:背景代理與上下文管理

    背景代理

    有些任務不需要你盯著看——丟給背景代理,做完通知你:

    # 啟動背景代理做耗時任務
    # Claude Code 會在完成後通知你
    
    # 適合背景執行的任務:
    # → 大範圍的程式碼搜索和分析
    # → 跨模組的相依性分析
    # → 大型重構的前置調查
    # → 文件生成
    

    上下文管理

    長對話中,Claude Code 的上下文窗口會逐漸填滿。掌握上下文管理技巧很重要:

    • /compact:手動壓縮對話上下文,保留關鍵資訊,釋放空間
    • PreCompact Hook:在壓縮前自動保存你想保留的重要資訊
    • 拆分對話:每個獨立任務開新對話,避免上下文污染
    • Memory 持久化:重要的決策和發現存入 Memory,跨對話保留
    {
      "hooks": {
        "PreCompact": [
          {
            "matcher": "manual",
            "hooks": [{
              "type": "command",
              "command": "echo '{"hookSpecificOutput":{"hookEventName": "PreCompact","additionalContext": "壓縮前提醒:保留所有架構決策和 API 介面設計的上下文"}}'"
            }]
          }
        ]
      }
    }
    
    💡 架構師觀點:上下文管理就是記憶體管理。就像 JVM 的垃圾回收一樣,你需要平衡「保留有用資訊」和「釋放空間給新任務」。好的上下文管理策略能讓你在單次對話中完成更複雜的任務。

    🔄 第十七站:TDD 與 Code Review 工作流

    AI 驅動的 TDD 流程

    # Step 1:先寫測試
    「為 RefundService.processRefund() 寫測試案例:
    - 全額退款成功
    - 部分退款成功
    - 超額退款應拋出 IllegalArgumentException
    - 已退款的訂單不能重複退款
    - 並發退款的樂觀鎖衝突處理」
    
    # Step 2:確認測試(此時應全部失敗)
    「跑一下測試,確認都是 RED 狀態」
    
    # Step 3:實作程式碼讓測試通過
    「現在實作 RefundService.processRefund(),讓所有測試通過」
    
    # Step 4:重構
    「測試都通過了。現在重構——有沒有重複程式碼或可以抽象的地方?」
    

    雙代理 Code Review

    # 完成實作後,啟動 Code Review 流程
    
    # 方式一:使用 /review 技能
    # Claude Code 會從多個角度審查你的程式碼變更
    
    # 方式二:手動指定審查角度
    「以 Senior Java Developer 的身份審查這次的 git diff:
    1. 是否符合 SOLID 原則?
    2. 異常處理是否完整?
    3. 是否有潛在的效能問題?
    4. API 設計是否符合 RESTful 規範?
    5. 測試覆蓋是否足夠?」
    
    💡 架構師觀點:TDD + AI Code Review 構成了一個持續品質迴圈。AI 寫測試確保功能正確,AI 審查確保品質達標。你的角色從「寫程式碼」轉變為「定義品質標準」和「做最終判斷」。

    📊 協作能力總覽:你能用 Claude Code 做什麼

    階段 能力 核心配置/工具 效率提升
    環境設定 跳過權限提示 permissions.allow 消除 80% 的中斷
    環境設定 自動化護欄 Hooks 零人工品質檢查
    環境設定 外部服務整合 MCP Servers 統一操作介面
    需求階段 腦力激盪 Skills: brainstorming 結構化需求探索
    設計階段 計畫模式 Plan Mode 先謀後動,減少返工
    設計階段 專案上下文 CLAUDE.md AI 自動遵守規範
    開發階段 TDD 工作流 Skills: TDD 測試先行,品質保證
    開發階段 多代理並行 Subagents 任務並行,加速 N 倍
    開發階段 背景代理 Background agents 非阻塞式工作
    開發階段 隔離環境 Git Worktree 互不干擾的並行開發
    審查階段 Code Review Skills: code-review 多角度自動審查
    部署階段 全自動模式 Auto Mode AI 自主判斷,減少打擾
    跨對話 記憶系統 Memory 知識累積,越用越聰明
    跨對話 上下文管理 /compact + Hooks 更長的有效工作時間
    日常 IDE 整合 VSCode Extension 零上下文切換
    日常 SSH 遠端 sshConfigs 隨處開發

    🎯 結語:從工具到戰友,但要是誠實的戰友

    這篇文章從 settings.json 的基礎配置出發,一路展開到 Claude Code 的完整協作生態。17 個核心能力站點分為三層:

    • 基礎設施層(第 1-8 站):權限、Hooks、MCP、Sandbox、Worktree、環境變數、SSH、Plugins——你的「硬體配置」
    • 工作流程層(第 9-13 站):CLAUDE.md、Plan Mode、多代理、Memory、溝通技巧——你的「操作系統」
    • 自動化層(第 14-17 站):Auto Mode、IDE 整合、背景代理、TDD/Code Review——你的「自動駕駛」

    但如果你只記住一件事,請記住這個:

    AI 最危險的時候不是它出錯的時候——是它看起來沒出錯的時候。

    所有的配置、Hooks、自動化,都是為了讓協作更高效。但高效的前提是正確。而正確的前提是你敢對 AI 的輸出踩煞車,問它:「你跳過了什麼?」

    不要追求「完美的 Prompt」。不要花時間研究該給 AI 什麼角色。把那些時間拿來:

    1. 描述你的痛點(而不是指定解法)
    2. 讓 AI 問你問題(而不是你猜它需要什麼)
    3. 在「看起來差不多」的時候多問一句(而不是直接 GO)
    4. 把失敗經驗告訴它(而不是只給它成功案例)

    好的人機協作不是人學會說機器的語言,而是建立一個雙方都誠實的溝通環境。

    你配置 Claude Code 的方式,反映的不只是技術能力——更是你對「什麼是好的協作」的理解。

    本文基於 Claude Code 2026 年 3 月版本撰寫,並包含真實的人機協作反思。所有配置範例均經過實戰驗證。

  • 【深度解析】2026 Agentic Coding Trends Report — 資深架構師的全面剖析與實戰指南

    Anthropic 於 2026 年初發布了《2026 Agentic Coding Trends Report》,提出了 8 大趨勢預測。作為一名在企業級系統架構領域深耕多年的架構師,我將逐一拆解每個趨勢,結合實際的代理操作經驗,為你呈現這份報告背後的深層意涵。


    🏗️ 基礎趨勢:地殼級的轉變

    趨勢 1:軟體開發生命週期(SDLC)將劇烈改變

    架構師視角

    這不只是「AI 幫你寫 code」這麼簡單。報告指出,從機器碼到組合語言、從 C 到現代高階語言,每一層抽象都在縮短人類思維與機器執行之間的距離。而 Agentic AI 是這條演化路線上最新的一步——人機對話式程式開發

    作為架構師,我看到的核心轉變是:工程師的角色從「實作者」變成「指揮者」。這就像軍隊中從士兵升為指揮官——你不再親自衝鋒陷陣,而是制定戰略、分配資源、審查成果。

    報告特別提到一個關鍵數據:工程師約 60% 的工作使用 AI,但只有 0-20% 能完全委派。這說明了一個事實——AI 是協作者,不是替代者。你仍然需要深厚的工程知識來判斷 AI 產出的品質。

    實戰操作:如何用 Coding Agent 重塑你的 SDLC

    場景一:快速上手陌生程式碼庫

    報告指出新人上手時間將從數週壓縮到數小時。以下是實際操作方式:

    # 使用 Claude Code 探索陌生程式碼庫
    # 步驟 1:讓代理理解整體架構
    $ claude "分析這個專案的整體架構,包括主要模組、依賴關係、資料流向"
    
    # 步驟 2:針對特定模組深入了解
    $ claude "解釋 src/auth/ 目錄下的認證機制,包括 token 生命週期和刷新策略"
    
    # 步驟 3:理解業務邏輯
    $ claude "追蹤一個訂單從建立到完成的完整流程,列出涉及的所有服務和資料表"
    

    場景二:架構決策輔助

    # 讓代理幫你評估架構方案
    $ claude "我們正在考慮將單體應用拆分為微服務。
    分析目前的程式碼耦合度,識別可以獨立拆分的邊界上下文(Bounded Context),
    並評估每個拆分方案的風險和收益"
    
    # 代理會:
    # 1. 掃描所有模組間的依賴關係
    # 2. 識別高耦合和低耦合的邊界
    # 3. 提出具體的拆分建議和遷移路徑
    

    架構師建議:建立一份「AI 委派矩陣」——明確定義哪些任務適合完全委派、哪些需要協作完成、哪些必須人工處理。例如:

    • 完全委派:單元測試撰寫、程式碼格式化、簡單 CRUD API、文件生成
    • 協作完成:複雜業務邏輯、效能優化、資料庫 schema 設計
    • 人工主導:架構決策、安全審計、合規性審查、系統設計

    ⚡ 能力趨勢:代理能做什麼

    趨勢 2:單一代理演化為協調團隊

    架構師視角

    這是我認為最具顛覆性的趨勢。報告中提到 Fountain 公司透過階層式多代理協調(Hierarchical Multi-Agent Orchestration)實現了 50% 更快的篩選速度和 2 倍的候選人轉化率。

    從架構角度來看,Multi-Agent 系統本質上就是分散式系統設計——這正是我們架構師的核心能力。想像一下:每個 Agent 就是一個微服務,擁有獨立的 context window(類似獨立的記憶體空間),透過 Orchestrator(類似 API Gateway 或 Message Broker)進行協調。

    關鍵的架構模式有三種:

    1. Orchestrator Pattern(編排模式):一個中央代理分配任務、收集結果
    2. Pipeline Pattern(管線模式):代理們串聯處理,每個處理完交給下一個
    3. Swarm Pattern(群體模式):多個代理平行處理,最後彙整結果

    實戰操作:建構多代理工作流

    場景:用多代理系統進行完整的 Feature 開發

    # 使用 Claude Code 的 subagent 機制
    # 主代理(Orchestrator)接收需求後,分派給專業子代理
    
    # Agent 1: 架構分析代理
    $ claude "作為架構分析代理,分析「新增用戶通知系統」這個需求,
    識別需要修改的模組、新增的介面、以及對現有系統的影響"
    
    # Agent 2: 測試代理 — 平行撰寫測試
    $ claude "作為測試代理,為用戶通知系統撰寫完整的測試案例,
    包括單元測試、整合測試、邊界條件測試"
    
    # Agent 3: 實作代理 — 根據架構分析進行開發
    $ claude "根據以下架構分析結果,實作用戶通知系統的核心模組..."
    
    # Agent 4: 安全審查代理
    $ claude "審查以下程式碼的安全性,檢查 OWASP Top 10 漏洞,
    特別關注輸入驗證、SQL Injection、XSS 防護"
    

    進階:使用 Claude Agent SDK 建構自動化多代理系統

    # 使用 Claude Agent SDK 建構 Multi-Agent Pipeline
    from claude_agent_sdk import Agent, Orchestrator
    
    # 定義專業代理
    architect_agent = Agent(
        role="architect",
        system_prompt="你是資深架構師,負責分析需求並產出技術設計文件",
        tools=["file_read", "codebase_search"]
    )
    
    test_agent = Agent(
        role="tester",
        system_prompt="你是測試工程師,負責撰寫全面的測試案例",
        tools=["file_write", "test_runner"]
    )
    
    impl_agent = Agent(
        role="implementer",
        system_prompt="你是實作工程師,根據設計文件和測試案例進行開發",
        tools=["file_write", "file_edit", "bash"]
    )
    
    reviewer_agent = Agent(
        role="reviewer",
        system_prompt="你是 Code Reviewer,負責品質和安全審查",
        tools=["file_read", "security_scanner"]
    )
    
    # 建構協調器
    orchestrator = Orchestrator(
        agents=[architect_agent, test_agent, impl_agent, reviewer_agent],
        workflow="sequential",  # 或 "parallel", "hierarchical"
        checkpoints=["after_design", "after_tests", "after_implementation"]
    )
    
    # 執行
    result = orchestrator.run("實作用戶通知系統,支援 Email、SMS、Push 三種管道")
    

    架構師建議:不要一開始就追求複雜的多代理架構。先從兩個代理開始——一個負責實作,一個負責審查——建立基本的「雙人檢查」機制,再逐步擴展。


    趨勢 3:長時間運行的代理建構完整系統

    架構師視角

    報告中的 Rakuten 案例極具說服力:Claude Code 在 7 小時內自主完成了在一個 1,250 萬行程式碼庫中的複雜實作,達到 99.9% 的數值精確度。

    從架構角度來看,長時間運行的代理本質上需要解決三個核心問題:

    1. 狀態管理(State Management):代理如何在長時間任務中維持一致的上下文?
    2. 錯誤恢復(Error Recovery):當代理遇到錯誤時,如何回退並嘗試替代方案?
    3. 檢查點(Checkpointing):如何設置人工介入點,確保代理沒有偏離方向?

    這些問題與我們設計分散式系統時面臨的挑戰如出一轍。Saga Pattern、Circuit Breaker、Retry with Backoff——這些架構模式都可以類比到代理系統的設計中。

    實戰操作:設置長時間運行的代理任務

    # 場景:讓代理自主重構整個模組
    
    # 步驟 1:提供清晰的目標和邊界
    $ claude "重構 src/legacy/payment/ 模組:
    目標:將回調式(callback)程式碼遷移到 async/await 模式
    邊界:
    - 不要修改公開 API 介面
    - 保持所有現有測試通過
    - 每完成一個檔案就執行測試套件
    - 如果測試失敗,回退該檔案的變更並報告問題
    檢查點:每處理 5 個檔案暫停,等待我的確認"
    
    # 步驟 2:利用 CLAUDE.md 提供長期上下文
    # 在專案根目錄建立 CLAUDE.md,讓代理記住專案規範
    
    # 步驟 3:使用 Git Worktree 隔離工作
    $ git worktree add ../payment-refactor feature/payment-async
    $ cd ../payment-refactor
    $ claude "開始重構工作..."
    

    架構師建議:為長時間代理任務設計「護欄(Guardrails)」——明確定義代理不能做的事情比定義它應該做什麼更重要。這就像 Kubernetes 的 Resource Limits 一樣,防止代理失控。


    趨勢 4:人類監督透過智慧協作擴展

    架構師視角

    報告揭示了一個「協作悖論」:工程師 60% 的工作使用 AI,但只有極小比例能完全委派。這不是 AI 能力不足,而是信任需要逐步建立

    從系統設計角度,這就是漸進式信任模型(Progressive Trust Model)

    • Level 0 – 監控模式:代理執行,人類逐行審查(適合初期導入)
    • Level 1 – 抽查模式:代理執行,人類抽樣審查(適合建立信任後)
    • Level 2 – 異常模式:代理執行 + 自我審查,只有異常才通知人類
    • Level 3 – 自主模式:代理全自主執行,人類只在策略層介入

    實戰操作:建立智慧監督機制

    # 利用 Claude Code 的 Hooks 機制建立自動化審查
    
    # 在 .claude/settings.json 中設定 hooks
    {
      "hooks": {
        "PostToolUse": [
          {
            "matcher": "Edit|Write",
            "command": "npm run lint --fix && npm test -- --bail"
          }
        ],
        "PostCommit": [
          {
            "command": "npm run security-audit"
          }
        ]
      }
    }
    
    # 這樣每次代理修改程式碼,都會自動:
    # 1. 執行 lint 檢查
    # 2. 執行測試
    # 3. 提交時執行安全掃描
    # 形成自動化的品質護欄
    

    場景:使用代理審查代理的產出

    # Agent A: 實作功能
    $ claude "實作用戶匯出功能,支援 CSV 和 Excel 格式"
    
    # Agent B: 審查 Agent A 的產出(獨立 context,避免偏見)
    $ claude "請審查以下程式碼變更(git diff),從以下角度:
    1. 安全性:是否有 injection 風險?大檔案是否會 OOM?
    2. 效能:匯出 100 萬筆資料時的記憶體和時間複雜度?
    3. 可維護性:是否符合專案既有的設計模式?
    4. 邊界條件:空資料、特殊字元、併發匯出等情況?"
    

    架構師建議:建立「代理信任儀表板」——追蹤代理產出的品質指標(測試通過率、Code Review 修改率、Bug 回報率),用數據驅動你的信任等級調整。


    趨勢 5:代理編程擴展到新領域和新用戶

    架構師視角

    報告指出 AI 正在打破「寫程式的人」和「不寫程式的人」之間的界線。這對架構師來說意味著一個巨大的設計挑戰:如何設計系統讓非技術人員也能安全地進行自動化

    想像一下你的法務團隊用 AI 建立了合約審查自動化、行銷團隊建立了 A/B 測試分析管線、HR 建立了招聘數據儀表板——這些都直接連接到你的核心系統。沒有良好的架構,這就是一場災難。

    實戰操作:為非技術團隊建立安全的代理環境

    # 場景:讓數據分析師用代理進行資料分析
    
    # 方式 1:提供受限的 Claude Code 環境
    # 建立專用的 CLAUDE.md 限制代理行為
    # 允許:讀取 /data/ 目錄、執行 Python 腳本、產生圖表
    # 禁止:修改任何程式碼、存取生產資料庫、安裝新套件
    
    # 方式 2:使用 MCP (Model Context Protocol) 提供安全的 API 存取
    {
      "mcpServers": {
        "company-data": {
          "command": "node",
          "args": ["mcp-server/data-access.js"],
          "env": {
            "DB_ROLE": "readonly",
            "MAX_ROWS": "10000"
          }
        }
      }
    }
    

    架構師建議:為每個非技術團隊的代理使用場景設計「沙盒(Sandbox)」。就像你不會給實習生 production 的 root 權限一樣,非技術人員的代理也需要明確的權限邊界。使用 Least Privilege 原則,只給代理完成任務所需的最小權限。


    📊 影響趨勢:代理將改變什麼

    趨勢 6:生產力提升重塑軟體開發經濟

    架構師視角

    報告中最引人注目的數據是:約 27% 的 AI 輔助工作是「原本不會做的事」。這不只是效率提升,而是價值創造

    從架構師角度,我把這稱為「技術債務清算窗口」。過去那些因為「沒時間」而累積的技術債——老舊的 API 版本、缺失的測試、過時的文件、效能瓶頸——現在都可以系統性地被代理消滅。

    報告提到三個乘數效應(Three Multipliers):代理能力提升 × 協調改進 × 人類經驗 = 指數級加速。這不是線性增長,而是複合增長。就像 DevOps 革命一樣,三者相互增強。

    實戰操作:系統性消滅技術債

    # 場景:用代理批量處理技術債
    
    # 步驟 1:讓代理掃描並分類技術債
    $ claude "掃描整個程式碼庫,識別以下類型的技術債:
    1. 已廢棄的 API 調用(deprecated warnings)
    2. 缺少測試覆蓋的關鍵路徑
    3. 硬編碼的配置值
    4. 重複的程式碼(DRY 違反)
    5. 不一致的錯誤處理模式
    按嚴重程度和修復成本排序,產出優先級清單"
    
    # 步驟 2:逐項自動修復
    $ claude "根據優先級清單,從最高優先級開始:
    - 每修復一項,執行完整測試套件
    - 每項修復獨立一個 commit
    - 如果修復可能影響其他模組,標記為需要人工審查"
    

    架構師建議:建立「20% 代理時間」制度——每個 Sprint 撥出 20% 的代理運算資源專門處理技術債。用代理來做那些人類「知道該做但沒時間做」的事。


    趨勢 7:非技術用例擴展至全組織

    架構師視角

    報告中 Anthropic 自家法務團隊的案例最具說服力:一位沒有程式碼經驗的律師用 Claude Code 建立了自助服務工具,將行銷審查周轉時間從 2-3 天縮短到 24 小時。

    Zapier 更是達到了 89% 的全組織 AI 採用率,部署了 800+ 個內部 AI 代理。

    作為架構師,這意味著你需要開始思考「代理治理(Agent Governance)」:誰可以建立代理?代理可以存取哪些系統?如何追蹤和審計代理的行為?代理出錯時的責任歸屬?

    實戰操作:建構組織級代理平台

    # 架構建議:建立內部的 Agent Platform
    
    # 1. 定義代理模板(Agent Templates)
    # marketing-agent-template.yaml
    name: marketing-automation-agent
    permissions:
      read: [marketing-data, analytics-api]
      write: [marketing-reports, draft-content]
      execute: [data-analysis-scripts]
      forbidden: [production-db, source-code, deployment]
    resource_limits:
      max_tokens_per_day: 1000000
      max_api_calls: 500
    audit:
      log_all_actions: true
      alert_on: [data-access, external-api-call]
    
    # 2. 建立自助服務入口
    # 非技術人員透過 Web UI 與代理互動
    # 所有操作都在沙盒環境中執行
    
    # 3. 監控儀表板
    # 追蹤全組織的代理使用情況:
    # - 各部門使用量和成本
    # - 代理產出的品質指標
    # - ROI 分析(節省的人力時間 vs 代理成本)
    

    架構師建議:把「代理治理」視為與「資料治理」同等重要的架構議題。建立 Agent Center of Excellence (ACoE),制定組織級的代理使用政策、安全標準和最佳實踐。


    趨勢 8:雙重用途風險需要安全優先架構

    架構師視角

    這是最被低估但最重要的趨勢。報告指出:同樣的 AI 能力既能強化防禦,也能助長攻擊

    從架構角度,這意味著安全不再是事後補救,而必須是設計時的第一考量(Security by Design)。當任何工程師都能用 AI 進行深度安全審查時,攻擊者也能用同樣的 AI 尋找漏洞。

    關鍵的架構原則:

    • Zero Trust Architecture:不信任任何內部或外部的代理輸出
    • Defense in Depth:多層防禦,即使一層被突破仍有保護
    • Shift Left Security:在開發早期就嵌入安全檢查

    實戰操作:用代理建立安全防線

    # 場景 1:自動化安全審查管線
    # 在 CI/CD Pipeline 中嵌入 AI 安全審查
    name: AI Security Review
    on: [pull_request]
    jobs:
      security-review:
        steps:
          - name: AI Security Scan
            run: |
              claude "審查這個 PR 的所有變更:
              1. OWASP Top 10 漏洞掃描
              2. 硬編碼的密鑰或憑證
              3. SQL/NoSQL Injection 風險
              4. XSS 和 CSRF 防護
              5. 權限提升風險
              6. 敏感資料洩漏
              以 SARIF 格式輸出結果"
    
    # 場景 2:用代理進行威脅建模
    $ claude "對以下系統架構進行威脅建模(STRIDE 方法):
    - 前端:React SPA
    - API Gateway:Kong
    - 後端:Spring Boot 微服務群
    - 資料庫:PostgreSQL + Redis
    - 訊息佇列:Kafka
    - 部署:Kubernetes on AWS"
    
    # 場景 3:AI 紅藍對抗
    # 用一個代理扮演攻擊者(Red Team)尋找漏洞
    # 另一個代理扮演防禦者(Blue Team)修補漏洞
    

    架構師建議:建立「AI 紅藍對抗」機制——用一個代理扮演攻擊者尋找漏洞,另一個代理扮演防禦者修補漏洞。這種持續的對抗演練能顯著提升系統安全性。


    🎯 我的行動建議:2026 年架構師優先事項

    綜合以上 8 大趨勢,我給出以下具體的行動清單:

    立即行動(本月)

    1. 建立 CLAUDE.md:為每個專案建立代理上下文文件,定義程式碼規範、禁止事項、測試要求
    2. 設定 Hooks:配置自動化品質護欄,確保代理每次修改都通過基本檢查
    3. 導入雙代理審查:一個代理寫程式碼,另一個代理審查,建立基本的品質保障

    短期規劃(本季)

    1. 建立 AI 委派矩陣:明確定義團隊中哪些任務適合委派給代理
    2. 啟動技術債清理專案:利用代理系統性處理積壓的技術債
    3. 設計代理安全框架:定義代理的權限邊界、審計機制、異常處理

    中期布局(今年)

    1. 建構多代理協調系統:根據團隊需求設計 Orchestrator 架構
    2. 推動非技術團隊採用:為業務團隊建立安全的代理沙盒環境
    3. 建立 Agent Governance 體系:制定組織級的代理使用政策和治理框架

    結語

    這份報告的核心訊息很清楚:2026 年的軟體開發正在從「寫程式碼」轉向「指揮寫程式碼的代理」。但這不是要取代工程師——恰恰相反,它要求工程師具備更高層次的思考能力:架構設計、系統思維、品質判斷、安全意識。

    作為架構師,我們正處於一個前所未有的機遇期。那些能夠設計良好的代理協作架構、建立有效的人機協作模式、並在組織層面推動代理治理的架構師,將成為這場變革的引領者。

    最後的忠告:不要等到完美才開始。今天就打開 Claude Code,給它一個你一直拖著沒做的重構任務,開始建立你的代理協作經驗。實踐出真知。

    本文基於 Anthropic《2026 Agentic Coding Trends Report》撰寫。報告原文共 18 頁,涵蓋基礎趨勢、能力趨勢、影響趨勢三大類別共 8 個趨勢預測。

  • 舊系統不死,AI 讓它進化:不重寫也能持續成長

    重點摘要

    • 舊系統不是問題,缺乏 AI 輔助才是問題——AI 讓「不重寫、持續演進」成為可行選項
    • 歷史證明:超過 80% 的「重寫計畫」以失敗或兩個系統都要維護收場
    • AI 最確定的價值是讀懂舊代碼、補文件、補測試,讓團隊敢繼續開發
    • 「AI 能不能讓大規模翻新變安全」——這是尚待驗證的命題,不宜過度樂觀

    你的公司有一套跑了十年的系統。它能動,它撐起了整個業務,但沒有人敢碰它。文件不齊、邏輯散落在各處、原始開發者早就離職了。每次有人提議「重寫」,討論就會陷入沉默——因為大家心裡都知道,這條路走過很多次,沒幾次是成功的。

    AI 的出現,讓這個困境有了新的解法。但不是你想像中的那種解法。

    為什麼重寫這麼難?歷史給了殘酷的答案

    軟體界有個著名的現象叫做 Second System Effect(第二系統效應),由《人月神話》作者 Fred Brooks 提出:工程師在重寫時,往往會把所有「本來想做卻沒做」的功能都塞進去,結果新系統比舊系統更複雜、更難維護。

    但更根本的問題是:舊系統裡有隱藏的業務邏輯,它們沒有寫在文件裡,只存在於代碼的行為中——某個奇怪的判斷式、某個例外處理、某個只在特定情境才觸發的路徑。這些邏輯,是十年來無數個「為什麼這樣做?」的答案。

    重寫計畫的典型失敗模式

    • 兩個系統並行期拉太長:新舊系統同時維護,工程師精力分散,bug 在兩邊都出現
    • 上線那天發現漏了邏輯:舊系統某個角落的行為,新系統根本沒有對應
    • 商業壓力中斷重寫:計畫進行到一半,業務需求改變,只能把新舊系統黏在一起
    • 重寫後反而更慢:新架構雖然「漂亮」,但少了十年累積的效能優化細節

    這不是悲觀,這是現實。重寫不是不可能,但它的成功率遠低於大多數人的預期。在 AI 出現之前,面對舊系統,企業只有兩條路:硬撐,或者賭一把。

    AI 帶來了第三條路:輔助成長

    AI 最確定的價值,不是幫你重寫系統,而是讓「不重寫、持續演進」這件事變得可持續。

    過去,舊系統的最大問題不是代碼本身,而是「沒有人理解它」。原始開發者離職了,知識沒有傳承;文件過時了,沒有人有時間更新;要改一個功能,必須花三天理解上下文,才敢動一行代碼。

    AI 改變了這個方程式。

    AI 能為舊系統做什麼?

    挑戰 過去的困境 AI 輔助後
    理解舊代碼 要花幾天甚至幾週閱讀 AI 幾分鐘內產出架構圖和流程說明
    補充文件 沒時間寫、寫了也快過時 AI 根據現有代碼生成,每次修改後更新
    補充測試 舊系統通常 0 測試,改動沒有安全網 AI 針對現有行為補寫測試,改動有保護
    修復 bug 怕改了 A 壞了 B,只敢最小化改動 AI 追蹤影響範圍,降低連帶破壞風險
    新人上手 要跟著老人學幾個月才敢動 AI 隨時解釋任何一段代碼的邏輯和背景
    新增功能 不知道該插在哪裡,怕破壞現有邏輯 AI 建議最小侵入式的擴充點

    實際做法:AI 如何輔助舊系統成長

    第一步:讓 AI 讀懂系統,產出活的文件

    不要急著改代碼。第一件事是讓 AI 理解現有系統,然後把理解結果固化成文件。

    # 讓 AI 讀整個 codebase,產出架構說明
    # 在 Claude Code 中,直接描述你的需求:
    
    「請閱讀這個專案的所有代碼,並產出:
    1. 系統架構圖(模組與模組之間的關係)
    2. 核心業務流程說明(從使用者角度描述主要流程)
    3. 高風險區域列表(邏輯最複雜、最不敢動的地方)
    4. 技術債清單(有哪些地方明顯需要改善)」

    這份文件不是給外部人看的,是給你的團隊每天使用的工作手冊。它會隨著系統改動而更新——這一點很重要,因為過去文件之所以沒用,是因為沒有人有時間維護它。AI 讓維護文件的成本降低了 90%。

    第二步:為現有行為補測試,建立安全網

    舊系統的問題不是「代碼爛」,而是「沒有測試保護」。任何一個修改都是在沒有安全網的情況下走鋼絲。

    AI 可以閱讀現有代碼,理解它的行為,然後為這些行為寫測試——即使這些行為從來沒有文件。

    # 範例:讓 AI 為現有函式補測試
    「這個函式 calculateDiscount() 已經跑了八年,
    請分析它的所有分支條件,為每個分支寫一個測試案例,
    包括正常情況、邊界值和異常情況。
    不要改動現有邏輯,只補充測試。」

    有了測試,團隊才敢改動。改動有安全網,系統才能持續演進而不是不斷累積技術債。

    第三步:最小侵入式地新增功能

    新增功能不等於重構整個模組。AI 擅長找到「最小侵入式的擴充點」——在不動現有邏輯的前提下,把新功能插進去。

    這個原則來自 Open/Closed Principle(開放封閉原則):對擴充開放,對修改封閉。即使舊系統沒有遵循這個原則,AI 也可以建議如何在外圍包一層,讓新功能不影響舊邏輯。

    第四步:漸進式現代化,而非大爆炸式重寫

    如果真的有部分需要改善,AI 輔助的方式是:一次只動一個模組,改完之後讓它穩定跑一段時間,確認沒有問題再動下一個。

    這不是「重寫」,這是「漸進式現代化」。兩者的關鍵差異:

    重寫 漸進式現代化
    範圍 全部 一次一個模組
    風險 集中在上線日 分散,每步都可以回滾
    業務中斷 長期並行維護兩個系統 系統持續運作,局部更新
    AI 的角色 「幫我重新實作這一切」 「幫我安全地改善這一塊」

    那麼,「重寫」這條路呢?

    這是一個需要誠實面對的問題。

    過去的答案很清楚:重寫計畫成功率低,風險高,通常不是好選擇。大多數成功的案例,仔細看都是「漸進式替換」而不是「一次性重寫」。

    AI 會改變這個答案嗎?

    這是一個尚待驗證的命題。AI 確實讓理解舊系統更容易,讓知識遷移成本降低,理論上應該讓重寫的準備工作做得更完整。但「做得更完整的準備」不等於「執行時不會出問題」。隱藏的業務邏輯、時序問題、效能細節——這些在代碼裡只有在跑了幾百萬筆資料之後才會浮現。

    更誠實的說法是:

    • AI 讓「輔助成長」這條路變得可行——這是現在就可以驗證的事
    • AI 讓「重寫」變得更安全——這是有可能的,但還需要更多實際案例來驗證
    • AI 能取代「漸進式替換」的謹慎原則——不太可能,這個原則的價值在於限制風險暴露,而不是技術能力

    所以,如果有人告訴你「有了 AI,重寫就不危險了」——保持懷疑。如果有人告訴你「AI 讓你不需要擔心舊系統的技術債了」——同樣保持懷疑。

    如何判斷你的系統需要什麼?

    面對舊系統,用這個框架來判斷方向:

    優先考慮 AI 輔助成長,如果:

    • 系統仍然在提供商業價值,只是難以維護
    • 核心業務邏輯複雜,沒有人完整理解
    • 團隊規模小,無法支撐兩個系統並行
    • 業務需求變化頻繁,不能停下來等重寫完成

    可以考慮漸進式替換(不是重寫),如果:

    • 某個模組已經明顯成為瓶頸,且邊界清晰
    • 有足夠的測試保護現有行為
    • 可以部署影子流量,讓新舊模組並行驗證
    • 有明確的回滾機制

    謹慎考慮大規模重寫,只有當:

    • 現有系統在技術上已經無法繼續擴充(不只是難,而是真的不可能)
    • 有足夠的資源支撐至少 18 個月的並行期
    • 有完整的行為規格文件(或 AI 幫你產出的等效文件)
    • 組織願意接受在過渡期期間功能停滯

    結語:舊系統不是問題,缺乏支援才是

    回到最初的問題:那套跑了十年的系統,它的問題不是年齡,而是孤立。沒有人理解它,沒有測試保護它,沒有文件說明它,改動它需要承擔巨大的個人風險。

    AI 能做的,是讓這個系統不再孤立。它可以成為每個工程師的「老前輩」——隨時解釋任何一段邏輯,隨時分析改動的影響,隨時生成測試保護現有行為。

    這不是重寫的故事,這是陪伴成長的故事。

    至於重寫——如果未來真的需要,AI 會讓你準備得更充分。但那是另一個故事,而且它的結局還沒有寫完。

  • 10 年舊系統如何安全導入 AI 開發:Strangler Fig 遷移方法論

    重點摘要

    • 10 年的舊系統能跑就是最有價值的資產,不要試圖先修好再遷移
    • 核心方法論:Strangler Fig 模式 — 新軌道在旁邊長起來,舊系統自然退場
    • AI 第一件事不是寫 code,而是讀懂 10 年的系統邏輯,再動手
    • 四個階段:快照現況 → 建平行新軌 → 一次搬一個服務 → 封存舊系統

    你的系統跑了 10 年。它很髒、沒有文件、CI/CD 靠手動、密碼可能在 .env 裡或者在某個工程師的腦袋裡。但它能跑,而且在服務真實的用戶。

    現在你想引入 AI 輔助開發,想現代化整個工作流。問題來了:要從哪裡開始? 要先把舊的修乾淨,還是直接用新方法?

    錯誤的答案是:「先把舊的修好。」正確的答案是:不要動正在跑的東西,在旁邊建一條新軌道。

    為什麼「先修好再用新方法」行不通?

    這個直覺很自然,但在實際工程上幾乎都會失敗,原因有三:

    1. 無法停止開發等你修 — 業務不會暫停,新需求還是會進來,你邊修邊開發,舊問題永遠追不完
    2. 「修好」的定義會不斷移動 — 一開始說只要加 .gitignore,結果發現歷史有密碼,要 filter-repo,然後發現測試覆蓋率是零…沒有終點
    3. 你在修一個不完全理解的系統 — 10 年的系統有太多隱性知識,修的過程中很容易把「能跑的」改成「不能跑的」

    工程界有一個著名的模式專門解決這個問題,叫做 Strangler Fig(絞殺榕)模式

    Strangler Fig 模式:不砍舊樹,讓新藤蔓長過去

    絞殺榕是一種熱帶植物。它的種子落在老樹上,慢慢向下長出根,包住舊樹,最後舊樹自然退場,絞殺榕站立在原位。整個過程中,舊樹從未停止「提供支撐」,直到新系統完全就緒。

    應用到 DevOps 遷移:

    ❌ 錯誤思維:
    舊系統(停機)→ 修好 → 接新流程 → 恢復服務
    
    ✅ 正確思維(Strangler Fig):
    舊系統(持續運行,不動)
        ↓
    新軌道在旁邊建立(不影響舊系統)
        ↓
    一次搬一個服務,驗證後切換流量
        ↓
    所有服務搬完,舊系統自然退場

    關鍵洞察:能跑的系統是你最有價值的資產,不是問題的來源。遷移的目標是「讓它繼續跑,同時讓新系統在旁邊成長」,不是「讓它停下來修好再說」。

    四個階段的完整遷移方法論

    階段一:快照現況(不動任何東西)

    第一步不是改 code,不是設定 CI/CD,而是把「現在是怎麼跑起來的」完整記錄下來。這份快照是整個遷移過程的地基。

    為什麼要快照?因為在 10 年的系統裡,repo 裡的 .env 可能是舊的,文件可能是錯的,只有正在跑的進程才是真相:

    # 從正在跑的容器抽出真實的環境變數
    docker inspect <container_name> \
      --format='{{range .Config.Env}}{{println .}}{{end}}' \
      > /tmp/real-env-snapshot.txt
    
    # 或直接讀進程的環境變數
    cat /proc/$(pgrep java)/environ | tr '\0' '\n' | grep -E "DB_|API_|SECRET_"
    
    # K8s 環境
    kubectl get pods -n production -o name | while read pod; do
      echo "=== $pod ==="
      kubectl exec $pod -n production -- env 2>/dev/null
    done > /tmp/real-k8s-env-snapshot.txt

    同時盤點服務清單和依賴關係:

    # 有哪些服務在跑
    docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
    
    # 服務之間怎麼通訊
    docker network inspect bridge
    
    # 對外開放哪些 port
    ss -tlnp | grep LISTEN

    這個階段的產出是一份真實架構圖和一份真實密碼清單(妥善保管,不進任何 repo)。

    階段二:AI 讀懂你的系統

    這是大多數人忽略的步驟,也是決定 AI 協作能否成功的關鍵。

    AI 第一件事不是寫 code。

    在 AI 動手之前,它需要讀你 10 年的系統。這個過程大概需要幾天,但會產出你可能從未有過的東西:

    AI 讀完後的產出 為什麼重要
    系統架構圖 你們可能自己也沒有,新人上手和遷移規劃的基礎
    模組依賴關係 知道改哪個地方會影響哪些服務
    高風險區域標記 「這段 code 10 個人改過,有 3 個已知 bug 的修復」
    技術債清單(按影響排序) 知道先解決什麼,不是看到髒的就改
    新人上手文件 從 code 反推出來,不需要老工程師口傳

    這個階段同樣不動任何 code。AI 只是閱讀和理解。等到真正開始寫新功能時,AI 已經知道你的系統慣例是什麼、有哪些地雷不能踩。

    階段三:建立平行的新軌道

    新建一個乾淨的 repo,在旁邊建立完整的現代化工作流,舊 repo 繼續照舊運作

    舊 GitLab repo(繼續跑,不動)
         │
         │  正在服務用戶的系統
         │
    新 repo(乾淨起點)
         │
         ├─ 正確的 .gitignore(.env 全部排除)
         ├─ CI/CD pipeline(gitleaks + build + sign)
         ├─ K8s Secrets(從快照搬進來)
         └─ Branch Protection Rules

    把真實密碼從快照搬到 K8s Secrets(不是從舊 repo 搬,是從正在跑的進程抽出來):

    # 從快照建立 K8s Secrets
    kubectl create secret generic app-prod-creds \
      --from-literal=DB_PASSWORD="$(grep DB_PASSWORD /tmp/real-env-snapshot.txt | cut -d= -f2)" \
      --from-literal=SHOPEE_KEY="$(grep SHOPEE_KEY /tmp/real-env-snapshot.txt | cut -d= -f2)" \
      -n production
    
    # 建立完成後,安全刪除快照
    shred -u /tmp/real-env-snapshot.txt

    階段四:一次搬一個服務

    這是遷移的主體。原則是:每次只搬一個服務,驗證通過才搬下一個

    服務搬移的優先順序建議:

    優先順序 選擇原則 理由
    第一批 流量最小的非核心服務 風險最低,可以放心試錯
    第二批 獨立性高、依賴少的服務 不會牽一髮動全身
    最後 核心業務邏輯(訂單、付款) 等前幾批證明新流程可靠後再動

    每個服務的搬移步驟:

    1. AI 在新 repo 重寫該服務的乾淨版本(理解舊 code 後重寫,不是 copy paste)
    2. Jenkins 構建新鏡像,部署到 Staging
    3. 用影子流量驗證新舊行為一致(新舊同時收請求,比對回應)
    4. 確認無誤,切換這個服務的流量到新系統
    5. 觀察 24-48 小時
    6. 舊服務下線

    影子流量驗證(用 nginx 實現,不影響用戶):

    # nginx 配置:新舊同時收請求,比對行為
    location /api/orders {
        mirror /mirror-new;       # 複製請求到新系統
        proxy_pass http://old-api; # 用戶實際收到舊系統的回應
    }
    
    location = /mirror-new {
        internal;
        proxy_pass http://new-api;  # 新系統的回應只寫 log,不回傳用戶
    }

    AI 在整個過程中的實際角色

    理解了遷移方法論後,AI 在這個過程中的職責非常清楚:

    AI 能做(且做得很好):
      ✅ 讀 10 年的舊 code,產出架構文件
      ✅ 識別技術債,按優先順序排列
      ✅ 用「符合你們系統慣例」的方式寫新功能
      ✅ 在 feature branch 開發,開 MR,等你 review
      ✅ 補測試(補現有 code 的測試覆蓋率)
      ✅ Debug(分析 log,找根因)
      ✅ 在新服務和舊系統的接縫處寫 adapter
    
    AI 不能做(也不應該做):
      ❌ 直接 push 到 main 或 production branch
      ❌ 決定什麼時候切換流量
      ❌ 接觸任何密碼或 production secrets
      ❌ 在沒有充分理解舊系統的情況下動手

    一個典型的 AI 協作對話長這樣:

    你:「我要加一個批次出貨的功能」
    
    AI:「讓我先讀一下現有的出貨相關 code...
         我看到 OrderService.java 的 shipOrder()
         和 ShipmentRepository,還有一個舊的
         BatchJob 在 legacy/ 目錄。
    
         注意:legacy/BatchJob 有個已知的
         transaction 問題(commit a3f2c1b 的修復紀錄),
         新功能要避開。
    
         建議的實作方向是...你確認嗎?」
    
    你:「方向對,去做吧」
    
    AI:「好,我開 feature/batch-shipment,
         預計改動:
         - 新增 BatchShipmentService(核心邏輯)
         - 修改 OrderController(加 API endpoint)
         - 不動 legacy/ 目錄
         
         完成後開 MR 給你 review」

    AI 因為讀過 10 年的系統,不會做出「不符合你們慣例」的 code,也不會踩進已知的地雷。

    最常遇到的三個現實問題

    問題一:「不知道哪個 .env 是現在真正在用的」

    10 年的系統通常有多個 .env 版本,有的是舊的,有的是工程師自己改過的。以正在跑的進程為準,不要相信文件

    # 找到 Java 進程真正使用的環境變數
    cat /proc/$(pgrep java)/environ | tr '\0' '\n' | grep -E "DB_|API_|SECRET_"
    
    # 不要用
    cat .env  # 這可能是 6 個月前的版本

    問題二:「團隊還在開發,不能凍結」

    不需要凍結。舊 repo 繼續用,新 repo 並行開發。重要的 bugfix 透過 cherry-pick 同步:

    舊 repo: feature → dev → main(繼續照舊)
                  │
                  └─ cherry-pick 重要修復
                          │
    新 repo:              └─ feature → dev → main(新流程)

    問題三:「歷史 commit 有密碼怎麼辦」

    分兩步處理:

    1. 立即輪換所有洩露的密碼 — 因為 GitHub/GitLab 可能已有快取,這一步不能等
    2. 舊 repo 等到遷移完成後再 archive — 不需要現在重寫歷史,新 repo 一開始就是乾淨的

    注意:很多人以為 git rm --cached .env 就安全了,但舊 commit 裡的內容仍然可以被 git show <old-commit>:.env 讀出。唯一的技術修復是 git filter-repo,但遷移方法論讓你可以跳過這一步——因為所有新開發都在新的乾淨 repo 上進行。

    時間軸規劃

    時間 工作 風險
    第 1 週 快照現況、輪換外部 API Key、AI 開始讀系統 零(不動任何 code)
    第 2-4 週 建新 repo、CI/CD pipeline、K8s Secrets、第一個服務搬過去 低(影子流量驗證)
    第 1-3 個月 逐服務遷移,每個驗證 24-48 小時後才繼續 中(每次只影響一個服務)
    遷移完成後 舊 repo archive、完整安全強化(RBAC、Audit Log、鏡像簽名) 低(新系統已穩定)

    決策樹:你現在該從哪裡開始

    你的系統現在能跑嗎?
      │
      ├─ 能跑 → 用 Strangler Fig 模式(本文的方法)
      │           │
      │           ├─ 步驟 1:快照現況(本週就做)
      │           ├─ 步驟 2:AI 讀系統(同步進行)
      │           ├─ 步驟 3:建新軌道(第 2-4 週)
      │           └─ 步驟 4:逐服務遷移(之後)
      │
      └─ 不能跑 → 先讓它跑起來,再回到這裡

    這套方法論的本質

    Strangler Fig 模式應用在 AI 輔助開發遷移上,核心洞察只有一個:

    「10 年的技術債是過去的決策的結果,你無法在不破壞現有價值的情況下一次消除它。但你可以選擇:從今天開始,所有新的工作都用正確的方式做。」

    舊系統是你團隊的集體記憶,AI 有能力閱讀並理解這些記憶,然後用現代化的方式繼續往前走。不需要推倒重建,也不需要凍結開發去修舊債——只需要一條平行的新軌道,和耐心地一次移動一個服務。

    想了解新軌道的 CI/CD 具體設計,可以參考上一篇文章:AI 輔助開發 CI/CD 工作流:Jenkins、K8s、ISO 27001 完整設計

  • AI 輔助開發 CI/CD 工作流:Jenkins、K8s、ISO 27001 完整設計

    重點摘要

    • AI 只負責寫 code、提 PR,不碰版本決策和 Production 部署,人類保留最終控制權
    • 透過 Git tag 觸發 Jenkins,Staging 全自動部署、Production 手動 helm 執行,兩階段驗證才上線
    • 敏感資訊三層隔離:.gitignore → K8s Secrets → etcd 加密,密碼永遠不進 repo
    • 補齊 RBAC、Audit Log、鏡像簽名、Secrets Scan 四大安全缺口,達到 ISO 27001 合規

    AI 輔助開發越來越普遍,但大多數團隊面臨同一個問題:AI 寫的 code 要怎麼安全地上線? 誰決定部署時機?密碼怎麼管?如果 AI 出錯了,有什麼防護網?

    本篇文章完整說明 ONEEC OMS 系統實際採用的 AI 協作工作流設計,包含完整的 User Story、Jenkins Pipeline 架構、三環境部署策略,以及通過安全審查後補齊的 RBAC、Audit Log、鏡像簽名等安全強化配置。

    核心設計理念:人類掌控節奏,AI 加速執行

    這套工作流的核心原則只有一句話:AI 是高效能的執行者,不是決策者。具體體現在以下四點:

    • AI 負責:寫 code、建 Dockerfile、提 PR、提供 Jenkins script 和 Helm chart
    • 用戶負責:code review、創建 git tag(決定版本和部署時機)、手動 helm 部署到 Production
    • 運維負責:管理 K8s Secrets、設定 Jenkins credentials、維護集群
    • 敏感資訊:密碼、API Key、SSL 憑證永遠不進入 Git repo

    完整 User Story:從需求到上線的 10 個步驟

    以下用一個真實場景說明整個流程:場景:優化訂單 API 的查詢效能

    Step 1:AI 開發(feature branch)

    AI 從 dev 分支切出 feature branch,完成開發後推送 PR:

    # AI 執行
    git checkout dev && git pull origin dev
    git checkout -b feature/order-api-optimize
    
    # 編寫程式碼...
    
    # 本地驗證
    docker-compose up -d
    curl http://localhost:8080/api/orders?status=pending
    # ✅ 回傳正確,效能提升 30%
    
    # 提交並推送
    git add . && git commit -m "feat(order-api): optimize query performance"
    git push origin feature/order-api-optimize
    # 建立 PR → dev

    Step 2:用戶 Code Review & Merge

    用戶在 GitHub UI 審查 PR:確認邏輯正確、有測試覆蓋、無敏感資訊後 approve 並 merge 到 dev。此時沒有任何自動化觸發,代碼靜靜等待部署決策。

    Step 3:用戶創建 Staging Tag → Jenkins 自動觸發

    用戶決定要部署到測試環境時,創建一個 staging-v* tag:

    # 用戶執行
    git tag staging-v1.0.1
    git push origin staging-v1.0.1
    
    # GitHub Webhook → Jenkins 自動執行:
    # ├─ Secrets 掃描(gitleaks)
    # ├─ docker build(所有 pods)
    # ├─ cosign 簽名鏡像
    # ├─ docker push to registry
    # ├─ helm deploy to Staging K8s(使用 values-staging.yaml)
    # └─ 通知用戶:Staging v1.0.1 is live

    Step 4:用戶在 Staging 驗證

    kubectl get pods -n staging
    curl https://staging-api.example.com/api/orders?status=pending
    # ✅ 功能正常,效能優化生效
    # ✅ 錯誤率 0%
    # ✅ 回應時間 < 100ms

    Step 5:用戶創建 Production Tag → Jenkins 構建正式鏡像

    # 用戶執行(確認 Staging 無誤後)
    git tag v1.0.1
    git push origin v1.0.1
    
    # Jenkins 執行:
    # ├─ Secrets 掃描
    # ├─ docker build(所有 pods,tag 改為 v1.0.1)
    # ├─ cosign 簽名鏡像
    # ├─ docker push to registry
    # ├─ 生成 Helm values(不含敏感資訊)
    # └─ 通知用戶:Images ready, run helm command

    Step 6:用戶手動部署到 Production

    Production 部署是整個流程中唯一純手動的步驟,這是刻意設計的——確保每一次正式上線都有人類判斷:

    # 用戶在本機執行
    helm upgrade --install order-api \
      /path/to/your/prod-configs/order-api/values-prod.yaml \
      --set image.tag=v1.0.1 \
      -n production
    
    # K8s 自動從 Secrets 注入密碼、API Key
    # Kyverno 自動驗證鏡像簽名(未簽名直接拒絕)
    # Deployment 完成 ✅

    Step 7:監控確認上線成功

    kubectl get pods -n production
    curl https://api.example.com/api/orders?status=pending
    # ✅ 正式環境驗證通過,上線成功

    三個部署環境的定義與分工

    環境 用途 部署方式 配置來源 觸發者
    Dev 本地開發驗證 docker-compose up .env.dev AI(開發時)
    Staging 測試環境(K8s) Jenkins 自動部署 values-staging.yaml(在 repo) 用戶(tag 觸發)
    Production 正式環境(K8s) 手動 helm 部署 values-prod.yaml(用戶維護)+ K8s Secrets 用戶(手動執行)

    Jenkins Pipeline 完整架構

    Jenkins Pipeline 由 GitHub Webhook(tag push)觸發,整個流程分為 6 個 Stage:

    Stage 0:Secrets 掃描(安全門控)

    這是整個 Pipeline 的第一道防線,也是最重要的安全門控。使用 gitleaks 掃描 repo 中是否含有密碼、API Key 等敏感資訊,發現即中止構建並通知安全告警

    stage('Secrets Scan') {
        steps {
            sh '''
                gitleaks detect \
                  --source . \
                  --config .gitleaks.toml \
                  --exit-code 1 \
                  --report-format json \
                  --report-path gitleaks-report.json
            '''
        }
        post {
            failure {
                sh 'sh scripts/notify-security-alert.sh ${TAG_NAME} gitleaks-report.json'
                error('❌ Secrets 掃描發現敏感資訊,構建中止!')
            }
        }
    }

    Stage 1:Tag 偵測(決定部署目標)

    根據 tag 名稱判斷本次構建的部署目標:

    stage('Detect Tag') {
        steps {
            script {
                if (env.TAG_NAME =~ /^staging-v.*/) {
                    env.DEPLOYMENT_ENV = 'staging'
                } else if (env.TAG_NAME =~ /^v.*/) {
                    env.DEPLOYMENT_ENV = 'production'
                } else {
                    error("❌ 未知 tag 格式: ${env.TAG_NAME}")
                }
            }
        }
    }

    Stage 2:Build Images

    構建所有 Pod 的 Docker 鏡像。鏡像本身不含任何配置、密碼、API Key,這是配置與代碼分離的核心原則:

    #!/bin/bash
    # scripts/build-docker.sh
    TAG=$1
    
    docker build -t registry.example.com/order-api:${TAG} ./simpleec-api
    docker build -t registry.example.com/user-app:${TAG} ./user-app
    docker build -t registry.example.com/channel-job:${TAG} ./simpleec-channel-job
    # ... 所有 pods

    Stage 3:Sign Images(供應鏈安全)

    使用 cosign 為每個鏡像簽名,確保 Production 只能部署來自 Jenkins 的受信任鏡像:

    stage('Sign Images') {
        steps {
            withCredentials([file(credentialsId: 'cosign-private-key', variable: 'COSIGN_KEY')]) {
                sh 'sh scripts/sign-docker.sh ${TAG_NAME} ${COSIGN_KEY}'
            }
        }
    }
    
    # scripts/sign-docker.sh
    for IMAGE in "${IMAGES[@]}"; do
        cosign sign --key "${COSIGN_KEY}" \
          --tlog-upload=false \
          "${IMAGE}"
    done

    Stage 4:Push Images

    推送到 Docker Registry。Registry 啟用 Immutable Tags,同一個 tag 無法被覆蓋,確保版本不可篡改:

    stage('Push Images') {
        steps {
            withCredentials([usernamePassword(
                credentialsId: 'docker-registry-creds',
                usernameVariable: 'REGISTRY_USER',
                passwordVariable: 'REGISTRY_PASS'
            )]) {
                sh 'sh scripts/push-docker.sh ${TAG_NAME}'
            }
        }
    }

    Stage 5a(Staging):自動部署到 Staging K8s

    stage('Deploy to Staging') {
        when { expression { env.DEPLOYMENT_ENV == 'staging' } }
        steps {
            withCredentials([file(credentialsId: 'kubeconfig-staging', variable: 'KUBECONFIG')]) {
                sh '''
                    helm upgrade --install order-api ./k8s/helm/order-api \
                      --values ./k8s/helm/order-api/values-staging.yaml \
                      --set image.tag=${TAG_NAME} \
                      -n staging
                '''
            }
        }
    }

    Stage 5b(Production):生成 Helm Values,通知用戶手動部署

    對於 Production tag,Jenkins 不自動部署,而是生成配置檔並通知用戶手動執行:

    stage('Generate Helm Values') {
        when { expression { env.DEPLOYMENT_ENV == 'production' } }
        steps {
            sh 'sh scripts/generate-helm-values.sh ${TAG_NAME}'
            // 生成 values-v${TAG_NAME}.yaml(不含敏感資訊)
            // 通知用戶:Images ready, run helm command
        }
    }

    Helm 配置隔離:敏感資訊三層防護

    配置分為三層,層層隔離:

    第一層:values-staging.yaml(在 repo,測試配置)

    # 主機名用占位符,從 Jenkins 環境變數注入,不硬編碼內網地址
    env:
      DATABASE_HOST: "${POSTGRES_STAGING_HOST}"
      DATABASE_NAME: simpleec_test
      REDIS_HOST: "${REDIS_STAGING_HOST}"
      API_LOG_LEVEL: DEBUG

    第二層:values-prod.yaml(用戶本機維護,不進 repo)

    # 用戶的私密文件,只在本機
    env:
      DATABASE_HOST: postgres-prod.example.com
      API_LOG_LEVEL: WARN
      # ⚠️ 資料庫密碼不在這裡!從 K8s Secrets 注入
    
    envFrom:
      - secretRef:
          name: database-prod-creds  # K8s Secret(運維管理)
      - secretRef:
          name: api-keys-prod        # K8s Secret(運維管理)

    第三層:K8s Secrets + etcd 加密

    # 運維在 Production K8s 上創建
    kubectl create secret generic database-prod-creds \
      --from-literal=username=prod_user \
      --from-literal=password=<secure-password> \
      -n production
    
    # K8s 預設 Secrets 以 base64 存在 etcd(並非加密!)
    # 必須啟用 encryption at rest
    # /etc/kubernetes/encryption-config.yaml
    apiVersion: apiserver.config.k8s.io/v1
    kind: EncryptionConfiguration
    resources:
      - resources: ["secrets"]
        providers:
          - aescbc:
              keys:
                - name: key1
                  secret: <base64-encoded-32-byte-key>

    安全強化:補齊四大缺口

    原始設計經過安全審查後,發現四個必須在投產前補足的缺口:

    缺口一:K8s RBAC 未定義

    三個角色各有最小權限(文件放在 k8s/rbac/):

    角色 允許操作 明確禁止
    Jenkins SA(staging) update/patch Deployments, get Pods 讀取任何 Secrets
    用戶(production) helm 部署相關資源 讀取業務 Secrets(DB 密碼、API Key)
    運維(production) Secrets 完整管理權
    # 驗證 Jenkins SA 無法讀取 Secrets(應輸出 no)
    kubectl auth can-i get secrets \
      --as=system:serviceaccount:staging:jenkins-deployer \
      -n staging

    缺口二:K8s Audit Log 未配置

    ISO 27001 A.12.4.1 要求所有敏感操作都要有日誌。以下 Audit Policy 至少記錄 Secrets 訪問和 Deployment 變更:

    # /etc/kubernetes/audit-policy.yaml
    apiVersion: audit.k8s.io/v1
    kind: Policy
    rules:
      - level: Metadata
        resources:
          - group: ""
            resources: ["secrets"]  # 所有 Secrets 訪問都記錄
    
      - level: Request
        verbs: ["create", "update", "delete", "patch"]
        resources:
          - group: "apps"
            resources: ["deployments"]
    
      - level: None
        users: ["system:kube-proxy"]
        verbs: ["watch", "list"]

    缺口三:鏡像簽名驗證(Kyverno 準入控制)

    確保集群只能部署來自 Jenkins 簽名的鏡像,防止鏡像替換攻擊:

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: verify-image-signatures
    spec:
      validationFailureAction: Enforce  # 未簽名鏡像直接拒絕
      rules:
        - name: check-image-signature
          match:
            any:
              - resources:
                  kinds: ["Pod"]
                  namespaces: ["staging", "production"]
          verifyImages:
            - imageReferences:
                - "registry.example.com/*"
              attestors:
                - count: 1
                  entries:
                    - keys:
                        publicKeys: |-
                          -----BEGIN PUBLIC KEY-----
                          # cosign.pub 內容
                          -----END PUBLIC KEY-----

    缺口四:GitHub Branch Protection 口頭約定 → 技術強制

    分支 Required Reviews CI 必須通過 Push 限制
    main 2 人 approve ✅ jenkins-build + secrets-scan 僅 team-lead
    staging 1 人 approve ✅ jenkins-build + secrets-scan 僅 team-lead
    dev 1 人 approve 必須透過 PR(AI 不能直接 push)

    Git 分支策略與 Tag 命名規範

    整個工作流的分支拓撲如下:

    main                     # Production 對應,受嚴格保護
     └─ tag: v1.0.0, v1.0.1  # 觸發 Jenkins 構建 Production 鏡像
    
    staging                  # 測試環境,中度保護
     └─ tag: staging-v1.0.0  # 觸發 Jenkins 自動部署到 Staging K8s
    
    dev                      # 開發積累,AI 透過 PR 提交
     └─ 來源:feature/* 合入
    
    feature/*                # AI 的工作分支(每個功能一個)
     ├─ feature/user-auth
     ├─ feature/order-api
     └─ feature/channel-job-momo

    敏感資訊完整隔離架構

    存放位置 可以存什麼 絕對不能存什麼 管理者
    Git Repository 代碼、Dockerfile、values-staging.yaml、Helm chart 模板 密碼、API Key、SSL 憑證、values-prod.yaml AI + 用戶
    Docker Registry 不含配置的乾淨鏡像(cosign 簽名) 任何敏感資訊 Jenkins(push)
    K8s Secrets(etcd 加密) database-prod-creds、api-keys-prod、SSL 憑證 運維
    Jenkins Credentials GitHub token、Registry credentials、cosign key、kubeconfig 運維

    回滾策略

    Staging 環境回滾

    # 快速回滾到上一個版本
    helm rollback order-api 0 -n staging
    
    # 或指定版本
    helm upgrade order-api ./k8s/helm/order-api \
      --values ./k8s/helm/order-api/values-staging.yaml \
      --set image.tag=staging-v1.0.0 \
      -n staging

    Production 環境回滾

    # 查看部署歷史
    helm history order-api -n production
    
    # 回滾到上一個版本
    helm rollback order-api 0 -n production
    
    # 所有 tag 在 Git 可追溯
    git log --oneline --all | grep "v1.0"

    投產前安全檢查清單

    在正式上線前,以下所有項目必須確認通過:

    代碼倉庫安全

    • ✅ .gitignore 包含 .env, .env.dev, **/values-prod.yaml
    • ✅ repo 根目錄存在 .gitleaks.toml 配置文件
    • ✅ pre-commit hook 已安裝
    • ✅ git log –all — ‘*.env’ 確認歷史中無敏感文件

    Jenkins Pipeline

    • ✅ 第一個 Stage 為 Secrets Scan(gitleaks)
    • ✅ Sign Images Stage 已配置(cosign)
    • ✅ Push Images 使用 Jenkins Credentials(非明文)
    • ✅ GitHub Webhook Secret 已配置(Jenkins + GitHub 雙端)

    K8s 訪問控制

    • ✅ k8s/rbac/ 三個 RBAC 文件已 apply
    • ✅ Jenkins SA 驗證:kubectl auth can-i get secrets … → no
    • ✅ Kyverno 已安裝,鏡像簽名驗證策略已 apply
    • ✅ etcd encryption at rest 已啟用(運維確認)

    審計和監控

    • ✅ K8s Audit Log 已配置(audit-policy.yaml)
    • ✅ Audit Log 保留策略 ≥ 90 天
    • ✅ 告警規則已配置(部署失敗、Secrets 掃描失敗)

    總結:這套工作流解決了什麼問題?

    AI 輔助開發的核心挑戰不是技術,而是信任邊界:誰能做什麼?誰為每個決定負責?這套工作流的答案很清楚:

    • AI 的邊界:寫 code、提 PR、建 Docker image — 技術執行層
    • 用戶的邊界:review 代碼、創建 tag、手動部署 Production — 決策層
    • 運維的邊界:管理 Secrets、維護集群、配置 credentials — 基礎設施層
    • 自動化的邊界:Jenkins 在 tag 觸發後執行既定腳本 — 不越界,不決策

    這種分層設計讓 AI 協作既高效又安全,每一個部署都有完整的審計軌跡,每一個敏感操作都需要人類授權。

  • 🏗️ LangChain/LangGraph 深度分析:架構師、顧問、個人公司的實戰指南

    **作者的話**:本文從架構設計、商業決策、工程化、生態演進、個人公司戰略等 8 個維度,深度分析 LangChain/LangGraph 在 AI 開發中的真實定位。本文附帶完整的 Jupyter Notebook,讓你能親身體驗多 LLM 集成的實際效果。

    **閱讀時間**:20-30 分鐘 | **難度**:中等偏高 | **實用度**:⭐⭐⭐⭐⭐

    📖 目錄

    • [現狀速覽](#現狀速覽)
    • [1️⃣ 架構設計維度](#1️⃣-架構設計維度)
    • [2️⃣ 工程化可維護性](#2️⃣-工程化可維護性)
    • [3️⃣ 性能特徵](#3️⃣-性能特徵)
    • [4️⃣ 生態成熟度](#4️⃣-生態成熟度)
    • [5️⃣ 供應商風險與多 LLM 價值](#5️⃣-供應商風險與多-llm-價值)
    • [6️⃣ 生產化成本](#6️⃣-生產化成本)
    • [7️⃣ 組織影響](#7️⃣-組織影響維度)
    • [8️⃣ 長期戰略](#8️⃣-長期戰略與演進)
    • [個人公司實戰指南](#個人公司的實戰指南)
    • [完整 Jupyter Notebook](#完整-jupyter-notebook)
    • [快速開始指南](#快速開始指南)
    • [最終決策框架](#最終決策框架)

    現狀速覽

    2026 年 3 月的 AI 框架生態:
    
                        複雜度
                         ↑
                ┌────────┴────────┐
                │   LangGraph    │ ← 複雜工作流
                │  (新興但專業)  │   多 Agent
                └────────┬────────┘
                ┌────────┴────────┐
                │   LangChain    │ ← 快速原型
                │   (成熟生態)   │   簡單應用
                └────────┬────────┘
        ┌───────┬────────┴────────┬───────┐
        │       │                 │       │
    Claude    GPT-4            Gemini  Llama
     SDK       SDK              API     API
    (最優)    (最優)          (最優)  (最優)
    
    規則:
    • 簡單 + 單 LLM     → 官方 SDK(最快)
    • 簡單 + 多 LLM     → LangChain(靈活)
    • 複雜 + 多 LLM     → LangGraph(專業)
    • 複雜 + 單 LLM     → 官方 SDK(官方優化)

    1️⃣ 架構設計維度

    LangChain:管道式思想(Pipeline Pattern)

    # LangChain 的核心抽象:Chain(順序執行)
    # 概念:A → B → C(線性管道)
    
    from langchain_anthropic import ChatAnthropic
    from langchain.chains import LLMChain
    from langchain.prompts import PromptTemplate
    
    # 簡單的 Chain
    llm = ChatAnthropic(model="claude-opus-4-6")
    
    prompt = PromptTemplate(
        input_variables=["task"],
        template="驗證:{task}"
    )
    
    chain = LLMChain(llm=llm, prompt=prompt)
    result = chain.run(task="檢查 API Schema")

    **架構評價**:

    LangGraph:狀態機思想(State Machine Pattern)

    # LangGraph 的核心抽象:Graph(有向無環圖)
    # 概念:在不同「狀態」間轉移
    
    from langgraph.graph import StateGraph, END
    from langchain_anthropic import ChatAnthropic
    from typing import TypedDict
    
    # 定義狀態
    class AuditState(TypedDict):
        api_findings: str
        db_findings: str
        ui_findings: str
        final_report: str
    
    # 定義節點(每個節點是狀態轉移)
    def verify_api(state: AuditState) -> dict:
        llm = ChatAnthropic(model="claude-opus-4-6")
        result = llm.invoke("驗證 API Schema...")
        return {"api_findings": result.content}
    
    def verify_db(state: AuditState) -> dict:
        # state 中自動帶了前一步的結果
        llm = ChatAnthropic(model="claude-opus-4-6")
        result = llm.invoke(f"根據 API 驗證結果:{state['api_findings']}... 驗證資料層...")
        return {"db_findings": result.content}
    
    def verify_ui(state: AuditState) -> dict:
        llm = ChatAnthropic(model="claude-opus-4-6")
        result = llm.invoke(f"根據 API 驗證結果:{state['api_findings']}... 驗證 UI...")
        return {"ui_findings": result.content}
    
    def final_report(state: AuditState) -> dict:
        # 可以訪問所有之前的結果
        llm = ChatAnthropic(model="claude-opus-4-6")
        report = llm.invoke(f"""
        綜合以下發現生成報告:
        API: {state['api_findings']}
        DB: {state['db_findings']}
        UI: {state['ui_findings']}
        """)
        return {"final_report": report.content}
    
    # 構建圖
    graph = StateGraph(AuditState)
    graph.add_node("api", verify_api)
    graph.add_node("db", verify_db)
    graph.add_node("ui", verify_ui)
    graph.add_node("report", final_report)
    
    # 定義流向(這就是架構)
    graph.add_edge("api", "db")
    graph.add_edge("api", "ui")  # 並行執行
    graph.add_edge("db", "report")
    graph.add_edge("ui", "report")
    graph.set_entry_point("api")
    graph.add_edge("report", END)
    
    # 編譯並執行
    workflow = graph.compile()
    result = workflow.invoke({})
    print(result["final_report"])

    **架構評價**:

    架構對比圖

    LangChain 的流程(線性):
    ═════════════════════
    
    Task 1: API 驗證
       ↓
       你需要手動管理 task1_result
       ↓
    Task 2: DB 驗證
       ↓
       你需要手動管理 task2_result
       ↓
    Task 3: UI 驗證
       ↓
    問題:狀態在各地傳遞,容易出錯
    
    
    LangGraph 的流程(DAG):
    ═════════════════════
    
            ┌─→ Task 2: DB 驗證 ─┐
            │                    ├─→ Task 4: 最終報告
    Task 1: API 驗證              │
            │                    ├─→ END
            └─→ Task 3: UI 驗證 ─┘
    
    好處:
    ✓ 並行執行(Task 2 和 3 同時跑)
    ✓ State 自動流轉(無需手動管理)
    ✓ 流程結構清晰(add_edge 就是架構)

    2️⃣ 工程化可維護性

    代碼複雜度對比:簡單 vs 複雜場景

    場景 A:簡單線性流程(3 個 Task)

    **用 LangChain 實現**:

    class SimpleAudit:
        def __init__(self, llm):
            self.llm = llm
            self.results = {}
    
        def task1_api_check(self):
            result = self.llm.invoke("檢查 API...")
            self.results['task1'] = result
            return result
    
        def task2_db_check(self):
            # 手動管理 task1 的結果
            prev = self.results['task1']
            result = self.llm.invoke(f"根據 {prev} 檢查資料層...")
            self.results['task2'] = result
            return result
    
        def task3_ui_check(self):
            prev = self.results['task2']
            result = self.llm.invoke(f"根據 {prev} 檢查 UI...")
            self.results['task3'] = result
            return result
    
        def run(self):
            self.task1_api_check()
            self.task2_db_check()
            self.task3_ui_check()
            return self.results['task3']
    
    # 問題:狀態散亂,難以追蹤
    # 程式碼行數:40 行

    **用 LangGraph 實現**:

    from langgraph.graph import StateGraph, END
    from typing import TypedDict
    
    class AuditState(TypedDict):
        task1_result: str
        task2_result: str
        task3_result: str
    
    graph = StateGraph(AuditState)
    
    def task1(state):
        result = llm.invoke("檢查 API...")
        return {"task1_result": result.content}
    
    def task2(state):
        result = llm.invoke(f"根據 {state['task1_result']} 檢查資料層...")
        return {"task2_result": result.content}
    
    def task3(state):
        result = llm.invoke(f"根據 {state['task2_result']} 檢查 UI...")
        return {"task3_result": result.content}
    
    graph.add_node("task1", task1)
    graph.add_node("task2", task2)
    graph.add_node("task3", task3)
    graph.add_edge("task1", "task2")
    graph.add_edge("task2", "task3")
    graph.add_edge("task3", END)
    
    # 好處:State 清晰,流程一目瞭然
    # 程式碼行數:25 行(簡潔 40%)

    場景 B:複雜分支流程(並行 + 分支)

    需求:
    Task 1 → [Task 2 並行 Task 3] → Task 4

    **用 LangChain 實現**(噩夢):

    import concurrent.futures
    import threading
    
    class ComplexAudit:
        def __init__(self, llm):
            self.llm = llm
            self.results = {}
            self.lock = threading.Lock()
    
        def task1(self):
            result = self.llm.invoke("Task 1...")
            with self.lock:
                self.results['task1'] = result
    
        def task2(self):
            # 需要等待 task1 完成
            while 'task1' not in self.results:
                time.sleep(0.1)
            result = self.llm.invoke(f"Task 2 based on {self.results['task1']}...")
            with self.lock:
                self.results['task2'] = result
    
        def task3(self):
            while 'task1' not in self.results:
                time.sleep(0.1)
            result = self.llm.invoke(f"Task 3 based on {self.results['task1']}...")
            with self.lock:
                self.results['task3'] = result
    
        def task4(self):
            while 'task2' not in self.results or 'task3' not in self.results:
                time.sleep(0.1)
            result = self.llm.invoke(f"Task 4 based on {self.results['task2']} and {self.results['task3']}...")
            with self.lock:
                self.results['task4'] = result
    
        def run(self):
            # 手動管理並行
            executor = concurrent.futures.ThreadPoolExecutor(max_workers=4)
    
            f1 = executor.submit(self.task1)
            f1.result()  # 等 task1 完成
    
            f2 = executor.submit(self.task2)
            f3 = executor.submit(self.task3)
            f2.result()
            f3.result()
    
            f4 = executor.submit(self.task4)
            f4.result()
    
            return self.results['task4']
    
    # 問題:手動管理並行,容易出 deadlock
    # 手動管理依賴,難以維護
    # 程式碼行數:70+ 行(複雜且容易出錯)

    **用 LangGraph 實現**(優雅):

    from langgraph.graph import StateGraph, END
    
    graph = StateGraph(AuditState)
    
    graph.add_node("task1", task1)
    graph.add_node("task2", task2)
    graph.add_node("task3", task3)
    graph.add_node("task4", task4)
    
    # 定義並行和依賴關係(自動處理)
    graph.add_edge("task1", "task2")
    graph.add_edge("task1", "task3")
    graph.add_edge("task2", "task4")
    graph.add_edge("task3", "task4")
    graph.add_edge("task4", END)
    
    # LangGraph 自動:
    # ✓ 並行執行 task2 和 task3
    # ✓ 等待兩個都完成後再執行 task4
    # ✓ 管理所有依賴
    
    # 程式碼行數:18 行(簡潔 75%,且完全無 bug)

    複雜度對比表

    ╔════════════════════╦══════════════╦═════════════╦══════════════╗
    ║     指標           ║ LangChain    ║ LangGraph   ║ Claude SDK   ║
    ╠════════════════════╬══════════════╬═════════════╬══════════════╣
    ║ 簡單線性           ║ 40 行        ║ 25 行       ║ 20 行        ║
    ║ 複雜並行           ║ 80+ 行       ║ 22 行       ║ 120+ 行      ║
    ║ 易於測試           ║ ⭐⭐         ║ ⭐⭐⭐⭐⭐ ║ ⭐⭐⭐       ║
    ║ 易於除錯           ║ ⭐⭐         ║ ⭐⭐⭐⭐   ║ ⭐⭐⭐       ║
    ║ 新人上手時間       ║ 1-2 天       ║ 3-5 天      ║ 1 天         ║
    ║ 複雜流程上手時間   ║ 2-3 周       ║ 1-2 周      ║ 3+ 周        ║
    ╚════════════════════╩══════════════╩═════════════╩══════════════╝

    3️⃣ 性能特徵

    執行效率測試

    測試場景:質量檢查系統(4 個 Task,各 1 次 LLM 調用)
    環境:16GB RAM,單用戶,冷啟動
    
    ╔════════════════════╦══════════════╦═════════╦═══════════╗
    ║ 方案               ║ 總執行時間   ║ 開銷    ║ 記憶體    ║
    ╠════════════════════╬══════════════╬═════════╬═══════════╣
    ║ Claude API 直調    ║ 48 秒        ║ 基準    ║ 120 MB   ║
    ║ LangChain          ║ 52 秒        ║ +8%     ║ 180 MB   ║
    ║ LangGraph          ║ 54 秒        ║ +12%    ║ 220 MB   ║
    ╚════════════════════╩══════════════╩═════════╩═══════════╝
    
    分析:
    ✓ 在 I/O 密集型(LLM 調用)中,開銷可忽略
    ✓ 實際瓶頸是 LLM API 延遲(30-40 秒),不是框架
    ✓ 高併發時(100+ 並行)資源差異才明顯

    高並發測試

    100 個同時請求,每個 4 個 Task:
    
    ╔════════════════════╦═══════════╦═════════════╗
    ║ 方案               ║ 總記憶體  ║ CPU 使用率  ║
    ╠════════════════════╬═══════════╬═════════════╣
    ║ Claude API 直調    ║ 2.5 GB    ║ 45%         ║
    ║ LangChain          ║ 3.8 GB    ║ 52%         ║
    ║ LangGraph          ║ 4.5 GB    ║ 58%         ║
    ╚════════════════════╩═══════════╩═════════════╝
    
    高並發時的差異較明顯,但:
    • 多數公司不會有 100 個同時 AI 請求
    • 可以用隊列和批處理解決
    • 不是技術選型的主要考慮

    4️⃣ 生態成熟度

    框架成熟度對比

    ╔════════════════════╦═══════════════╦══════════════╦═══════════════╗
    ║ 維度               ║ LangChain     ║ LangGraph    ║ Claude SDK    ║
    ╠════════════════════╬═══════════════╬══════════════╬═══════════════╣
    ║ GitHub Star        ║ 90k+          ║ 新興         ║ 新興          ║
    ║ 文檔品質           ║ ⭐⭐⭐ 豐富 ║ ⭐⭐ 完善中 ║ ⭐⭐⭐⭐⭐ ║
    ║ Stack Overflow     ║ ⭐⭐⭐⭐      ║ ⭐          ║ ⭐⭐⭐⭐⭐   ║
    ║ 企業採用           ║ ⭐⭐⭐⭐      ║ 新興         ║ 新興          ║
    ║ 更新頻率           ║ 每週          ║ 每月         ║ 每週          ║
    ║ 向後相容性         ║ ⚠️ 經常破壞  ║ ✅ 穩定      ║ ✅ 穩定       ║
    ║ 第三方集成         ║ ⭐⭐⭐⭐⭐   ║ ⭐⭐        ║ ⭐⭐⭐⭐     ║
    ╚════════════════════╩═══════════════╩══════════════╩═══════════════╝

    生態演進預測

    時間軸:2024-2029
    
    2024:分化和專業化開始
    ├─ LangChain:從「全能」變成「簡單應用」
    ├─ LangGraph:從「升級」變成「複雜工作流標準」
    └─ 官方 SDK:從「簡單」變成「優化和專業」
    
    2025:明確分層
    ├─ 官方 SDK(Claude/OpenAI/Gemini)⭐⭐⭐⭐⭐
    │  用戶:想要最優化的,願意被鎖定
    │
    ├─ LangGraph ⭐⭐⭐⭐
    │  用戶:複雜工作流,需要多 LLM
    │
    └─ LangChain ⭐⭐⭐
       用戶:快速原型,簡單應用
    
    2026-2029:優勝劣汰
    ├─ LangGraph 成為業界標準(類似 Docker)
    ├─ LangChain 邊緣化為「輕量級」工具
    └─ 官方 SDK 深度優化(強者恆強)

    5️⃣ 供應商風險與多 LLM 價值

    多 LLM 成本-收益分析

    場景 1:純粹的成本優化

    現狀:用 Claude Opus,月成本 $5,000
    
    優化後:
    - 複雜任務用 Opus($3,000)
    - 簡單任務用 Sonnet($500)
    - 標準任務用 GPT-4($1,000)
    
    結果:月成本 $4,500(-10%)
    
    但需要投入:
    ✓ 學習 LangGraph:2-3 周
    ✓ 測試不同 LLM:1-2 周
    ✓ 维护多模型邏輯:+20% 維護成本
    
    淨收益(年):
    成本節省:$6,000
    維護成本:$3,000
    實際節省:$3,000(不值得)

    場景 2:供應商備份(企業級需求)

    風險:
    ├─ Claude 故障 → 全系統掛
    ├─ Claude 漲價 100% → 成本翻倍
    └─ Claude 停止服務(小概率)
    
    對策:支持 Claude + GPT-4 自動備份
    
    實現成本:
    ✓ 用 LangGraph:+50% 代碼(已在複雜系統中攤銷)
    ✓ 測試備份邏輯:1-2 周
    ✓ 維護兩個模型:+30% 維護
    
    收益:
    ✓ 可用性 99.95% → 99.99%(0.04% 提升)
    ✓ 如果 Claude 故障,無損切換
    ✓ 談判籌碼增加(買方權力提升)
    
    適用場景:
    ✓ 企業級應用(可用性要求高)
    ✓ 金融/醫療(SLA 要求)
    ✓ 長期服務(>3 年)
    
    不適用場景:
    ❌ 初創應用
    ❌ 成本敏感(成本優先)
    ❌ 短期項目

    多 LLM 決策樹

    你需要多 LLM 嗎?
    
    ├─ Q1: 月 LLM 成本 > $3,000?
    │  ├─ YES → 可能值得優化成本
    │  └─ NO → 跳過
    │
    ├─ Q2: 有企業級客戶(SLA 要求)?
    │  ├─ YES → 供應商備份很重要
    │  └─ NO → 降低優先級
    │
    ├─ Q3: 預計 3 年內有 5+ 複雜項目?
    │  ├─ YES → 框架複用價值高
    │  └─ NO → 單項目的框架學習成本太高
    │
    └─ 結論:
       3 個 YES → 學 LangGraph + 多 LLM(ROI > 1.5x)
       2 個 YES → 考慮學,但不急
       1 個 YES → 暫不需要
       0 個 YES → 保持官方 SDK(省事)

    6️⃣ 生產化成本

    6 個月全生命週期成本對比

    ╔═════════════════════╦══════════════╦═════════════╦══════════════╗
    ║ 環節                ║ LangChain    ║ LangGraph   ║ Claude SDK   ║
    ╠═════════════════════╬══════════════╬═════════════╬══════════════╣
    ║ 1. 開發成本         ║              ║             ║              ║
    ║   ├─ 學習          ║ 3 天 ($600)  ║ 5 天 ($1k)  ║ 2 天 ($400)  ║
    ║   ├─ 寫代碼        ║ 4 天         ║ 3 天        ║ 5 天         ║
    ║   └─ 測試          ║ 2 天         ║ 1 天        ║ 1 天         ║
    ║   小計:           ║ $3,400       ║ $3,200      ║ $3,000       ║
    ╠═════════════════════╬══════════════╬═════════════╬══════════════╣
    ║ 2. 部署成本         ║              ║             ║              ║
    ║   └─ 監控/日誌      ║ $2,000       ║ $2,000      ║ $3,000       ║
    ╠═════════════════════╬══════════════╬═════════════╬══════════════╣
    ║ 3. 運維成本(6月)  ║              ║             ║              ║
    ║   ├─ LLM API       ║ $18,000      ║ $18,000     ║ $18,000      ║
    ║   ├─ 監控工具      ║ $600         ║ $600        ║ $3,000       ║
    ║   └─ 人力維護      ║ $3,600       ║ $1,800      ║ $3,600       ║
    ║   小計:           ║ $22,200      ║ $20,400     ║ $24,600      ║
    ╠═════════════════════╬══════════════╬═════════════╬══════════════╣
    ║ 總成本              ║ $27,600      ║ $25,600     ║ $30,600      ║
    ║ 初期貴 vs LangGraph ║ +$2,000      ║ 基準        ║ +$5,000      ║
    ║ 長期便宜度(/年)   ║ -$1,200      ║ -$2,400     ║ +$1,200      ║
    ╚═════════════════════╩══════════════╩═════════════╩══════════════╝
    
    結論:
    • LangGraph 初期略貴,但長期最便宜
    • Claude SDK 初期便宜,但運維成本高(缺監控)
    • 複雜項目超過 1 年,LangGraph ROI 最高

    監控工具成本對比

    ╔════════════════════╦═══════════════╦═════════════════╦═══════════╗
    ║ 功能               ║ LangSmith*    ║ 自建監控        ║ Claude無  ║
    ║                    ║ (LangChain)   ║ (Claude SDK)    ║ 原生工具  ║
    ╠════════════════════╬═══════════════╬═════════════════╬═══════════╣
    ║ Agent 追蹤         ║ ✅ 內置       ║ 手動寫 logging  ║ ❌        ║
    ║ 成本               ║ $100-500/月   ║ $1,000 setup    ║ $0        ║
    ║ 可視化             ║ ✅ Web UI     ║ ❌ CLI only     ║ ❌        ║
    ║ 版本管理           ║ ✅            ║ ❌              ║ ❌        ║
    ║ 易用性             ║ ⭐⭐⭐⭐      ║ ⭐              ║ -         ║
    ║ 6 月成本           ║ $600-3,000    ║ $1,000+人力     ║ $0        ║
    ╚════════════════════╩═══════════════╩═════════════════╩═══════════╝
    
    *LangSmith 支持 LangChain 和 LangGraph

    7️⃣ 組織影響維度

    團隊規模與框架選擇

    團隊規模:1 人
    ├─ LangChain: ✅ 簡單快速
    ├─ LangGraph: ⚠️ 一人維護複雜項目困難
    └─ Claude SDK: ✅ 官方最快
    
    團隊規模:2-3 人
    ├─ LangChain: ⭐⭐⭐ 合適,相對簡單
    ├─ LangGraph: ⭐⭐⭐ 複雜項目用它更清晰
    └─ Claude SDK: ⭐⭐⭐ 也可以,複雜項目時新人難上手
    
    團隊規模:4-5 人
    ├─ LangChain: ⭐⭐ 開始混亂,每個人 chain 寫法不同
    ├─ LangGraph: ⭐⭐⭐⭐⭐ 最優(標準化架構)
    └─ Claude SDK: ⭐⭐⭐ 可以,但複雜項目時溝通成本高
    
    團隊規模:10+ 人
    ├─ LangChain: ❌ 災難(無標準)
    ├─ LangGraph: ⭐⭐⭐⭐⭐ 完美(可複用框架)
    └─ Claude SDK: ⭐⭐⭐ 需要層層抽象才能用

    知識遷移成本

    在同一團隊中,第 2 個複雜項目的成本:
    
    LangChain:
    ├─ 第 1 個項目:7 天開發
    ├─ 第 2 個項目:6 天開發(相似度 +1 天)
    ├─ 第 3 個項目:5.5 天開發
    └─ 問題:每個項目的 chain 組織方式不同,無法直接複用
    
    LangGraph:
    ├─ 第 1 個項目:8 天開發
    ├─ 第 2 個項目:4 天開發(框架直接複用 -50%)
    ├─ 第 3 個項目:3 天開發(框架 + patterns 複用)
    ├─ 第 4 個項目:2.5 天開發
    └─ 優勢:框架標準化,新項目變成填空題
    
    Claude SDK:
    ├─ 第 1 個項目:7 天開發
    ├─ 第 2 個項目:7 天開發(複雜項目要重新設計)
    ├─ 第 3 個項目:7 天開發
    └─ 問題:每個複雜項目都要「重新輪子」
    
    轉折點:
    5 個項目後,LangGraph 團隊節省 > 20 天
    = 節省 $10,000 人力成本

    8️⃣ 長期戰略與演進

    3 年技術景觀預測

    2026 年 3 月(現在)
    ═══════════════════
    
    成熟度曲線:
      功能性
        ↑
        │        官方 SDK
        │     ╱────────╲
        │   ╱          ╲
        │  ╱  LangChain  ╲
        │ ╱                ╲    預期
        ├──────────────────────→ 時間
        │              LangGraph
        │         ╱──────
        │      ╱
        └────╱
    
    LangChain:成熟期(市場份額 40-50%)
    LangGraph:成長期(市場份額 15-20%)
    官方 SDK:優化期(市場份額 30-40%)
    
    
    2026 年 12 月(1 年後)
    ═════════════════════
    
    預測:
    ├─ LangGraph 市場份額 ↑ 25-30%
    ├─ LangChain 邊緣化到「簡單應用」
    ├─ 官方 SDK 加強 Agent 功能
    └─ 出現新的垂直框架(垂直行業專用)
    
    
    2028 年(2 年後)
    ═════════════════
    
    穩定格局:
    ├─ 官方 SDK:40%(強者恆強)
    ├─ LangGraph:35%(業界標準)
    ├─ LangChain:15%(輕量級遺產)
    └─ 其他新框架:10%
    
    LangGraph 地位:
    類似 Docker(容器標準)或 Terraform(IaC 標準)
    = 學好 LangGraph 的人會很值錢

    對不同角色的影響

    對開發者:
    ├─ 現在學 LangGraph → 3 年後稀缺技能
    ├─ 工資溢價:+20-30%
    └─ 就業機會:多(所有複雜 AI 項目都用)
    
    對企業主(個人公司):
    ├─ 現在投 LangGraph → 成為專家
    ├─ 能做 $10k+ 的大項目
    └─ 競爭對手少(優勢期 2-3 年)
    
    對顧問:
    ├─ 現在掌握 → 成為「多 LLM 架構顧問」
    ├─ 諮詢費:$200-500/小時
    └─ 稀缺度:高(很少人懂跨 LLM 架構)
    
    對企業 CTO:
    ├─ 現在採用 LangGraph → 技術領先
    ├─ 吸引人才(用最新技術)
    └─ 降低風險(不被 LLM 廠商鎖定)

    個人公司的實戰指南

    3 年商業規劃

    Year 1:「活著」 (現金流 $3k-5k/月)
    ════════════════════════════════
    
    目標:
    ✓ 月收 $3k-5k,活著
    ✓ 積累 5+ 個項目案例
    ✓ 建立初步品牌
    
    技術策略:
    ✅ 用 Claude SDK(最快)
    ✅ 多做簡單項目(量的積累)
    ✅ 不投 LangGraph(現金流太緊)
    
    客戶定位:
    - 預算 $2k-5k 的小項目
    - 中小 SaaS,簡單 AI 需求
    
    利潤模式:
    - 快速交付 = 高周轉率
    - 靠項目量賺錢
    
    風險:
    ⚠️ 技術債累積
    ⚠️ 被有團隊的公司碾壓複雜項目
    ⚠️ 月收入天花板(個人規模)
    
    
    Year 2:「競爭」 (現金流 $5k-10k/月)
    ═══════════════════════════════════
    
    目標:
    ✓ 月收 $5k-10k,穩定
    ✓ 建立技術品牌
    ✓ 完成 2-3 個複雜項目
    
    技術策略:
    ✅ 評估多 LLM 需求(看客戶反饋)
    ✅ 如果有複雜項目 → 投 2-3 周學 LangGraph
    ✅ 開始有意識地設計可複用框架
    ✅ 寫技術博客(建立影響力)
    
    客戶定位:
    - 升級到 $5k-15k 的項目
    - 中型企業開始看重品質
    - 複雜 AI 需求的客戶
    
    利潤模式:
    - 品質溢價(能做複雜項目,競爭少)
    - 技術諮詢(不只寫代碼)
    - 開始有長期維護合約
    
    技術積累:
    - 沉澱「複雜 Multi-Agent 系統設計」
    - 建立 LangGraph 的內部框架
    
    
    Year 3:「擴展」 (現金流 $10k-20k/月+)
    ═══════════════════════════════════════
    
    目標:
    ✓ 月收 $10k-20k,或融資,或招人
    ✓ 成為某領域的專家
    ✓ 建立品牌和 IP
    
    技術策略:
    ✅ LangGraph 完全掌握(成為專家)
    ✅ 多 LLM 支持變成標配
    ✅ 考慮開源項目(建立 IP)
    ✅ 建立「標準交付流程」(為招人做準備)
    
    客戶定位:
    - 大型企業的 POC/試驗
    - 或連續的長期合約
    - $15k-50k 以上
    
    利潤模式:
    - 顧問 + 開發(高價值)
    - 長期維護 + 迭代(穩定現金流)
    - 可能融資(有 IP 有客戶)
    
    技術 IP:
    - 「複雜 Agent 系統」的業界聲譽
    - LangGraph 專家(稀缺性)
    - 可能有開源項目

    POC 階段正確的行動清單

    **你現在在 POC + 找 TA 階段,應該這樣做:**

    優先級排序:
    
    1️⃣ 找到 TA(目標客戶)⭐⭐⭐⭐⭐
       時間:現在 - 4 周
       行動:
       □ 列出 5-10 個潛在客戶類型
       □ 分析他們的痛點
       □ 評估付費意願
       □ 深入訪談 2-3 個最有潛力的
    
       為什麼:沒有 TA,框架選擇沒意義
    
    2️⃣ 快速 POC Demo⭐⭐⭐⭐
       時間:第 3-4 周
       行動:
       □ 用 Claude API 直接寫腳本(2-3 天)
       □ 不用框架(省時間)
       □ 快速迭代(客戶反饋驅動)
    
       為什麼:驗證想法,不需要完美代碼
    
    3️⃣ Beta 測試和反饋⭐⭐⭐⭐
       時間:第 5-8 周
       行動:
       □ 找 3-5 個 beta 用戶
       □ 快速迭代(週期 1-2 周)
       □ 記錄反饋
    
       為什麼:市場信號最重要
    
    4️⃣ 評估和決策
       時間:第 9-12 周
       決定:
       ✓ 有付費意向?→ 準備 Productize
       ✓ 需求清晰?→ 投 LangGraph
       ✓ 方向不對?→ 及時止損或轉向
    
    5️⃣ 技術選型(這時才考慮)⭐⭐
       時間:12 周以後
       決策:
       • 簡單應用 → Claude SDK
       • 複雜工作流 → LangGraph
       • 多 LLM 需求 → LangGraph + 多 LLM
    
    千萬別:
    ❌ 現在投 2-3 周學 LangGraph
    ❌ POC 代碼寫得很漂亮
    ❌ 等完美再給客戶看

    完整 Jupyter Notebook

    下面是完整的、可運行的 Jupyter Notebook 代碼。你可以複製到 `.ipynb` 文件中運行。

    📌 準備工作

    # 1. 安裝依賴
    pip install langchain langchain-anthropic langchain-openai langchain-google-genai langgraph pandas matplotlib python-dotenv
    
    # 2. 創建 .env 文件
    cat > .env << EOF
    ANTHROPIC_API_KEY=your_claude_api_key
    OPENAI_API_KEY=your_openai_api_key
    GOOGLE_API_KEY=your_google_api_key
    EOF
    
    # 3. 運行 Jupyter
    jupyter notebook

    🔧 完整 Notebook 代碼

    Cell 1:安裝依賴

    import subprocess
    import sys
    
    packages = [
        'langchain',
        'langchain-anthropic',
        'langchain-openai',
        'langchain-google-genai',
        'langgraph',
        'pandas',
        'matplotlib',
        'python-dotenv'
    ]
    
    print("📦 安裝必要的包...")
    for package in packages:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", package])
        print(f"✅ {package}")
    
    print("\n🎉 安裝完成!")

    Cell 2:配置 API Keys

    import os
    from dotenv import load_dotenv
    
    # 加載 .env 文件中的 API Keys
    load_dotenv()
    
    # 檢查 API Keys
    apis = {
        'ANTHROPIC_API_KEY': '🔑 Claude (Anthropic)',
        'OPENAI_API_KEY': '🔑 GPT-4 (OpenAI)',
        'GOOGLE_API_KEY': '🔑 Gemini (Google)'
    }
    
    print("\n📍 檢查 API Keys 狀態:\n")
    available_apis = []
    
    for env_var, name in apis.items():
        if os.getenv(env_var):
            status = f"✅ {name}: 已配置"
            available_apis.append(env_var)
        else:
            status = f"❌ {name}: 未配置"
        print(status)
    
    if not available_apis:
        print("\n⚠️ 警告:沒有設置任何 API Key!")
        print("請按照上面的說明設置 .env 文件或環境變量。")
    else:
        print(f"\n✅ 可用的 LLM:{len(available_apis)} 個")

    Cell 3:初始化 LLM

    from langchain_anthropic import ChatAnthropic
    from langchain_openai import ChatOpenAI
    from langchain_google_genai import ChatGoogleGenerativeAI
    import time
    import json
    
    print("\n🚀 初始化多個 LLM...\n")
    
    # 初始化 LLM(都初始化,但只會使用可用的)
    llms = {}
    llm_configs = {
        'Claude': {
            'class': ChatAnthropic,
            'params': {'model': 'claude-opus-4-6'},
            'env': 'ANTHROPIC_API_KEY'
        },
        'GPT-4': {
            'class': ChatOpenAI,
            'params': {'model': 'gpt-4-turbo', 'temperature': 0.7},
            'env': 'OPENAI_API_KEY'
        },
        'Gemini': {
            'class': ChatGoogleGenerativeAI,
            'params': {'model': 'gemini-pro'},
            'env': 'GOOGLE_API_KEY'
        }
    }
    
    # 嘗試初始化每個 LLM
    for name, config in llm_configs.items():
        try:
            if os.getenv(config['env']):
                llm = config['class'](**config['params'])
                llms[name] = llm
                print(f"✅ {name}: 初始化成功")
            else:
                print(f"⏭️  {name}: 跳過(未設置 {config['env']})")
        except Exception as e:
            print(f"❌ {name}: 初始化失敗 - {str(e)[:50]}")
    
    if llms:
        print(f"\n✅ 成功初始化 {len(llms)} 個 LLM")
    else:
        print(f"\n⚠️ 沒有成功初始化任何 LLM,請檢查 API Keys")
    
    available_llms = list(llms.keys())
    print(f"\n📋 可用的 LLM:{', '.join(available_llms)}")

    Cell 4:對比測試

    # 定義測試任務
    TEST_PROMPT = """簡短回答(不超過 100 字):
    什麼是 LangChain 和 LangGraph 的主要區別?
    
    用 JSON 格式回答:
    {
      "差異": "...",
      "適用場景": "..."
    }
    """
    
    print("\n📝 測試任務:")
    print(f"提示詞:{TEST_PROMPT[:80]}...\n")
    
    # 存儲結果
    results = {}
    execution_times = {}
    
    print("\n🔄 執行中...\n")
    print("="*80)
    
    # 對每個可用的 LLM 執行
    for llm_name, llm in llms.items():
        print(f"\n▶️  {llm_name} 開始...")
    
        start_time = time.time()
    
        try:
            response = llm.invoke(TEST_PROMPT)
            elapsed = time.time() - start_time
    
            results[llm_name] = response.content
            execution_times[llm_name] = elapsed
    
            print(f"✅ {llm_name} 完成 ({elapsed:.2f}s)")
            print(f"\n📄 回答:")
            print(f"{response.content[:150]}...")
            print("\n" + "-"*80)
    
        except Exception as e:
            print(f"❌ {llm_name} 出錯:{str(e)[:100]}")
            print("\n" + "-"*80)
    
    print("\n" + "="*80)
    print(f"\n✅ 測試完成!共執行 {len(results)} 個 LLM")

    Cell 5:執行時間對比

    import pandas as pd
    import matplotlib.pyplot as plt
    
    # 創建時間對比表
    if execution_times:
        df_times = pd.DataFrame([
            {'LLM': name, '執行時間 (秒)': time}
            for name, time in execution_times.items()
        ]).sort_values('執行時間 (秒)')
    
        print("\n⏱️  執行時間對比")
        print("="*50)
        print(df_times.to_string(index=False))
        print("="*50)
        print(f"\n平均時間:{df_times['執行時間 (秒)'].mean():.2f}s")
        print(f"最快:{df_times.iloc[0]['LLM']} ({df_times.iloc[0]['執行時間 (秒)']:.2f}s)")
    
        # 繪製柱狀圖
        plt.figure(figsize=(10, 5))
        colors = ['#FF6B6B' if t == df_times['執行時間 (秒)'].min() else '#4ECDC4'
                  for t in df_times['執行時間 (秒)']]
    
        plt.bar(df_times['LLM'], df_times['執行時間 (秒)'], color=colors, alpha=0.7, edgecolor='black')
        plt.ylabel('執行時間 (秒)', fontsize=12)
        plt.xlabel('LLM', fontsize=12)
        plt.title('🏃 多 LLM 執行時間對比', fontsize=14, fontweight='bold')
        plt.grid(axis='y', alpha=0.3, linestyle='--')
    
        # 添加數值標籤
        for i, v in enumerate(df_times['執行時間 (秒)']):
            plt.text(i, v + 0.1, f'{v:.2f}s', ha='center', fontweight='bold')
    
        plt.tight_layout()
        plt.show()
    
    else:
        print("⚠️  沒有執行時間數據")

    Cell 6:質量對比

    # 分析回答質量
    if results:
        print("\n📊 回答質量對比")
        print("="*80)
    
        quality_metrics = []
    
        for llm_name, response in results.items():
            # 計算指標
            length = len(response)
            word_count = len(response.split())
            has_json = '{' in response and '}' in response
    
            quality_metrics.append({
                'LLM': llm_name,
                '字數': length,
                '詞數': word_count,
                'JSON 格式': '✅' if has_json else '❌'
            })
    
        df_quality = pd.DataFrame(quality_metrics)
        print(df_quality.to_string(index=False))
        print("="*80)
    
        # 詳細回答
        print("\n📄 詳細回答:\n")
        for llm_name, response in results.items():
            print(f"\n▶️  {llm_name}:")
            print("-" * 70)
            print(response)
            print("-" * 70)

    Cell 7:LangGraph 演示

    from langgraph.graph import StateGraph, END
    from typing import TypedDict
    
    if len(llms) >= 2:
        print("\n🏗️  使用 LangGraph 構建多 LLM 工作流")
        print("="*80)
    
        # 定義狀態
        class ComparisonState(TypedDict):
            task: str
            results: dict  # 存儲多個 LLM 的結果
    
        # 為每個 LLM 定義一個節點
        def create_llm_node(llm_name, llm):
            def node_func(state: ComparisonState) -> dict:
                print(f"\n▶️  {llm_name} 處理中...")
                try:
                    response = llm.invoke(state['task'])
                    result = {
                        'response': response.content[:200] + '...',
                        'status': '✅ 成功',
                        'timestamp': time.time()
                    }
                    state['results'][llm_name] = result
                    print(f"✅ {llm_name} 完成")
                except Exception as e:
                    state['results'][llm_name] = {
                        'error': str(e)[:100],
                        'status': '❌ 失敗'
                    }
                    print(f"❌ {llm_name} 失敗")
    
                return state
    
            return node_func
    
        # 構建 Graph
        graph = StateGraph(ComparisonState)
    
        # 為每個 LLM 添加節點
        for llm_name in llms:
            graph.add_node(llm_name, create_llm_node(llm_name, llms[llm_name]))
    
        # 連接節點(全部並行執行,然後到 END)
        graph.set_entry_point(list(llms.keys())[0])
        for i, llm_name in enumerate(list(llms.keys())[:-1]):
            graph.add_edge(llm_name, list(llms.keys())[i+1])
        graph.add_edge(list(llms.keys())[-1], END)
    
        # 編譯并執行
        workflow = graph.compile()
    
        print("\n📋 執行工作流...\n")
    
        test_task = "用一句話解釋 LangGraph 的核心優勢"
    
        try:
            workflow_result = workflow.invoke({
                'task': test_task,
                'results': {}
            })
    
            print(f"\n✅ 工作流完成!\n")
            print("📊 結果:")
            print("="*80)
    
            for llm_name, result in workflow_result['results'].items():
                print(f"\n{llm_name}:")
                print("-"*70)
                if 'error' in result:
                    print(f"❌ 錯誤:{result['error']}")
                else:
                    print(f"{result['response']}")
    
            print("\n" + "="*80)
    
        except Exception as e:
            print(f"❌ 工作流執行失敗:{str(e)}")
    
    else:
        print("⚠️  需要至少 2 個 LLM 才能演示工作流")

    Cell 8:成本對比

    # 模擬成本數據(基於實際 API 定價 2026 年 3 月)
    cost_data = {
        'Claude': {
            'name': 'Claude Opus 4.6',
            'input_cost': 0.003,  # 每 1K tokens
            'output_cost': 0.015,
            'speed': '中等',
            'quality': '⭐⭐⭐⭐⭐',
            'price_tier': '高端'
        },
        'GPT-4': {
            'name': 'GPT-4 Turbo',
            'input_cost': 0.01,
            'output_cost': 0.03,
            'speed': '快',
            'quality': '⭐⭐⭐⭐⭐',
            'price_tier': '最高'
        },
        'Gemini': {
            'name': 'Gemini Pro',
            'input_cost': 0.0005,
            'output_cost': 0.0015,
            'speed': '最快',
            'quality': '⭐⭐⭐⭐',
            'price_tier': '經濟'
        }
    }
    
    print("\n💰 成本和性能對比")
    print("="*90)
    print(f"{'LLM':<15} {'速度':<10} {'質量':<15} {'輸入成本':<15} {'輸出成本':<15} {'定位':<10}")
    print("="*90)
    
    for llm_name, data in cost_data.items():
        if llm_name in llms:
            status = "✅"
        else:
            status = "⏭️ "
    
        print(f"{status}{llm_name:<13} {data['speed']:<10} {data['quality']:<15} "
              f"${data['input_cost']:<14} ${data['output_cost']:<14} {data['price_tier']:<10}")
    
    print("="*90)
    
    # 估算月成本(假設 1000 萬 tokens 使用)
    print("\n📊 月成本估算(假設 1000 萬 input tokens + 500 萬 output tokens)")
    print("="*60)
    
    cost_estimates = []
    input_tokens = 10_000_000
    output_tokens = 5_000_000
    
    for llm_name, data in cost_data.items():
        monthly_cost = (input_tokens / 1000 * data['input_cost'] +
                       output_tokens / 1000 * data['output_cost'])
        cost_estimates.append({
            'LLM': llm_name,
            '月成本': f"${monthly_cost:.2f}",
            '成本占比': f"{monthly_cost / sum([((input_tokens / 1000 * cost_data[k]['input_cost'] + output_tokens / 1000 * cost_data[k]['output_cost'])) for k in cost_data]) * 100:.1f}%"
        })
    
    df_costs = pd.DataFrame(cost_estimates)
    print(df_costs.to_string(index=False))
    print("="*60)
    
    print("\n💡 建議:")
    print("  • 複雜任務 → 用 Claude(質量最好)")
    print("  • 簡單任務 → 用 Gemini(成本最低)")
    print("  • 要求快速 → 用 GPT-4(速度最快)")
    print("  • 多 LLM 支持 → 用 LangGraph(靈活切換)")

    Cell 9:框架對比

    print("\n🔄 架構對比:LangChain vs LangGraph")
    print("\n" + "="*80)
    
    comparison = {
        "方面": [
            "代碼行數(簡單流程)",
            "代碼行數(複雜流程)",
            "狀態管理",
            "並行執行",
            "易於測試",
            "新人上手",
            "適用場景"
        ],
        "LangChain": [
            "~40 行",
            "80+ 行(複雜)",
            "手動(state 散亂)",
            "極其困難",
            "⭐⭐(中等)",
            "1-2 天",
            "簡單應用、快速原型"
        ],
        "LangGraph": [
            "~25 行",
            "22 行(簡潔)",
            "自動(State TypedDict)",
            "⭐⭐⭐⭐⭐ 天生支持",
            "⭐⭐⭐⭐⭐(優秀)",
            "3-5 天(陡峭但有回報)",
            "複雜工作流、多 Agent"
        ]
    }
    
    df_comparison = pd.DataFrame(comparison)
    print(df_comparison.to_string(index=False))
    print("="*80)
    
    print("\n🎯 何時選擇:")
    print("\n✅ 選 LangChain 當:")
    print("   • 時間緊張(< 2 周)")
    print("   • 應用簡單(< 3 個 Agent)")
    print("   • 快速原型")
    
    print("\n✅ 選 LangGraph 當:")
    print("   • 複雜工作流(3+ Agent)")
    print("   • 有並行邏輯")
    print("   • 需要多 LLM 支持")
    print("   • 長期維護和擴展")
    print("   • 團隊規模 > 3 人")

    Cell 10:最終總結

    print("\n" + "🎯 "*40)
    print("\n📊 你的實驗總結:")
    print("\n" + "="*80)
    
    if execution_times:
        print(f"\n✅ 已測試 {len(llms)} 個 LLM")
        fastest = min(execution_times, key=execution_times.get)
        slowest = max(execution_times, key=execution_times.get)
        print(f"   • 最快:{fastest} ({execution_times[fastest]:.2f}s)")
        print(f"   • 最慢:{slowest} ({execution_times[slowest]:.2f}s)")
        print(f"   • 平均:{sum(execution_times.values())/len(execution_times):.2f}s")
    
    print(f"\n✅ 框架對比結論:")
    print(f"   LangChain: 適合簡單應用、快速原型")
    print(f"   LangGraph: 適合複雜工作流、多 Agent、多 LLM")
    
    print(f"\n✅ 多 LLM 切換的好處:")
    print(f"   • 成本優化:同一套代碼,根據任務選 LLM")
    print(f"   • 供應商備份:一個 LLM 故障,自動切換")
    print(f"   • 市場適應:新 LLM 出現,快速集成")
    
    print(f"\n✅ 給個人公司的建議:")
    print(f"   Year 1: 用 Claude SDK,多做項目(現金流優先)")
    print(f"   Year 2: 評估 LangGraph,學習投入(複雜項目有收益)")
    print(f"   Year 3: 成為專家,多 LLM 支持(競爭優勢)")
    
    print("\n" + "="*80)
    print(f"\n🚀 下一步行動:")
    print(f"   1. 根據你的 POC 找到具體的 TA(目標客戶)")
    print(f"   2. 驗證市場需求(beta 用戶反饋)")
    print(f"   3. 決定是否投資 LangGraph 學習")
    print(f"   4. 考慮多 LLM 支持(如果客戶有需求)")
    
    print(f"\n" + "🎯 "*40)

    快速開始指南

    🎯 5 分鐘快速開始

    # 1. 安裝依賴
    pip install jupyter notebook
    
    # 2. 創建 .env 文件
    cat > .env << EOF
    ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
    OPENAI_API_KEY=sk-xxxxxxxxxxxx
    GOOGLE_API_KEY=xxxxxxxxxxxx
    EOF
    
    # 3. 創建 Jupyter Notebook
    jupyter notebook
    
    # 4. 在 Notebook 中粘貼上面的代碼
    # 5. 依次執行 Cells

    🔑 API Keys 獲取

    📋 Notebook 執行順序

    1. ✅ Cell 1:安裝依賴 2. ✅ Cell 2:配置 API Keys 3. ✅ Cell 3:初始化 LLM 4. ✅ Cell 4-5:對比測試 5. ✅ Cell 6:質量分析 6. ✅ Cell 7:LangGraph 演示 7. ✅ Cell 8:成本對比 8. ✅ Cell 9:框架對比 9. ✅ Cell 10:總結

    最終決策框架

    三位一體:老闆 × 顧問 × PM

    你同時是三個身份,優先級根據情況變化:
    
    情況 1:現金流緊張(< 1 月)
    優先級:老闆 > PM > 顧問
    決策:快速賺錢最重要
      ├─ 用 Claude SDK(快)
      ├─ 多做小項目
      └─ 不學新框架
    
    情況 2:穩定現金流(3+ 月)
    優先級:顧問 > PM > 老闆
    決策:給客戶好方案,建立品牌
      ├─ 評估 LangGraph(複雜項目)
      ├─ 提高服務質量
      └─ 長期客戶關係
    
    情況 3:複雜項目 + 預算充足
    優先級:PM > 顧問 > 老闆
    決策:交付成功最重要
      ├─ 用 LangGraph(管理複雜度)
      ├─ 投前期設計時間
      └─ 降低風險

    快速決策矩陣

    ╔═══════════════════════════════════════════════════════════════╗
    ║                 你應該選哪個框架?                           ║
    ╠═══════════════════════════════════════════════════════════════╣
    
    1. 項目複雜度?
       ├─ 簡單(1-2 Agent)→ 看 Q3
       ├─ 中等(3-5 Agent)→ 看 Q3
       └─ 複雜(5+ Agent 或並行)→ LangGraph ✓
    
    2. 多 LLM 需求?
       ├─ 不需要 → 用官方 SDK
       └─ 需要 → 加 LangGraph
    
    3. 時間線?
       ├─ < 2 周 → Claude SDK(快)
       ├─ 2-4 周 → LangChain(平衡)
       └─ > 1 月 → LangGraph(品質優先)
    
    4. 團隊規模?
       ├─ 1-2 人 → Claude SDK(簡單)
       ├─ 3-5 人 → LangGraph(標準化)
       └─ 10+ 人 → LangGraph(可複用)
    
    5. 長期規劃?
       ├─ 1 個項目 → Claude SDK(不值得學)
       ├─ 2-3 個 → 考慮 LangGraph
       └─ 5+ 個 → 必須 LangGraph(ROI 高)
    
    ╠═══════════════════════════════════════════════════════════════╣
    
    最終建議:
    
    ✅ 用 Claude SDK 的條件:
       • 簡單應用(< 3 Agent)
       • 時間緊張(< 2 周)
       • 團隊小(1-2 人)
       • 短期項目(< 1 個項目規劃)
    
    ✅ 用 LangChain 的條件:
       • 快速原型
       • 簡單應用
       • 想支持多 LLM(但工作流簡單)
       • 喜歡靈活性
    
    ✅ 用 LangGraph 的條件:
       • 複雜工作流(> 3 Agent)
       • 並行執行或分支邏輯
       • 多 LLM 支持
       • 長期項目規劃(3+ 個)
       • 團隊 > 3 人
    
    ╚═══════════════════════════════════════════════════════════════╝

    核心結論

    1. 框架選擇不是技術問題,是商業問題
       ✓ 有付費客戶?有複雜項目?有長期規劃?
       ✗ 這些都沒有?先驗證市場
    
    2. LangGraph 的價值在於「長期」
       • 第 1 個項目:LangGraph 可能慢
       • 第 3 個項目:LangGraph 快 50%
       • 第 5 個項目:LangGraph 快 70%
    
    3. 多 LLM 不是為了省錢,而是為了自由
       • 供應商備份(可用性)
       • 成本優化(可選)
       • 市場適應(長期)
    
    4. POC 階段最重要的是市場驗證,不是技術選擇
       • 1 周市場反饋 > 2 周完美代碼
       • TA 決定一切
       • 框架是後話
    
    5. 個人公司的出路是「垂直深化」,不是「技術秀肌肉」
       • 某個領域的專家 > 全能技術人
       • $10k-20k 的垂直項目 > $2k-5k 的通用項目
       • 品質溢價 > 技術先進性

    後記

    **給你的最後話**:

    你已經掌握了 Claude Agent SDK,這給了你第一步的優勢。現在的問題不是「選哪個框架」,而是「選哪個市場」。

    LangChain/LangGraph 是在你確定市場和客戶後,為了「長期優化」的選擇。不是「先進」,而是「務實」。

    現在就出去找 TA,快速驗證想法。3 個月後,當你有 3-5 個清晰的客戶需求時,再回過頭來考慮技術選擇。那時候的決策會基於真實數據,而不是假設。

    同時,寫好你的博客。「Claude Agent SDK 深度實踐指南」會成為你的品牌。未來的「LangGraph 多 LLM 架構指南」會是補充。

    競爭力不來自「最新技術」,而來自「解決真實問題的深度」。

    **撰寫時間**:2026-03-17 **版本**:1.0 **包含**:完整分析 + Jupyter Notebook + 決策框架

    **加油!👊**

  • Agent Team 多輪迭代:從失敗到成功的設計演進

    Document Status: Living Document (持續更新)
    Last Updated: 2026-03-17
    Author: Claude Code + Tom
    Purpose: 從 SimpleEC OMS 多次失敗的 Agent Team 經驗中提煉最佳實踐

    🎯 重點摘要

    • 問題:4 次 Agent Team 啟動都在 24+ 小時後卡住,根本原因不在代碼,而在設計與 Prompt
    • 核心原則:編碼依賴(Task.blockedBy/blocks)、明確停止條件、2 小時 timeout、結構化交付物
    • 關鍵對比:Provider Chain (複雜) vs Sequential Phase (簡單) — 後者減少隱式依賴、自動強制約束
    • Prompt 檢查清單:5 大維度、17 項細節檢查,防止 Agent 卡住或無限期等待
    • 成功設計:明確的時間表、具體的交付物格式 (JSON)、禁止行為列表、協調者角色

    序言:為什麼我們一直失敗

    從 2026-03-03 到 2026-03-17,我們嘗試啟動過至少 4 個 Agent Team,每一次都卡住 24+ 小時:

    1. simpleec-oms-audit (3/3) — 任務分配錯亂,Agent 互相等待
    2. simpleec-oms-bidirectional-audit (3/10) — 複雜的雙向驗證設計,Agent 不知道什麼時候應該停止
    3. simpleec-oms-quality-audit (3/16) — Task 被分配給錯誤的 Agent,導致 3 個 Agent 空轉 24 小時

    根本原因不在代碼,而在於

    • ❌ 設計太複雜,隱式依賴沒有編碼
    • ❌ Prompt 寫得不清楚,Agent 不知道什麼時候應該停止或等待
    • ❌ 沒有 Timeout 機制,導致無限期等待
    • ❌ 任務分配邏輯複雜,容易出錯
    • ❌ Agent 沒有明確的”停止條件”,導致亂工作或空轉

    本文將詳細解析這些問題,並提供可複製的最佳實踐。

    🎯 你需要打什麼讓我一步到位

    複製以下內容給 Claude

    我要啟動 Agent Team 做 [你的任務]
    
    系統:[系統名]
    檢查維度:[A], [B], [C]
    時間:[時間限制]
    Agent:[N 個]
    
    創建:TEAM_PLAN.md / AGENT_PROMPTS.md / CHECKLIST.md / settings.json

    📋 成功的 Prompt 範本

    You are ARCHITECT on [TEAM_NAME].
    
    Verify [SYSTEM]:
    - [Check A]
    - [Check B]
    
    DELIVERABLE (JSON):
    { "task_id": 1, "findings": { "score": X, "ready": true } }
    
    BEGIN PHASE 1 NOW.

    第一部分:為什麼 Agent Team 會卡住?

    原因 1:複雜的隱式依賴

    ❌ 壞設計示例:使用 Provider Chain + Consumer Chain 雙向驗證(複雜且失敗)。有 4 個同步點,但都是文字描述,沒有編碼到 Task 系統。Task 之間的依賴關係是隱式的(”Task #1 完成後才能開始 Task #2″,但沒有在 blockedBy 里標記)。Agent 不知道應該等待誰被誰等待

    後果:當任務分配出錯(比如 Task #2 被分給了錯誤的 Agent),整個鏈條斷裂。Architect 和 Backend-QA 無所事事,空轉 24+ 小時,持續消耗內存。

    原因 2:Prompt 寫得不清楚 → Agent 不知道什麼時候該停止

    Prompt 缺少明確的停止條件。完成 Task #1 後,Agent 不知道應該做什麼——是否應該主動聯繫其他 Agent?是否應該重新檢查自己的工作?內存會持續增長(因為 Agent 一直在運行)。

    實際情況:Architect 完成 Task #1 後,發現沒有 Task #2 和 #3 的結果(因為被分配錯了)。開始懷疑,重新讀一遍所有文件。14 小時後,內存從 380MB 漲到 440MB。最後 OOM → 系統當機。

    原因 3:沒有 Timeout 機制

    舊設計 新設計
    Agent Task 超時限制:無
    → 可以無限期等待
    → 可以無限期工作
    → 內存持續增長,最終 OOM
    Agent Task 超時限制:2 小時
    → 2 小時後,自動標記 timeout
    → 解鎖下一個任務或停止
    → 即使出錯,也不會無限期卡住

    原因 4:Agent 之間沒有同步點

    舊設計中,Task #1 在工作,Task #2 也在工作,但 Task #2 應該等待 Task #1。沒人告訴他們應該等待誰。新設計中,用 Task.blockedBy = [1, 2] 明確表示”我要等 Task #1, #2″。

    第二部分:好的 Agent Team 設計原則

    原則 1:Show, Don’t Tell(編碼依賴,不要寫文字)

    為什麼? Task 系統會自動強制依賴順序,不會分配錯誤。不依賴人工判斷。系統可以自動檢測循環依賴或孤立任務。

    原則 2:一個 Agent 做一件事

    ❌ 壞:Task #2 包含 3 個不同的東西(Schema 驗證、Kafka 驗證、Handler 驗證)。Agent 容易分心,難以判斷什麼時候”完成”。

    ✅ 好:Task #2 目標清晰:”驗證數據層能否支持 API 承諾”。包含 3 個驗證點,但都是同一件事的一部分。交付物是一個結構化的 JSON 對象。

    原則 3:明確的交付物結構

    ❌ 壞:”Generate audit report with Executive summary, Critical issues list…” 模糊,無法驗證是否合格。

    ✅ 好:返回結構化 JSON,包含量化指標(alignment score)、布爾標誌(ready_for_next_phase)、具體問題列表。下一個 Agent 可以用 JSON parser 讀取。

    原則 4:Prompt 要明確定義”停止條件”

    Prompt 必須明確說:完成 Task 後,Agent 應該做什麼(答案是:停止工作,等待通知)。沒有”循環工作”的空間。明確的等待機制(team-lead 會告訴你什麼時候開始下一個 Phase)。

    原則 5:Timeout 是必需的

    新設計:2 小時 timeout。時間到了,自動標記 timeout。自動解鎖下一個 Task(即使當前 Task 沒完成)。自動通知 team-lead。防止無限期等待。

    第三部分:Prompt 編寫終極檢查清單

    A. 責任清晰度(Clarity of Responsibility)

    • 一個 Agent,一件事 — 避免重載式任務設計
    • 目標可測 — 不是”驗證 schema 完整性”,而是”生成 JSON with schema_integrity score”
    • 交付物明確 — 結構化 JSON,而不是自由文本報告

    B. 停止條件明確(Clear Stop Conditions)

    • Prompt 明確說什麼時候應該停止 — “After Task #1 is complete, do NOT continue. Wait for team-lead notification.”
    • 沒有”循環工作”的空間 — “After generating findings JSON, stop. Do not re-read files.”
    • 明確的等待機制 — “Wait for team-lead message: ‘Phase 2 begins’”

    C. 依賴關係編碼(Dependency Encoding)

    • Task.blockedBy 明確填寫"blockedBy": [1] 表示”我等 Task #1″
    • Task.blocks 明確填寫"blocks": [3, 4] 表示”我阻擋 Task #3 和 #4″
    • 沒有循環依賴 — Task #1 blocks #2, #2 blocks #3, #3 blocks #1 ← 循環!

    D. 超時保護(Timeout Protection)

    • Prompt 中明確提到超時時間 — “You have 2 hours to complete Task #1”
    • 告訴 Agent 超時時會發生什麼 — “If 2 hours pass, next phase will begin regardless”
    • Timeout 不應該導致錯誤,只是解鎖 — 後自動繼續下一階段

    E. Agent 之間的協調(Inter-Agent Coordination)

    • 明確說是否應該主動聯繫其他 Agent — “Do NOT contact backend-qa or frontend-qa”
    • 明確說如何接收通知 — “You will receive explicit notification from team-lead when Phase 2 begins”
    • 明確說何時應該報告問題 — “Report them in your findings JSON. Do NOT try to fix them yourself.”

    第四部分:Prompt 好與壞的完整對比

    ❌ 壞 Prompt(導致失敗)

    缺少:明確的完成後行為、明確的等待規則、Timeout 時間、停止條件、交付物格式的具體性。

    後果:Architect 完成 Task #1 後,發現沒有 Task #2 和 #3 的結果。不知道應該等待還是繼續工作。開始懷疑自己的分析,重新讀文件。持續讀文件和重新分析 14+ 小時。內存從 380MB 漲到 440MB。最後 OOM,系統當機。

    ✅ 好 Prompt(成功設計)

    特點:明確的時間表(0-2h Phase 1, 2-4h 等待, 4-6h Phase 4)。明確的停止條件(”完成後停止,不要做任何其他事”)。明確的交付物(結構化 JSON)。明確的等待機制(team-lead 會告訴你什麼時候開始 Phase 4)。明確的禁止行為(❌ 列出了不應該做的事)。

    後果:Architect 完成 Task #1。知道自己應該停止(Prompt 明確說了)。進入等待模式(不讀文件,不重新分析)。2 小時後,如果沒有 Task #4 通知,自動 timeout。內存穩定在 380MB(沒有持續增長)。系統正常運行。

    第五部分:常見錯誤與修正

    錯誤 1:Prompt 寫得太長和太複雜

    修正:用清晰的結構(Markdown headers)。用列表而不是段落。用例子而不是抽象描述。用”禁止行為”而不是”允許行為”。目標:500 字清晰 Prompt,而不是 2000 字複雜 Prompt。

    錯誤 2:隱式假設 Agent 會自己推斷

    ❌ 壞:”After Task #1, you will know when to start Task #2″(Agent 怎麼知道?沒人告訴他!)

    ✅ 好:”After Task #1, wait for team-lead message: ‘Task #2 begins’. Only then should you proceed.”

    錯誤 3:交付物格式模糊

    ❌ 壞:”Generate a report with findings”

    ✅ 好:生成 JSON,具有明確的字段結構 (status, findings, critical_issues 等)

    錯誤 4:沒有明確的超時時間

    ✅ 修正Timeout: 2 hours — If 2 hours pass, your task is automatically marked timeout. Next phase will proceed regardless. You will be notified when your timeout occurs.

    第六部分:Agent Team 設計檢查清單

    Pre-Launch Checklist

    系統狀態:內存充足 (>8GB available)。沒有舊的 Agent Team 在運行。Task 目錄是空的。

    Task 設計:每個 Task 有明確的 id, subject, description。每個 Task 的 blockedBy 和 blocks 已填寫(沒有循環依賴)。沒有孤立的 Task。每個 Task 有 2 小時的隱式 timeout。

    Prompt 設計:每個 Agent 的 Prompt 有明確的責任(一件事)。每個 Prompt 有明確的停止條件。每個 Prompt 有具體的交付物格式(JSON)。每個 Prompt 有明確的等待機制。每個 Prompt 禁止了不應該做的事情(❌ 列表)。

    交付物定義:所有交付物都是結構化的(JSON)。每個交付物都有 status 字段。下一個 Agent 能解析上一個 Agent 的交付物。交付物不應該是自由文本,應該是結構化數據。

    同步機制:有明確的”team-lead”角色負責協調。有明確的通知機制。有明確的失敗恢復流程。沒有 Agent 之間的直接通信(都通過 team-lead)。

    Launch Checklist

    監控:每 30 分鐘檢查一次內存使用。監控是否有 Agent 卡住。準備好 2 小時後手動檢查 timeout 機制。

    信號:知道什麼樣的行為表示”卡住”(讀同一個文件超過 1 小時,內存持續增長 10% 以上,沒有進展 30 分鐘以上)。準備好應急措施(2 分鐘內關掉所有 Agent,清理內存,回滾到之前的狀態)。

    第七部分:迭代和改進

    本文將根據實驗結果進行迭代。每當我們啟動新的 Agent Team 時:

    1. 記錄過程 — 啟動時間、Agent 行為、完成時間、內存使用、任何卡住或異常情況
    2. 在本文中更新 — 如果發現新的問題、更好的 Prompt 寫法、或 Timeout 時間不合適的情況
    3. 版本控制 — 每次大的更新,提升版本號。在文件頂部記錄更新日期和內容

    總結

    從失敗中學到的核心真理

    1. 設計要簡單,依賴要明確 — 不要用複雜的 Provider Chain,用簡單的 Sequential Phase
    2. 編碼依賴,不要寫文字blockedByblocks 必須填寫,隱式依賴是毒藥
    3. Prompt 要明確停止條件 — Agent 必須知道什麼時候應該停止
    4. Timeout 是必需的保險 — 沒有 timeout,Agent 可以無限期卡住
    5. 交付物要結構化 — JSON 而不是自由文本,下一個 Agent 能解析
    6. 有一個協調者(team-lead) — 不要讓 Agent 之間直接通信

    下一步:用 v2 設計啟動 Quality Audit Team。記錄過程和結果。根據結果更新本文。建立標準範本(Task 和 Prompt 的 template)。

    實施深度:v3 計畫的四層架構

    前面的原則是設計哲學。但實際部署 v3 計畫時,我們加入了四項關鍵實施細節,把抽象的原則轉換為可監控、可恢復、可自動化的運作

    ①分層監控架構(Team-lead 的心跳)

    v3 計畫引入了 Team-lead 監控層,專職於此,间隔嚴格:30秒 Session 健康檢查、30分鐘超時檢查、60分鐘進度報告、5分鐘內存監控。

    ②事件驅動協調(4 個事件)

    v3 計畫改為事件驅動模型,完全由 Team-lead 控制狀態轉遷。4個事件:Task#1完成→解鎖Task#2&3、Task#2&3都完成→通知Architect進行Task#4、Task#4完成→生成報告。

    ③應急與恢復(5 個故障模式)

    v3 計畫為5種情況預先定義恢復策略:Orphaned Agents(中止審計)、Multiple Timeouts(部分報告)、Invalid JSON(記錄錯誤繼續)、OOM Event(強制超時解鎖)、Stalled Task(檢測重啟或強制超時)。

    ④完整實現範例

    完整的Task生命週期:t=0初始化、t=0-30分鐘Architect驗證、t=25觸發Event1解鎖Task#2&3、t=25-50並行執行QA驗證、t=50觸發Event2&3通知Architect、t=50-110Task#4最終驗證、t=115報告生成完成。總耗時115分鐘,4個Agent共消耗1.8GB內存。

    v3 計畫 vs v2:7 個關鍵改進

    依賴編碼從文字敘述改為JSON(blockedBy/blocks)、停止條件從暗示改為明確、超時機制從提到改為實現(120min+30min+自動unlock)、監控從無改為Team-lead 30秒心跳、協調從Agent間通信改為Team-lead主控、交付物從文字改為JSON schema、故障恢復從無預案改為5個策略。

    「後即時」監控與自動恢復

    v3 計畫的終極目標是達到「後即時(Near Real-Time)監控」:不是等Task失敗才發現,而是任何異常2分鐘內自動檢測並響應。解決之前24小時卡住的問題。

  • Agent SDK vs 傳統 If-Else:客服系統從 500 行代碼到 10 行的蛻變

    📥 Download Jupyter Notebook

    Download complete Jupyter Notebook


    Agent SDK vs 傳統 If-Else:客服系統從 500 行代碼到 10 行的蛻變

    📋 快速摘要

    • Agent SDK 將 500+ 行 if-else 邏輯簡化為 ~10 行配置
    • 維護成本從「高」降到「低」—— 新增規則只需改提示,無需改代碼
    • 適用場景:客服回覆、內容審核、工單分類
    • 不適用場景:金融交易、爬蟲、醫療診斷(需要 100% 確定性)
    • 本文包含可運行的 Jupyter Notebook 對比演示

    爲什麽選擇 Agent SDK 而非傳統 If-Else?

    想象你在維護一個客服系統。每當新的詢問類型出現,你就得添加 5-10 行 if-elif-else 代碼。6 個月後,代碼變成 500+ 行的怪獸,充滿邊界情況處理。

    現在有一個更好的方式:用 Agent SDK 讓 AI 自動理解客戶意圖,不需要每次都改代碼。

    實例對比:傳統方式 vs Agent SDK

    ❌ 傳統方式:500+ 行代碼

    典型的 if-else 實現(簡化版本):

    def traditional_customer_service(inquiry: str) -> str:
        if "退貨" in inquiry or "return" in inquiry.lower():
            if "7天" in inquiry or "7 days" in inquiry.lower():
                return "✓ 好消息!7 天內的商品我們接受退貨。請提供訂單號和退貨原因。"
            elif "30天" in inquiry or "30 days" in inquiry.lower():
                return "⚠ 30 天內的商品需要評估狀況。請寄回商品,我們會判斷是否可退。"
            else:
                return "✗ 超過退貨期限(30天),無法退貨。詳見購買頁面。"
        # ... 還有物流、商品、預設回覆,加起來 500+ 行
        else:
            return "感謝您的詢問。請告訴我更多細節,我會盡快幫您解決。"

    問題:

    • 新增詢問類型 → 需要改代碼 → 需要測試 → 需要重新部署
    • 邊界情況處理複雜(用戶說「退貨」的 10 種不同表達方式)
    • 代碼量隨詢問類型線性增長
    • 維護成本高、Bug 多

    ✨ Agent SDK 方式:~10 行配置

    from claude_agent_sdk import query, ClaudeAgentOptions
    
    async for message in query(
        prompt="You are a customer service agent. Understand customer inquiries and help with returns, invoices, shipping, and product issues.",
        options=ClaudeAgentOptions(
            allowed_tools=["Retrieve Policy", "Query Order", "Update Status"],
            permission_mode="acceptEdits"
        )
    ):
        if isinstance(message, ResultMessage):
            print(message.result)  # AI-generated response

    優勢:

    • 新增規則 → 只需改系統提示,無需改代碼
    • 自動理解變通說法
    • 代碼量固定,不隨規則增加而增加
    • 維護成本低、Bug 少

    真實測試結果

    5 個實際客戶詢問測試:

    測試 傳統方式 Agent SDK 勝者
    回覆時間 0.03ms 150ms If-Else (快 5000x)
    代碼行數 500+ ~10 ✨ Agent SDK (簡潔 50x)
    新增規則難度 高(改代碼→測試→部署) 低(改提示→即時生效) ✨ Agent SDK
    維護成本 ✨ Agent SDK
    用戶體驗 生硬、標準化 自然、親切 ✨ Agent SDK

    何時使用 Agent SDK vs If-Else

    ✅ 適合 Agent SDK 的場景

    • 客服回覆 — 自然理解客戶意圖
    • 內容審核 — 判斷垃圾信息、仇恨言論
    • 工單分類 — 自動分類優先級
    • 推薦系統 — 推薦相關商品
    • 數據提取 — 從非結構化文本提取信息

    ❌ 不適合 Agent SDK 的場景

    • 金融交易 — 需要 100% 確定性
    • 醫療診斷 — 需要絕對準確
    • 法律判決 — 需要精確遵循規則
    • 實時系統 — AI 延遲 100-500ms
    • Web 爬蟲 — 需要精確控制

    Claude API vs Agent SDK:核心差異

    這是很多人困惑的地方。讓我用實例說明。

    場景:客服回答「我的訂單呢?」

    系統需要:

    1. 查訂單資料庫
    2. 查物流資料庫
    3. 組合信息回答客戶

    ❌ Claude API(你控制流程)

    from anthropic import Anthropic
    
    client = Anthropic()
    
    # 第 1 次調用
    response1 = client.messages.create(
        model="claude-opus-4-6",
        messages=[{
            "role": "user",
            "content": "客戶說:我 3 月 10 號買的商品,現在還沒收到"
        }]
    )
    # Claude:「我需要查一下你的訂單...」
    
    # ❌ 你必須手動查資料庫
    order = query_order_db(customer_id, "2026-03-10")
    
    # ❌ 第 2 次調用 Claude
    response2 = client.messages.create(
        model="claude-opus-4-6",
        messages=[{
            "role": "user",
            "content": f"""訂單信息:{order}
    
    請回答客戶。"""
        }]
    )
    
    # ❌ 如果客戶追問,又要第 3、4 次調用...

    你的應用程式在做決策:

    • 「我應該先查訂單」
    • 「我應該問 Claude 什麼問題」
    • 「我應該再查一次物流」

    ✅ Agent SDK(Claude 自動控制流程)

    from claude_agent_sdk import query, ClaudeAgentOptions, ResultMessage
    
    # 就一次調用,Claude 自動做一切
    async for message in query(
        prompt="""你是客服系統。根據客戶問題,查詢訂單和物流信息,給出完整回答。
    
    客戶問題:「我 3 月 10 號買的商品,現在還沒收到,怎麼辦?」
    
    工具說明:
    - query_order(customer_id, date):查訂單
    - query_shipping(tracking_id):查物流
    
    請自動使用這些工具,給出完整回答。""",
    
        options=ClaudeAgentOptions(
            allowed_tools=["query_order", "query_shipping"]
        )
    ):
        if isinstance(message, ResultMessage):
            print(message.result)
            # 完成!Claude 自動完成了一切

    Claude 自動做決策:

    • ✅ Claude 看到問題
    • ✅ Claude 決定「我需要查訂單」
    • ✅ Claude 自動調用工具
    • ✅ Claude 看結果,決定「我還需要查物流」
    • ✅ Claude 自動調用工具
    • ✅ Claude 綜合所有信息,給出回答

    一句話總結

    Claude API 我知道要查 DB 的順序 → 我來組織
    Agent SDK 我把查 DB 的工具做好 → Claude 自己組織順序

    Agent SDK vs Claude API 完整對比

    特性 Claude API Agent SDK
    使用場景 一次性請求、內容生成 決策型任務、自動化工作流
    流程控制 你的應用程式控制 Claude 自動決策
    工具調用 手動查 DB,手動傳給 Claude Claude 自動調用工具和解析
    複雜度 簡單 – 一個請求,一個回應 複雜 – 多步驟推理、工具調用
    代碼量 多(需要寫 loop 邏輯) 少(一句話啟動)
    安全性 你負責驗證輸出 內置權限管理、審計日誌

    決策樹:選擇正確的工具

    你的任務來了
        ↓
    「這個任務需要 AI 自己決策嗎?」
        ├─ YES → 「結果容錯為零嗎?」
        │         ├─ YES → ❌ 不用 AI,用硬編碼邏輯
        │         └─ NO  → ✅ 用 Agent SDK
        │
        └─ NO  → 「只是單純生成內容/回答嗎?」
                  ├─ YES → ✅ 用 Claude API
                  └─ NO  → 「需要多步驟工作流嗎?」
                            ├─ YES → 你控制流程 + Claude API
                            └─ NO  → ✅ Claude API 就夠了

    真實案例:電商商品自動分類系統

    背景: 某線上購物平台(如東森)需要自動將客戶上傳的商品歸類到正確的分類。

    情況說明

    規模: 4 萬個商品分類(電子產品、服裝、家居、運動等)

    挑戰: 如何在成本可控的情況下,快速準確地進行分類?

    方案 1:傳統 TFIDF 模型

    實現方式:

    1. 收集所有商品描述 + 人工標註的分類
    2. 用 TFIDF 算法訓練模型,提取關鍵詞權重
    3. 客戶輸入新商品描述 → 模型計算與各分類的相似度 → 返回排名前 3 的分類
    # 傳統 TFIDF 方法
    from sklearn.feature_extraction.text import TfidfVectorizer
    from sklearn.neighbors import NearestNeighbors
    
    # 1. 訓練
    vectorizer = TfidfVectorizer()
    tfidf_matrix = vectorizer.fit_transform(product_descriptions)
    model = NearestNeighbors(n_neighbors=3, metric='cosine')
    model.fit(tfidf_matrix)
    
    # 2. 預測
    new_product = "輕便防水的戶外登山背包,容量 40L"
    new_tfidf = vectorizer.transform([new_product])
    distances, indices = model.kneighbors(new_tfidf)
    
    # 結果:前 3 個分類
    # [運動戶外, 旅遊用品, 箱包配飾]

    優勢:

    • ⚡ 毫秒級回應(無網路延遲)
    • 💰 零成本(本地運行)
    • 🎯 可控、可解釋(看得到關鍵詞權重)

    缺點:

    • ❌ 無法理解語義(「便宜的手機」vs「經濟型手機」被當作完全不同的商品)
    • ❌ 變通說法識別差(「登山背包」識別不了,但「戶外登山用雙肩包」就被歸錯類)
    • ❌ 每次添加新分類或修改規則都需要重新訓練
    • ❌ 無法跨語言(中文和英文分開訓練)
    • ❌ 無法處理複雜邏輯(「防水的同時是否防塵?」這類二次判斷)

    方案 2:單純 AI 分類(Claude API)

    天真的做法:把 4 萬個分類都給 Claude

    from anthropic import Anthropic
    
    client = Anthropic()
    
    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        messages=[{
            "role": "user",
            "content": f"""根據這個商品描述進行分類:
    
    商品描述:輕便防水的戶外登山背包,容量 40L
    
    可用分類:
    - 電子產品
    - 服裝鞋履
    ... (共 4 萬個)
    
    返回最相關的前 3 個分類 + 置信度。"""
        }]
    )

    問題: 4 萬個分類 × 10 tokens/分類 = 40 萬 tokens 光是分類列表

    • 成本:$5 / 次(按 Claude Opus 定價)
    • 日成本(10,000 商品):$50,000 / 天 = **$1.5M / 月** ❌
    • 完全不可行

    方案 3:向量搜尋 + AI 精確分類(最優)

    核心思想: 不是把 4 萬個分類都給 Claude,而是:

    1. 預先計算: 將 4 萬個分類嵌入向量空間(一次性,離線)
    2. 實時檢索: 商品描述進來 → 向量相似度搜尋 → 找出最相關的 Top 50 分類
    3. 精確分類: 只把 50 個候選分類傳給 Claude
    4. 結果: 成本 = 原本的 1/800,準確度反而更高
    # 向量檢索 + AI 分類架構
    
    from sentence_transformers import SentenceTransformer
    from milvus import connections, Collection
    from anthropic import Anthropic
    
    client = Anthropic()
    
    # ============ 階段 1:預先計算分類向量(一次性) ============
    def initialize_category_embeddings():
        """將 4 萬個分類嵌入向量空間"""
        connections.connect("default", host="127.0.0.1", port="19530")
        collection = Collection("products_categories")
    
        # 從資料庫讀取所有分類
        categories = get_all_categories_from_db()
    
        # 計算向量(使用本地模型)
        model = SentenceTransformer('all-MiniLM-L6-v2')
        embeddings = model.encode([cat['name'] for cat in categories])
    
        # 插入向量資料庫
        collection.insert({
            "id": [cat['id'] for cat in categories],
            "category_name": [cat['name'] for cat in categories],
            "embedding": embeddings
        })
        collection.load()
        print("✅ 4 萬個分類向量化完成!")
    
    # ============ 階段 2:實時檢索 + AI 分類 ============
    def classify_product_optimized(product_description):
        """實時分類流程"""
    
        # 1. 將商品描述向量化
        model = SentenceTransformer('all-MiniLM-L6-v2')
        query_embedding = model.encode(product_description)
    
        # 2. 向量搜尋:找出最相關的 Top 50 分類(< 50ms)
        connections.connect("default", host="127.0.0.1", port="19530")
        collection = Collection("products_categories")
    
        search_results = collection.search(
            data=[query_embedding],
            anns_field="embedding",
            param={"metric_type": "L2", "params": {"nprobe": 10}},
            limit=50  # 只取 Top 50
        )
    
        top_categories = [hit.entity.get("category_name") for hit in search_results[0]]
        categories_text = '\n'.join([f"- {cat}" for cat in top_categories])
    
        print(f"✓ 向量搜尋找到 50 個候選分類(用時:< 50ms)")
    
        # 3. Claude 從 50 個候選中精確選擇(150ms)
        response = client.messages.create(
            model="claude-opus-4-6",
            max_tokens=1024,
            messages=[{
                "role": "user",
                "content": f"""根據這個商品描述進行分類:
    
    商品描述:{product_description}
    
    相關分類候選(已按相似度排序,僅展示 Top 50):
    {categories_text}
    
    請從上述候選中選擇最相關的前 3 個分類 + 置信度。
    
    返回格式:
    1. 分類名稱 (置信度: 95%)
    2. 分類名稱 (置信度: 80%)
    3. 分類名稱 (置信度: 65%)
    
    同時說明理由。"""
            }]
        )
    
        return response.content[0].text

    性能對比:

    指標 TFIDF 純 AI
    (全部分類)
    向量 + AI
    (推薦)
    分類傳輸 不適用 40 萬 tokens 500 tokens(50 個)
    成本/次 $0 $5.00 $0.005
    日成本(10K 商品) $0 $50,000 $50
    響應時間 1ms 1-2 秒 200ms
    準確度 中(容易混淆) ⭐⭐⭐ 高
    語義理解 ❌ 差 ✅ 強 ✅ 強
    多語言支持 ❌ 差 ✅ 強 ✅ 強

    如何讓 Agent SDK / Claude 存取動態分類列表?

    問題: 上面的案例中,分類是硬編碼或簡單傳輸。但在真實系統中,分類會經常變動。Agent SDK 怎麼知道最新的分類清單?

    三種方案對應不同規模

    方案 A:應用層查詢(適合 < 500 分類)

    流程: 應用程式 → 查詢資料庫 → 替換提示詞佔位符 → Agent 使用

    import sqlite3
    from anthropic import Anthropic
    
    client = Anthropic()
    
    # 應用程式層:查詢資料庫
    def get_categories_from_db():
        conn = sqlite3.connect('products.db')
        cursor = conn.cursor()
        cursor.execute('SELECT name FROM categories WHERE active = 1 ORDER BY name')
        categories = [row[0] for row in cursor.fetchall()]
        conn.close()
        return categories
    
    # 獲取最新分類
    categories = get_categories_from_db()
    categories_text = '\n'.join([f"- {cat}" for cat in categories])
    
    # 生成提示詞
    prompt = f"""根據商品描述選擇分類:
    
    商品描述:輕便防水的戶外登山背包,容量 40L
    
    可用分類:
    {categories_text}
    
    返回前 3 個分類。"""
    
    # Claude 使用最新分類進行分類
    response = client.messages.create(
        model="claude-opus-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}]
    )

    優勢: 簡單、直接、零複雜度

    缺點: 每次請求都要查資料庫

    方案 B:Agent 工具查詢(適合 500-5000 分類)

    流程: Agent 調用自訂工具 → 工具查詢資料庫 → Agent 使用結果

    from anthropic import tool
    import sqlite3
    
    @tool
    def query_categories(keyword: str = None) -> str:
        """查詢可用的商品分類。
    
        Args:
            keyword: 可選的搜尋關鍵詞(例如:'電子' 會返回 '電子產品')
        """
        conn = sqlite3.connect('products.db')
        cursor = conn.cursor()
    
        if keyword:
            cursor.execute(
                'SELECT name FROM categories WHERE active = 1 AND name LIKE ? ORDER BY name',
                (f'%{keyword}%',)
            )
        else:
            cursor.execute('SELECT name FROM categories WHERE active = 1 ORDER BY name')
    
        categories = [row[0] for row in cursor.fetchall()]
        conn.close()
        return ', '.join(categories)
    
    # Agent 可以調用工具
    prompt = """根據商品描述選擇分類:
    
    商品描述:輕便防水的戶外登山背包,容量 40L
    
    步驟:
    1. 使用 query_categories 工具查詢所有或相關分類
    2. 從結果中選擇最相關的前 3 個
    
    返回格式:
    1. 分類名稱 (置信度: 95%)
    ...
    """

    優勢: 動態、Agent 可以「思考」查詢策略

    缺點: 增加 API 往返次數

    方案 C:向量檢索(適合 > 5000 分類,如東森 4 萬)

    流程: 預先嵌入分類 → 商品描述進來 → 向量搜尋 Top 50 → Claude 精確選擇

    (詳見上方「向量搜尋 + AI 精確分類」段落)

    方案選擇表

    分類規模 推薦方案 成本 延遲 複雜度
    < 100 方案 A(直接傳) 最低 最快 ⭐ 最簡
    100-500 方案 A(推薦) ⭐ 簡
    500-5000 方案 B(推薦) ⭐⭐ 中
    > 5000(東森 4 萬) 方案 C(必須) 最低 最快 ⭐⭐⭐ 複

    工具設計的正確思路:從問題出發

    這是最重要的一個章節。 很多工程師設計 Agent 工具時,會陷入「工具先行」的誤區。但正確的做法是「需求驅動」。

    ❌ 錯誤的做法:工具先行

    「我要做 Agent SDK」
      ↓
    「我需要什麼工具?」
      ↓
    設計工具:query(), update(), delete()
      ↓
    「我怎麼用這些工具?」
      ↓
    慢慢找場景...
      ↓
    結果:工具太通用、有遺漏、或過度設計

    ✅ 正確的做法:從問題出發

    「我的系統可能遇到什麼問題?」
      ↓
    列舉所有可能的問題
      ↓
    反推需要什麼工具來解決
      ↓
    設計這些工具(不多不少)
      ↓
    套入 Agent SDK
      ↓
    結果:工具精準、完整、適中

    實例 1:東森商品分類系統

    第 1 步:列舉可能的問題

    系統運行時會遇到什麼問題?
    
    用戶層面:
      ✓ 「我怎麼知道這個商品該放哪一類?」
      ✓ 「系統選的分類對嗎?」
      ✓ 「能不能推薦其他可能的分類?」
    
    系統層面:
      ✓ 「分類資料庫有沒有更新?」
      ✓ 「分類規則有沒有衝突?」
      ✓ 「某個分類底下有沒有商品?」
    
    邊界問題:
      ✓ 「這個商品可能屬於多個分類嗎?」
      ✓ 「怎麼處理新加的分類?」
      ✓ 「怎麼回滾到之前的分類?」

    第 2 步:反推需要的工具

    問題                                 → 需要的工具
    ──────────────────────────────────────────────────
    「能推薦其他可能的分類?」            → search_similar_categories()
    「分類有沒有更新?」                  → get_latest_categories()
    「分類規則有沒有衝突?」              → validate_category_rules()
    「某分類有沒有商品?」                → count_products_in_category()
    「可能屬於多個分類嗎?」              → get_ambiguous_categories()

    第 3 步:只設計這些工具

    @tool
    def search_similar_categories(keyword: str, top_k: int = 5) -> list:
        """找相關分類"""
    
    @tool
    def get_latest_categories(updated_after: str = None) -> list:
        """取最新分類資料"""
    
    @tool
    def validate_category_rules(category_id: str) -> dict:
        """驗證分類規則有沒有問題"""
    
    @tool
    def count_products_in_category(category_id: str) -> int:
        """某分類有多少商品"""
    
    @tool
    def get_ambiguous_categories(product_desc: str) -> list:
        """找可能有歧義的分類"""

    就這 5 個工具,不多不少!

    實例 2:客服系統

    列舉問題 → 推斷工具

    問題列表:
    1. 「客戶的訂單存在嗎?」
    2. 「訂單現在在哪裡?」
    3. 「這個客戶有沒有退貨紀錄?」
    4. 「退貨政策允許嗎?」
    5. 「要問主管才能退嗎?」
    6. 「怎麼記錄這次交互?」
    
    需要的工具:
    1. query_order()
    2. get_shipping_status()
    3. get_customer_return_history()
    4. check_return_policy()
    5. escalate_to_manager()
    6. log_interaction()

    就這 6 個,不多不少!

    為什麼這樣設計好?

    優勢 解釋
    ✅ 不會過度設計 只有解決實際問題的工具
    ✅ 不會有遺漏 所有可能的問題都考慮到
    ✅ Claude 理解清楚 系統邊界明確,工具語義清晰
    ✅ 工具粒度適中 既不太大也不太小
    ✅ 易於維護和擴展 添加新問題 = 添加新工具

    設計 Agent 工具時的關鍵決策:工具粒度

    基於「從問題出發」的思路,現在我們討論工具粒度。 粒度(granularity)決定了 Claude 能否有效使用工具。

    三種極端情況

    ❌ 工具太大(做太多事)

    @tool
    def query_order_everything(
        customer_id: str,
        order_id: str = None,
        status: str = None,
        start_date: str = None,
        end_date: str = None,
        shipping_status: str = None,
        include_items: bool = True,
        include_history: bool = True
    ) -> dict:
        """一個工具做所有事"""
        # 6 個 WHERE 條件
        # ...

    問題:

    • Claude 很容易參數填錯(太多選擇)
    • Claude 不知道應該用哪些參數組合
    • 你寫了 6 個 WHERE,Claude 可能只需要 1 個,浪費

    ❌ 工具太小(太細碎)

    @tool
    def query_by_customer_id(customer_id: str) -> list:
        """只查客戶"""
    
    @tool
    def query_by_status(status: str) -> list:
        """只查狀態"""
    
    @tool
    def query_by_date_range(start: str, end: str) -> list:
        """只查日期"""
    
    # ... 還有 10 個工具

    問題:

    • Claude 要調用 3-4 次工具才能完成一個查詢
    • 延遲高、成本高
    • Claude 要自己 join 結果,容易出錯

    ✅ 工具適中(語義相關的組合)

    @tool
    def get_customer_order_status(customer_id: str, order_id: str = None) -> dict:
        """查客戶的訂單,可選篩選特定訂單"""
        # WHERE customer_id = ? AND (order_id = ? if provided)
    
    @tool
    def get_orders_by_date(start_date: str, end_date: str) -> list:
        """查某個時間範圍的訂單"""
        # WHERE created_at BETWEEN ? AND ?
    
    @tool
    def get_orders_by_status(statuses: list) -> list:
        """查特定狀態的訂單"""
        # WHERE status IN (...)

    優勢:

    • 每個工具有單一職責(符合 SOLID 原則)
    • Claude 能清楚理解用途
    • 通常 1-2 次調用完成查詢
    • 參數數量合理(不超過 3-4 個)

    工具粒度判斷清單

    設計工具時,問自己這些問題:

    判斷點 好的工具 差的工具
    工具名能清楚表達意圖嗎? get_orders_by_customer() query_db()
    參數數量 < 4 個 > 5 個
    Claude 能猜到用途嗎? 「我看到名字就知道查什麼」 「我完全不知道這是什麼」
    通常多少次調用完成任務? 1-2 次 3-5 次或更多
    工具代表一個業務概念嗎? 「訂單狀態」「物流追蹤」 「數據庫查詢」「參數組合」

    實際案例:東森分類系統

    ❌ 太大的工具

    @tool
    def search_categories(
        keyword: str = None,
        parent_category: str = None,
        min_products: int = None,
        max_products: int = None,
        active_only: bool = True,
        sort_by: str = "name"
    ):
        """搜尋分類"""
        # 這是什麼?搜分類還是搜商品?太模糊

    ✅ 適中的工具(基於問題驅動)

    @tool
    def search_categories_by_keyword(keyword: str) -> list:
        """用關鍵詞搜分類
    
        例:keyword="運動" → 返回 [運動戶外, 運動服飾, ...]
        """
    
    @tool
    def get_category_children(parent_id: str) -> list:
        """取某分類的子分類"""
    
    @tool
    def get_products_in_category(category_id: str, limit: int = 100) -> list:
        """取分類下的商品"""

    Claude 使用:

    「我要分類一個『防水戶外背包』的商品」
    ↓
    Claude:「我先搜 '戶外' 相關分類」
      → search_categories_by_keyword("戶外")
      → 返回 [運動戶外, 戶外用品, ...]
    
    Claude:「運動戶外 有什麼子類別?」
      → get_category_children("運動戶外")
      → 返回 [登山, 露營, 滑雪, ...]
    
    Claude:「登山 分類有什麼產品,我看看背包在哪」
      → get_products_in_category("登山")
      → 自動判斷這個背包應該是「運動戶外 > 登山」

    Claude 自動組織,不需要你預先決定順序!

    工具粒度的黃金法則

    問自己:「Claude 看著這個工具名和參數,會不會用?」

    • 如果會 → 工具大小合適
    • 如果不會 → 工具太大或太模糊,要拆或改名

    總結:何時遷移到 Agent SDK

    如果你符合以下任何一個,考慮 Agent SDK:

    • 代碼包含 200+ 行 if-elif-else 邏輯
    • 每月都在添加新的處理規則
    • 用戶經常報告「系統沒理解我」
    • 客服系統無法適應變通表達方式
    • 維護成本不斷上升

    核心優勢總結:

    • 代碼行數:500+ → 10(50 倍簡化)
    • 新增規則:改代碼+測試+部署 → 改提示(即時生效)
    • 用戶體驗:生硬規則化 → 自然親切
    • 維護成本:高 → 低

    工具設計思路:

    • ❌ 不要:先設計工具,再找用處
    • ✅ 要:從問題出發,反推需要的工具
    • ✅ 結果:工具精準、完整、易用

    準備好了嗎?下載 Jupyter Notebook,親手測試,然後在你的項目中試用 Agent SDK。

  • Claude Code 完全教學指南

     

    Claude Code:AI 驅動的軟體開發革命

     

    你可能經歷過這個場景:下午 3 點,產品經理說:「客戶要新功能,明天就要。」你打開編輯器,開始敲代碼。腦子裡同時在想:資料庫欄位、API 端點、錯誤處理、邊界情況、測試用例……你一個人在腦子裡跑著整個開發流程。

    Claude Code 改變了什麼?想像你有個高級工程師坐在身邊。你說:「我需要一個使用者認證系統。」他問:「SQL 還是 NoSQL?」你說 PostgreSQL,他立刻開始寫。你看著代碼,說:「這個有漏洞」,他改。整個過程,你只需要說出你想什麼。

    這就是 Claude Code 的核心:

      • 你專注想什麼(目標、邏輯、決策)

      • Claude Code 專注怎麼做(實現、語法、細節)

      • 你可以用一個人的時間,做一隊工程師的工作

    第 1 章:快速入門

    1.1 三分鐘安裝

    macOS

    brew install anthropic/tap/claude-code

    Linux

    sudo apt update && sudo apt install claude-code

    Windows

    從 https://claude.com/download 下載 .exe

    1.2 設定 API 金鑰

      1. 去 https://console.anthropic.com

      1. 登入 → API Keys → Create Key

      1. 複製金鑰(只顯示一次)

      1. 執行:claude config set-key YOUR_KEY

    1.3 第一個對話

    claude

    開始輸入:「寫一個 Python 函數,檢查質數」

    第 2 章:核心概念

    2.1 對話思維

    不是:「寫個登入頁面」(50% 符合)

    而是:逐步談論,每步精煉。第一版 80%,加要求→90%→100%。

    2.2 理解能力邊界

    能看到:你的項目文件、提到的內容、之前的對話

    看不到:其他項目、密碼、網路信息(除非 WebFetch)

    第 3 章:20+ 工具詳解

    3.1 工具分類

    表 1: Claude Code 工具分類速查表

    此表格按功能分類列出 Claude Code 的所有工具。左欄是功能類型(檔案、執行等),中欄是對應的工具名稱,右欄說明每個工具的用途。

    類型 工具 做什麼
    檔案 Read, Edit, Write, Glob 讀、寫、編輯、搜尋文件
    執行 Bash, Pytho 跑代碼,看結果
    搜尋 Grep, Agent 找東西,分析代碼
    版本控制 Git 提交、看歷史、合併
    Web WebFetch, WebSearch 調 API,查信息
    管理 TaskCreate, TaskUpdate 管理任務,追蹤進度

    第 4 章:Skills 與 Workflows

    Skill 是預定義的工作流程。例如 TDD(先寫測試再寫代碼)、Code Review、Debugging、Agent 派遣。

    第 5 章:MCP 插件系統

    MCP:讓 Claude Code 直接連接外部服務(資料庫、Figma、Discord 等)。

    沒 MCP:你說 → Claude Code 生成 → 你複製 → 你跑 → 你粘貼 → Claude Code 分析。太慢。

    有 MCP:一氣呵成,快很多。

    第 6 章:進階用法(用得更好的祕訣)

    6.1 Prompt 工程:怎樣問問題很重要

    同樣的需求,不同的問法,結果天差地別。看這個對比:

    表 2: Prompt 範例對比 – 如何提問更好

    此表格展示同一個需求的三種提問方式。用來學習如何寫出高質量的 prompt。

    維度 壞問題 好問題 結果差異
    問題 「寫個登入頁面」 「Vue 3 + TypeScript 的登入頁面,記住我、3 次失敗鎖定、Tailwind CSS」
    Claude Code 需要猜的東西 框架?UI 庫?功能?設計?認證方式? 全都說了,不用猜
    生成的代碼符合度 ~50% ~100% 提升 50%
    你需要改的次數 5-6 次 0-1 次 省時間 80%
    Token 消耗 5000+ tokens 1500 tokens 省 70%
    總時間 35 分鐘 5 分鐘 快 7 倍

    「好問題」的三要素 + 對比表

    表 3: 好 Prompt 的三個必要元素

    此表格拆解一個優秀 prompt 的三個要素。用來檢查自己的 prompt 是否齊全。

    要素 例子 為什麼重要
    上下文 「我在寫後台管理系統,Vue 3 + TypeScript」 Claude Code 知道框架、語言、用途。消除最大的猜測。
    具體需求 「功能:用戶名 + 密碼、記住我、錯誤提示」 功能清單,一項一項。不用用戶去想「還要什麼」。
    約束條件 「UI:Tailwind CSS、安全:防 XSS」 限制技術選擇,防止 Claude Code 過度設計。

    6.2 Context 管理:怎樣讓 Claude Code 聚焦

    Context 聚焦的三層級對比

    表 4: Context 管理 – 不同範圍的效能對比

    此表格比較不同 Context 範圍的效率和品質。用來決定每次應該給 Claude Code 多少上下文。

    層級 範圍 Context 大小 執行速度 答案品質 何時用
    全項目 所有 780 個文件 50,000+ tokens ⏱️ 很慢 ⭐ 60% 罕見,只在架構設計
    一個模塊 src/orders/(~50 個文件) 5,000 tokens ⏱️⏱️ 中等 ⭐⭐⭐⭐⭐ 95% 大部分工作,推薦
    一個文件或函數 getOrders()(~30 行) 500 tokens ⏱️⏱️⏱️ 瞬間 ⭐⭐⭐⭐⭐ 99% 精細調整、除錯

    經驗法則:項目 <50 個文件 → 全項目沒問題 | 50-500 → 聚焦模塊 | >500 → 聚焦文件/函數

    6.3 性能優化:寫出快速的代碼

    案例:交易策略回測的優化過程

    表 5: 真實案例 – 性能優化的具體耗時

    此表格展示交易回測項目從 5 分鐘優化到 3 秒的完整過程。用來了解 Claude Code 的實際優化效果。

    版本 實現方法 執行時間 加速倍數 瓶頸
    v1(原始) 三層 Python 迴圈 5 分 0 秒 1x CPU 單核執行 1.25M 次迭代
    v2(矢量化) NumPy 矢量操作 8 秒 37.5x 記憶體讀取
    v3(並行) NumPy + 多進程 3 秒 100x 磁碟 I/O
    v4(快取) v3 + LRU 快取 1.5 秒 200x 實時使用可行

    常見優化模式的效果對比

    表 6: 常見優化技巧的效果對比

    此表格列出開發中常用的優化技巧和預估加速倍數。用來評估哪些優化最值得做。

    優化模式 應用場景 典型加速 實現難度 何時用
    迴圈 → 矢量化 批量計算、數據處理 10-100 倍 Python 迴圈跑得慢
    重複計算 → 快取 同一數據多次計算 5-50 倍 看到重複 print 語句
    全表掃描 → 索引 資料庫查詢 100-1000 倍 WHERE 很慢
    同步 → 非同步 網路請求、I/O 3-10 倍 等待外部服務
    串行 → 並行 獨立計算 2-8 倍 多核 CPU 閒置

    6.4 成本優化:不浪費 Toke

    典型操作的 Token 消耗

    表 7: Token 成本速查表 – 常見操作的費用

    此表格列出日常開發操作的 token 消耗和估算成本。用來計算:「這個任務要花多少錢?」

    操作 典型 Token 數 成本(Opus) 優化方式
    讀一個小文件(<1KB) 50-100 $0.0002 只讀需要的部分
    寫一個函數 500-1000 $0.002 一次寫多個相關函數
    修改一個文件 1000-2000 $0.005 一次改多處,不要改多次
    讀整個大項目 5000-10000 $0.02 聚焦到一個模塊
    派遣一個 Agent 2000-5000 $0.01 只在真的需要時派遣

    模型選擇指南(按任務類型)

    表 8: 模型選擇指南 – 按任務類型選用 Opus/Soet/Haiku

    此表格幫助選擇合適的 Claude 模型。用來回答「我應該用 Opus 還是 Soet?」

    模型 價格 速度 推薦用途 例子
    Opus $3/$15 ⏱️ 慢 架構決策、複雜邏輯、Code Review 「檢查系統的認證設計」、「找性能瓶頸」
    Soet $3/$15 ⏱️⏱️ 中等 一般代碼生成、改 bug、寫測試 「寫登入頁面」、「修復崩潰」、「寫單元測試」
    Haiku $0.8/$4 ⏱️⏱️⏱️ 快 搜索、讀文件、簡單改動、查詢 「找所有 API 端點」、「讀這個文件」、「改個變量名」

    第 7 章:踩坑指南(學到的血淚教訓)

    7.1 常見失敗模式速查表

    表 9: 常見失敗模式 – 新手容易踩的 8 個坑

    此表格列出使用 Claude Code 最常見的失敗場景和解決方案。用來快速診斷「為什麼我的結果不對?」

    失敗模式 症狀 根本原因 修復方案 預防檢查
    期望太高 想讓 Claude Code 寫整個平台,結果亂七八糟 把 Claude Code 當自動化工廠,不是思考夥伴 拆解成小功能,逐步迭代 □ 功能清單有多於 5 個嗎?拆小。
    Context 爆炸 回答很差,執行很慢 讀了整個大項目,context 滿了 聚焦到一個模塊或文件 □ Context 有超過 5000 tokens 嗎?聚焦。
    不驗證結果 上生產後才發現 bug 沒跑代碼驗證,直接相信 Claude Code 讓 Claude Code 跑代碼,看實際輸出 □ 你跑過這段代碼嗎?沒有就先跑。
    安全忽視 API 沒認證,客戶能查別人數據 沒明確提出安全需求 明確列出安全要求(認證、防注入、加密) □ 有提到「安全」「認證」「防護」嗎?
    被建議騙了 按 Claude Code 的建議做,結果更複雜 建議太通用,不適合你的場景 提供約束條件(預算、人力、規模) □ 有說明你的約束條件嗎?

    7.2 真實項目教訓對比表

    表 10: 血淚教訓 – 真實項目中的失敗案例

    此表格記錄實際項目中發生過的重大問題和解決方案。用來學習別人的教訓。

    項目 問題 症狀 修復 教訓
    SimpleEC OMS Agent Team OOM 當機 派遣 9 個 Opus Agent,機器 16GB 記憶體爆炸 分批執行,一次 3-5 個 Agent 消耗 ~1.5GB 每個,要算好預算
    iDempiere 動態查詢失敗 SQL 查詢經常報「Unknown column」錯誤 先查詢 schema,確認欄位名 複雜系統要讀文檔,不要假設
    交易策略 優化後結果不一致 矢量化快 37 倍,但數字精度不同 優化前鎖定正確性,改後驗證 性能優化要漸進,不要一下改太多

    7.3 成本 & ROI 實際數字

    表 11: 成本與投資回報 – 真實項目的數字

    此表格列出真實項目的成本構成和投資回報。用來評估投資 Claude Code 是否值得。

    項目 代碼量 對話次數 Token 消耗 成本 節省時間 ROI
    SimpleEC OMS 50,000 行 500 次 5M tokens $20 200 小時(2 個月 → 2 週) 10 倍
    iDempiere 自訂 30,000 行 300 次 2M tokens $8 100 小時 12 倍
    交易策略 10,000 行 100 次 500K tokens $2 40 小時 20 倍

    結論:Claude Code 成本微乎其微(單項目 $2-20),但節省的時間是數週到數月。任何項目 ROI 都在 10 倍以上。

    7.4 避坑檢查清單

    表 12: 預發布檢查清單 – 交付前必檢項目

    此表格是交付代碼前的檢查清單。用來確保代碼質量和完整性。

    階段 檢查項目 不檢查的後果
    需求定義 ☐ 明確上下文(「我在做什麼項目」) Claude Code 猜測,符合度 50%
    ☐ 列出功能清單(一項一項) 遺漏功能,改多次
    ☐ 說出約束條件(性能、安全、技術棧) 實現不符需求,推倒重來
    實現階段 ☐ 聚焦 Context(「現在只看這部分」) Context 爆炸,品質下降 70%
    ☐ 讓 Claude Code 跑代碼驗證 Bug 進入生產,客戶投訴
    ☐ 關鍵改動要提交(不要等全部完成) 一個地方出錯,整個項目回滾
    優化階段 ☐ 明確性能要求(「<100ms」不是「儘量快」) 優化方向錯誤,白費力氣
    ☐ 優化後驗證正確性一致 快了但結果錯了,worse than before
    團隊協作 ☐ Agent Team 控制數量(最多 5 個) 資源耗盡,OOM 當機
    ☐ 監控成本(知道 token 消耗) 一個月花 $500 都沒發現

    7.5 遇到問題的除錯決策樹

    代碼不工作?按這個順序診斷:

    代碼崩潰?n  ├─ 是 → 看錯誤信息(線索在這)n  │       ├─ 語法錯誤? → 讓 Claude Code 修n  │       ├─ Runtime 錯誤? → 隔離問題,寫個最小測試n  │       └─ 邏輯錯誤? → 跑 debug 代碼,看變量值n  │n  └─ 否(運行但結果錯)→ 對比預期 vs 實際n          ├─ 部分錯? → 這部分代碼邏輯問題n          ├─ 都錯? → 理解錯誤,回到「需求定義」n          └─ 有時錯? → 邊界條件遺漏,寫測試複現

    金律:「不要瞎猜,運行代碼。」99% 的問題都能通過運行 + 看錯誤 + 寫測試解決。

    第 8 章:Agent Team 協作指南

    8.1 什麼時候用 Agent Team?

    一個 Claude Code 不夠時,就該考慮多個 Agent 分工。

    表 13: 單個 Claude vs Agent Team – 何時升級

    此表格對比單個 Claude Code 和 Agent Team 的應用場景。用來決定是否需要升級到多 Agent。

    特徵 單個 Claude Agent Team
    場景 簡單任務(寫功能、修 bug) 複雜項目(需要並行工作、分角色)
    執行時間 30 分鐘內 1-2 小時或更長
    決策成本 低(你直接說) 中(角色分工、資源預算)
    回報倍數 5-10x(人力) 30-100x(多角色並行)
    實際例子 寫個登入頁面 架構大重構、多模塊並行開發

    判斷法則:

    – 任務可以分成 3+ 個獨立部分? → 考慮 Agent Team

    – 這些部分需要同時進行? → 確定用 Agent Team

    – 部分之間無強依賴? → 完美

    8.2 角色設計:避免混亂和重複

    核心原則

    表 14: Agent Team 設計原則 – 好設計 vs 壞設計

    此表格列出 Agent Team 設計的核心原則和常見錯誤。用來避免設計失誤。

    維度 ✅ 好設計 ❌ 壞設計
    角色數量 3-5 個 9+ 個(資源爆炸)
    職責邊界 清晰、無重疊 模糊、功能重疊
    通信方式 Team Lead 統一協調 每個 Agent 互相溝通(亂套)
    模型選擇 任務匹配(opus/soet/haiku) 都用同一個模型(資源浪費)

    常見角色類型

    領導層:Team Lead(Haiku)n  ├─ 分配任務、協調進度、整合結果n  └─ 不需要高智力,需要協調能力實現層:Developer Agent(Soet)n  ├─ 寫代碼、修 bug、測試n  └─ 需要快速完成、成本敏感研究層:Architect / Researcher(Opus)n  ├─ 設計決策、技術選型、深度分析n  └─ 需要高質量、可容忍慢可選層:QA Agent(Soet)n  ├─ 執行測試、驗證結果n  └─ 提高品質、並行檢查

    角色劃分檢查清單

    □ 每個 Agent 只負責一個邏輯完整的工作(不要分成太細)

    □ 不同 Agent 的職責無重疊(問自己:Agent A 的工作會被 Agent B 做嗎?)

    □ Team Lead 能清楚地把任務分配給各 Agent

    □ Team Lead 有辦法整合各 Agent 的輸出

    □ 總共 ≤ 5 個 Agent(否則資源問題,見 8.3)

    8.3 記憶體控制:避免當機

    資源現狀(16GB 機器)

    表 15: 記憶體預算 – 16GB 機器上的 Agent 配置

    此表格列出每種模型的記憶體消耗和最多同時 Agent 數。用來規劃 Agent Team 的規模。

    Agent 模型 每個消耗 最多同時跑 常見配置
    Opus ~1.0GB 5-6 個 高精度任務
    Soet ~0.6GB 10-12 個 通用實現
    Haiku ~0.4GB 15+ 個 快速搜尋、協調

    2026/3/3 事故根因:同時跑 9 個 Opus Agent → OOM 當機

    記憶體預算公式

    可用記憶體 = free -h 的 available 列 - 2GB(系統保留)需求 = Σ(各 Agent 記憶體) + 0.5GB(Team Lead)✅ 需求 < 可用 → 可以啟動n❌ 需求 ≥ 可用 → 必須分批

    分批策略(超過 5 個 Agent)

    不要同時啟動 9 個 Opus!必須分批:

    批次 1:Agent A + B + C + D + E(5 個)同時跑n        ↓(全部完成)n批次 2:Agent F + G + H + I + J(5 個)同時跑n        ↓(全部完成)n批次 3:Team Lead 整合所有結果

    即時監控命令

    # 檢查系統可用記憶體(秒級更新)nwatch -n 1 'free -h'# 檢查 Claude 進程數(最多不超過 5 個 opus)nps aux | grep claude | wc -l# 如果用 claude-limited(cgroup 限制)ncat /sys/fs/cgroup/memory/claude/memory.limit_in_bytes  # 限制ncat /sys/fs/cgroup/memory/claude/memory.usage_in_bytes  # 實際用量

    8.4 測試策略:避免「虛假成功」

    問題根源

    「測試全過卻 UI 點到抓狂」的本質:測試驗證的不是用戶真正體驗的東西。

    表 16: Mock 陷阱 – 測試環境 vs 真實環境的差異

    此表格說明為什麼本地測試通過但生產環境失敗。用來理解測試策略的重要性。

    差距 測試環境 真實環境 後果
    資料 乾淨 fixtures 髒資料、邊界值 NaN 顯示、閃爍
    執行 同步、可預測 非同步、競態條件 重複提交、資料丟失
    網路 即時或 mock 延遲、超時、失敗 loading 無限轉
    使用者 按劇本操作 快速連點、返回鍵 狀態錯亂、記憶體洩漏

    Mock 的三大致命陷阱

    陷阱 1:Over-mocking(mock 了不該 mock 的)n───────────────────────────────────────njest.mock("../api/auth", () => ({ login: () => "success" }))n❌ 你測的是:「假設 API 永遠正確」n✅ 你應該測:「API 格式改了怎麼辦」陷阱 2:Stale Mocks(mock 跟實作不同步)n────────────────────────────────────n後端改了 userName → displayNamen前端 mock 還返回 userNamen→ 測試過 ✅ 但線上爆炸 ?陷阱 3:Happy Path Only(只 mock 成功路徑)n──────────────────────────n所有 mock 都返回 200 + 完美資料n→ 從不測 401、500、timeoutn→ 用戶看白屏或無限 loading

    前期設計檢查清單

    在開始寫功能前,問自己:

    □ 這個功能會失敗嗎?(網路斷線、伺服器 500、用戶輸入錯誤)

    □ 失敗時怎麼展示錯誤?(空白 vs 友善訊息)

    □ 在網路慢的情況下怎麼工作?(loading、禁用按鈕防重複提交)

    □ 用戶會怎樣濫用?(快速連點、關閉瀏覽器、返回鍵)

    □ 邊界資料怎麼處理?(null、空字串、超大數字)

    這些問題回答不了 → 代碼寫不好 → 測試也救不了

    測試策略三層次(按優先級)

    層級 1:組件集成測試(最重要,投資回報最高)n────────────────────────────────────n✅ 用真實組件、mock API 層(用 MSW,不是 jest.mock)n✅ 測:點擊 → API 呼叫 → 結果渲染n✅ 覆蓋:成功 + 失敗 + loading 狀態n✅ 工具:React Testing Library、@testing-library/user-event層級 2:E2E 測試(關鍵流程)n────────────────────────n✅ 測:登入 → 操作 → 結果n✅ 不要 mock 任何東西(真實後端 + 測試資料庫)n✅ 工具:Playwright、Cypress層級 3:單元測試(純邏輯)n──────────────────────n✅ 純計算函數(格式化、排序、驗證)n✅ 工具函數、資料轉換n❌ 不要測組件內部細節(太脆弱)

    常見功能的測試清單

    登入功能:

    – □ [E2E] 輸入帳密 → 點登入 → 跳轉首頁 → 顯示用戶名

    – □ [集成] 密碼錯誤 → 顯示錯誤訊息

    – □ [集成] 提交時禁用按鈕(防重複提交)

    – □ [集成] 網路超時 → 重試機制

    – □ ❌ 不要 mock router(登入後跳轉是核心行為)

    – □ ❌ 不要 mock localStorage(token 存取就是測試重點)

    支付流程:

    – □ [E2E] 選商品 → 結帳 → 支付 → 成功頁

    – □ [集成] 金額計算:小計 + 稅金 + 折扣 + 運費 = 總計

    – □ [集成] 支付失敗 → 錯誤訊息 + 可重試

    – □ [單元] 折扣碼驗證邏輯

    – □ [E2E] 重複提交防護(連點不會重複扣款)

    8.5 實戰案例:SimpleEC OMS 失敗與修復

    失敗原因:

    – 資料庫連線池沒關閉 → 頻繁操作時耗盡

    – 測試環境用 mock,生產環境真實資料 → 資料格式不同

    – 測試只覆蓋成功路徑 → 沒測過並發競態

    修復步驟:

    1. 新增集成測試(對真實資料庫,測並發場景)

    2. 移除過度 mock(只 mock 第三方 API)

    3. 新增 E2E 測試(真實業務流程)

    結果: 問題率從 15% 降到 2%

    8.6 小結

    Agent Team 三黃金規則:

    1. 角色要清晰 — 不要讓兩個 Agent 做同樣的事

    2. 資源要預算 — 先算再建,分批執行

    3. 測試要前置 — 設計時就考慮失敗情況,不要事後補救

    最後的話: 多 Agent 協作能 100 倍加速工作,但複雜度也倍增。沒有架構設計,光有工具沒用。

    總結

    從入門到精通:8 章的進階路線

    • 第 1-2 章:基礎與核心概念
    • 第 3-4 章:工具與工作流程
    • 第 5 章:系統集成(MCP)
    • 第 6 章:進階技巧
    • 第 7 章:實戰失敗案例
    • 第 8 章:多 Agent 協作

    Claude Code 的價值不在寫代碼有多快,而在於你能專注「想什麼」而不是「怎麼做」。當你掌握了 Agent Team 協作,一個人可以做一個小隊的工作。但記住:強大的工具也需要謹慎使用。