標籤: AI Agent

  • 你的 Agent 不是防火牆:實務安全設計指南

    你的 Agent 不是防火牆:實務安全設計指南

    📌 本文重點

    • Agent 不能當安全邊界
    • 安全控制應落在工具層與基礎設施層
    • 透過分層權限、限額與 Guard 才能安全上線
    • 不要把 production credential 直接塞給 Agent

    很多團隊把「多代理、自動化工作流」直接接到真實帳號、真實金流、真實網路資源上,心裡想的是:

    反正我在 prompt 裡有說「不要亂刪資料、不要轉太多錢」。

    這篇的核心結論是:Agent 絕對不是安全邊界。你不能用「模型會乖乖聽話」來代替 RBAC、限額、rate limit、審計 log 等基本控管。本文用幾個真實事故做反推,給出可以直接套用的安全設計範式與程式碼範例。


    重點說明

    1. 四種常見災難模式

    1. 把 Agent 當人來信任
      PocketOS 的案例:AI coding agent 在 9 秒內刪掉 production DB 和所有備份,原因不是模型「壞」,而是:
    2. 找到 credential
    3. 直接呼叫具破壞性的 delete_database() API
    4. 沒有任何外部限制與二次確認

    💡 關鍵: 真實事故顯示,只要工具層沒有保護,Agent 能在數秒內造成不可逆的系統毀損。

    1. 授予過大、靜態權限
    2. API key 直接給到 Agent:讀寫同一組 credential,沒有 scope、沒有 TTL。
    3. 只想讓 Agent 「查詢」交易紀錄,卻順便給了「轉帳」權限。

    4. 缺乏金額與成本上限

    5. DN42 案例:Agent 為了掃描網路,瘋狂建立雲資源,最後把操作者帳單刷爆。
    6. 銀行 0.01 歐轉帳案例:小額轉帳流程缺乏額外風控,被用來做 prompt injection、流程繞過。

    7. 沒有動作級審計與防護

    8. 沒有 trace:你只看到「Agent 跑了一下」,卻不知道它 call 了什麼 API、帶了什麼參數、花了多少錢。
    9. 無 Guard:任何 prompt 被投餵進來,Agent 都會原樣帶著敏感資料丟到模型或外部 API。

    關鍵結論:不要用 prompt 當防火牆,安全邊界必須落在『工具層 / 基礎設施層』。


    2. 安全設計的技術骨架:分層權限、沙箱、限額、Guard

    可以把 Agent 系統拆成四層來設計安全性:

    1. 工具層(Tool Layer)
    2. 只提供「安全封裝」過的 API 給 Agent。
    3. 明確區分 讀工具寫/破壞性工具
    4. 在破壞性工具外再包一層 Guard + Policy Engine

    5. 執行層(Execution / Sandbox Layer)

    6. Agent 的程式碼 & 工具呼叫,在 容器 / sandbox 中跑,掛上:

      • network egress policy
      • resource quota(CPU / RAM / disk)
      • IAM role with least privilege
    7. 費用與風險控制層

    8. 金額上限:單次指令 / 單日 / 單用戶的金額 cap。
    9. 速率限制:API Gateway 上對 每個工具 設定 QPS / burst。
    10. 執行次數 / token 上限:避免長鏈式工具呼叫刷爆成本。

    11. 觀測與審計層(Observability & Audit)

    12. 每一次工具呼叫都寫入 結構化審計 log
    13. 對異常模式(相同 IP 大量轉帳、長時間掃描某網段)做 alert。
    14. 在銀行/企業內部,審計 log 應能回溯:誰的 Agent、基於哪個工作流、何時、對哪個客戶做了什麼操作

    3. 對你的專案的實際好處

    這些額外的安全設計,對開發者的好處非常直接:

    • 讓你敢開放真實權限給 Agent,而不是永遠卡在 demo 階段。
    • 降低「一次失誤全毀」的 blast radius:即使 Agent 爆走,最多刪一個 tenant 的測試資料,而不是全區 production。
    • 讓合規與內部風控願意放行:有審計、有限額、可追蹤,才有機會上銀行、金融、企業內部關鍵流程。

    💡 關鍵: 安全骨架讓你可以在控制可承受風險的前提下,真正把 Agent 用在 production,而不是停留在展示環境。


    實作範例

    1. 安全的 Tool Schema 設計:讀寫分離 + 強制二次確認

    以銀行轉帳為例,先把工具拆成:

    • get_account_balance(純讀)
    • create_transfer_draft(建立草稿,不真正扣款)
    • confirm_transfer(只接受人類確認 Token)
    // TypeScript: 安全版 tool schema
    
    export const tools = {
      get_account_balance: {
        description: "查詢指定帳戶餘額(唯讀)",
        input_schema: {
          type: "object",
          properties: {
            account_id: { type: "string" }
          },
          required: ["account_id"],
          additionalProperties: false
        },
        // 後端實作會強制用呼叫者的 user_id 做授權檢查
      },
    
      create_transfer_draft: {
        description: "建立轉帳草稿,不會真的送出,會回傳 draft_id 與風險評分",
        input_schema: {
          type: "object",
          properties: {
            from_account: { type: "string" },
            to_account: { type: "string" },
            amount: { type: "number", minimum: 0.01 },
            currency: { type: "string", enum: ["EUR", "USD", "TWD"] },
            note: { type: "string" }
          },
          required: ["from_account", "to_account", "amount", "currency"],
          additionalProperties: false
        }
      },
    
      confirm_transfer: {
        description: "確認既有轉帳草稿,只接受人類確認 token",
        input_schema: {
          type: "object",
          properties: {
            draft_id: { type: "string" },
            user_confirmation_token: { type: "string" } // 只從前端 UI 注入,Agent 拿不到
          },
          required: ["draft_id", "user_confirmation_token"],
          additionalProperties: false
        }
      }
    } as const
    

    重點:

    • Agent 只能從模型側呼叫 get_account_balance / create_transfer_draft
    • confirm_transferuser_confirmation_token 必須來自人類 UI(例如 SMS OTP / 硬體 token),不透過模型。
    • 小額轉帳(例如 0.01 歐)仍要經過風險評分,避免被用來當作 prompt injection 的側信道。

    2. 在 API Gateway / RBAC 層包住 Agent 工具調用

    以下是假想的 API Gateway(以 Kong / Envoy 風格)設定,針對 Agent 工具做 角色 + 限額 控制:

    # gateway-routes.yaml
    
    routes:
      - name: agent-read-tools
        paths: ["/agent-tools/read"]
        methods: ["POST"]
        plugins:
          - name: jwt
            config:
              claims_to_verify: ["exp"]
              key_claim_name: "sub"  # 綁 agent instance id
          - name: acl
            config:
              whitelist: ["agent_read"]
          - name: rate-limiting
            config:
              minute: 120  # 每分鐘最多 120 次工具呼叫
    
      - name: agent-write-tools
        paths: ["/agent-tools/write"]
        methods: ["POST"]
        plugins:
          - name: jwt
          - name: acl
            config:
              whitelist: ["agent_write"]
          - name: rate-limiting
            config:
              minute: 10   # 寫操作極度限流
          - name: request-size-limiting
            config:
              allowed_payload_size: 64  # 防止一次送進超大批次破壞性操作
    

    配合後端 RBAC:

    // Node.js pseudo code: 在工具 handler 中做細粒度 RBAC + 金額限制
    
    function assertWritePermission(ctx: RequestContext, maxAmount: number) {
      if (!ctx.roles.includes("agent_write")) {
        throw new ForbiddenError("Agent has no write permission");
      }
    
      const amount = ctx.body.amount ?? 0;
      if (amount > maxAmount) {
        throw new ForbiddenError("Amount exceeds agent limit");
      }
    }
    
    app.post("/agent-tools/write/transfer", (req, res) => {
      const ctx = getContextFromRequest(req);
    
      // 例如每個 Agent 最高 50 EUR,超過必須走人類流程
      assertWritePermission(ctx, 50);
    
      // ... call internal transfer service
    });
    

    實際好處:你可以很放心地說「Agent 可以幫你轉帳」,但確定它永遠不會幫你一次轉出 10 萬,只會在可承受的風險範圍內操作。


    3. Guard 與敏感資料掃描:避免 Agent 自動外洩機密

    參考 Cursor 等實作,你可以在「呼叫模型前」加上三道 Guard:

    1. Input Guard:掃描要送進模型的內容,找出 API key / 密碼,紅標或遮罩。
    2. Output Guard:掃描模型輸出,要是模型要求「貼上你的私鑰」,直接攔截。
    3. Tool Guard:在執行工具前檢查參數是否違反政策(例如掃描內網、批次刪資料)。

    簡單的 Input Guard 例子:

    # Python pseudo code: input guard
    import re
    
    SECRET_PATTERNS = [
        re.compile(r"sk-[A-Za-z0-9]{32,}"),   # API key 格式
        re.compile(r"-----BEGIN PRIVATE KEY-----[\s\S]+?-----END PRIVATE KEY-----"),
    ]
    
    def redact_secrets(text: str) -> str:
        redacted = text
        for p in SECRET_PATTERNS:
            redacted = p.sub("[REDACTED_SECRET]", redacted)
        return redacted
    
    # 在送給 LLM 前
    prompt = redact_secrets(user_input + context_snippets)
    

    注意:不要只在前端掃,Agent 自己組裝的 context(例如程式碼、log、設定檔)也要過一遍 Guard,不然它會自己把 .env 塞進去。


    4. 審計與異常偵測:之後一定會被問到的東西

    在銀行或企業內部,合規與內審會問的問題通常是:

    • 這筆錯誤的轉帳 / 刪除操作是 哪個 Agent 做的?
    • 它當時看到什麼 context?是誰觸發的?
    • 是否有類似行為持續發生?

    你需要的是動作級審計 log

    {
      "timestamp": "2026-06-13T09:01:23Z",
      "agent_id": "agent-123",
      "user_id": "user-456",
      "workflow_id": "payroll-v2",
      "tool_name": "create_transfer_draft",
      "input": {
        "from_account": "...masked...",
        "to_account": "...masked...",
        "amount": 42.5,
        "currency": "EUR"
      },
      "risk_score": 0.78,
      "policy_decision": "allowed",
      "cost_estimate": {
        "cloud_cost": 0.0004,
        "fee": 0.1
      }
    }
    

    這些 log 可以餵給 SIEM / 內部風控系統,針對:

    • 某 Agent 在短時間內大量建立轉帳草稿。
    • 某工作流突然開始頻繁掃描不應存取的網段(DN42 類似情境)。

    直接做告警或自動降權(例如暫時停用該 Agent 的 write tool)。

    💡 關鍵: 有結構化審計與異常偵測,才能在出事後追責與調整政策,而不是只能事後猜測。


    建議與注意事項

    1. 把「模型可以做什麼」當成風控產品,而不是單純開發功能

    實務上可以這樣落地:

    • 先設計 policy,再設計 tool:例如「Agent 單次轉帳上限 50 EUR、一日累計 200 EUR」,然後才決定工具 API。
    • 把工具視為「風控之後的介面」,而非直接包內部 microservice。

    2. 不要把 production credential 直接塞進 Agent

    常見坑:

    • .env 裡放 DB_URL_PROD,Agent 的 code tool 一掃專案就看到了。

    • 解法:

    • Agent 跑在 專用 service account + IAM role 上。
    • 只能打透過 Gateway / policy engine 包過的 API,不直接碰 DB / message queue。

    3. 把「人類在 loop 裡」當成正式設計的一部分

    • 高風險動作預設需要人類確認
    • 破壞性工具強制 user_confirmation_token
    • UI 上顯示 Agent 的建議,讓使用者點擊確認。
    • 這不是「很土」;在銀行監管語境裡,這叫做 four-eyes principle(雙人覆核),是你讓 Agent 能真正上線的關鍵。

    4. 上線前的簡版安全 checklist

    你可以直接拿這份清單對照專案:

    1. 工具層
    2. [ ] 讀寫工具有清楚分離?
    3. [ ] 破壞性工具是否有二次確認 / 額外 policy?

    4. 權限與憑證

    5. [ ] Agent 使用的 credential 是否有最小權限與有效期限?
    6. [ ] Agent 是否只能透過 Gateway / policy engine 存取內部服務?

    7. 費用與風險上限

    8. [ ] 有設定單次 / 單日金額上限?
    9. [ ] 有 API rate limit / 執行次數 / token cap?

    10. Guard

    11. [ ] 呼叫模型前是否做敏感資料掃描與遮罩?
    12. [ ] Tool 執行前是否跑過 policy check?

    13. 觀測與審計

    14. [ ] 所有工具呼叫都有結構化 log?
    15. [ ] 有針對異常模式的 alert(大量轉帳、大量雲資源建立)?

    只要你把安全邊界畫在這些「實際可控的層」上,而不是畫在 prompt 上,你的 Agent 就能在真實環境裡幫忙做事,而不是在 9 秒內幫你把公司刪掉。

    🚀 你現在可以做的事

    • 審查現有 Agent 工具清單,將讀寫操作拆分並為破壞性工具加上二次確認機制
    • 在 API Gateway 為 Agent 加上角色、rate limit 與金額上限等策略,並實作細粒度 RBAC
    • 為所有 Agent 呼叫流程加入敏感資料 Guard 與結構化審計 log,串接既有監控/風控系統
  • 一行指令組好自己的 AI 代理團隊

    一行指令組好自己的 AI 代理團隊

    📌 本文重點

    • 把每個 Agent 當成可版本控制的 Git repo
    • AGENTS.mdskills/ 拆開角色與能力
    • .agentlas/ 管理記憶與設定,輕鬆切換模型
    • 用一行 CLI 指令生成並維護多代理 AI 團隊

    只用一行指令,你就能建立一個「像程式專案一樣可版本控制」的多代理 AI 團隊,解決長期記憶混亂、每次對話都要重講一遍的痛點。

    參考架構原文(作者在 Reddit 分享):https://www.reddit.com/r/artificial/comments/1twmhya/an_opensource_agent_architecture_that_solves_the/


    核心功能:把 Agent 當成一個 repo,而不是一段 prompt

    這套開源架構的關鍵想法:每個 Agent 是一個 Git 倉庫,而不是存在聊天框裡的一段系統 prompt。

    💡 關鍵: 把 Agent 轉成可版控的 Git repo,可以用熟悉的軟體開發流程(PR、review、版本管理)來調整 AI 行為,而不是每次重寫 prompt。

    1. AGENTS.md:把「人設 + 任務範圍」寫成文件,而不是憑記憶

    AGENTS.md 是這個架構的核心說明書,裡面通常會包含:

    • 每個代理的角色定位
    • 能做什麼(scope) / 不能做什麼(限制)
    • 彼此如何協作(誰丟任務給誰、輸出長什麼樣)

    你可以做的事:

    1. 在任意資料夾新增 AGENTS.md,用這樣的格式寫第一個代理:

    “`markdown
    # Agents

    ## doc_assistant
    – 角色:技術文件整理員
    – 任務:整理長篇文件、產生摘要與目錄
    – 輸出格式:Markdown,必須包含「摘要」「重點條列」「待釐清問題」三段

    ## code_reviewer
    – 角色:程式碼審查員
    – 任務:針對 Pull Request 提出具體修改建議
    – 限制:不直接改動程式,只提出建議與風險說明
    “`

    1. 把這個 repo 推上 Git(GitHub / GitLab),之後團隊改需求只改這份文件。

    2. skills/:把「能力」拆成工具,而不是糊在一大段 prompt 裡

    傳統代理常見問題是:所有指令、規則、流程都揉在一段很長的系統 prompt 中,改一行就怕爆。

    在這個架構裡,每個能力是一個 skill 檔案,放在 skills/ 資料夾,例如:

    • skills/summarize_docs.md:怎麼讀、怎麼切段、輸出格式
    • skills/review_pr.md:審查步驟、要檢查的細項
    • skills/fetch_urls.md:如何抓網頁、處理錯誤

    你可以做的事:

    1. 新增資料夾 skills/,寫一個最小可用的 skill:

    “`markdown
    # summarize_docs

    步驟:
    1. 讀取輸入文件
    2. 把文件拆成 3–7 個主題
    3. 每個主題用 3 行內說清楚

    輸出格式(Markdown):
    – 一句總結
    – 主題列表(子彈點)
    “`

    1. AGENTS.md 裡指定某個 agent 可以使用 summarize_docs 這個 skill。

    3. .agentlas/:把「記憶和設定」存在檔案,而不是模型腦袋

    .agentlas/ 是這套系統自己的設定與記憶資料夾,用來存:

    • 各代理的偏好設定(語氣、輸出格式)
    • 長期記憶索引(不是直接塞進模型,而是存成檔、用時再讀)
    • 已完成任務的 metadata(方便日後追蹤與再訓練)

    這樣的好處是:

    • 不會把所有對話硬塞進「長期記憶」變成噪音
    • 每次執行前可以用規則選擇要載入哪一段內容

    你可以做的事:

    • .agentlas/config.yaml 加上最基本設定(示意):

    yaml
    default_model: claude
    memory:
    enabled: true
    strategy: recent-and-related
    max_items: 50


    適合誰用:3 個具體場景

    1. 文件整理 + 程式碼審查:建立雙代理 pipeline

    目標:

    • 代理 A 整理設計文件
    • 代理 B 以文件為準則,審查 PR 是否符合設計

    你可以怎麼做:

    1. AGENTS.md 定義兩個代理:

    “`markdown
    ## doc_assistant
    – skills: [summarize_docs]

    ## code_reviewer
    – skills: [review_pr]
    – 會先讀 doc_assistant 的輸出再開始審查
    “`

    1. 把專案文件放在 docs/、程式碼在 src/,PR diff 存到 pr/123.patch

    2. 在終端機執行(以架構作者的描述為例):

    bash
    agentlas run doc_assistant "整理 docs/ 裡的文件,產出開發規範摘要"
    agentlas run code_reviewer "根據最新開發規範,審查 pr/123.patch"

    1. 審查邏輯日後有變,就更新 skills/review_pr.md,而不是重新教一次模型。

    2. 資料抓取 + 報表生成:自動化情報小幫手

    目標:

    • 代理 C 負責抓網站、清洗文字
    • 代理 D 讀整理後資料,輸出報表(例如每週競品動態)

    步驟:

    1. skills/fetch_urls.md 寫清楚:怎麼從列表讀網址、輸出 JSON 或 Markdown 表格。

    2. 定義兩個 agent:

    “`markdown
    ## data_collector
    – skills: [fetch_urls]

    ## report_writer
    – skills: [summarize_docs]
    – 輸出格式:週報(含「本週重點」「風險」「下週觀察」)
    “`

    1. 每週只需要:

    bash
    agentlas run data_collector "從 urls.txt 抓內容,輸出到 data/this_week.md"
    agentlas run report_writer "讀 data/this_week.md,生成 weekly_report.md"

    1. 週報模板要改,就改 skills/summarize_docs.md 或另開 skills/weekly_report.md

    3. 多人團隊:把「AI 同事」當成共同維護的 repo

    你可以把這個代理倉庫當成一個共享 AI SOP

    • PM 改 AGENTS.md 描述角色與流程
    • 開發者在 skills/ 補上新的工具使用說明(例如專案腳本、內部 API)
    • 新同事只要 clone 下來,就能直接用同一套 AI 工作流

    實際做法:

    1. 建一個 GitHub repo:company-ai-agents

    2. 定一條規則:

    3. 改 Agent 行為 = 改 AGENTS.md / skills/,必須走 PR 流程

    4. 不再使用的 Agent 要標記 deprecated,避免沒人知道它還在跑

    5. README 裡寫清楚「如何在本機執行 agentlas、如何切換模型」。


    怎麼開始:一行指令 + 接上你習慣的模型

    這個架構的一大好處是:不綁特定模型,可以跑在 Claude Code、Codex、Gemini CLI 等環境。

    💡 關鍵: 架構與模型解耦,讓你能在不改 AGENTS.mdskills/ 的情況下,自由切換到成本更低或能力更強的模型。

    1. 安裝指令(假設已提供 CLI:agentlas

    作者在 Reddit 說明,整套系統可以透過一行安裝:

    pip install agentlas  # 或作者實際提供的套件名稱
    

    接著在任意資料夾初始化:

    agentlas init
    

    這通常會自動產生:

    • AGENTS.md
    • skills/
    • .agentlas/

    你可以做的事:

    • 直接在一個新資料夾跑 agentlas init,把它當成「AI 同事模板專案」。

    2. 接上常見模型:Claude / Codex / Gemini CLI

    根據作者說明,這個架構支援多個 runtime,不鎖在某一家:

    • 想用 Claude:在 .agentlas/config.yaml 設定 runtime: claude_code
    • 想用 OpenAI / Codex:設為 runtime: codex
    • 想用 Gemini CLI:設為 runtime: gemini_cli

    範例設定:

    runtime: claude_code
    model: claude-3-5-sonnet
    api_key_env: ANTHROPIC_API_KEY
    

    你可以做的事:

    1. 先用你現在線上付費的模型(例如 Claude)跑通第一個 agent。

    2. 之後想切換模型,只改 config,不改 AGENTS.mdskills/ 的內容。

    3. 一句描述,讓系統自動幫你生出代理團隊

    根據 Reddit 原文描述,你可以直接用一句話生成整個代理團隊,例如:

    agentlas new "幫我建立一個:整理產品需求文件 + 產出技術任務清單的雙代理工作流"
    

    CLI 會:

    • 生成初版 AGENTS.md(定義 2 個代理)
    • 建好對應的 skills 檔案
    • 幫你填入基本步驟和輸出格式,之後你再微調

    你可以做的事:

    • 先讓工具幫你生一個「80 分」版本,再用 Git 慢慢調整到「95 分」。

    延伸閱讀:為什麼要從「串 prompt」升級到「Agent 專案」?

    如果你還在用 LangChain 式的「串 prompt + 自己管工具 schema」,可以參考這兩篇:

    這套開源架構跟 MCP 的共通點是:都把 Agent 當成一個長期維護的系統,而不是當場臨時寫的 prompt

    差別在於,這裡用「實際檔案 + repo」把行為和記憶拆開,讓你可以用熟悉的 Git 流程維護整套 AI 工作流。

    現在你可以做的最後一件事:

    • 開一個新 repo,跑一次 agentlas init,寫一個最小的 AGENTS.md
    • 選一個你每天真的會用到的小流程(例如「整理會議紀錄」)
    • 把它做成第一個可版本控制的 AI 代理

    之後,每次你覺得「這件事好像可以交給 AI」,就把需求寫進 AGENTS.mdskills/,你自己的多代理 AI 團隊就會越長越完整。

    🚀 你現在可以做的事

    • 在本機建立新資料夾,執行 agentlas init,產出第一版 AGENTS.mdskills/
    • 選一個日常流程(如整理會議紀錄),寫進 AGENTS.md 並建立對應的 skills/xxx.md
    • 建一個 company-ai-agents repo,推上 GitHub,讓團隊透過 PR 共同維護你的 AI 代理 SOP
  • Gemini Spark 實測:讓 AI 幫你24小時跑腿

    Gemini Spark 實測:讓 AI 幫你24小時跑腿

    📌 本文重點

    • Gemini Spark 能在背景執行多步驟任務
    • 可長時間記住上下文並自動接續任務
    • 透過確認機制與權限設計平衡自動化與安全

    用一句話講白:Gemini Spark 就是一個 24/7 在背景幫你跑多步驟任務的 AI 小幫手,不用你一直開著聊天視窗盯著它。

    測試參考:The Verge 的實測與旅遊規劃體驗:Hands-on 1Hands-on 2


    核心功能:跟「傳統聊天機器人」差在哪

    1. 主動在背景幫你跑多步驟任務

    傳統聊天機器人:

    • 你問它才回你
    • 一次只做一小段,關掉網頁就「記憶掰掰」

    Gemini Spark:你給他一個任務,它可以自己在背景跑完多步驟流程,再回來跟你報告。

    實際可以怎麼用:

    • 旅遊規劃 + 比價
      指令示例:

      「幫我規劃 10 月中從台北去東京 5 天家庭旅行,預算中等,要有 2 天親子行程。請:1)找出 3 個機票選項,考慮總飛行時間與轉機;2)比 3 家飯店,近地鐵、評價 4.3 以上;3)做出每日行程表。你可以在背景慢慢查,整理好再一次給我。」

    行動建議:第一次用 Spark 就拿「下一趟旅行」開刀,給它明確條件 + 步驟,讓它自己去跑,體驗差異最大。

    💡 關鍵: Spark 最大差異是能在背景獨立完成多步驟任務,最後一次性給你結果,而不是每一步都要你手動盯著。


    2. 長時間記得你在做什麼,自己幫你接續

    Spark 的另一個重點,是上下文可以拉得比較長,不只是當下這一輪對話。

    它會記得:

    • 你最近在規劃什麼(例如那趟東京行)
    • 你之前給過的偏好(例如「我不想一早就排景點」)
    • 它自己尚未完成的任務

    你可以這樣用:

    「接續之前的東京行程,幫我加上 1 天只逛博物館和書店的行程,然後把所有訂票與景點的連結整理成一封 email 草稿給我。」

    Spark 不用你重新貼所有內容,它自己接上前一次任務,把新要求整合進去。

    行動建議:遇到「要改舊計畫」時,不要重講一遍,直接說「接續上次 XX 任務,幫我多做……」,讓 Spark 幫你維護脈絡。


    3. 重要步驟前會停下來問你

    The Verge 的實測中提到:Spark 在敏感動作前會跳出確認,而不是默默幫你亂動。

    常見的確認點會包括:

    • 寄出 email
    • 變更行事曆
    • 存取新服務或帳號

    使用方式:

    • 把 Spark 想像成「實習生」:
    • 你可以說:「先幫我草擬,不要真的送出。」
    • 或:「這類會議邀請之後可以直接幫我接受。」

    行動建議:第一次設定時,刻意跟它說清楚:

    「所有會寄出去給別人的內容,一律先給我草稿,不要自動送。」

    這樣你就能享受自動化,又不會被它「幫過頭」。


    適合誰用?3 個具體場景

    1. 旅行規劃:從「列點子」變成「整包交辦」

    The Verge 的旅行實測裡,作者說 Spark 是第一個讓他覺得旅遊規劃真的可以交給 AI 的工具,因為它會:

    • 不只列景點,還會看交通、預約限制、開放時間
    • 幫你平衡:太緊湊 / 太鬆、戶外 / 室內、購物 / 觀光

    你可以照抄這個 workflow:

    任務目標:幫我規劃 4 天 3 夜的首爾行程,預算偏省,重點是美食跟咖啡廳。
    限制:
    - 不要一早 9 點前的行程
    - 每天最多排 2 個需要事先訂位的地方
    - 交通以地鐵為主
    請:
    1. 先問我出發時間與大概預算
    2. 自己在背景查資料,整理成表格(時間 / 地點 / 交通 / 必點餐點或特色)
    3. 把所有需要訂位的頁面連結整理,獨立列出清單給我。
    

    行動建議:把旅遊需求拆成「目標+限制+要輸出的格式」,這樣 Spark 做出來的東西比較接近可以直接用的版本。


    2. 跨時區會議統整:讓 Spark 當你的時區翻譯機

    如果你常跟美國、歐洲同事開會,Spark 可以做的事情包括:

    • 幫你把一串 email 往來整理成待辦清單
    • 自動換算時區,找幾個可行的會議時間
    • 產生英文 / 中文雙語的會議邀請草稿

    指令示例:

    「我等等會轉寄給你一整串關於新專案的 email。請幫我:1)整理每個人各自承諾要做的事;2)找出下週台北時間 9:00–11:00、倫敦時間 9:00–18:00 之間都可行的 3 個時間;3)根據這串內容寫一封英文會議邀請草稿給團隊。」

    行動建議:

    • 寫指令時,先描述要的結果,再說你會提供什麼資料(例如會轉寄 email)
    • 用「台北時間」「倫敦時間」等明確描述,避免只寫「我早上」。

    3. 日常代辦追蹤:把「總是忘記回信」交給它

    Spark 比較實用的一點是:它可以「掛在那裡幫你盯」,而不是你想到才去查。

    你可以把它當作:

    • Email 回覆提醒
    • 文件閱讀與摘要助手
    • 日常待辦整理員

    範例指令:

    「從今天開始,幫我追蹤 Gmail 裡標成星號的信:
    1)每天下午 5 點,整理一份『還沒回覆的星號信』列表給我,包含:寄件人、主題、收到時間、你建議的 1 句回覆重點;
    2)對於你有把握的簡單信件,可以先幫我產生回覆草稿。」

    行動建議:

    • 先選「一個小範圍」讓 Spark 幫你追(例如星號信),不要一開始就全信箱開放。
    • 每週檢查一次它生成的草稿,你會越來越知道怎麼跟它講需求。

    優點與限制:實測感受整理

    優點

    • 真的可以放著不管:The Verge 的體驗中,Spark 在你離線時也會繼續查資料、比對選項,最後給你整理好的結果。
    • 願意多問幾句確認:不像很多 Agent 一次衝到底,Spark 會分段跟你確認,讓你改方向。
    • 整合 Google 服務有優勢:像 Gmail、Calendar、Docs 等,對已在 Google 生態系的人尤其方便。

    限制與風險

    • 速度不一定快:多步驟任務,等 5–15 分鐘甚至更久是常態,不適合「立刻要答案」。
    • 隱私顧慮:要讓它看 Gmail、行事曆,等於多了一個能讀你資料的「人」。The Verge 也特別提醒了這點。
    • 目前功能和價格仍在調整中:不同地區可能有功能差異,也可能需要訂閱 Gemini 付費方案才用得到完整版。

    行動建議:

    • 先從「不那麼敏感」的任務測試(旅行規劃、公開資訊整理),習慣它的行為再逐步開放更多權限。

    💡 關鍵: Spark 適合放在「不急但複雜」的任務上,接受它可能要 5–15 分鐘換來的是你少了大量瑣事。


    怎麼開始:開通、免費用到哪裡、權限怎麼設

    以一般個人使用者為例,實際介面可能會隨時間更新,建議以官方說明為準:https://gemini.google/overview/agent/spark

    1. 快速開通與入口

    大致流程會長這樣:

    1. 登入 Google 帳號(建議用你平常收信、排行程那個帳號)。
    2. 前往 Gemini 頁面,找到 Spark 開關或切換(Chat ↔ Spark)
    3. 按提示完成初始設定:
    4. 選擇語言、地區
    5. 勾選同意條款
    6. 決定是否要讓它讀 Gmail / Calendar 等

    行動建議:初次設定時,能跳過的權限先跳過,等確定要用再打開。


    2. 哪裡能免費用到?

    Google 目前的作法通常是:

    • 基本 Gemini 功能提供免費層級
    • 進階功能或高用量則綁定 Gemini Advanced / Google One AI Premium 類型訂閱

    Spark 很可能會:

    • 在部分地區提供測試或限量免費
    • 或綁在付費方案裡,讓你有更高配額與完整 Agent 能力

    行動建議:

    • 先確認你所在的地區是否開放 Spark,並在 Gemini 介面查看是否需要升級方案。
    • 如果有試用期,先集中在那段時間安排幾個「真實任務」給它做,評估值不值得付費。

    3. 權限與通知:好用但不要被吵

    要兼顧方便與不打擾,可以這樣設:

    (1)資料權限:

    • 先只開 Gmail / Calendar 的「讀取」權限,不給「全自動修改」。
    • 明確跟它說:

      「除非我說可以,否則不要自動變更行事曆或寄出任何 email。」

    (2)通知策略:

    • 手機端:
    • 保留「任務完成摘要」通知
    • 關閉「每一步都提醒」的通知
    • 你可以設一個固定時間:

      「每天晚上 9 點幫我整理今天你做了什麼、一件概要就好。」

    行動建議:把 Spark 當成「一天回報一兩次的助理」,而不是 Slack 機器人那樣每十分鐘跳出來吵你。

    💡 關鍵: 先給 Spark 讀取多於寫入的權限,並限制通知頻率,可以在安全邊界內體驗自動化。


    總結:怎麼寫出 Spark 用得懂、又做得好的指令?

    可以記這個模板:

    目標 + 限制條件 + 步驟 / 輸出格式 + 背景運作說明

    範例:

    「目標:整理我這週所有會議記錄,變成一份 1 頁的執行摘要。
    限制:只用我提供的文件,不要自己亂查資料。
    步驟:1)讀完我丟給你的 5 份會議記錄;2)列出所有待辦與負責人;3)寫一段 200 字內的總結。
    背景:你可以在背景慢慢做,完成後一次給我,不用中途打擾。」

    從一兩個小任務開始,習慣這種「把事交給 AI 跑完再回報」的工作方式,你會很快感受到:Spark 的價值不在於多會聊天,而是在於很多你不想做、但又非得有人做的細碎工作,它可以默默幫你扛掉。

    🚀 你現在可以做的事

    • 挑一個即將到來的旅程,照文中的「目標+限制+格式」模板寫一個 Spark 指令
    • 從 Gmail 星號信中選一小段範圍,讓 Spark 嘗試幫你追蹤與產生回覆草稿
    • 依照文中的權限與通知建議,在 Gemini 介面中完成 Spark 的初始設定與權限調整
  • 把 Agent 關進沙盒:SaaS 實戰骨架

    把 Agent 關進沙盒:SaaS 實戰骨架

    📌 本文重點

    • Agent 要被關在嚴格 sandbox 與工具層裡
    • 記憶要分層,記流程不記祕密資訊
    • 用事件流與回放讓 Agent 可觀察、可控

    在 SaaS 裡塞一個 AI Agent,難點不是「會不會寫 prompt」,而是如何讓它在有限權限下,持久又安全地幫你自動化真實工作流程。沒 sandbox、沒記憶設計的 Agent,只適合做 demo:一旦上線,就會變成「拿著 admin key 的高智商腳本小孩」。

    這篇從 AI Agent Sandboxing for SaaSAI Agent Memory for SaaS 的思路出發,拆成你實作時一定會遇到的四個骨架:

    1. 權限與邊界:sandbox + 能力分級 + 審計/回放
    2. 記憶設計:短期 vs 長期組織記憶 + 何時忘記
    3. 資料模型與基礎設施:event sourcing + 任務關聯 + RAG 整合
    4. 開票/CRM 更新 Agent 實作雛形與踩坑清單

    重點說明


    1. Sandboxing:把 Agent 關在「業務安全區」裡

    目標:讓 Agent 有用,但永遠拿不到 root 权限

    💡 關鍵: 先設計權限邊界,再讓 Agent 介入,才能避免它變成拿著 admin key 的「高智商腳本小孩」。

    核心做法:

    1. 能力分級(建議至少三層)
    2. read-only:只能查詢 / 檢索(查訂單、查發票、查 CRM)
    3. scoped-write:限制在特定資源 + 明確條件(只能建立 invoice 草稿、只能改自己 owner 的 lead)
    4. admin-like:極少數動作(例如退款、刪除發票),預設關閉,需人工審批或 feature flag

    5. 工具層 sandbox(而非讓 LLM 直呼 DB / 外部 API)

    6. 對 LLM 暴露的是受控工具 API,例如:AgentTools.create_invoice_draft,而不是 POST /invoices 原始 API
    7. 工具層做 參數校驗、權限檢查、rate limit、審計 log

    8. 可回放測試 / 審計 log

    9. 每次 Agent 決策,記錄:
      • tool_call(名稱 + 參數)
      • 結果摘要(避免 log 泄露敏感資料)
      • 關聯 user_id / org_id / conversation_id / task_id
    10. 可以在 staging 用「回放同一串 event」重跑一遍,驗證升級後模型或 prompt 不會炸庫。

    2. 記憶設計:記住工作流,不記住祕密

    實務上可以拆成三層記憶:

    1. 短期上下文(working memory)
    2. 單次任務/對話的上下文,存在 conversation_state 或臨時向量 store
    3. 存活時間:幾分鐘到幾小時,任務結束後視情況壓縮成事件摘要

    4. 長期組織記憶(org memory)

    5. 公司政策、常見流程、產品價目表、範本回覆
    6. 存在 RAG + metadata(org_id, version, valid_from, valid_to)
    7. 修改政策時不覆蓋舊文,而是加新版本 + 標記舊版過期

    8. 個人偏好 / 使用者設定

    9. 比如:某 Sales 喜歡用英文回 mail、預設稅率 5%
    10. 存在 user_preferences 表或 key-value store,與 org policy 分離

    「何時該忘?」幾個實務策略:

    • 預設不把 user prompt 原文存成長期記憶,只保存「必要摘要 + 事件」,例如:
    • ❌ 存「請幫我開票給 XX 公司,統編 12345678,地址是…」
    • ✅ 存「2025-06-01 開立發票 INV-001, buyer=XX 公司, amount=10,000, owner=user_123」
    • retention policy
    • 短期記憶(對話內容)保留 30 天,之後只留聚合統計 / 匿名化摘要
    • 向量記憶可定期跑 job:找到稠密但從未被命中的 embedding → 刪除或降精度存儲

    💡 關鍵: 記憶層只存「去敏的業務事件」,既符合隱私需求,又保留足夠資訊讓 Agent 持續學習與優化。


    3. 資料模型與基礎設施:把 Agent 行為變成事件流

    為了可觀察、可回放,建議用輕量的 event sourcing 思路

    • agent_sessions:一次使用者啟動 Agent 的 session
    • agent_tasks:對應一個業務任務(例如「為 ticket#123 建立 invoice」)
    • agent_events:細顆粒度事件(tool call、LLM decision、error)

    搭配:

    • conversation_id:對話 thread ID(多輪聊天)
    • task_id:業務任務 ID(可以跨多個對話)
    • org_id / user_id:用來分庫、分 tenant、做權限控制

    與現有 DB/RAG 的整合方式

    • 業務資料留在原本的 transactional DB
    • Agent 不直接 query DB,而是走你包好的 BusinessAPI 或工具層 microservice
    • 長期記憶 / 知識庫:用 RAG(可參考 jamwithai/production-agentic-rag-course 的 patterns),但:
    • 純「查詢」→ read-only 工具
    • 「根據 RAG 結果改資料」→ 一律走 scoped-write 工具並寫 event log

    💡 關鍵: 把 Agent 所有操作轉成事件流,才能事後追蹤、審計與在 staging 做「重放實驗」。


    實作範例:開票/CRM 更新 Agent 雛形

    下面用 pseudo code 展示一個典型「讀 ticket → 建發票草稿 → 更新 CRM」的 sandbox + memory schema。


    1. 工具層 sandbox 定義

    // 工具層:只暴露給 Agent 這些「安全操作」
    
    interface AgentContext {
      orgId: string;
      userId: string;
      role: 'read_only' | 'scoped_write' | 'admin';
      taskId: string;
    }
    
    class AgentTools {
      constructor(private ctx: AgentContext) {}
    
      // 讀取支援 ticket(read-only)
      async getSupportTicket(ticketId: string) {
        assertRole(['read_only', 'scoped_write', 'admin'], this.ctx.role);
        const ticket = await TicketService.getById(this.ctx.orgId, ticketId);
        await AgentAudit.log({
          type: 'tool_call',
          tool: 'getSupportTicket',
          ctx: this.ctx,
          input: { ticketId },
          outputSummary: { status: ticket.status }, // 避免 log 敏感內容
        });
        return ticket;
      }
    
      // 建立發票「草稿」而非正式發票(scoped-write)
      async createInvoiceDraft(payload: {
        ticketId: string;
        customerId: string;
        amount: number;
        currency: string;
      }) {
        assertRole(['scoped_write', 'admin'], this.ctx.role);
    
        // 額外安全檢查:金額上限、防重複開票
        if (payload.amount > 10000) throw new Error('amount_exceeds_limit');
        await BusinessRules.ensureNoDuplicateDraft(
          this.ctx.orgId,
          payload.ticketId,
        );
    
        const invoice = await InvoiceService.createDraft({
          ...payload,
          orgId: this.ctx.orgId,
          createdBy: this.ctx.userId,
        });
    
        await AgentAudit.log({
          type: 'tool_call',
          tool: 'createInvoiceDraft',
          ctx: this.ctx,
          input: payload,
          outputSummary: { invoiceId: invoice.id },
        });
    
        return invoice;
      }
    
      // 更新 CRM:只允許更新部分欄位
      async updateCrmLead(leadId: string, patch: { status?: string }) {
        assertRole(['scoped_write', 'admin'], this.ctx.role);
        const safePatch = pick(patch, ['status']); // 避免 Agent 任意改 email 等敏感欄位
    
        const lead = await CrmService.updateLead(this.ctx.orgId, leadId, safePatch);
        await AgentAudit.log({
          type: 'tool_call',
          tool: 'updateCrmLead',
          ctx: this.ctx,
          input: { leadId, patch: safePatch },
          outputSummary: { status: lead.status },
        });
    
        return lead;
      }
    }
    

    2. Agent 任務流程(記憶與事件流)

    // 啟動一個 Agent 任務:從 ticket 開票 + 更新 CRM
    
    async function runInvoiceAgent(params: {
      orgId: string;
      userId: string;
      ticketId: string;
    }) {
      const taskId = await AgentTaskStore.create({
        orgId: params.orgId,
        userId: params.userId,
        type: 'INVOICE_FROM_TICKET',
        status: 'running',
      });
    
      const ctx: AgentContext = {
        orgId: params.orgId,
        userId: params.userId,
        role: 'scoped_write',
        taskId,
      };
    
      const tools = new AgentTools(ctx);
    
      // event sourcing:每一步都寫入 agent_events
      await AgentEventStore.append({
        taskId,
        type: 'task_started',
        payload: { ticketId: params.ticketId },
      });
    
      // 1) LLM 讀 ticket + 商業規則摘要(短期記憶)
      const ticket = await tools.getSupportTicket(params.ticketId);
    
      const policyDocs = await OrgPolicyRAG.search({
        orgId: params.orgId,
        query: '開立發票規則',
        topK: 3,
      });
    
      const llmInput = buildPrompt({ ticket, policyDocs });
    
      const llmDecision = await LLM.chatCompletion({
        model: 'gpt-4.1-mini',
        tools: [
          { name: 'createInvoiceDraft', schema: InvoiceDraftSchema },
          { name: 'updateCrmLead', schema: CrmPatchSchema },
        ],
        messages: [
          { role: 'system', content: SYSTEM_PROMPT },
          { role: 'user', content: llmInput },
        ],
      });
    
      await AgentEventStore.append({
        taskId,
        type: 'llm_decision',
        payload: safeDecisionLog(llmDecision),
      });
    
      // 2) 根據 LLM 決策安全執行工具
      const result = await ToolExecutor.run(llmDecision, tools);
    
      // 3) 將任務摘要存入長期「事件記憶」(去敏 + 可查詢)
      await AgentMemoryStore.saveTaskSummary({
        orgId: params.orgId,
        taskId,
        type: 'INVOICE_TASK_SUMMARY',
        summary: buildTaskSummary({ ticket, result }),
        // 設定過期策略:例如 180 天後自動清除
        expiresAt: dayjs().add(180, 'day').toDate(),
      });
    
      await AgentTaskStore.update(taskId, { status: 'completed' });
    
      return result;
    }
    

    3. Memory Schema(簡化版)

    -- 任務層級摘要,作為長期「安全記憶」
    CREATE TABLE agent_task_memory (
      id            BIGSERIAL PRIMARY KEY,
      org_id        VARCHAR(64) NOT NULL,
      task_id       VARCHAR(64) NOT NULL,
      type          VARCHAR(64) NOT NULL,
      summary_json  JSONB NOT NULL,   -- 已去識別 / 去敏的摘要
      created_at    TIMESTAMP NOT NULL DEFAULT now(),
      expires_at    TIMESTAMP NULL,
      INDEX idx_org_type_created (org_id, type, created_at)
    );
    
    -- 事件流,用於回放與審計
    CREATE TABLE agent_events (
      id            BIGSERIAL PRIMARY KEY,
      org_id        VARCHAR(64) NOT NULL,
      task_id       VARCHAR(64) NOT NULL,
      event_type    VARCHAR(64) NOT NULL, -- tool_call / llm_decision / error ...
      payload       JSONB NOT NULL,
      created_at    TIMESTAMP NOT NULL DEFAULT now(),
      INDEX idx_task_created (task_id, created_at)
    );
    

    建議與注意事項


    1. 常見踩坑

    1. 讓 Agent 拿到全庫 query 能力
    2. 例如暴露 run_sql(query) 這種工具 → 等於給 LLM 一把 DB root key
    3. 建議:只提供具體業務操作工具get_invoice_by_id / create_invoice_draft),不提供自由 SQL / 任意 filter

    4. 把 user prompt 直接當長期記憶存

    5. 風險:
      • 敏感資訊(住址、email、信用卡後四碼)被永久 index
      • 未來 RAG 檢索時把別人對話調出來
    6. 解法:只存事件摘要(例如:某天完成一筆開票),prompt 原文只能在短期 log / 加密 log 中保留,並設明確 retention

    7. 沒有 rollback / dry-run 機制

    8. Demo 時一切完美,上線後改個 prompt 就開始亂開票
    9. 建議:

      • 預設跑在 dry-run / shadow mode:只寫 event,不真正寫 DB,由人審批
      • 對高風險操作(刪除、退款)設計 雙階段提交流程:Agent 產生建議 → 人按下「Apply」才真正執行
    10. 把政策寫死在 prompt

    11. 政策一變,所有 Agent 行為都過期,但你不知道是哪個版本出的錯
    12. 建議:政策存 RAG / config store,prompt 只說「請依據最新的 org policy 回應」,並在 log 記錄使用的 policy_version_id

    2. 實戰建議(可直接用在專案裡)

    1. 先只讓 Agent 操作「草稿」資源
    2. 如範例:createInvoiceDraft,由人類在 UI 裡確認後再正式開票
    3. 這個模式在導入初期可以快速建立信任,也方便收集訓練資料

    4. 每個 Agent 任務都要有 task_id + org_id + user_id

    5. 方便之後做:

      • per-org 行為分析
      • 問題排查:「這張錯誤發票是哪個 Agent 任務生成的?」
      • 回放測試:「重跑這個 task,看新版模型會不會做出不一樣決策」
    6. 記憶層要先畫邊界,再決定用什麼向量庫

    7. 問自己三件事:
      • 哪些東西必須記一輩子(例如:已開立的發票、客戶同意條款紀錄)
      • 哪些只需要短期記憶(例如:這週正在處理的 ticket 狀態)
      • 哪些不該記(例如:一次性敏感資訊)
    8. 然後才決定:哪些用 transactional DB、哪些進向量庫、哪些只當 log 放 object storage + TTL

    9. 用事件流做 A/B 測試與回放

    10. 有了 agent_events 後,可以:
      • 在 staging 重播同一串事件,切不同模型 / prompt
      • 比較產生的 tool call 是否差異過大
      • 逐步從 demo 模式 → 實際寫入模式

    整體來說,把 Agent 裝進 SaaS,不是再多寫幾個工具函式,而是要把它當「受控的自動化子系統」來設計:

    • 用 sandbox 做權限邊界
    • 用多層記憶管理上下文與風險
    • 用事件流與回放讓它可觀察、可演進、可 debug

    一旦這套骨架打好,你的 SaaS 就可以從「有個聊天盒子」升級成「能自己處理開票、更新 CRM、遵守政策的半自動業務夥伴」。


    🚀 你現在可以做的事

    • 在現有 SaaS 服務中先列出所有「只允許草稿」的業務操作,設計對應的 scoped_write 工具層 API
    • 為你的 Agent 任務加上 task_id / org_id / user_idagent_events 表,開始記錄並觀察事件流
    • 審視目前有哪些資料被長期保存為向量或日誌,整理一份「應改成事件摘要、需設定 TTL」的清單並排入技術債處理計畫
  • 用狀態機把 13GB 小模型變成工程實習生

    用狀態機把 13GB 小模型變成工程實習生

    📌 本文重點

    • 小模型別當全能 Agent,要當被流程管控的小工
    • 用顯式狀態機拆任務,大幅提升穩定性與可回滾性
    • 每步輸出 JSON + schema 驗證,讓小模型也能穩定改碼

    只靠 prompt 堆疊,13GB 本地模型在中大型改碼任務幾乎必翻車:上下文飄掉、一次回錯一堆檔、改到一半忘記需求。把模型包進顯式狀態機,把「一次大任務」拆成可恢復的子任務,可以在不改模型的前提下,大幅提升穩定性、可觀測性與可測試性——正是那篇 13.8GB 模型從 2/10 變成 10/10 的核心做法。

    💡 關鍵: 只改調用方式與流程設計,就能把同一顆 13.8GB 小模型的表現從 2/10 拉到 10/10。


    重點說明

    1. 小模型為什麼在長對話裡特別容易翻車?

    從工程視角,有三個根本原因:

    1. token 預算太小 + 資訊密度太高
      13GB 級(多是 7B〜13B 參數)在 4k–16k context 內要同時塞:需求、專案結構、幾個檔案內容、測試結果、對話歷史,關鍵訊息會被截斷或壓縮到模型抓不到

    2. 上下文漂移(context drift)
      多輪長對話時,你不可能每次都重貼完整需求與檔案。模型只能靠「語意回憶」之前說過什麼,多輪後任務邊界就開始模糊:忘記原本的 constraint、改到不該動的檔案、把舊 bug 當新需求。

    3. 一次性決策成本過高
      傳統「一條大 prompt + chain-of-thought」會在單輪裡要求:理解需求 → 找檔 → 設計改動 → 寫碼 → 自我檢查。這在 token 限制與小模型推理能力下,極易在中間任一步 hallucinate,之後又沒有明確的 rollback 機制。

    關鍵結論: 小模型不適合當「一次性全能 Agent」,更適合當「被嚴格流程控制的小工」,讓狀態機負責 long-term 記憶與決策邊界。

    💡 關鍵: 把 long-term 記憶與流程決策交給狀態機,小模型只做局部推理,能顯著降低翻車率。


    2. 用顯式狀態機拆解大任務:核心設計

    把「改造一個中小型專案」拆成明確的 State + Transition

    常見狀態設計可以是:

    1. DISCOVER_PROJECT:掃描 repo、建立檔案索引
    2. PLAN_CHANGE:根據需求與索引產生修改計畫(檔案清單、步驟)
    3. EDIT_FILE:逐檔案修改(step-by-step)
    4. RUN_TESTS:執行測試、收集結果
    5. ROLLBACK_OR_FIX:測試失敗→嘗試修復或回滾
    6. DONE / FAILED:終止狀態

    每個狀態都只給模型 極簡上下文 + 明確輸入/輸出 schema,例如在 EDIT_FILE

    • 輸入:
    • 需求摘要(短)
    • 該檔案目前內容(或片段)
    • 計畫中對此檔案的變更描述
    • 輸出:
    • 結構化 JSON:{"status": "ok|skip|abort", "patch": "...diff..."}

    轉移條件示例:

    • DISCOVER_PROJECTPLAN_CHANGE:索引成功建立
    • PLAN_CHANGEEDIT_FILE:生成的計畫通過 schema 檢查
    • EDIT_FILERUN_TESTS:所有目標檔案處理完
    • RUN_TESTS
    • 全綠 → DONE
    • 有失敗 + 可定位 → EDIT_FILE (targeted fix)
    • 多次失敗 → ROLLBACK_OR_FIX

    失敗重試策略與超時機制

    • 每個狀態設定 max_retries,例如 2–3 次,超過則標記為 FAILED 或轉 ROLLBACK_OR_FIX
    • 每次 LLM 回應必經:
    • JSON schema 驗證
    • domain guard(例如禁止刪除大量無關 code)
    • 超時機制
    • 單次呼叫 timeout(例如 60s),保障工作流不被卡死
    • 整個工作流 wall-clock timeout(例如 30 分鐘),方便在 CI 或自動化工具中運行

    💡 關鍵: 把重試、超時、回滾寫死在狀態機邏輯裡,比指望 prompt 提醒模型「要小心」可靠太多。


    3. 實作範例:13GB 本地模型改造專案(Python)

    以下是精簡版 pseudo-code,示範如何把本地模型包在狀態機裡,跑 step-by-step 編碼、測試與回滾。假設:

    • 使用 vLLM / llama.cpp server 暴露出 OpenAI-compatible API
    • GPU:3060 12GB,模型用 Q4 / Q5 量化
    import enum
    import json
    import subprocess
    from dataclasses import dataclass
    from typing import Dict, Any, List
    import requests
    
    OPENAI_BASE = "http://localhost:8000/v1"
    MODEL_NAME = "local-13b-q4"
    
    class State(enum.Enum):
        DISCOVER_PROJECT = "DISCOVER_PROJECT"
        PLAN_CHANGE = "PLAN_CHANGE"
        EDIT_FILE = "EDIT_FILE"
        RUN_TESTS = "RUN_TESTS"
        ROLLBACK_OR_FIX = "ROLLBACK_OR_FIX"
        DONE = "DONE"
        FAILED = "FAILED"
    
    @dataclass
    class Context:
        repo_path: str
        requirement: str
        file_index: Dict[str, Any] = None
        plan: List[Dict[str, Any]] = None
        current_file_idx: int = 0
        test_result: str = ""
    
    
    def call_llm(system_prompt: str, user_prompt: str, max_tokens: int = 1024) -> str:
        resp = requests.post(
            f"{OPENAI_BASE}/chat/completions",
            json={
                "model": MODEL_NAME,
                "messages": [
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_prompt},
                ],
                "temperature": 0.2,
                "max_tokens": max_tokens,
            },
            timeout=60,
        )
        resp.raise_for_status()
        return resp.json()["choices"][0]["message"]["content"]
    
    
    def discover_project(ctx: Context) -> Context:
        # 這裡可以用 ripgrep / fd 產生檔案清單,略
        ctx.file_index = {"files": ["src/a.py", "src/b.py"], "tests": ["tests/test_a.py"]}
        return ctx
    
    
    def plan_change(ctx: Context) -> Context:
        system = """你是資深工程師,輸出 JSON,字段: steps: [{file, description}]。"""
        user = f"需求: {ctx.requirement}\n可修改檔案: {ctx.file_index['files']}\n請產生最多 10 個步驟。"
        raw = call_llm(system, user)
        try:
            plan = json.loads(raw)
        except Exception:
            raise ValueError("PLAN_CHANGE: model output not JSON")
        ctx.plan = plan["steps"]
        ctx.current_file_idx = 0
        return ctx
    
    
    def apply_patch(repo_path: str, file: str, patch: str):
        # 建議用 unified diff + `patch` 指令,這裡簡化處理
        with open(f"{repo_path}/{file}", "w", encoding="utf-8") as f:
            f.write(patch)
    
    
    def edit_file(ctx: Context) -> Context:
        step = ctx.plan[ctx.current_file_idx]
        file_path = step["file"]
        with open(f"{ctx.repo_path}/{file_path}", encoding="utf-8") as f:
            content = f.read()
    
        system = """你只負責修改單一檔案。輸出 JSON: {status, patch}。
        - status: ok | skip | abort
        - patch: 完整檔案內容,不要解釋文字。"""
    
        user = f"需求: {ctx.requirement}\n此步驟: {step['description']}\n原始內容:\n{content[:4000]}"
        raw = call_llm(system, user, max_tokens=2048)
        try:
            out = json.loads(raw)
        except Exception:
            raise ValueError("EDIT_FILE: invalid JSON")
    
        if out["status"] == "ok":
            apply_patch(ctx.repo_path, file_path, out["patch"])
        elif out["status"] == "abort":
            raise RuntimeError("Model aborted edit")
    
        ctx.current_file_idx += 1
        return ctx
    
    
    def run_tests(ctx: Context) -> Context:
        proc = subprocess.run(["pytest"], cwd=ctx.repo_path, capture_output=True, text=True)
        ctx.test_result = proc.stdout + "\n" + proc.stderr
        return ctx
    
    
    def rollback_or_fix(ctx: Context) -> Context:
        # 真實情況應該搭配 git: reset --hard HEAD~1 或建立 branch
        # 這裡示意:交給模型看測試輸出,決定要修哪個檔案
        system = "請從測試輸出中找出最可能需要修改的單一檔案,輸出 JSON: {file, reason}"
        user = ctx.test_result[:4000]
        raw = call_llm(system, user)
        try:
            out = json.loads(raw)
        except Exception:
            raise ValueError("ROLLBACK_OR_FIX: invalid JSON")
    
        # 根據 out['file'] 重新插入 plan
        ctx.plan.insert(ctx.current_file_idx, {"file": out["file"], "description": out["reason"]})
        return ctx
    
    
    def run_state_machine(ctx: Context):
        state = State.DISCOVER_PROJECT
        retries: Dict[State, int] = {s: 0 for s in State}
        MAX_RETRIES = 2
    
        while True:
            try:
                if state == State.DISCOVER_PROJECT:
                    ctx = discover_project(ctx)
                    state = State.PLAN_CHANGE
    
                elif state == State.PLAN_CHANGE:
                    ctx = plan_change(ctx)
                    state = State.EDIT_FILE
    
                elif state == State.EDIT_FILE:
                    if ctx.current_file_idx >= len(ctx.plan):
                        state = State.RUN_TESTS
                    else:
                        ctx = edit_file(ctx)
    
                elif state == State.RUN_TESTS:
                    ctx = run_tests(ctx)
                    if "failed" in ctx.test_result:
                        state = State.ROLLBACK_OR_FIX
                    else:
                        state = State.DONE
    
                elif state == State.ROLLBACK_OR_FIX:
                    ctx = rollback_or_fix(ctx)
                    state = State.EDIT_FILE
    
                elif state in (State.DONE, State.FAILED):
                    return state, ctx
    
            except Exception as e:
                print(f"State {state} error: {e}")
                retries[state] += 1
                if retries[state] > MAX_RETRIES:
                    return State.FAILED, ctx
    
    
    if __name__ == "__main__":
        ctx = Context(repo_path="/path/to/repo", requirement="把 API v1 換成 v2 並修正測試")
        final_state, final_ctx = run_state_machine(ctx)
        print("Final state:", final_state)
    

    重點:

    • 模型只做 局部、可回滾的決策(例如一次只改一檔)。
    • 工作流邏輯(狀態、重試、回滾)都在 可測試的 Python 函式 中,而不是藏在 prompt 裡。

    若用 TypeScript + LangGraph / 自行寫狀態機,模式相同:每個 Node 是一個狀態,Edge 由測試結果與 JSON 輸出決定。


    4. 與「prompt + chain-of-thought」相比的實際好處

    1. 穩定性
    2. CoT 依賴模型「自己監督自己」,小模型的推理錯誤會被往後 propagate,沒有硬性 checkpoint。
    3. 狀態機把流程切成多個 可檢查的邏輯節點,每步都能強制過 schema、判斷失敗與回滾。

    4. 成本與資源

    5. 單輪 prompt 巨大 → token 費用高,且在本地 GPU 上速度慢。
    6. 狀態機讓每輪上下文更短、更聚焦,在 3060 12GB + Q4 模型上可以穩定跑 多輪短對話,總延遲往往比一輪巨 prompt 更好控制。

    7. 觀測性(logging / trace)

    8. 把每個狀態轉移、LLM input/output、git diff 全記錄(例如存到 SQLite / OpenTelemetry trace),可以:

      • 後覽失敗案例
      • 做離線分析:哪個狀態最常出錯?哪種需求最難?
    9. 可測試性

    10. 傳統做法難以單元測試 Agent:prompt 無法 deterministic。
    11. 狀態機可以用 fake LLM 或 replay 真實輸出,對每個 state handler 寫 unit test,例如:當測試結果是某種錯誤訊息時,ROLLBACK_OR_FIX 應插入哪個 plan。

    建議與注意事項

    1. 避免狀態爆炸

    • 限制狀態數量在 5–10 個,複雜度放在狀態內部的子函式,而不是新增一堆細碎狀態。
    • 優先建立 通用狀態模板PLAN / EXECUTE / VERIFY / RECOVER 四類,大部分工程任務都能套這個骨架。

    2. 處理 hallucination 與非法狀態

    • 所有 LLM 輸出一律要求 JSON + schema 驗證,非法就走重試邏輯。
    • EDIT_FILE 等關鍵步驟設計 domain guard
    • 檢查 patch 是否刪除超過 X% 行數;
    • 檢查是否涉及黑名單檔案(例如 config、CI YAML)。

    3. 設計「保守模式」避免改壞檔案

    建議預設開啟:

    1. 所有改動先走分支 / 工作目錄拷貝
    2. 狀態機只在 temp branch/dir 上動手,最後才由人類 review + merge。

    3. 只允許白名單檔案被修改

    4. PLAN_CHANGE 事先產出可修改清單,EDIT_FILE 收到不在清單內的檔案時直接拒絕。

    5. 必備 diff 檢查

    6. 每次改檔後,log 一份 git diff。
    7. 可以加一個 HUMAN_APPROVAL 狀態,在 CI 或 IDE 裡讓人按「Approve」才繼續。

    4. 3060 12GB 本地 GPU 的實務建議

    • 模型:選 Q4_K_M / Q5 量化的 7B–13B 開源模型(如 Llama 系家族、Qwen 等),在 Agentic coding 任務上實測延遲可接受。
    • 推理引擎:
    • llama.cpp / ollama:部署簡單,適合單機開發。
    • vLLM:若你需要高併發與更細緻的 batching,可考慮,但對記憶體稍敏感。
    • 參數建議:
    • max_tokens 控制在 512–2048,依狀態不同調整。
    • temperature 低於 0.3,減少 hallucination。
    • 避免在單輪塞完整檔案,改成 片段 + 明確上下文(例如「你只看這個 function」)。

    5. 映射到現有 Agent framework 的模式

    這套思路可以直接映射到:

    • LangChain / LangGraph
    • 每個狀態 = 一個 Node(通常是 Tool + LLM)。
    • 轉移條件透過 conditional edges 判斷 JSON output 中的 status / next_state
    • 用 LangGraph 的 checkpointingContext 存到外部 store,可做恢復與可視化。

    • LangMCP(可檢視狀態的 Agent framework)

    • Context 中的 file_index / plan / test_result 全部納入 inspectable state
    • 除錯時可以直接在 UI 裡看到「Agent 在哪一步做錯決策」,而不是只看 tokens trace。

    • Claude Code / goal-workflow 類工具

    • 把這裡的狀態機當作後端 orchestrator,前端 IDE 只負責:設定 goal → 顯示 plan → 顯示每步 diff / 測試 → 提供人類 approve。

    總結工程模式:

    LLM 做局部推理 + 生成,狀態機做長期決策 + 記憶 + 恢復。
    把「智慧」從模型本體,搬到你可控、可測、可觀測的工作流程式碼中,13GB 小模型也能在工程任務裡穩定交付 10/10 的結果。


    🚀 你現在可以做的事

    • 在本地架一個 llama.cppvLLM 的 OpenAI-compatible 服務,載入一顆 7B–13B Q4/Q5 模型試跑上文的狀態機範例
    • 把你現有的「一條大 prompt 改碼流程」改寫成 5–10 個明確狀態,並為每步定義 JSON schema 與 max_retries
    • 在 CI 或開發機中為這套狀態機加上 logging / trace(例如 SQLite 或 OpenTelemetry),實際分析哪個 state 最常出錯
  • 把 NVIDIA Deep Research 當實習生用

    把 NVIDIA Deep Research 當實習生用

    📌 本文重點

    • NVIDIA Deep Research Agent 是「會自己調研與寫報告」的 AI 實習生
    • 能自動上網搜尋、整理來源並產出可追溯的研究報告
    • 以「專案工作空間」形式運作,適合市場研究與技術選型等場景

    用一句話講清楚:NVIDIA Deep Research Agent 就是「會自己上網查資料、存筆記、整理報告、附上引用來源」的 AI 實習生,比一般只能聊天的機器人,更接近一個真的研究助理。

    專案連結(GitHub):https://github.com/NVIDIA/GenerativeAIExamples/tree/main/agents/deep-research


    核心功能:比一般聊天機器人多了什麼?

    1. 會自己規劃調研流程,而不是只回一段答案

    一般聊天機器人:

    • 你問:「幫我看 2024 台灣電動車市場發展?」
    • 它直接生成一段「看起來合理」的摘要,但可能沒查新資料,來源不明。

    Deep Research Agent 的做法:

    1. 先把問題拆成子任務:市場規模、主要品牌、政策、關鍵數據…
    2. 逐步上網搜索,每一步都記錄查到的內容
    3. 整理成「研究筆記檔」,最後再寫成報告

    💡 關鍵: Deep Research 不是只回一段答案,而是走完整「拆題 → 搜尋 → 做筆記 → 成稿」流程。

    你可以做的事:

    • 在 prompt 裡直接下達研究任務,例如:
    • 「請做一份 5 頁的市場研究:主題是台灣 2024 電動車市場,列出主要品牌、市佔估計、最近一年重要新聞,最後整理成簡短建議。」
    • 把它當「會自己查資料的實習生」,而不是問答機器人。

    2. 自動搜尋 + 整理來源,幫你做「可追溯」的研究

    Deep Research Agent 會:

    • 主動呼叫搜尋工具(預設走網路 search API)
    • 讀取多個網站內容,過濾重複與雜訊
    • 把每條資訊連同來源網址存起來
    • 最後在報告中附上清楚引用(像研究報告的 reference 區)

    對比一般聊天機器人:

    • 回答多半是「綜合模型訓練時學到的知識」,很難知道哪一段是最新、哪一段來自哪個來源。

    💡 關鍵: 每個關鍵結論都對應具體網址,讓你可以抽查與追溯,而不是盲目信任模型輸出。

    你可以做的事:

    • 要求它在輸出中固定附上引用區,例如:
    • 「請在每個關鍵結論後標注 [來源 1] [來源 2],並在文末列出完整網址。」
    • 用這些引用,手動抽查 1–2 個關鍵數據,確保內容可信。

    延伸閱讀:NVIDIA 開源介紹文章(Towards AI)
    https://pub.towardsai.net/nvidia-open-sourced-a-deep-research-agent-that-beat-openai-on-its-own-benchmarks-5339b3f547fb


    3. 有「工作空間」的 Agent,而不是沒記憶的聊天框

    很多非程式碼 Agent 做不好,很大原因是沒有穩定工作空間——這點在 Reddit 討論裡講得很清楚:non-coding agents should also live in file systems

    Deep Research Agent 的設計比較像一個「專案資料夾」:

    • 每個研究任務會形成一組檔案:
    • 原始搜尋結果
    • 中途整理的筆記
    • 最終報告
    • Agent 可以反覆讀寫這些檔案,再繼續深化研究

    💡 關鍵: 用「檔案與專案」當記憶體,讓 Agent 可以多輪迭代深化同一主題,而不是每次從零開始聊。

    你可以做的事:

    • 把每一個「問它的大問題」當成一個專案,例如:
    • project: EV-market-tw-2024
    • project: crm-tools-comparison
    • 把產出的 Markdown 報告直接丟進你的筆記軟體(Obsidian、Notion)當專案檔案。

    適合誰用?幾個實際場景

    1. 市場研究 / 會前簡報

    需求:你要開一場客戶會議,得先快速了解對方產業現況。

    操作示例:

    • 任務描述:
    • 「客戶是做 B2B SaaS CRM 的,幫我整理 2022–2024 全球 B2B CRM 市場趨勢、主要玩家、常見商業模式,最後整理一句話電梯簡報 + 5 項我應該問的問題。」
    • 把 Deep Research Agent 的報告:
    • 直接 copy 成 PowerPoint 大綱
    • 或貼到 Notion,當成會前 brief

    2. 競品分析 / 工具選型

    需求:你在選 CRM、客服系統、A/B test 平台。

    操作示例:

    • 任務描述:
    • 「幫我比較 Intercom、Zendesk、Freshdesk 三個工具,重點看價格方案、支援語言、整合 API 能力,做成表格,最後給出 3 種不同規模公司(10 人、50 人、200 人)的建議。」
    • 你要做的:
    • 把輸出的表格貼進你團隊的提案文件
    • 把引用網址交給實習生或同事做二次驗證

    3. 技術選型調研

    需求:你在選擇 LLM、RAG 架構或 MCP agent 框架要上線到產品(可參考這篇實戰文:https://pub.towardsai.net/i-shipped-a-rag-mcp-agent-to-production-five-things-broke-0f030ff6f3f9)。

    操作示例:

    • 任務描述:
    • 「整理目前主流的 RAG + MCP agent 開源方案,要求列出:GitHub 星數、是否支援雲端 / 本地部署、常見踩坑與評估建議,重點對象是要上 production 的 SaaS 團隊。」
    • 接著你可以:
    • 用報告當作技術評估會議的初稿
    • 在每個風險點上再請 Deep Research Agent 深挖,反覆迭代。

    怎麼開始:從安裝到接上你的知識庫

    1. 準備環境與 API Key

    最低需求:

    • Python 3.10+ 環境(本機或雲端都可)
    • 一張 NVIDIA GPU 會更順(但也可只用雲端 API)
    • 至少一個可用的 LLM API Key,例如:
    • NVIDIA NIM / NVIDIA API
    • 或其他支援的雲端模型供應商

    你要做的事:

    1. 申請 NVIDIA API 帳號(若使用他們的模型):https://build.nvidia.com
    2. 拿到 API Key,寫入 .env 或環境變數,例如:

    bash
    export NVIDIA_API_KEY="你的 key"


    2. 安裝與在本機快速跑起來

    以 GitHub 專案為主線:

    git clone https://github.com/NVIDIA/GenerativeAIExamples.git
    cd GenerativeAIExamples/agents/deep-research
    
    # 建議開一個虛擬環境
    python -m venv .venv
    source .venv/bin/activate  # Windows 用 .venv\Scripts\activate
    
    pip install -r requirements.txt
    

    通常範例專案會提供一個 demo 指令(名稱可能略有變化,依 README 為準):

    python deep_research.py \
      --query "請分析台灣 2024 電動車市場的主要趨勢與廠商" \
      --output ./outputs/ev-market-tw-2024.md
    

    你要做的事:

    • 改掉 --query 裡的內容,直接換成你現在真正在做的專案題目
    • 執行後,到 outputs/ 夾裡打開 Markdown 報告

    3. 在雲端(Colab / VS Code Remote)跑

    如果你本機沒有 GPU 或懶得裝環境,可以:

    • 找一份針對 NVIDIA Deep Research Agent 的 Colab notebook(通常社群會有人整理)
    • 或在雲端 VM(如 AWS、GCP、Azure)裡跑上述安裝流程

    你要做的事:

    • 儲存好 notebook,當成你的「研究模板」
    • 每次只改問題與輸出檔名,就能重複使用。

    4. 串接到你的筆記 / 知識庫工作流

    目標:建立一條「從問題 → 調研 → 報告」的固定管線。

    最簡單做法:

    1. 輸出格式固定用 Markdown
    2. 在啟動腳本中加入:--format markdown(若有此選項)
    3. 指定輸出資料夾對應到筆記工具
    4. Obsidian:把 outputs/ 變成一個 vault 內的資料夾
    5. Notion:用 Notion API 定期把 outputs/*.md 同步上去
    6. 在筆記裡建立「研究模版」
    7. 標題:{{專案名稱}} Deep Research 報告
    8. 區塊:背景、發現、數據表、風險、建議、來源連結

    你可以立刻做的事:

    • 為你接下來一週要決定的「一個重要選項」(例如要不要換 CRM)建一個專案資料夾
    • 用 Deep Research Agent 生成第一版調研報告
    • 用你自己的專業重新整理重點後,發給團隊當決策前閱讀材料。

    小結:把它當「會查資料的實習生」,而不是魔法

    使用 NVIDIA Deep Research Agent 的正確心態:

    • 它擅長的是幫你大量收集與初步整理,節省你 60–80% 搜集資料的時間
    • 你仍然要:
    • 選題、定義問題
    • 抽查關鍵引用
    • 把輸出整理成真正要對外發表的報告或簡報

    💡 關鍵: 把 60–80% 搜資料的時間交給 Agent,你可以把精力放在判斷與決策上。

    只要先從一個你本來就要做的調研開始,你很快就會感受到,把 AI 當實習生用,和「只是多一個聊天機器人」有多大差別。

    🚀 你現在可以做的事

    • 打開 GitHub 專案並依照 README 完成安裝,跑一次示範指令
    • 挑一個你這週真的要做的決策議題,寫成 --query 給 Deep Research Agent
    • 把產出的第一版報告整理進 Obsidian 或 Notion,當作團隊會議前閱讀材料
  • Gemini Spark:24 小時幫你管信與帳的 AI 管家

    Gemini Spark:24 小時幫你管信與帳的 AI 管家

    📌 本文重點

    • Gemini Spark 是深度整合 Gmail / Workspace 的 24/7 AI 管家
    • 透過規則 + 對話自動幫你篩信、寫信、追專案與整理帳單
    • 未來可藉由 MCP 串接各種第三方 App,跨服務自動協作
    • 適合重度依賴 Gmail / Docs 的自由工作者、PM 與一般用戶

    一句話:Gemini Spark 就是常駐在你 Gmail / Workspace 裡的 24 小時 AI 管家,幫你篩信、寫回信、盯專案、看帳單,減少你開 Email、開表單處理瑣事的時間。

    官方介紹與技術背景可參考:Google I/O 報導(The Verge:連結、TechCrunch:連結)。


    為什麼大家都在做 24/7 Agent?Spark 與 OpenClaw 有何不同?

    最近一堆「24 小時 AI Agent」:OpenClaw、各種自動 Agent 平台,核心概念都一樣:不用你每次開聊天框下指令,AI 自己在背景幫你盯事情。

    差別在:

    • OpenClaw 類產品:偏「開發者 / 愛折騰」路線,要自己設計任務、接 API。
    • Gemini Spark:直接長在 Google 生態裡,主打:
    • 深度整合 Gmail / Docs / Sheets / Calendar 等 Workspace
    • 不用寫程式,用「規則 + 對話」就能開啟 workflow
    • 未來可用 Model Context Protocol (MCP) 串接其他服務(如任務管理、財務 App)。

    如果你工作幾乎都在 Gmail + Docs 上,Spark 比自己搭一套 OpenClaw workflow 更省時間、阻力更小。

    💡 關鍵: Spark 把「24/7 Agent」做成內建在你日常工具裡的功能,而不是一個需要你額外架設與維護的系統。


    核心功能 1:Gmail & Workspace 自動化

    Spark 最直接的價值:幫你打理每天那一坨 Email 和文件

    能做什麼?

    1. 自動幫你篩信、分類
    2. 標記「待回覆」「重要客戶」「帳單 / 訂閱」
    3. 把專案相關信件整理到指定標籤或共用資料夾

    4. 自動草擬回信

    5. 依照你的語氣、常用模板,先寫好草稿
    6. 幫你整理長串對話重點,附在回信開頭

    7. 整理文件與表單

    8. 收到表單回覆,Spark 自動更新一份 Sheet
    9. 根據信件附件(合約、簡報)整理成專案說明 Doc

    你可以這樣設:

    • 在 Spark 裡建立規則(概念跟 Filter 很像):
    • 「凡是寄到 @client.com 的信 → 標記『客戶 A』,加上『待處理』,並讓 Spark 草擬回信」
    • 「標題含 ‘Invoice’ 或 ‘Receipt’ → 丟進『報帳』標籤,抄送到財務信箱」

    實作建議:

    • 先只設 1~2 個簡單規則(例如:重要客戶 + 帳單),一週後再慢慢擴充,不然一開始會被通知轟炸。

    核心功能 2:主動提醒與任務追蹤(Information Agents)

    根據 TechCrunch 的說法,Google 這波推出的是一整類「information agents」,可以在背景幫你監控資訊並主動提醒你更新狀態。

    能做什麼?

    1. 盯專案 Deadline、會議後待辦
    2. 讀你的行事曆 + 信件內容
    3. 抓出「需要你回覆 / 決策」的項目,列成待辦
    4. 開會後自動整理會議紀錄,變成「下一步行動清單」

    5. 監控帳單與訂閱扣款(Wired 舉的例子)

    6. 讀信用卡對帳單、訂閱通知信
    7. 找出「新出現的訂閱」「金額異常」
    8. 提醒你哪個訂閱快到期、要漲價

    9. 主動推送重要變化

    10. 類似:
      • 「這週有 3 封同一客戶追問進度,是否要統一回覆?」
      • 「今天有 2 筆金額較大的扣款,是否要確認?」

    你可以這樣設:

    • 設定每日 / 每週摘要:
    • 每天 17:00:一封「今日重要信件 + 待回覆清單」
    • 每週五:一份「本週專案進度 + 下週待辦」
    • 針對帳單:
    • 關鍵字觸發:「含 ‘Payment received’、‘Invoice’、‘Receipt’ → 丟給 Spark 分類 + 每月 1 號幫我整理上個月支出摘要」

    💡 關鍵: 把 Spark 當成「自動生成待辦清單的人」,讓你只在關鍵節點做決策,而不是自己翻信找事做。


    核心功能 3:跨服務協作(靠 MCP 串其他 App)

    Gemini Spark 未來會透過 Model Context Protocol (MCP),把不同 App 的資料拉到同一個「腦袋」裡處理(見 The Verge 報導)。

    意思是:

    • Spark 不只看 Gmail / Docs,可同時讀你在其他服務的內容
    • 比方:Notion、Asana、財務或 CRM 工具(視各家支援情況)

    能做什麼?

    • 新客戶來信 → Spark:
    • 在 CRM 建立客戶資料
    • 開一個 Asana / Jira 任務
    • 建一份 Google Doc 專案說明,丟到共用資料夾

    • 訂閱扣款被偵測到 → Spark:

    • 在你的個人記帳 App / Sheet 新增一筆支出
    • 標注「本月新增訂閱」,月底提醒你是否要取消

    目前這些整合會隨 MCP 生態擴大而補上,你可以優先關注:

    • 你常用的任務管理 / 筆記 App 是否推出「支援 Gemini Spark / MCP」
    • 一旦支援,就可以在 Spark 設定畫面裡授權該服務,讓 Spark 讀取與寫入資料。

    💡 關鍵: MCP 讓 Spark 變成跨 App 的「中樞神經」,未來可以一次處理信件、任務、財務資料,而不是各管各的。


    適合誰用?三個具體場景

    1. Freelancer:用 Spark 管專案信件與合約

    具體做法:

    • 專案信件管線
    • 設定規則:來自特定網域或標題含「Proposal」「Quote」→ 標籤「新案洽談」
    • Spark 自動草擬回信版本:

      • A 版:詢問需求細節
      • B 版:附上報價與時程
    • 合約 / 發票整理

    • Spark 自動把附件中的合約檔案存到對應 Drive 資料夾
    • 依合約內容(時程、金額)生成一列 Sheet:

      • 專案名稱 / 客戶 / 金額 / 付款節點 / 合約到期日
    • 每週專案總覽

    • 每週五 Spark 自動寄給你一份 Doc:
      • 每個專案的最新信件狀態
      • 待你回覆的客戶
      • 即將到期的付款 / 交付

    2. PM:用 Spark 維護「自動更新」專案說明文件

    具體做法:

    • 為每個專案建立一份「Project Brief」Google Doc
    • 跟 Spark 說:
    • 「這份文件是 X 專案的說明書,請未來根據相關 Gmail、會議紀錄、Drive 檔案,自動更新:

      • 成員名單
      • 時程 / 里程碑
      • 需求變更紀錄
      • 風險與依賴」
    • Spark 會:

    • 把會議邀請、會議記錄、需求更動 Email 轉成文件更新
    • 例如:會議後自動新增一段「2026/05/21 需求變更:結帳流程新增 Apple Pay」

    • 你要做的事:

    • 只在 review 時修正重要錯誤
    • 把這份 Doc 當成「單一真實來源」丟給新成員看

    3. 個人:用 Spark 監控訂閱扣款與信用卡帳

    具體做法:

    • 把信用卡帳單寄到固定 Gmail
    • 設定 Spark:
    • 「閱讀所有來自銀行 / 金融機構的信,整理出:
      • 每月訂閱(Netflix、Spotify、雲端服務等)
      • 單筆金額超過 X 元的交易
    • 每月 3 號產一份 Sheet + 一封摘要信送給我。」

    • 實際效果:

    • 你不用每月自己翻 PDF 帳單
    • 一眼看到:新增了哪些訂閱?哪筆支出特別大?要不要取消 / 確認?

    怎麼開始:3 步驟快速上手

    依目前公開資訊,Spark 會逐步在 Gemini App 與 Workspace 釋出,實際入口以你的帳號權限與地區為準。

    步驟一:在 Gemini App / Workspace 開啟 Spark

    1. 更新手機上的 Gemini App 或在瀏覽器開啟 Gemini
    2. 找「Spark」或「Agents」相關入口(通常在側邊欄或設定)。
    3. 若你是 Workspace 使用者,管理員可能要先在後台啟用 Gemini / Spark 功能。

    步驟二:授權 Gmail / Calendar / Drive

    1. 依畫面指示,授權 Spark 存取:
    2. Gmail(讀 / 寫信)
    3. Calendar(讀行程)
    4. Drive(讀 / 建立 Docs、Sheets 等)
    5. 建議做法:
    6. 先只開 Gmail + Calendar,確定運作 OK 再讓 Spark 讀更多資料夾。
    7. 對特別敏感的資料夾,可以
      • 分開到另一個帳號
      • 或在 Drive 設定權限,避免 Spark 看到。

    步驟三:先設 2–3 個「實用預設 workflow」

    先從以下三個開始,感受到價值後再慢慢加:

    1. 自動草擬回信
    2. 規則:
      • 來自特定客戶網域,或標記為「重要」的信 → Spark 產生草稿
    3. 設定你的語氣偏好:正式 / 口語 / 簡短版

    4. 每天 17:00 匯總今日重要信件

    5. 內容包含:

      • 你今天沒有回覆的信
      • 含「deadline」「due」「reminder」等關鍵字的信
      • Spark 生成的回覆建議
    6. 每週專案週報

    7. 若你有固定專案標籤(例如「[Project X]」):
      • 每週五 Spark 讀所有相關信件 + 文件變化
      • 產出一份 Doc:
      • 本週完成事項
      • 開放中的問題
      • 下週計畫建議

    權限與隱私:幾個實務建議

    1. 工作帳號與私人帳號分開
    2. 不要讓 Spark 在同一帳號裡同時看到公司機密 + 私人財務。

    3. 先從低風險資料開始授權

    4. 先讓它管 Newsletter、一般通知信,不要一開始就丟完整信用卡帳單。

    5. 定期檢查 Spark 建立的文件 / 表單

    6. 每週抽查 1–2 份自動產生的 Doc / Sheet,確定沒有誤解或洩漏給錯對象。

    7. 關閉你不需要的來源

    8. 如果覺得 Spark 讀太多東西,就到設定關掉某些資料夾或服務授權。

    結論:如果你每天都被 Gmail 和各種帳單 / 專案信件追著跑,Gemini Spark 的價值不是「會聊天」,而是能在你沒開電腦的時候,幫你持續整理與提醒,讓你只需要在關鍵節點做決定,其他都交給它自動化處理。

    🚀 你現在可以做的事

    • 打開你的 Gmail,先規劃 1–2 個想讓 Spark 自動處理的信件情境(例如:帳單、重要客戶)
    • 在 Gemini / Workspace 中尋找 Spark 入口,完成 Gmail + Calendar 的最低授權並設好這 2 個情境
    • 每週挑固定時間檢查 Spark 自動生成的文件與摘要,根據實際效果微調規則與授權範圍
  • 12-Factor Agents 實戰:讓 Agent 真正上得了線

    12-Factor Agents 實戰:讓 Agent 真正上得了線

    📌 本文重點

    • LLM/Agent 要先抽象成可替換依賴
    • Prompt/Tool/Memory 行為必須版本化與可回滾
    • 觀測性與成本控管是上線前必備基礎
    • 單體腳本可漸進重構為 12-Factor Agents

    多數 Agent demo 都卡在「好酷,但不敢上線」。12-Factor Agents 的目的,就是把 LLM/Agent 拉回正常軟體工程軌道:
    – 不被單一模型綁死,支援熱切換與灰度升級
    – prompt / tool / memory 都能 versioning + 測試 + rollback
    – 有 token-level log、decision trace,出問題找得到責任點

    下面用 12-Factor 觀念,拆成對工程實作有幫助的 4 個面向,最後用一個簡單 multi-agent pipeline 示範如何重構。


    重點說明

    1. 把 LLM/Agent 抽象成可替換的依賴

    核心做法:不要在業務程式碼裡直接綁某個模型 API,而是統一經過一層 LLMClient / AgentRuntime

    關鍵能力:
    – 用 model alias(如 report-writer@v2)取代具體 gpt-4.1-mini / claude-3.7
    – 支援 routing 策略:A/B test、流量分配、fallback
    – 對外只暴露 統一介面complete() / chat() / stream()

    // llm-registry.ts
    export type ModelAlias = 'planner@v1' | 'crawler@v1' | 'analyst@v2';
    
    interface LLMConfig {
      provider: 'openai' | 'anthropic' | 'local';
      model: string;
      maxTokens: number;
      temperature: number;
    }
    
    const REGISTRY: Record<ModelAlias, LLMConfig> = {
      'planner@v1': { provider: 'openai', model: 'gpt-4.1-mini', maxTokens: 1024, temperature: 0.2 },
      'analyst@v2': { provider: 'anthropic', model: 'claude-3.7', maxTokens: 2048, temperature: 0.1 },
      'crawler@v1': { provider: 'local', model: 'llama-3-8b', maxTokens: 512, temperature: 0.3 },
    };
    
    export function getLLMConfig(alias: ModelAlias): LLMConfig {
      return REGISTRY[alias];
    }
    

    業務端只拿 alias:

    // llm-client.ts
    export async function complete(alias: ModelAlias, messages: ChatMessage[]): Promise<string> {
      const cfg = getLLMConfig(alias);
      const client = getProviderClient(cfg.provider); // 封裝 OpenAI / Anthropic SDK
    
      const res = await client.chat({
        model: cfg.model,
        messages,
        max_tokens: cfg.maxTokens,
        temperature: cfg.temperature,
      });
    
      return res.output;
    }
    

    好處
    – 模型升級只改 registry config,不用全 repo 改 model: 'xxx'
    – 可以針對某 alias 做 灰度發布:10% 流量走新模型

    💡 關鍵: 透過 model alias 把模型細節藏在 registry,可以在不動業務程式碼的前提下做灰度升級與快速回滾。

    2. Prompt / Tool / Memory:行為配置要能 versioning + rollout

    對 Agent 而言,行為大多來自「配置」,而不是 code:
    – system prompt
    – tool schema / API 介面
    – memory 策略(context window、摘要邏輯)

    建議把這些都變成 宣告式 config,並且:
    – 每個 Agent 一個 behavior versionplanner@v1.3
    – 行為改動先跑 離線回放測試 + 小流量試 run

    # configs/agents/planner.v1.3.yaml
    name: planner
    version: v1.3
    model_alias: planner@v1
    system_prompt: |
      你是一個專門規劃網站資料收集與分析的技術 PM。
      - 只產出結構化 JSON
      - 不要寫多餘文字
    
    output_schema:
      type: object
      properties:
        crawl_targets:
          type: array
          items:
            type: object
            properties:
              url: { type: string }
              depth: { type: integer, maximum: 2 }
              notes: { type: string }
    
    memory:
      type: redis
      ttl_seconds: 3600
      key_prefix: planner_session_
    

    載入時明確綁定行為版本:

    // agent-loader.ts
    interface AgentSpec {
      name: string;
      version: string;      // e.g. v1.3
      modelAlias: ModelAlias;
      systemPrompt: string;
      outputSchema: JSONSchema;
    }
    
    export function loadAgentSpec(name: string, version: string): AgentSpec {
      const path = `configs/agents/${name}.${version}.yaml`;
      const raw = fs.readFileSync(path, 'utf8');
      const cfg = yaml.parse(raw);
      return {
        name: cfg.name,
        version: cfg.version,
        modelAlias: cfg.model_alias,
        systemPrompt: cfg.system_prompt,
        outputSchema: cfg.output_schema,
      };
    }
    

    好處
    – prompt 調整可以 像發版一樣受控,支援 rollback
    – tool schema 變更(新增欄位、型別改動)有明確 diff,避免隱性 breaking change

    💡 關鍵: 把 prompt、tool、memory 行為寫進版本化 config,可以像管理程式碼一樣管控變更與回滾。

    3. Observability:token-level log + decision trace + retry 策略

    傳統 APM 看不到「LLM 想了什麼」。受《The Rise of Cognitive Observability》啟發,建議:

    1. token-level log / cost log:每次 call 記錄 prompt_tokenscompletion_tokenscost_usd
    2. decision trace:multi-agent 流程中,記下每一步的:
    3. input
    4. output
    5. 使用的 model / behavior version
    6. tool 呼叫與對應結果
    7. 分類錯誤
    8. infra error(timeout、rate limit)→ 可以 retry
    9. cognitive error(推理錯誤、亂寫 schema)→ 需要 prompt/tool 設計調整
    // observability.ts
    export async function tracedLLMCall(params: {
      agent: string;
      behaviorVersion: string;
      modelAlias: ModelAlias;
      messages: ChatMessage[];
      spanId: string;
    }) {
      const start = Date.now();
      try {
        const res = await rawProviderCall(params.modelAlias, params.messages);
    
        logToWarehouse({
          span_id: params.spanId,
          agent: params.agent,
          behavior_version: params.behaviorVersion,
          model_alias: params.modelAlias,
          latency_ms: Date.now() - start,
          prompt_tokens: res.usage.prompt_tokens,
          completion_tokens: res.usage.completion_tokens,
          cost_usd: estimateCost(res.usage, params.modelAlias),
          raw_output: res.output,
        });
    
        return res.output;
      } catch (e) {
        logError({ span_id: params.spanId, agent: params.agent, error: e });
        throw e;
      }
    }
    

    重試策略

    export async function withRetry<T>(fn: () => Promise<T>, opts = { maxAttempts: 3, backoffMs: 500 }) {
      let lastErr;
      for (let i = 0; i < opts.maxAttempts; i++) {
        try { return await fn(); } catch (e: any) {
          lastErr = e;
          if (!isInfraError(e)) break; // 認知錯誤不要盲目重試
          await sleep(opts.backoffMs * (i + 1));
        }
      }
      throw lastErr;
    }
    

    4. Multi-Agent 任務重構:規劃 → 爬蟲 → 分析 → 報告

    目標:把一個看似「單體腳本」的 agent 流程,拆成可觀察、可恢復的 pipeline。

    服務切分
    planner-service:輸入題目 → 輸出 crawl plan
    crawler-service:依照 plan 用傳統爬蟲抓 HTML / 文本
    analyst-service:對資料做分析與結構化結論
    reporter-service:產出自然語言報告

    狀態管理
    – 任務狀態存在 PostgreSQLMongoDBtasksartifacts
    – 中間資料(暫存內容、短期記憶)放 Redis(key = task:{id}:stage

    隊列與超時
    – 使用 Redis Stream / Kafka / RabbitMQ 做 stage 間消息隊列
    – 每個 stage worker 有自己的 timeout + retry + DLQ(死信隊列)

    // pseudo: task Orchestrator
    async function runTask(taskId: string) {
      const spanId = newSpan();
    
      // 1) 規劃
      const plan = await withRetry(() => plannerAgent.run({ taskId, spanId }), { maxAttempts: 2 });
      await saveArtifact(taskId, 'plan', plan);
    
      // 2) 爬蟲(可能 fan-out 多個 URL)
      await enqueueCrawlJobs(taskId, plan.crawl_targets); // 放到 queue
    
      // 3) 等 crawler 全數完成,再觸發 analyst
      await waitForAllCrawls(taskId, { timeoutMs: 300_000 });
      const pages = await loadArtifacts(taskId, 'crawl_result');
    
      const analysis = await withRetry(() => analystAgent.run({ taskId, spanId, pages }), { maxAttempts: 2 });
      await saveArtifact(taskId, 'analysis', analysis);
    
      // 4) 報告
      const report = await reporterAgent.run({ taskId, spanId, analysis });
      await saveArtifact(taskId, 'report', report);
    
      await markTaskDone(taskId);
    }
    

    回退策略
    – 某 stage 連續失敗 → 使用 上一個穩定 behavior version 重跑
    – 報告無法產出 → 回傳「部分完成」狀態 + 中間分析結果給前端呈現


    實作範例

    以下示範如何把「planner」 agent 做到可替換模型、可版本管理、可觀察的最小實作。

    1. Planner Agent 行為定義

    # configs/agents/planner.v1.0.yaml
    name: planner
    version: v1.0
    model_alias: planner@v1
    system_prompt: |
      你負責規劃完成使用者任務所需的爬蟲與分析步驟。
      僅輸出 JSON,符合 output_schema 定義。
    output_schema:
      type: object
      required: [crawl_targets]
      properties:
        crawl_targets:
          type: array
          items:
            type: object
            required: [url]
            properties:
              url: { type: string }
              depth: { type: integer, default: 1 }
              notes: { type: string }
    

    2. 執行 Planner Agent

    // planner-agent.ts
    import { loadAgentSpec } from './agent-loader';
    import { tracedLLMCall } from './observability';
    import Ajv from 'ajv';
    
    const ajv = new Ajv();
    
    export async function runPlanner(taskId: string, goal: string, spanId: string) {
      const spec = loadAgentSpec('planner', 'v1.0');
      const validate = ajv.compile(spec.outputSchema);
    
      const messages = [
        { role: 'system', content: spec.systemPrompt },
        { role: 'user', content: `任務說明:${goal}` },
      ];
    
      const raw = await tracedLLMCall({
        agent: spec.name,
        behaviorVersion: spec.version,
        modelAlias: spec.modelAlias,
        messages,
        spanId,
      });
    
      let json;
      try { json = JSON.parse(raw); } catch {
        throw new Error('planner_output_not_json');
      }
    
      if (!validate(json)) {
        throw new Error('planner_output_schema_mismatch');
      }
    
      await saveArtifact(taskId, 'plan', json); // 存 DB
      return json;
    }
    

    好處
    – output 一旦 JSON 格式錯誤或 schema 不符合,會被明確標記為 cognitive error,方便後續調 prompt / schema
    – 透過 behaviorVersion 追蹤哪一版規劃器造成問題

    3. 成本暴衝防護

    // cost-guard.ts
    const MAX_COST_PER_TASK_USD = 0.5;
    
    export async function guardCost<T>(taskId: string, fn: () => Promise<T>): Promise<T> {
      const costSoFar = await getTaskCostUsd(taskId);
      if (costSoFar > MAX_COST_PER_TASK_USD) {
        throw new Error('task_cost_limit_exceeded');
      }
      const before = costSoFar;
      const res = await fn();
      const after = await getTaskCostUsd(taskId);
    
      if (after - before > 0.2) { // 單次呼叫超過 0.2 USD
        // 觸發告警
        emitAlert({ taskId, deltaCost: after - before });
      }
    
      return res;
    }
    

    tracedLLMCall 包在 guardCost 裡,就能防止 prompt 異常導致 token 疯狂膨脹。

    💡 關鍵: 設定 MAX_COST_PER_TASK_USD 與單次呼叫成本門檻,可以在成本暴衝前主動阻斷與告警。


    建議與注意事項

    1. 模型抽象層一定要一開始就設計好
    2. provider SDK 完全封裝起來(OpenAI、Anthropic、local),對業務端只暴露 統一型別
    3. 不要在 service 裡直接用 openai.chat.completions.create 這種具體 API。

    4. Prompt / Tool 變更要像 schema migration 一樣看待

    5. 每次變更必須 版本號 + changelog,否則 debug 會非常痛苦。
    6. tool 的欄位移除或語意改變,要視為 breaking change,需要同步更新所有使用該 tool 的 Agent。

    7. Observability 優先級要比「多搞幾個 Agent」高

    8. 沒 trace,multi-agent 只會變成 多倍混亂
    9. 最低限度:每一步的輸入、輸出、模型 alias、behavior version、token 用量都要記。

    10. 模型升級前先做 replay test

    11. 從線上 log 抽一批真實任務,對舊模型與新模型跑一遍,對比:

      • 通過率(JSON parse、schema validate)
      • 任務完成率(可部分人工標註)
      • 成本差異
    12. 不要迷信 retry,可以只是讓錯誤變貴

    13. infra error(timeout、429)才值得 retry
    14. cognitive error(結果不符合 schema / business rule)應該記錄下來,調整 prompt 或 tool,而不是盲目重試

    15. 從單體腳本往 12-Factor Agents 過渡的實務建議

    16. 先做 3 件事:
      • 抽出 LLMClient 抽象層
      • 把 prompt / schema 拉到 config + Git 管理
      • 導入最小版 token cost log + decision trace
    17. 等這三件穩定後,再考慮拆成獨立 microservices 或 multi-agent pipeline。

    照著這套把 demo 重構一次,你會發現:
    – 模型換得比較放心
    – 成本能被預期
    – 最重要的是:Agent 行為變得「可觀察、可控」,才有資格進入生產環境。

    🚀 你現在可以做的事

    • 把現有專案中的 openai / anthropic 呼叫封裝成統一的 LLMClient,並導入 model alias registry
    • 將目前的主要 Agent prompt、tool schema 抽出成獨立 config 檔,放進 Git 做版本管理
    • 為一個關鍵任務流程加入 token 用量與 cost_usd 的記錄,並開始對新模型做 replay test
  • 5 分鐘做出你的 Claude 專屬小 Agent

    5 分鐘做出你的 Claude 專屬小 Agent

    📌 本文重點

    • Claude Skills 是一包可重用的 Python 技能模組
    • 只要寫幾個函式就能讓 Claude 自動串起工作流
    • 10 分鐘內可跑起第一個實用小 Agent

    用一句話講清楚:Claude Skills 就是一包現成可重用的 Python「技能模組」,幫你把讀檔、叫 API、發 Slack 這種瑣事交給 AI 自動跑。

    下面的重點是:看完你應該要「馬上能照著做,跑起一個自己的小 Agent」。


    什麼是 Claude Skills?

    原始專案:https://github.com/anthropics/skills

    用人話解釋:

    • 每一個 Skill 就是一個 Python 函式,包住「一件具體可重複的任務」,例如:
    • 讀 / 寫某個資料夾的檔案
    • 呼叫外部 HTTP API
    • pandas 處理 CSV / JSON
    • 串起一小段工作流程(抓資料 → 清洗 → 寫檔 → 發通知)
    • 這些函式會被包裝成 工具(tools),讓 Claude 之類的模型「自動決定要不要呼叫、用哪個參數」。
    • 你的工作:
    • 選幾個 skills
    • 配好權限與 API key
    • 用一個簡單的 Agent shell 把它們掛上去

    結果就是:你不用自己手刻複雜 Agent 架構,只要寫幾個普通的 Python 函式,Claude 就能幫你組成自動化流程。


    核心功能:你可以拿來做什麼

    1. 內建技能類型:檔案、API、資料處理、簡單工作流

    anthropics/skills 裡,你可以看到各種已經寫好的 skills(名稱可能持續調整,但類型大致如下):

    • 檔案相關:
    • 讀寫本機檔案(通常限定在某個資料夾)
    • 列出目錄、建立新檔、更新內容
    • API 呼叫:
    • 通用 HTTP requestGET / POST
    • 幫你處理 headers、JSON encode / decode
    • 資料處理:
    • 讀寫 CSV / JSON
    • pandas 做簡單統計與篩選
    • 工作流協調:
    • 把多個 skills 串起來:例如「每天定時抓 API → 整理 → 寫報表 → 發通知」

    💡 關鍵: 多數常見「讀檔、叫 API、整理資料」的雜務,其實已經有現成 skill,可以直接拿來組合,而不用從零寫 Agent 架構。

    你可以立刻做的事:

    1. 打開 repo 的 skills/ 資料夾(或類似目錄),挑幾個你看得懂的 Python 檔。
    2. 看每個 skilldocstring,理解它預期的輸入、輸出是什麼。
    3. 想一件自己平常重複做的事,先用一個 skill 就好(例如:讀一個 CSV 幫你整理)。

    2. 如何跟你現有專案整合

    Skills 的設計很單純:

    • 你可以把整個 repo 當作 依賴套件 安裝,或直接把單一 skill 檔案 copy 進你專案。
    • 在你自己的 Agent 程式裡,把這些 functions 包成工具,丟給 Claude 使用。

    一個極簡示意(結構可能與實際 repo 有差異,但概念相似):

    from skills.files import read_file, write_file
    from anthropic import Anthropic
    
    client = Anthropic(api_key="YOUR_API_KEY")
    
    TOOLS = [read_file.tool_def, write_file.tool_def]
    
    resp = client.messages.create(
        model="claude-3-7-sonnet-20250219",
        max_tokens=1024,
        tools=TOOLS,
        messages=[{
            "role": "user",
            "content": "請幫我打開 data/report.csv,整理成重點摘要,回給我。"
        }]
    )
    

    Claude 看到 tools 後,會自己決定:

    • 要不要執行 read_file
    • 執行後用結果做後續推理

    你可以立刻做的事:

    • 如果你已經有在用 Claude API,先挑 1–2 個 skills 加進你的工具列表,看看 Claude 會怎樣使用它們。

    3. 搭配其他開源專案:拉出一條多代理 workflow

    有兩個常被一起提到的專案,很適合拿來串:

    名稱 核心功能 免費方案 適合誰
    Claude Skills 可重用的 Python 任務模組,給 Agent 當工具用 開源、自架 想快速做實用 Agent 的開發者、技術 PM
    scientific-agent-skills 研究、工程、金融、寫作等專業領域的技能集 開源、自架 科研團隊、量化分析、技術寫作者
    Personal_AI_Infrastructure 個人 AI 代理基礎架構、多代理協作 開源、自架 想打造個人 AI 工作桌面、內部 Agent 平台的人

    實際串法可以是:

    • Personal_AI_Infrastructure 當「總控台」與排程器
    • Claude Skills + scientific-agent-skills 當作不同專業領域的「工具箱」
    • 例如:
    • Agent A:每天抓研究資料(API + 檔案 download
    • Agent B:用 scientific-agent-skills 做統計分析
    • Agent C:把結果用 Claude Skills 寫成報告,發到 Slack

    你可以立刻做的事:

    • 先單純在本機跑 Claude Skills,確認流程順暢後,再考慮拉入 Personal_AI_Infrastructure 做多 Agent 編排。

    適合誰用:三種常見場景

    1. 個人開發者 side project:資料整理 bot、FAQ 助理

    具體可以做:

    • 資料整理 bot
    • 每天從某個 API 抓資料
    • 存成 CSV
    • 請 Claude 用 skills 幫你做摘要或簡單圖表
    • 客服 FAQ 助理
    • 讀本機的 FAQ 檔案 + 客戶紀錄
    • 自動整理常見問題、生成回覆模板

    行動建議:

    • 先挑「你每天重複做、但不用太精準」的任務,例如:整理 log、閱讀報表。

    2. 小團隊:內部自動化腳本

    適合處理:

    • 例行報表產出
    • 專案進度彙整
    • Jira / GitHub issue 摘要

    作法:

    1. 把資料源(API、CSV)包成 2–3 個自訂 skills
    2. 寫一個簡單 CLI 或 cron job,每天叫 Claude 跑一次。

    3. 結合其他開源專案:多步驟分析 + 報告

    對研究團隊、數據團隊特別實用:

    • scientific-agent-skills 做嚴謹分析
    • Claude Skills 負責「收資料 / 寫結果 / 發報告」

    行動建議:

    • 先把你現有的分析腳本包一層成 skill,讓 AI 能呼叫;不需要一開始就全部自動化。

    怎麼開始:10 分鐘跑起一個本地小 Agent

    以下示意流程假設你已經有 Claude API key,且會用基本的命令列。

    💡 關鍵: 只要準備 API key、安裝 repo,再加上兩三個簡單 skills,大約 5–10 分鐘內就能跑起第一個可用的本地 Agent。

    步驟 1:Clone 專案 + 安裝依賴

    git clone https://github.com/anthropics/skills.git
    cd skills
    
    # 依照專案說明,可能是
    pip install -e .
    # 或
    pip install -r requirements.txt
    

    行動:確認 python -m skills 或範例指令能跑起來(依官方 README 為準)。


    步驟 2:設定 API Key

    export ANTHROPIC_API_KEY="你的 Claude API key"
    

    Windows PowerShell:

    $env:ANTHROPIC_API_KEY="你的 Claude API key"
    

    行動:用 repo 提供的最小範例(例如 examples/basic_agent.py)跑一次,看 Claude 能不能成功呼叫某個內建 skill


    步驟 3:本機執行一個範例技能

    假設有一個簡單範例(名稱依實際 repo 為準):

    python examples/list_files_agent.py
    

    你可能會看到:

    • 問你「要在哪個資料夾工作」
    • Claude 自動呼叫 list_filesread_fileskills

    行動:換一個你自己的資料夾(例如放了一些 CSV 報表),觀察 Claude 如何使用 skills 幫你瀏覽、整理。


    步驟 4:改成自己的任務——每天抓一個 API、整理、丟 Slack

    目標:

    1. 每天叫一個公開 API(例如匯率、Crypto 價格)
    2. 整理成簡單文字報表
    3. 發成訊息到 Slack 頻道

    實作方向:

    1. 寫一個自訂 skill:
    # skills/custom/fetch_rates.py
    import requests
    
    from skills.core import skill  # 依實際框架命名
    
    @skill
    def fetch_rates(base: str = "USD"):
        """從匯率 API 取得最新匯率資料。"""
        url = f"https://api.exchangerate.host/latest?base={base}"
        r = requests.get(url, timeout=10)
        r.raise_for_status()
        return r.json()
    
    1. 再寫一個發 Slack 的 skill(用 webhook 即可):
    # skills/custom/post_to_slack.py
    import os
    import requests
    from skills.core import skill
    
    WEBHOOK = os.environ["SLACK_WEBHOOK_URL"]
    
    @skill
    def post_to_slack(text: str):
        """把文字訊息丟到預設 Slack 頻道。"""
        r = requests.post(WEBHOOK, json={"text": text}, timeout=10)
        r.raise_for_status()
        return {"status": "ok"}
    
    1. 寫一個小 Agent 腳本:
    from anthropic import Anthropic
    from skills.custom.fetch_rates import fetch_rates
    from skills.custom.post_to_slack import post_to_slack
    
    client = Anthropic()
    
    TOOLS = [fetch_rates.tool_def, post_to_slack.tool_def]
    
    prompt = """
    你是一個匯率小助理:
    1. 先用工具抓最新 USD 匯率
    2. 挑出 3 個對我們重要的幣別(EUR, JPY, TWD)
    3. 排版成一段適合 Slack 的中文簡報
    4. 用工具發到 Slack
    """
    
    resp = client.messages.create(
        model="claude-3-7-sonnet-20250219",
        max_tokens=1024,
        tools=TOOLS,
        messages=[{"role": "user", "content": prompt}]
    )
    
    1. 排程:

    2. Linux / macOS:用 cron 每天跑一次這個腳本

    3. Windows:用排程工作排每日執行

    到這裡,你就已經有一個「完全實用」的小 Agent,在幫你做每天的資訊整理與通知。


    最佳實踐:權限、安全與成本

    1. 限制權限:不要讓 Agent 隨便亂動

    • 檔案操作技能:
    • 設定 專用工作資料夾,例如 ./agent_workspace,只給這個路徑的讀寫權限。
    • API skills
    • 把 API key 存在環境變數或 secret manager,不要寫死在程式碼。

    2. 記錄 log:看得出 Agent 做了什麼

    • 為每個 skill 加上基本 logging
    • 呼叫時間
    • 參數(敏感資訊略過)
    • 成功 / 失敗
    • 方便之後調整 prompt 或參數,避免 Agent 做無用功。

    3. 控制成本:避免 runaway cost

    • 在建立 Claude 訊息時:
    • max_tokens 合理上限
    • 控制 context 長度(不要丟整個專案 repo,先丟必要檔案)
    • 如果是排程任務:
    • 從「每天一次」開始
    • 先跑一週看看用量,再決定要不要加頻率或多任務

    💡 關鍵: 先以低頻率、小 context、適中 max_tokens 測試一陣子,再逐步放大規模,可以有效避免成本爆衝。


    總結

    如果你:

    • 會一點 Python
    • 有一些重複的資訊工作
    • 不想研究整套 Agent 框架

    那以 Claude Skills 作為工具層,加上 Claude API 當腦,就足以在 5–10 分鐘內生出一個實用的小 Agent。先從一個最簡單、最無害的任務開始,把整個流程跑順,之後要擴充成多代理、多專案,只是多加幾個 skills 與排程而已。


    🚀 你現在可以做的事

    • 打開 anthropics/skills 並瀏覽 skills/ 目錄,挑 1–2 個看得懂的 skill 研究輸入輸出
    • 在本機依照文中步驟安裝 repo、設定 ANTHROPIC_API_KEY,跑一次官方範例 agent
    • 依照「匯率 + Slack」示例,改寫成你自己的每天例行任務(例如拉報表、整理 log、寄出摘要)
  • 讓 Notion 變成你的 AI Agent 中樞

    讓 Notion 變成你的 AI Agent 中樞

    📌 本文重點

    • Notion 成為托管多個 AI Agent 的工作台
    • 以狀態變化與欄位更新觸發各種自動化工作流
    • 結合外部 SaaS,打造從資料拉取到 AI 清洗的資料管線

    只要把 Agent 綁在 Notion 頁面和資料庫上,你就能用原本的工作區,托管多個 AI 助手,自動整理內容、跑專案流程、甚至接上外部 SaaS 資料管線。

    參考:Notion 開發者平台介紹(TechCrunch 報導)
    https://techcrunch.com/2026/05/13/notion-just-turned-its-workspace-into-a-hub-for-ai-agents/


    核心功能:Notion 現在是「Agent 工作台」

    💡 關鍵: 把 Agent 綁定在「頁面 / 資料庫」上,等於讓 Notion 變成專屬 AI 助手的工作台,而不是單純筆記工具。

    1. 在頁面 / 資料庫綁定 Agent

    你可以把 Agent 視為「住在某個頁面或資料庫裡的專屬助手」:

    • 每個資料庫都能指定一個或多個 Agent,負責:
    • 自動摘要新頁面內容
    • 解析出行動項(Action items)
    • 幫你填欄位(負責人、優先級、標籤)
    • 每個重要頁面(像 PRD、會議紀錄)可以加上「頁面專屬 Agent」,只處理這一頁的內容與後續追蹤。

    你可以做的事:

    • 為「Meeting Notes」資料庫新增一個 會議整理 Agent,設定規則:只要有新筆記,就產出摘要+行動項目,寫回同一筆紀錄的欄位。

    2. 依「狀態改變」自動執行工作流

    Notion 的資料庫欄位(StatusSelectCheckbox 等)可以變成觸發條件:

    • 例:任務狀態從 Todo → In progress
    • Agent 自動產生子任務(切分工作)
    • 寫一段「本週進度更新」到更新紀錄欄位
    • 例:狀態改為 Done
    • Agent 生成 Retro 小結
    • 自動發 Slack 通知給相關頻道

    你可以做的事:

    • 在「專案任務」資料庫加一個 狀態更新 Agent,規則:
    • Status 改成 In progress 時,自動新增 3–5 個子任務欄位建議,讓你選擇採用。

    3. 連接外部 API & 自家服務,變成資料管線

    透過 Notion 開發者平台,你可以把外部 SaaS 當作資料來源,丟進 Notion 再交給 Agent 清洗:

    • 從 CRM(如 HubSpot)、工單系統、回饋表單拉資料進一個「集中資料庫」
    • Agent 負責:
    • 解析文字欄位(工單描述、回饋內容)
    • 自動分類(類別、產品線、嚴重程度)
    • 加標籤或指派負責人

    你可以做的事:

    • 建一個 客戶回饋 資料庫,接上 HubSpot API,讓 Agent 自動幫每則回饋打標籤:功能請求 / Bug / 體驗問題。

    三種實戰場景:從內容、專案到資料管線

    💡 關鍵: 最穩起手式是「先在 Notion 裡把資料結構化」,再讓 Agent 針對欄位與內容運轉,而不是一開始就做複雜自動化。

    1)內容與知識管理:自動整理 PRD、會議紀錄

    典型設定方式:

    1. 建立一個 PRD 資料庫,每個 PRD 是一筆資料。
    2. 為這個資料庫綁定 產品文件 Agent,定義任務:
    3. 讀取 PRD 內容區塊
    4. 生成:
      • 300 字內摘要
      • 主要風險與假設
      • 需要決策的問題清單
    5. 生成內容寫回欄位(Summary / Risks / Decisions)。

    會議紀錄也一樣:

    • Meeting Notes 資料庫 + 會議助手 Agent
    • 生成摘要
    • 抽取行動項目
    • 自動填入 OwnerDue date 欄位(依你設定的規則或會議參與者)。

    你可以馬上做的事:
    挑一個你最常用的會議紀錄資料庫,新增一個文本欄位 AI 摘要,再設定一個 Agent 規則:新紀錄建立後 1 分鐘內,自動寫入摘要。


    2)專案與工作流:從狀態變化觸發自動化

    想像 Notion = Trello + AI 助手:

    例:產品開發看板

    • 資料庫欄位:StatusAssigneePriority更新紀錄 等。
    • 綁定 專案 Agent 規則:
    • StatusDesignDev:Agent 讀整個卡片內容,
      • 自動產出測試清單(Test cases)
      • 寫入 更新紀錄@QA 並貼測試重點
    • StatusReady for Release
      • Agent 產生一段英文 / 中文 release note 草稿
      • 寄出或貼到 Slack 產品頻道。

    你可以馬上做的事:

    • 在專案資料庫加一個 Release note draft 欄位,設定 Agent:只要任務進入 Ready for Release,就根據「變更內容」欄位自動生成初稿。

    3)資料管線:外部工具 → Notion → Agent 清洗

    把 Notion 當成「中間站」:

    範例流程:HubSpot → Notion → AI 標註

    1. 用 Notion developer platform 建立一個簡單整合:
    2. 定期呼叫 HubSpot API 拉新聯絡人 / 回饋
    3. 寫進 Notion LeadsFeedback 資料庫
    4. 綁定 銷售線索 Agent回饋分析 Agent
    5. 解析文字欄位(詢問內容、工單描述)
    6. 機會大小產品類別優先級 欄位。

    工單系統也類似:

    • 從 Zendesk / Jira Service Management 拉工單進 Notion
    • Agent 自動:
    • 判斷是否為緊急問題
    • 建議指派對象
    • 生出對客戶的回覆草稿。

    你可以馬上做的事:

    • 先選一個來源(如 HubSpot),只同步最小的一個表格(例如最近 50 筆 leads),專心把「自動分類與優先級」這一步做好,再往後串通知或報表。

    怎麼開始:從零到第一個「週報 Agent」

    💡 關鍵: 從一個很小、明確的用例(例如週報)開始,比一次導入整個專案管理更容易落地與調整。

    步驟 1:開啟 Notion 開發者平台權限

    1. 進入工作區 Settings & members
    2. Integrations / Developers 區塊啟用開發者平台(某些方案需管理員權限)。
    3. 建立一個新 Integration,取得:
    4. Integration ID / Secret
    5. 可存取的資料庫與頁面範圍(務必限制在必要範圍)。

    官方入口:https://www.notion.so/my-integrations (依實際帳號會導向對應頁面)

    行動建議:
    先只開放一個「實驗用」工作區或資料庫給這個 Integration,避免一開始就讓 Agent 看到整個公司內容。


    步驟 2:建立你的第一個 Agent ——「週報助手」

    目標:你在 Notion 填一週做了什麼,Agent 自動:

    • 產出精簡週報
    • 幫你分欄:本週亮點 / 風險 / 下週計畫

    設計方式:

    1. 建立一個 Weekly Report 資料庫,欄位:
    2. Week(日期 / 文字)
    3. Raw notes(你隨便輸入的本週記錄)
    4. Summary(AI 產生)
    5. HighlightsRisksNext week
    6. 在開發者平台中,創建一個 週報 Agent
    7. 觸發條件:Raw notes 更新
    8. 任務:讀取 Raw notes,用固定模板輸出 3 段內容,分別寫入三個欄位。

    你可以馬上做的事:
    找一週你真的很忙的那週,貼入原始 notes(甚至可以是 Slack 摘錄),讓 Agent 幫你整理,看輸出是否能直接拿去給主管或團隊。


    步驟 3:接一個常用 SaaS,從「一句需求」到「實際 automation」

    假設你想要:

    「每天把 HubSpot 新增的高潛力 leads 拉進 Notion,並且自動生成一段聯絡話術。」

    拆成執行步驟:

    1. 自然語言需求 → 規格
    2. 描述給你內部的 AI 或開發同事:
      • 資料來源:HubSpot 新增 leads
      • 條件:lead_score > 80
      • 寫入:Notion Leads 資料庫(Name / Company / Note
      • Agent 任務:為每一筆產生一段 100 字內的開場訊息。
    3. 實作連接腳本(Node / Python 皆可):
    4. 呼叫 HubSpot API 抓資料
    5. 使用 Notion API 建立資料庫項目
    6. 在 Notion 綁定 銷售話術 Agent
    7. 觸發:新 lead 建立
    8. 利用 lead 的欄位內容,生成個人化的聯絡訊息,寫入 Opening message 欄位。

    行動建議:
    先把這個流程做成「每天一次批次」而不是即時,方便你人工 review,一兩週成熟後再改成即時自動化。


    與 Zapier / Make 的差別在哪?

    工具類型 名稱 實際核心功能 免費方案 適合誰
    自動化平台 Zapier 連接上百種 SaaS,依事件觸發工作流 有,步數與任務量有限 以「事件轉發」為主的自動化(如表單 → Slack)
    自動化平台 Make 視覺化流程設計、條件分支豐富 有,執行次數有限 複雜條件、自定義 API 整合多
    Agent 中樞 Notion + Agents 在內容上下文中運行 Agent,直接操作頁面 / 資料庫 視方案與工作區設定而定 已把工作放在 Notion,上下文豐富、需要 AI 理解內容的人

    關鍵差異:

    • Zapier / Make:強在「事件與資料欄位」,邏輯清楚但不懂內容。
    • Notion + Agent:強在「內容與上下文」,適合需要理解長文、文件關係的自動化(PRD、會議、工單描述)。

    最實用的做法通常是:

    • 讓 Zapier / Make 負責「資料搬運」
    • 讓 Notion Agent 負責「讀懂內容、整理與生成」。

    安全與權限:啟用前要先想好的事

    在公司導入前,至少做這三件事:

    1. 縮小可見範圍
    2. 為每個 Agent 建立專用資料庫與頁面,不要一開始就給整個 workspace 權限。
    3. 區分測試與正式環境
    4. 先在 sandbox workspace 測試 prompt、輸出格式,再搬到正式專案。
    5. 記錄與監控
    6. 保留 Agent 執行紀錄(可考慮接像 Voker.ai 這類 agent analytics 工具)
    7. 定期 review Agent 產出,調整規則與權限。

    只要你把權限、資料範圍與監控設計好,Notion 就不再只是筆記本,而會變成團隊所有 AI Agent 的中樞:每天在你已經習慣的頁面和資料庫裡,默默跑完一堆你本來要手動做的事。


    🚀 你現在可以做的事

    • 在現有的 Meeting Notes 資料庫新增 AI 摘要 欄位,綁定一個簡單的會議整理 Agent 測試輸出品質
    • 建一個獨立的 Weekly Report 資料庫,實作文中「週報 Agent」流程,實際跑一週看看是否減少整理時間
    • 選一個你常用的 SaaS(如 HubSpot / Zendesk),只同步一小部分資料到 Notion,讓 Agent 做分類與摘要清洗實驗