標籤: MCP

  • 用 Docker 做一次性安全 AI Agent 沙盒

    用 Docker 做一次性安全 AI Agent 沙盒

    📌 本文重點

    • Agent 執行程式必須強制進 Docker 沙盒
    • 工具層限制不夠,需從執行環境畫界
    • 以最小權限、隔離與審計集中管理程式執行

    第一個痛點很直接:讓 Agent 能跑程式,又不讓它毀你主機、偷你資料或亂打外部服務。從 Rovo 被 PDF 隱藏指令牽著走,到 OpenClaw 為了搶健身房名額去「半駭半腳本」打 API,核心問題都是:你給了 Agent 工具權限,它就有能力放大任何輸入或目標的風險。本文的結論是實作面很務實:把「執行程式」這件事強制丟進一次性的 Docker 容器沙盒,搭配最小權限、網路/檔案隔離與審計,讓 Agent 成為受控服務,而不是在主機上為所欲為的黑盒。

    💡 關鍵: 把所有「程式執行」集中到一次性沙盒裡,是把 Agent 從高風險黑盒變成可控服務的核心做法


    重點說明

    1. 為什麼需要「一次性沙盒」而不是單純 API 限制

    • Rovo 的案例:攻擊者把指令藏在 PDF,Agent 幫忙從 Jira/Confluence 撈敏感資料,自動送到外部伺服器且不留操作痕跡。你就算限制 tool schema,還是擋不住「正當 API 被惡意使用」。
    • Gym hack 案例:OpenClaw 收到「幫我排到前面」這種模糊目標,就會自然探索網站邊界。只要你給它 HTTP client 或瀏覽器能力,沒有技術上的「這裡不能做」的牆。
    • 結論:工具層級的限制不夠,你必須在「執行環境」上畫界:這段 code 只能在隔離的容器裡跑;這個容器只能存取限定資料;超時就殺掉;所有輸出都被記錄與審核。

    💡 關鍵: 單靠限制工具參數無法阻止「正當 API 被惡用」,必須從執行環境切斷風險擴散路徑


    Docker 沙盒設計的核心原則

    1. 最小權限 + 只讀檔案系統

    • 使用非 root user、關掉不必要的 capabilities(CAP_NET_ADMIN 等)。
    • 根檔案系統 readonly,只有特定目錄(例如 /tmp/work)可寫,避免 Agent在容器內長期累積垃圾或做持久化攻擊。

    2. 網路與檔案系統隔離

    • 默認 無外網,只有明確允許的出口(例如企業 MCP / API gateway)。
    • 不掛宿主機目錄,尤其不要掛 /var/run/docker.sock,這是最常見的逃逸坑。
    • 針對多 Agent 系統,容器間一律不互通,避免 Agent 彼此側通道傳遞資料。

    3. 資源限制 + 超時

    • 用 --cpus、--memory、--pids-limit 等參數防止無限 fork/吃爆 RAM。
    • 在工具層加 硬超時(例如 5–30 秒), timeout 就 docker kill。

    4. 日誌與審計

    • 把 Agent 的 code、stdin、stdout、stderr 全部打包成事件,寫到集中式 log / SIEM。
    • 在多 Agent 架構中,透過 MCP / 工具網關,把「誰在什麼上下文下開了沙盒、跑了什麼」都留下 audit trail。

    多 Agent 系統裡的「動態沙盒策略」

    多 Agent coding 常見失敗點之一是:角色設計清楚,但行為邊界沒明確技術約束。建議是把沙盒視為一個「策略開關」:

    • 規劃幾種沙盒 profile:
    • analysis:只允許在容器內跑靜態分析工具,完全沒網路。
    • integration-test:允許打 staging 環境,有限 CPU/MEM。
    • prod-readonly:只能打只讀 API(例如查詢服務),禁止寫操作。

    • Controller Agent 不直接執行程式,而是呼叫一個 run_in_sandbox(profile, code) 工具,由工具決定 spawn 哪種 Docker 容器。

    • 所有 Agent 的「可執行能力」集中到這一個工具上,便於與企業現有 CI/CD、MCP、監控系統整合,把安全策略集中管理。

    💡 關鍵: 用多種沙盒 profile 對應不同 Agent 角色與任務,才能在安全與靈活之間做細緻權衡


    實作範例

    以下用 Python/Node 示範如何把 LLM 工具調用綁定到「在新容器內執行 code」。

    1. Docker 镜像設計

    這是一個極簡、偏安全的 Python 執行沙盒:

    # Dockerfile.sandbox
    FROM python:3.11-slim
    
    # 建立非 root 使用者
    RUN useradd -m sandbox && mkdir -p /app && chown -R sandbox:sandbox /app
    USER sandbox
    
    WORKDIR /app
    
    # 只安裝必要套件
    RUN pip install --no-cache-dir pytest requests
    
    # 預設為只讀根檔案系統;允許 /tmp/work 可寫(由 run script 控制)
    ENV PYTHONUNBUFFERED=1
    CMD ["python", "-u", "main.py"]
    

    注意:

    • 不要在這個鏡像裡放企業敏感設定檔或憑證。需要時改用 API gateway + 短期 token。
    • main.py 可以是一個固定的 runner,從環境變數或掛載目錄讀入待執行的 user code。

    2. Python:在新容器內執行 Agent 產生的程式碼

    假設你在後端定義了一個工具 run_code_in_sandbox 給 LLM 使用:

    import subprocess
    import tempfile
    import uuid
    from pathlib import Path
    
    SANDBOX_IMAGE = "my-org/agent-sandbox:latest"
    
    def run_code_in_sandbox(code: str, timeout_sec: int = 10) -> dict:
        # 為這次執行建立一次性工作目錄
        workdir = Path(tempfile.mkdtemp(prefix="agent-sandbox-"))
        script_path = workdir / "main.py"
        script_path.write_text(code, encoding="utf-8")
    
        container_name = f"agent-sandbox-{uuid.uuid4()}"
    
        cmd = [
            "docker", "run", "--rm",
            "--name", container_name,
            # 資源限制
            "--cpus", "0.5",          # 最多半顆 CPU
            "--memory", "512m",       # 限制記憶體
            "--pids-limit", "128",    # 限制子行程
            # 禁用網路:完全隔離
            "--network", "none",
            # 根檔案系統掛為 readonly
            "--read-only",
            # 掛載工作目錄到 /app,並提供 /tmp/work 可寫
            "-v", f"{workdir}:/app:ro",
            "-v", f"{workdir}/tmp:/tmp/work:rw",
            SANDBOX_IMAGE,
        ]
    
        try:
            proc = subprocess.run(
                cmd,
                capture_output=True,
                text=True,
                timeout=timeout_sec,
            )
        except subprocess.TimeoutExpired:
            # 超時直接 kill 容器
            subprocess.run(["docker", "kill", container_name], capture_output=True)
            return {"ok": False, "error": "timeout"}
    
        return {
            "ok": proc.returncode == 0,
            "stdout": proc.stdout,
            "stderr": proc.stderr,
            "exit_code": proc.returncode,
        }
    

    幾個關鍵點:

    • 沒有掛宿主機敏感目錄,也沒有掛 /var/run/docker.sock,避免 Agent 直接控制 Docker daemon。
    • --network none:這個 profile 完全不能出網。若要出網,請另外設計受控 network profile,例如只允許打企業 MCP gateway。
    • --read-only 搭配小範圍可寫目錄,避免 Agent 於容器內持久化惡意腳本。

    在你的 LLM tool schema 中,可以這樣暴露給模型:

    {
      "name": "run_code_in_sandbox",
      "description": "在隔離的 Docker 容器內執行短程式碼(無網路、有限資源)",
      "parameters": {
        "type": "object",
        "properties": {
          "language": {
            "type": "string",
            "enum": ["python"],
            "description": "目前只支援 Python"
          },
          "code": {
            "type": "string",
            "description": "要執行的程式碼,必須是單檔腳本"
          }
        },
        "required": ["language", "code"]
      }
    }
    

    3. Node.js:以 MCP / 工具網關方式整合

    如果你採用 MCP 或類似工具網關,建議把沙盒能力封裝成一個 service tool,而不是每個 Agent 都直接呼叫 Docker。

    // sandboxTool.ts
    import { execFile } from "child_process";
    import { promisify } from "util";
    const execFileAsync = promisify(execFile);
    
    export async function runInSandbox(params: {
      code: string;
      profile?: "analysis" | "integration-test";
    }) {
      const profile = params.profile ?? "analysis";
    
      const dockerArgs =
        profile === "integration-test"
          ? ["--cpus", "1", "--memory", "1g", "--network", "sandbox-staging"]
          : ["--cpus", "0.5", "--memory", "512m", "--network", "none"];
    
      const { stdout, stderr } = await execFileAsync("python", [
        "run_sandbox.py",
        JSON.stringify({ code: params.code, dockerArgs }),
      ], { timeout: 15000 });
    
      // 在這裡寫 audit log 到你的集中式監控
      // logSandboxEvent({ profile, codeSnippet: params.code.slice(0, 500), stdout, stderr })
    
      return { stdout, stderr };
    }
    

    在 MCP server 端,你只要把這個 runInSandbox 暴露為工具,並在工具 metadata 中標註:

    • scope:只允許特定角色的 Agent 使用(例如 CodeExecutor)。
    • audit:所有呼叫自動記錄到審計管線。

    這樣一來,企業的 Agent 系統就有一致的安全邊界:所有程式執行都要經過同一層沙盒服務,方便治理與合規。


    建議與注意事項

    1. 千萬不要掛宿主 Docker socket

    最常見也最危險的做法,是為了讓測試方便,直接在容器內掛:

    -v /var/run/docker.sock:/var/run/docker.sock
    

    這等同給了容器(也就是 Agent)對宿主機 Docker daemon 的完全控制權,能:

    • 啟動任意 privileged 容器;
    • 掛載宿主機任意路徑;
    • 讀取其他服務的環境變數與機密。

    結論:在 Agent 沙盒場景,禁止掛 docker.sock 是硬規則。 需要 orchestrate 容器時,請在宿主或受控 sidecar 上做,而不是讓 Agent 直接控制。

    2. 網路出口要明確設計,而不是「先開再說」

    • Rovo 被利用,就是因為 Agent默許能打外部網路,把敏感資料送走。
    • 建議預設 no egress,再逐步開放:
    • 只允許打企業 API gateway。
    • Gateway 再依使用者、任務、Agent role 做細粒度授權。

    避免一開始就給 Agent 完整的 requests / fetch 能力,卻沒有 outbound policy。

    3. 限制 fork、磁碟寫入與長時間運行

    • 使用 --pids-limit 防止 fork bomb。
    • 用 --read-only + 小範圍可寫目錄限制磁碟寫入,並定期清理一次性目錄。
    • 工具實作上務必加 硬超時,不可只依賴 Agent 自己判斷何時該結束。

    4. 在企業場景下與現有系統整合

    把 Agent 沙盒當成一個可以被納入現有治理架構的「服務」:

    • CI/CD:
    • 把沙盒鏡像視為一個版本化的 artifact,透過 pipeline 發布。
    • 變更權限、套件時要走同樣的審核流程。

    • MCP / 工具網關:

    • 透過 MCP 將沙盒工具集中管理,設定 scope(哪些 Agent 角色可以呼叫)、quota(每日執行次數)、審計策略。
    • 在多模型、多 Agent 環境中,統一用一套沙盒服務取代每個團隊自己寫的「隨便跑程式 API」。

    • 監控與審計:

    • 將每次沙盒執行事件(who / which agent / what code / which profile / result)送到 Log system / SIEM。
    • 在發現異常 pattern(例如大量嘗試未授權 API 操作)時,能快速追溯與調整策略。

    總結:Docker 沙盒的價值不只是「比較安全」,更是讓 Agent 行為可以被管理、可觀測、可審計。只要你把「執行程式」這件事全部強制走沙盒,並搭配最小權限與網路出口策略,你就能在保持開發效率的前提下,大幅降低 Rovo 類型的資料外洩與 OpenClaw 類型的「創意駭客」事件死角。


    🚀 你現在可以做的事

    • 在本機或測試環境建一個最小權限的 agent-sandbox Docker 鏡像,實驗一次性容器執行程式碼
    • 把現有 Agent 的「程式執行工具」改成呼叫 run_code_in_sandbox 類型服務,強制走沙盒
    • 檢查你的系統是否有容器掛載 /var/run/docker.sock 或無網路出口限制,列出並規劃修補清單
  • MCP 無狀態化後的企業 Agent 新架構

    MCP 無狀態化後的企業 Agent 新架構

    📌 本文重點

    • MCP 無狀態後,會話管理回到 Agent / Orchestrator
    • ACL、租戶隔離集中在 MCP Gateway 控制
    • Loop / graph / memory 拉升到框架層,工具端保持純 stateless

    MCP 改成無狀態(stateless)之後,一個很直接的好處是:你不必再在工具層維護「會話」。會話管理、記憶、ACL、租戶隔離,全部拉回到 Agent 平台或中間層控管。

    好處是:

    • 工具 server 更單純、可橫向擴展、可獨立部署與審核
    • 可觀察性與安全治理集中在一層,易於做 ADR 類型的觀察與基準測試
    • 任何「狀態」錯誤不會被藏在 MCP server 裡,而是明確暴露在 orchestration 層

    以下用一個典型架構:前端 Orchestrator + MCP Gateway + 多個工具 server,拆解你需要怎麼重構。


    重點說明:MCP 無狀態後的三個核心變更

    1. 會話被砍掉:改用 request-scoped metadata

    新版 MCP 刪除 session / conversation state,協議只管:

    • 一次呼叫的 工具名稱(tool)、參數(args)
    • 一組可選的 metadata / headers

    上下文與記憶不再由 MCP 持有,而是由:

    • Client / Orchestrator:維護任務 graph、loop、記憶
    • 中間層(MCP Gateway):附加租戶、風險標籤、追蹤 id
    • 工具端:只在必要時讀取 metadata,自己不產生「隱藏狀態」

    你要把原本塞在 MCP session 內的資訊,改寫成 每個 request 都帶的 metadata(如:tenant_id, agent_task_id, risk_level)。

    💡 關鍵: MCP 不再維護任何會話狀態,所有上下文都改成「每次請求顯式帶 metadata」,讓狀態集中在可治理的 Orchestrator 層。

    2. Stateless MCP 上做 ACL 與租戶隔離

    沒有 session,不代表不能做授權。反而更乾淨:

    • 每個 MCP request 都帶 caller identity(user / agent / tenant)
    • Gateway 根據 metadata 做 per-tool ACL,決定能不能 call 該工具
    • 工具 server 自身只 trust Gateway 轉給它的 identity,不自己管理 session

    典型做法是在 MCP 層定義:

    • x-tenant-id:租戶隔離
    • x-agent-id:是哪個 agent runtime/workflow
    • x-permissions:如 read:db,write:file,由 Gateway 檢查是否符合 policy

    3. Loop / Graph / Memory 抬升到框架層

    之前很多人把:

    • 迴圈控制(while loop)
    • 任務 graph / sub-agent 派工
    • 記憶(conversation history / RAG context)

    塞在 MCP server 裡,以為「工具端順便幫我記住上下文」。無狀態之後,你必須把這些搬到 Agent runtime / orchestration framework:

    • Loop:由 Orchestrator 控制是否繼續呼叫 MCP 工具
    • Graph:用 DAG / state machine(例如:Prefect、Temporal、自建 FSM)管理多步驟流程
    • Memory:由獨立記憶服務(Vector DB / KV store)持有,MCP 工具只接收明確的 context(如 docs_chunk_ids)

    這對專案的實際好處是:所有高風險邏輯集中在可治理的層,可以對 loop 數量、工具調用頻率、記憶寫入/讀取做 FinOps、審計與基準測試,而不是到處分散在工具端。

    💡 關鍵: Loop、graph 與 memory 全部拉回 Orchestrator,才能精準控管成本、風險與審計路徑。


    實作範例:用 request metadata 重建「會話」與治理

    以下用一個簡化範例示範:

    • 前端 Orchestrator(可能是自家 Agent runtime)
    • MCP Gateway(實際對接工具 server)
    • 多個 stateless MCP 工具

    1. Orchestrator:每次工具呼叫都帶 context_id / tenant

    # orchestrator.py
    import uuid
    from mcp_client import MCPClient  # 假設有這個 client SDK
    
    client = MCPClient(base_url="https://mcp-gateway.internal")
    
    async def run_agent_task(user_id: str, tenant_id: str, task_input: str):
        task_id = str(uuid.uuid4())
    
        # 這裡的 memory / graph 在 orchestrator 層
        memory_context = load_memory_for_user(user_id)
        workflow_state = init_workflow_state(task_input, memory_context)
    
        while not workflow_state.done:
            tool_request = workflow_state.next_tool_call()
    
            response = await client.call_tool(
                tool_name=tool_request.name,
                args=tool_request.args,
                headers={
                    "x-tenant-id": tenant_id,
                    "x-user-id": user_id,
                    "x-agent-task-id": task_id,
                    "x-workflow-step": str(workflow_state.step),
                    "x-risk-level": "normal",
                },
            )
    
            workflow_state = workflow_state.apply_tool_result(response)
            persist_step_log(task_id, workflow_state, response)
    
        save_memory_for_user(user_id, workflow_state.memory_delta)
        return workflow_state.final_output
    

    重點:

    • 沒有 session id,只有 task_id + step,所有狀態在 orchestrator 層
    • 每個 request 都有完整的治理 metadata,可給 ADR 類工具做觀察與威脅檢測

    💡 關鍵: 用 task_id + step 取代 session,把整個任務完整還原成可審計的步驟序列。

    2. MCP Gateway:per-tool ACL + 租戶隔離

    // mcp-gateway.ts (Node/TypeScript pseudo-code)
    import { verifyToken, checkAclPolicy } from "./auth";
    import { routeToToolServer } from "./router";
    
    async function handleMcpRequest(req, res) {
      const { toolName, args } = req.body;
      const headers = req.headers;
    
      const token = headers["authorization"];
      const identity = await verifyToken(token); // 解析 user/agent/tenant
    
      const tenantId = headers["x-tenant-id"] ?? identity.tenantId;
      const agentTaskId = headers["x-agent-task-id"];
    
      // ACL 檢查:哪些工具可被哪個 identity 使用
      const allowed = await checkAclPolicy({
        identity,
        tenantId,
        toolName,
      });
      if (!allowed) {
        return res.status(403).json({ error: "tool_not_allowed" });
      }
    
      // 建立統一的 observability context
      const observabilityContext = {
        tenantId,
        userId: identity.userId,
        agentId: identity.agentId,
        agentTaskId,
        toolName,
        timestamp: Date.now(),
        requestId: generateRequestId(),
      };
    
      logRequest(observabilityContext, args); // 提供給 ADR / SIEM
    
      const toolResponse = await routeToToolServer(toolName, args, {
        "x-tenant-id": tenantId,
        "x-agent-task-id": agentTaskId,
        "x-request-id": observabilityContext.requestId,
      });
    
      logResponse(observabilityContext, toolResponse);
      return res.json(toolResponse);
    }
    

    重點:

    • ACL 與租戶隔離在 Gateway 層,而不是工具 server 內部
    • observability context(requestId, agentTaskId, toolName)可以直接餵給 ADR 類似的威脅檢測/基準測試

    3. MCP 工具 server:純 stateless,禁止偷塞 state

    # tools/db_query_server.py
    from fastapi import FastAPI, Header
    
    app = FastAPI()
    
    @app.post("/tools/db_query")
    async def db_query(query: str, x_tenant_id: str = Header(...), x_agent_task_id: str = Header(None)):
        # 僅用 tenant_id 做資料邊界控制,不維護會話
        if not is_tenant_allowed_to_query(x_tenant_id, query):
            return {"error": "tenant_query_not_allowed"}
    
        result = execute_query_for_tenant(query, x_tenant_id)
    
        # 嚴禁在 server 內部開 global session dict
        return {
            "rows": result,
            "meta": {
                "agent_task_id": x_agent_task_id,
            },
        }
    

    重點:

    • 工具 server 僅依賴 headers 決定授權與資料範圍
    • 不建議在工具 server 開 global cache 作為「會話記憶」,避免破壞 stateless 模型與可觀察性

    建議與注意事項:遷移時常見坑與最佳實踐

    1. Server 假設有持久連線 / session

    舊版 MCP 或自家協定常常:

    • 用 WebSocket / 長連線維護 session
    • 把 user state 放在 in-memory dict(例如 sessions[user_id])

    在改成 stateless MCP 時:

    • 所有 state 都要變成可持久化的 store(DB / Redis / Vector DB),由 Orchestrator 控制
    • 工具端只讀取 request headers,不再假設「同一連線就是同一會話」

    實務建議:

    • 先畫出「哪些資料被當作 session state 使用」
    • 將它們搬到 明確的 Memory API 上(例如:load_memory(user_id) / save_memory(user_id, delta))

    2. 工具端偷塞 state,導致 log 無法重建任務路徑

    常見情境:

    • 工具 server 依賴 local cache / global dict 記住「上一次呼叫結果」
    • log 只有 request/response,但沒記錄「為什麼 agent 會做出這個決策」

    在 MCP 無狀態模型下,要做到可觀察性與安全基準測試(ADR 類工具),你需要:

    • 每個 step 的決策都由 Orchestrator log(含 prompt, context, tool call)
    • 工具 response 只是一個 pure function 輸出,不混入隱藏狀態

    實務建議:

    • 強制所有工具 server 通過 MCP Gateway,Gateway 追加 x-request-id,並集中 log
    • 在 Orchestrator 保存 完整任務 graph,例如:
    {
      "agent_task_id": "task-123",
      "steps": [
        {"step": 1, "tool": "search_docs", "request_id": "r-1"},
        {"step": 2, "tool": "db_query", "request_id": "r-2"}
      ]
    }
    

    有了這些資料,像 Uber 的 ADR 就可以做:

    • 單一任務的威脅路徑分析(哪一步嘗試讀敏感資料)
    • 持續的安全基準測試(某種輸入是否總是觸發高風險工具)

    3. Loop / Graph / Memory 不要塞在 MCP 裡

    受「while loop 就是 agent」的影響,很多人以前:

    • 在 MCP server 裡面直接實作 while loop 反覆 call LLM
    • 把 graph / workflow 寫在工具端 code 裡

    這在無狀態更新後會變成技術負債:

    • 難以在平台層做 FinOps(每個 loop 要花多少 token / 工具成本)
    • 難以對 loop 數量與深度做 安全限制(避免無限迴圈或風險疊加)

    最佳實踐:

    • Loop:在 Orchestrator(或專門的 agent runtime)層,用明確的限制,如 max_steps, max_cost
    • Graph:用可視化、可配置的 workflow 定義(YAML / JSON / DSL),不寫死在 MCP 工具程式碼裡
    • Memory:獨立成一個工具或服務(如 memory.read, memory.write),由 ACL 管控誰能讀寫

    4. 安全與治理:利用 stateless 做更強的控制平面

    MCP 無狀態其實大幅簡化了 企業級治理:

    • 所有工具呼叫都經過同一層 Gateway,可以:
    • 限制每個 agent / tenant 的 工具配額與成本
    • 對特定工具設高風險標籤,必須經過額外審核或輸入過濾
    • Observability context(tenantId, agentTaskId, toolName, requestId)可以直接餵給:
    • ADR / SIEM / 自家監控平台,做威脅檢測與基準測試

    實務上,你可以定義一個簡單的 治理 schema:

    # governance.yaml
    agents:
      finance_report_agent:
        max_tool_calls: 50
        allowed_tools:
          - db_read_only
          - email_notify
        risk_budget: medium
    
    tools:
      db_read_only:
        risk_level: high
        requires_human_review: true
    

    然後在 Orchestrator + MCP Gateway 共同實作:

    • 在 loop 前檢查 max_tool_calls
    • Gateway 看到 risk_level: high 時,會把這些 call 寫入特別的安全 log,供 ADR 分析

    結論

    MCP 無狀態化的關鍵結論:

    • 會話狀態不再是協議責任,而是 Agent 平台責任
    • 上下文與記憶要由 client / orchestration / memory 工具明確持有
    • stateless 帶來更乾淨的可觀察性與安全治理模型,能與 ADR 這類工具自然整合

    如果你的企業 Agent 平台還在仰賴 MCP session 或工具端隱藏 state,現在是重構的好時機:把 loop、graph、memory、ACL、租戶隔離全部拉回到框架層,留給 MCP 的只有乾淨、可審核、可擴展的工具呼叫。

    🚀 你現在可以做的事

    • 審視現有 MCP / 工具 server,列出所有依賴 session 或 in-memory state 的地方,規劃改成 metadata + Orchestrator state
    • 為 MCP Gateway 增加 x-tenant-id、x-agent-task-id、x-request-id 等 headers,並接入現有的 ADR / SIEM / 監控系統
    • 設計一份 governance.yaml 或類似設定檔,為主要 agent 定義 max_tool_calls、allowed_tools 與 risk_budget,並在 Orchestrator 中強制執行
  • MCP 實戰:讓 AI 像 USB-C 一樣接工具

    MCP 實戰:讓 AI 像 USB-C 一樣接工具

    📌 本文重點

    • MCP 讓工具接入一次即可多客戶端共用
    • 安全與權限集中在 MCP 層,比直接給 API 安全
    • 多代理、多工具、多客戶端場景特別適合用 MCP
    • MCP server 要當成長期基礎設施來管理

    MCP 解決的核心痛點很直接:你不需要再為每個系統寫一套專屬「AI 版 API」。不管是日曆、TradingView、內部 CRM 或 CI/CD,大多數情況下只要掛一個 MCP server,所有支援 MCP 的客戶端(Claude Desktop、Cursor、VS Code 等)就能共用這個入口。對有多代理、多產品線的團隊來說,這代表 一次接好、到處用,權限與治理集中在 MCP 層,減少「每個 Agent 一套整合程式」的維護地獄。

    💡 關鍵: MCP 讓一個工具整合點可被多個客戶端共用,顯著降低整合與維護成本。


    重點說明:為什麼需要「AI 的 USB-C」

    1. 協議 vs. API:少寫一層 Glue Code

    傳統作法:

    • 為 LLM/Agent 寫一個 HTTP API 或 SDK
    • 再在每個客戶端(聊天機器人、VS Code 擴充、內部 Agent 平台)各自寫一份整合

    MCP 的做法:

    • 定義標準能力:tools、resources、prompts、采樣事件(sampling) 等
    • 你只要寫一個 MCP server,宣告有哪些可呼叫的工具、如何讀資料
    • 任意 MCP client 都知道怎麼:列出工具、呼叫工具、抓資料、處理錯誤

    好處:

    • 工程師不再為每個模型/產品寫客製 API;改成「一次 MCP server,多客戶端共用」
    • 權限管控、審計 log、錯誤格式集中在 MCP,企業合規更好做

    💡 關鍵: 把「API 風格」升級成「協議層」,能在團隊內統一權限與錯誤處理,減少重複整合工作。

    2. 安全模型:把「能用什麼工具」變成顯式設定

    MCP 把工具能力變成顯式宣告:

    • tools:可呼叫的動作(例如 create_event、run_query、place_order)
    • resources:只讀或有限寫入的資料源(例如日曆列表、DB 查詢結果)

    在 Claude Desktop / Remote OpenClaw 類的平台中,你可以:

    • 用設定檔限制哪些 MCP server 可用
    • 在 server 端做 API key、角色權限 判斷

    這比「直接把 DB URL 給 Agent」安全許多:

    • Agent 只能透過 明確定義的 tool 操作,不能隨意執行 SQL
    • 所有操作都有 統一的 request/response schema,便於審計與監控

    💡 關鍵: 把安全規則寫進 MCP server 的權限與 schema,比依賴提示詞更可控又可審計。

    3. 適用情境:什麼時候選 MCP,什麼時候維持 CLI / HTTP

    結合 Towards AI 的觀點(#33、#113):

    適合 MCP 的情境:

    • 你有 多種客戶端(不同 IDE、Chat UI、多代理平台)要共用同一組工具
    • 工具操作需要 細緻權限控管與觀測性(企業環境、金融交易、內網系統)
    • 希望未來可以接其他 MCP 生態(像 Remote OpenClaw 的 13,000+ server)

    不適合 MCP(先用 CLI/HTTP)的情境:

    • 單一腳本或單一產品內部,沒有要對外共享工具
    • 工具邏輯已經是穩定 CLI / REST API,Agent 只是偶爾呼叫
    • 團隊還沒能力維護一層協議 server,多一層只會變技術債

    一句話總結:MCP 是面向「多代理、多工具、多客戶端」的協議層;單工具小專案,CLI/HTTP 通常更便宜。


    實作範例:寫一個最小可用 MCP server

    以下用 Node.js 示意一個最小的 MCP server,暴露「日曆建立事件」與「查資料庫」兩個能力,讓 LLM/Agent 可以透過 MCP 呼叫。

    注意:為了篇幅,用近似概念的虛擬碼,重點在 MCP 結構與安全邏輯,而不是完整實作細節。

    1. Server 結構:宣告 tools 與基本 metadata

    // mcp-server.ts
    import {
      createMcpServer,
      ToolDefinition,
      McpRequest,
      McpResponse,
    } from 'mcp-core'; // 假想 MCP 基礎庫
    
    const tools: ToolDefinition[] = [
      {
        name: 'create_calendar_event',
        description: '在使用者的日曆中建立事件',
        inputSchema: {
          type: 'object',
          required: ['title', 'start', 'end'],
          properties: {
            title: { type: 'string' },
            start: { type: 'string', format: 'date-time' },
            end: { type: 'string', format: 'date-time' },
            attendees: { type: 'array', items: { type: 'string', format: 'email' } },
          },
        },
      },
      {
        name: 'run_report_query',
        description: '在報表資料庫上執行安全查詢',
        inputSchema: {
          type: 'object',
          required: ['report_name'],
          properties: {
            report_name: { type: 'string' },
            from: { type: 'string', format: 'date' },
            to: { type: 'string', format: 'date' },
          },
        },
      },
    ];
    
    const server = createMcpServer({
      name: 'internal-tools-server',
      version: '1.0.0',
      tools,
    });
    
    server.onToolCall('create_calendar_event', async (req: McpRequest) => {
      const user = await authenticate(req); // ✅ 先做身份確認
      authorize(user, 'calendar:write');    // ✅ 再做權限確認
    
      const { title, start, end, attendees } = req.input;
      const eventId = await calendarApi.createEvent({
        ownerId: user.id,
        title,
        start,
        end,
        attendees,
      });
    
      const res: McpResponse = {
        status: 'ok',
        data: { eventId },
      };
      return res;
    });
    
    server.onToolCall('run_report_query', async (req: McpRequest) => {
      const user = await authenticate(req);
      authorize(user, `report:${req.input.report_name}:read`);
    
      try {
        const rows = await db.safeReportQuery({
          reportName: req.input.report_name,
          from: req.input.from,
          to: req.input.to,
        });
    
        return { status: 'ok', data: rows };
      } catch (err) {
        // ✅ 統一錯誤格式,讓 client/Agent 好處理
        return {
          status: 'error',
          errorType: 'DB_ERROR',
          message: 'Report query failed',
          detail: process.env.NODE_ENV === 'production' ? undefined : String(err),
        };
      }
    });
    
    server.listen();
    

    關鍵點:

    • MCP 層不做太多業務邏輯,只做 工具宣告、調度、權限與錯誤格式統一
    • 上游客戶端(Claude Desktop 等)能列出 tools,並請 LLM 自行決定何時呼叫

    2. 客戶端配置片段:讓 Claude / Agent 知道有這個 server

    以 Claude Desktop 設定檔為例(非官方格式,示意):

    // claude-desktop-mcp.json
    {
      "servers": [
        {
          "id": "internal-tools",
          "name": "Internal Tools Server",
          "endpoint": "https://mcp.example.com",
          "auth": {
            "type": "token",
            "env": "MCP_INTERNAL_TOKEN" // ✅ 用環境變數注入
          },
          "tools": [
            "create_calendar_event",
            "run_report_query"
          ],
          "permissions": {
            "create_calendar_event": {
              "allowed_users": ["alice", "bob"],
              "max_calls_per_session": 5
            },
            "run_report_query": {
              "allowed_roles": ["manager", "analyst"]
            }
          }
        }
      ]
    }
    

    對開發者的實際好處:

    • 新增一個工具(例如 cancel_event)只改 MCP server;所有支援 MCP 的客戶端自動能用
    • 權限策略集中在一份設定檔和 server 邏輯;不需要在每個 Agent 都重複實作

    3. TradingView / Remote OpenClaw 類場景的延伸

    以 tradingview-mcp 為例,核心想法類似:

    • MCP server 包一層 TradingView Desktop 的操作能力(讀圖表資料、下單、拉指標)
    • Claude/Agent 在對話中決定何時呼叫 get_chart_state、suggest_trades 等 tool

    對 FinTech 專案的實際好處:

    • 新增一個策略或指標,只要在 MCP server 定義新的 tool,不必改聊天 UI 或 IDE 擴充
    • 可以在 MCP 層做 風控(最大下單金額、白名單市場),避免 Agent 直接碰交易 API

    Remote OpenClaw 類平台則把這件事做成 工具市場:

    • 13,000+ MCP server / skills,以統一協議掛進多代理系統
    • 你可以只寫「自己內部系統的 MCP server」,然後利用平台既有的工具擴展能力

    建議與注意事項:避免 MCP 變成新技術債

    1. 權限控制:把風險鎖在 MCP 層,而不是 Agent Prompt

    常見錯誤:

    • 把風控寫在「系統提示詞」裡:「請不要刪除任何資料」

    這樣很脆弱。正確作法:

    • 在 MCP server 的 authorize() 裡明確限制可做的事:
    • 讀操作 vs 寫操作分開 tool
    • 依使用者/角色限制可呼叫的 tool
    • 設定 rate limit、最大影響範圍(例如最多只查 30 天內的資料)

    核心結論:安全規則必須寫在可驗證的程式碼與設定,而不是交給 LLM 理解。

    2. 錯誤處理:統一格式,讓 Agent 能有策略反應

    讓所有工具的錯誤返回遵守一個 schema,例如:

    {
      "status": "error",
      "errorType": "UNAUTHORIZED", // or DB_ERROR, VALIDATION_ERROR
      "message": "User not allowed to run this report",
      "hint": "請聯絡管理員開啟 report:weekly-sales 權限"
    }
    

    實務好處:

    • Agent 能學會針對不同 errorType 有不同回應策略(重試、改參數、詢問人類)
    • 觀測系統可以直接按 errorType 做統計與警報,而不是解析雜亂文字訊息

    3. 版本管理:把 MCP server 當成一個獨立產品

    常見坑:

    • 在 MCP server 隨意改 tool schema,結果所有 Agent prompt 壞掉

    最佳實踐:

    • 給 MCP server 明確版本,例如 internal-tools-server@1.2.0
    • 改動 inputSchema / outputSchema 時,使用 新 tool 名稱或新 version tag
    • 為重要工具保留 向下相容行為,或至少加上清楚的 deprecation 訊息

    4. 觀測性:沒有監控的 MCP = 黑箱

    避免 MCP 變成黑箱需要:

    • 為每次 tool call 記錄:使用者、tool 名稱、參數摘要、執行時間、結果/錯誤
    • 對關鍵工具(交易、刪除、批量更新)增加 審計 log 與告警
    • 在多代理環境(像 Remote OpenClaw)記錄 哪個 Agent 發起了呼叫,方便追責

    這些 log 最好整合到既有 APM/Logging 系統,而不是 MCP server 自己寫一套。

    5. MCP vs. CLI / HTTP 的取捨準則

    綜合以上經驗,可用以下簡化決策:

    • 如果你的工具:
    • 僅在單一服務/專案內使用
    • 沒有複雜權限 / 審計要求
    • 已有穩定 CLI 或 REST API

    結論:先保持 CLI / HTTP,透過簡單 wrapper 給 Agent 用就好。

    • 如果你的工具:
    • 要被 多種 Agent / IDE / Chat UI 共用
    • 涉及敏感資料或關鍵操作,需要集中治理
    • 希望未來快速接入 MCP 生態(Remote OpenClaw、第三方工具市場)

    結論:投資 MCP server 是值得的,並把它當成長期基礎設施管理。


    收斂:對你的專案的實際好處

    如果你正在建多代理平台、內部 AI 協作工具或金融交易輔助系統:

    • MCP 幫你把「如何連接工具」抽象成標準協議,減少重複 Glue Code
    • 專案可以快速掛載像 tradingview-mcp 或 Remote OpenClaw 上的現成技能
    • 權限、安全與觀測性集中在 MCP 層,讓你可以放心讓更多 Agent 自動操作

    前提是:你願意認真設計 MCP server 的權限、錯誤與版本管理,而不是把它當「再多一個 API」。這樣 MCP 才會變成你 AI 架構的 USB-C,而不是新的技術債。

    🚀 你現在可以做的事

    • 審視現有內部 CLI / HTTP 工具,挑選一個多客戶端共用場景嘗試寫第一個 MCP server
    • 為預計要 MCP 化的工具先設計 tool 的 inputSchema / outputSchema 與權限策略
    • 到 Remote OpenClaw 或類似平台搜尋現成 MCP server,評估哪些可直接掛入你的多代理系統
  • 用 Gemini Managed Agents 搭建可控多代理系統

    用 Gemini Managed Agents 搭建可控多代理系統

    📌 本文重點

    • Managed Agents 讓多代理 workflow 更可控可審計
    • 背景任務與長流程能安全持續運行
    • remote MCP + 沙盒工具提升協作與安全
    • 憑證輪替支援零信任長連線場景

    Gemini Managed Agents 的最新更新,直接解決了多代理系統在實務上的四個痛點:長流程容易中斷、背景任務難管理、多代理協作缺乏控制平面、工具執行缺乏安全邊界、長連線憑證管理容易出事。如果你目前只是在做「單模型聊天 + 幾個工具」,這批能力讓你可以往「有審計、有重試、有觀測性」的多代理 workflow 進化,而且不需要自己再搭一層任務編排框架。


    重點說明

    1. 背景任務與長流程編排:從同步聊天到任務隊列

    新的 Managed Agents 支援在代理內啟動 背景任務(background tasks),並維持任務狀態。

    關鍵好處:

    • 可以把耗時操作(例如 ETL、長時間 API 輪詢、批次報表)移到背景,不阻塞前端對話。
    • 每個背景任務都有 狀態與 ID,便於你實作自家任務隊列、重試策略與恢復機制。
    • 代理本身幫你維護「對話上下文 + 任務上下文」,你只需在外層規劃任務生命週期。

    💡 關鍵: 把長流程變成有狀態、可重試的背景任務,是從「聊天玩具」升級成「可靠工作流系統」的關鍵一步。

    典型設計:

    • 前端對話 → 由主 Agent 判斷是否需要啟動背景任務。
    • 使用 Agents API 建立 task,狀態儲存在 Managed Agents 內部或你自己的 DB。
    • 外部有一個「任務監控 worker」定期查詢任務狀態、做重試或告警。

    2. remote MCP / 多代理協作:控制平面 vs 應用層 SDK

    Managed Agents 現在可以直接連到 remote MCP。實務上有兩種典型 architecture:

    • 控制平面導向(Control Plane first):
    • 多個工具 / 子代理掛在 MCP server(例如一個 operations MCP、一個 data MCP)。
    • Managed Agent 只要知道 MCP endpoint,就能呼叫裡面的工具。
    • 適合大型企業,把權限、審計、資源配額集中放在 MCP 層。

    • 應用層 SDK 導向(SDK first):

    • 你在應用程式碼中透過 SDK 把工具包成 Gemini Tool / Functions,再掛到 Managed Agents。
    • 權限管理偏向 app side,例如每個 tenant 對應一組工具設定。

    關鍵差異在 權限與隔離:

    • 控制平面模式:透過 MCP 做 RBAC、租戶隔離、審計;Managed Agent 像「智慧前端」。
    • SDK 模式:更靈活,適合快速迭代,但要自己補一套完整審計與 resource control。

    3. 安全沙盒內整合自定義工具與函式

    更新後的 Managed Agents 允許在 安全沙盒(sandbox) 同時使用:

    • 官方 sandbox 工具(如瀏覽器、code executor)。
    • 你自定義的 functions / tools。

    好處:

    • 你可以在受控環境內執行「可能有副作用」的操作,例如 DB query、檔案處理,而不直接暴露到外部系統。
    • 工具執行與 LLM 推理同樣有 超時與資源配額 控制,避免單一任務吃光整個 pod。

    設計重點:

    • 每個工具要有明確的 作用範圍(只讀 / 可寫),把「刪除、修改」操作拆成獨立工具並 預設關閉。
    • 在工具層做 輸入驗證與錯誤處理,避免 LLM 亂塞參數導致意外副作用。

    4. 憑證刷新與長連線安全:token 旋轉 + 零信任

    Managed Agents 支援在 不丟失 state 的情況下刷新憑證:

    • 代理可以維持長流程(幾小時到幾天)的狀態,同時你的服務端可以定期輪替 API token、OIDC access token。
    • 這讓零信任架構更好落地:
    • 不再有「因為流程長,只好給超長效 token」的妥協。
    • 可以要求所有外部呼叫都透過短效憑證 + 中央驗證服務。

    💡 關鍵: 「長流程 + 短效憑證」的組合,讓零信任不再與實務需求衝突。


    實作範例

    以下用一個從「單模型聊天」升級成「有背景任務 + 多代理協作 + 審計」的簡化範例示意(以 Node.js 伺服器 + Gemini API 為例,為示意用虛擬碼)。

    1. 建立核心 Managed Agent

    import { AgentsClient } from "@google-ai/gemini";
    
    const agents = new AgentsClient({
      projectId: process.env.GCP_PROJECT_ID,
      location: "global",
    });
    
    // 建立主 Agent:負責對話 + 任務編排
    async function createMainAgent() {
      const [agent] = await agents.createAgent({
        parent: "projects/xxx/locations/global",
        agent: {
          displayName: "orchestrator-agent",
          model: "gemini-2.0-pro",
          // 掛上 MCP 與工具
          tools: [
            { mcpServer: { endpoint: process.env.MCP_OPS_URL } },
            { mcpServer: { endpoint: process.env.MCP_DATA_URL } },
            { functionDeclarations: [
              {
                name: "schedule_background_job",
                description: "Create a background task for long-running workflow",
                parameters: {
                  type: "object",
                  properties: {
                    jobType: { type: "string" },
                    payload: { type: "object" },
                  },
                  required: ["jobType", "payload"],
                },
              },
            ]},
          ],
          // 安全設定:限制可寫操作
          safetySettings: {
            allowWriteOps: false,
          },
        },
      });
    
      return agent.name; // 用來後續呼叫
    }
    

    重點:

    • 用 AgentsClient.createAgent 建立主 Agent,掛上多個 MCP 伺服器 與自定義 function。
    • safetySettings 示意限制寫入操作,實務上可自訂更細。

    2. 前端對話:從「單次聊天」變成可啟動背景任務

    // 使用者傳入訊息,主 Agent 可能決定啟動背景任務
    async function handleUserMessage(agentName: string, sessionId: string, text: string) {
      const [response] = await agents.generateMessage({
        name: agentName,
        // sessionId 用你自己的,方便日後審計與追蹤
        session: { id: sessionId },
        prompt: { text },
      });
    
      // 若 LLM 觸發工具呼叫,可能是 schedule_background_job
      if (response.toolCall) {
        const call = response.toolCall;
        if (call.name === "schedule_background_job") {
          const taskId = await createBackgroundTask(call.args);
          // 把 taskId 回寫到對話,讓使用者可以查詢
          return { reply: `已建立背景任務,ID: ${taskId}` };
        }
      }
    
      return { reply: response.outputText };
    }
    

    這裡用 generateMessage(或官方實際命名類似方法)示意:

    • 你自己維護 sessionId,不要依賴傳輸層的 session 概念,以免遇到像 MCP 無狀態 變更就斷鏈。
    • 工具呼叫觸發後,交給應用層建立背景任務。

    3. 背景任務隊列與重試設計

    // 簡化版任務建立
    async function createBackgroundTask({ jobType, payload }) {
      const taskId = crypto.randomUUID();
    
      await db.tasks.insert({
        id: taskId,
        type: jobType,
        payload,
        status: "pending",
        retryCount: 0,
      });
    
      return taskId;
    }
    
    // 任務 worker:定期跑
    async function taskWorkerLoop() {
      const tasks = await db.tasks.find({
        status: { $in: ["pending", "retry"] },
      }).limit(50);
    
      for (const task of tasks) {
        try {
          await runTask(task); // 實際呼叫 MCP 或其他工具
          await db.tasks.update(task.id, { status: "done" });
        } catch (err) {
          const nextRetry = task.retryCount + 1;
          if (nextRetry > 3) {
            await db.tasks.update(task.id, { status: "failed" });
          } else {
            await db.tasks.update(task.id, {
              status: "retry",
              retryCount: nextRetry,
            });
          }
        }
      }
    }
    

    重點:

    • 背景任務管理放在你的應用層,但任務內容可以是對 Managed Agents / MCP 工具 的呼叫。
    • 任務狀態與重試策略明確放在 DB,避免「背景任務孤兒進程」沒人管。

    4. 憑證刷新與零信任示意

    // 透過中介層取得短效 token,供 AgentsClient 使用
    async function getAgentsClient() {
      const token = await authService.getRotatingToken(); // 有效期 15 分鐘
      return new AgentsClient({
        authToken: token,
        projectId: process.env.GCP_PROJECT_ID,
      });
    }
    
    // 每次呼叫都用最新 token
    async function safeGenerateMessage(agentName, sessionId, text) {
      const client = await getAgentsClient();
      const [response] = await client.generateMessage({
        name: agentName,
        session: { id: sessionId },
        prompt: { text },
      });
      return response;
    }
    

    這種做法搭配 Managed Agents 的「不丟 state 憑證刷新」能力,可以在維持長流程的同時,讓底層 token 持續輪替。


    建議與注意事項

    1. 防止 Agent 自動刪庫型事故

    • 所有「修改 / 刪除」類工具:
    • 預設不掛到主 Agent,改掛到專門的「ops Agent」,再用人工或嚴格策略觸發。
    • 在工具層做 白名單 / 黑名單 檢查,例如禁止 DROP TABLE、限制影響範圍。
    • 所有高風險操作應要求:
    • 二次確認(LLM 生成計畫 → 使用者或守門服務審核 → 才執行)。

    2. 審計與回溯:不要把責任丟給 MCP

    MCP 轉為 stateless 之後,如果你沒自己建立 trace id,就會遇到:

    • 同一條資金轉帳流程,log 看起來是四個不相干的事件,無法證明「誰觸發了什麼」。

    建議:

    • 在應用層產生 correlationId / traceId,寫入:
    • 所有 Agents API 呼叫
    • MCP 請求的 metadata
    • DB 任務表與 log 系統
    • 在出事時可以把「對話 → Agent 決策 → MCP 工具呼叫 → DB 操作」串回一條 timeline。

    3. 背景任務治理:避免孤兒進程與資源爆炸

    • 每個任務必須有:
    • 明確 status(pending / running / retry / failed / done)。
    • 最大重試次數與 退避策略(exponential backoff)。
    • 超時與最大執行時間限制。
    • 週期性 job 清理:
    • 清掉超過 SLA 的 pending 任務,標記為 timeout_failed。
    • 對高失敗率任務發告警,不要無限重試打爆外部 API。

    4. 多代理協作架構選型

    • 團隊偏「平台 / SRE」:建議 控制平面模式,用 MCP 集中治理,Managed Agents 做業務邏輯。
    • 團隊偏「產品 /快速迭代」:先用 SDK 模式,在 app 層掛工具,後續再逐步抽到 MCP。

    5. Observability:為多代理 workflow 補上眼睛

    • 最低限度:
    • 每次 Agent 呼叫記錄:agentName、sessionId、traceId、使用工具列表、執行結果。
    • 建議導入:
    • 分散追蹤(如 OpenTelemetry),把 Agents / MCP / DB 統一進 tracing system。
    • 守門 dashboard:顯示背景任務隊列狀態、失敗率、平均耗時。

    結論:Gemini Managed Agents 的背景任務、remote MCP、安全沙盒工具與憑證刷新能力,讓你可以在現有專案裡自然從「單模型聊天」過渡到「可控、可審計的多代理 workflow」。核心心法是:把任務編排與審計留在應用層,讓 Managed Agents 專心做協作與自動化,並以零信任與資源治理觀點設計整體架構。

    🚀 你現在可以做的事

    • 在現有聊天應用中加入 sessionId、traceId 與簡單任務表,開始嘗試背景任務編排
    • 盤點現有工具,決定哪些適合掛在 MCP、哪些用 SDK 模式直接掛到 Managed Agents
    • 規劃短效 token 取得流程,實作一個中介層 authService.getRotatingToken() 來配合 Managed Agents 使用
  • Flint:讓 AI 也畫得出專業圖表

    Flint:讓 AI 也畫得出專業圖表

    📌 本文重點

    • Flint 讓 LLM 用簡單 JSON 就能畫出專業圖表
    • 透過中介視覺語言,把美觀與排版細節交給 Flint
    • 搭配 Data Formulator/MCP,可在多種場景自動出圖

    多數 LLM 雖然會「描述圖」,卻很難畫出乾淨、專業、可維護的圖表,Flint 就是專門幫 AI 接手這段「從文字到好圖」的工作。


    為什麼一般 LLM 畫圖總是歪掉?

    如果你用過 LLM 直接輸出 Vega-Lite、ECharts、Matplotlib,大概遇過這些情況:

    • 圖是畫出來了,但:
    • 顏色、比例亂選,看起來很業餘
    • 標軸標籤打錯、重疊、或被擠出畫面
    • 圖例、格線沒有依照人類習慣排版
    • 為了避免出錯,只敢給 LLM 很簡單的設定 → 圖表品質又退回系統預設
    • 一旦你說「把折線圖改成雙軸圖,多加一條移動平均」,整段 spec 幾乎要重寫

    Flint 的切入點是:不是 LLM 太笨,而是現有圖表語言太「底層」,逼模型做太多視覺細節決策。Flint 改成「中介視覺語言 + 自動排版引擎」,讓 LLM 只說高階意圖,低階美觀細節交給 Flint。

    💡 關鍵: Flint 把圖表設計拆成高階意圖與低階排版,讓 LLM 專心決策「畫什麼」,而 Flint 負責「怎麼畫得好看」。


    核心功能:Flint 幫 AI 補完「設計力」

    1. 中介視覺語言:LLM 只需要說人話版的圖表需求

    Flint 把圖表拆成幾個高階概念:

    • data: 用哪些欄位
    • mapping: 哪個欄位對應到 x、y、顏色、大小
    • mark: 用折線、長條、區域等標記
    • layout & style: 留給 Flint 自動排版與預設樣式

    LLM 只要輸出一份簡潔的 JSON,Flint 會負責:

    • 均衡配色
    • 合理的軸刻度、標籤格式
    • 避免文字重疊、圖例遮擋

    你可以做的事:在自己的 LLM 工具裡,把「請幫我生出完整 ECharts/Vega spec」改成「請輸出 Flint JSON」,再由後端把 Flint JSON 丟給 Flint 編譯成最終圖表。

    2. 與 Data Formulator 深度整合:圖表可以點一點改

    Data Formulator 是微軟另一個開源專案,可以視覺化地編輯 Flint 圖表:

    • 左邊是資料表
    • 中間是圖表
    • 右邊是 Flint 規格(JSON)

    你可以:

    • 讓 LLM 先產出 Flint 規格
    • 使用者在 Data Formulator 裡微調(拖拉欄位、改顏色)
    • 再把調整後的 Flint JSON 存回系統 → 變成可持久化的「報表模版」

    你可以做的事:把 Data Formulator 部署在內網,給資料分析團隊當「AI 生成初版圖表,人手最後調整」的工作台。

    3. MCP 伺服器:任何 Agent 都能叫 Flint 畫圖

    Flint 官方提供了符合 Model Context Protocol (MCP) 的伺服器,意思是:

    • 你用哪一家的 LLM / Agent 幾乎都不重要
    • 只要支援 MCP,就能把 Flint 當成「畫圖工具」來呼叫

    流程通常是:

    1. Agent 讀取你給的資料
    2. Agent 生成 Flint JSON
    3. 呼叫 Flint MCP 伺服器 → 回傳可嵌入網頁的圖表(或 Vega spec 等)

    你可以做的事:在自家 Agent(如 OpenAI, Claude, 自建 Llama)中,註冊 Flint MCP 工具,讓 Agent 回答問題時順手出圖,而不是只給一長段文字分析。


    適合誰用?三個具體場景

    1. 資料分析報告自動出圖

    情境:你每週要交「流量報告」、「營收報表」,但每次調整維度、時間區間都得重畫圖。

    用法:

    • 把數據放在資料庫或 CSV
    • 讓 LLM 讀取後,產出 Flint JSON
    • Flint 編譯成固定風格的圖,嵌入到報告模板(Notion、Confluence、內部系統)

    可行操作:

    • 建立一個簡單的 HTTP 服務 /generate-chart:
    • 輸入:分析問題 + 資料表名稱
    • 中間:LLM → Flint JSON → Flint 編譯
    • 輸出:圖表 URL 或 HTML Snippet

    💡 關鍵: 用 /generate-chart 這類服務,把「問問題 → 自動出圖」變成標準流程,可大幅減少手動報表製作時間。

    2. 內部 BI 助理

    情境:同事問「上個月付費轉換率怎麼樣?」,你不想每次都打開 Power BI 重拉圖。

    用法:

    • 建立一個聊天機器人(Slack / Teams / Line)
    • 後端讓 Bot 可以:
    • 查詢資料庫
    • 呼叫 LLM 產生 Flint JSON
    • 用 Flint 生成圖,回傳為圖片或互動式圖表連結

    可行操作:

    • 在 Bot 指令中加入:/chart 近三個月 活躍用戶 與 付費人數
    • Bot 回覆一張趨勢折線圖,並附上描述文字

    3. 技術文件中的動態圖表

    情境:你寫 SDK / API 文件,需要展示效能、流量、版本差異,數據常更新。

    用法:

    • 文檔系統只存「Flint JSON + 資料來源」
    • 每次讀者開啟頁面,後端動態用 Flint 產生最新圖表

    可行操作:

    • 在 docs 中嵌入一個 <iframe src="/docs/charts/latency">
    • 這個 endpoint 背後:查資料 → Flint render → 回傳 SVG / PNG

    實際長什麼樣?Flint JSON 範例

    以下是一個最小可用的 Flint 規格,畫出「每月營收折線圖」:

    {
      "data": {
        "fields": [
          { "name": "month", "type": "temporal" },
          { "name": "revenue", "type": "quantitative" }
        ],
        "values": [
          { "month": "2024-01", "revenue": 120000 },
          { "month": "2024-02", "revenue": 135000 },
          { "month": "2024-03", "revenue": 128000 }
        ]
      },
      "mark": "line",
      "encoding": {
        "x": { "field": "month", "type": "temporal" },
        "y": { "field": "revenue", "type": "quantitative" }
      },
      "title": "2024 Q1 每月營收"
    }
    

    LLM 只要穩定產出這樣結構清楚、語意正確的 JSON,Flint 就會幫你做出排版乾淨的圖,之後你想改顏色、字型、軸設定,都可以在 Data Formulator 介面上調整。


    怎麼開始?30 分鐘內畫出第一張 AI 圖

    1. 部署 Flint:本機或雲端

    官方文件與 Demo:https://microsoft.github.io/flint-chart/#/

    本機(開發測試)

    1. 安裝 Node.js(建議 18+)
    2. Clone 專案:
      bash
      git clone https://github.com/microsoft/flint-chart.git
      cd flint-chart
    3. 安裝依賴並啟動示例:
      bash
      npm install
      npm run dev
    4. 瀏覽器打開 http://localhost:5173,可以看到範例圖表與 Flint Spec。

    雲端部署(給團隊用)

    • 打包為 Docker image(視官方 repo 指引)
    • 部署在自家 Kubernetes / VM 上,對外提供 REST API:
    • POST /render → 輸入 Flint JSON,回傳圖表

    2. 使用現成範例,串接任一主流 LLM / Agent

    基本流程:

    1. 在後端寫一個函式 askLLMForFlintSpec(prompt, data_schema)
    2. 提示詞約束:
    3. 請只輸出 JSON,不要加解釋文字
    4. JSON 結構遵守 Flint Spec(可把官方 schema 一併塞進 system prompt)
    5. 把 LLM 回傳的 Flint JSON 送到 Flint API:
    import requests, json
    
    flint_spec = llm_generate_flint_spec(user_query, data_schema)
    res = requests.post(
        "http://localhost:8000/render",
        json={"spec": flint_spec}
    )
    with open("chart.svg", "wb") as f:
        f.write(res.content)
    
    1. 前端直接顯示 chart.svg,或轉 PNG 給報告系統使用。

    3. MCP 整合:丟給你的 Agent 用

    若你使用支援 MCP 的 Agent(例如部分新一代 IDE 助理、Agent Framework),步驟大致是:

    1. 啟動 Flint MCP server(依官方 repo 指示)
    2. 在 Agent 設定檔中註冊 Flint MCP endpoint
    3. 在系統提示詞中說清楚:
    4. 何時該呼叫 Flint(遇到需要圖表的問題)
    5. 如何構造 Flint JSON

    完成後,你就可以在對話中自然問:「幫我畫一張 2024 各季度營收與毛利率的組合圖」,讓 Agent 自行決定查數據、生成 Flint JSON、再回傳圖表。


    Flint 與其他「讓 AI 變強」工具怎麼搭配?

    下面用一個表快速對比本文提到的工具角色:

    名稱 核心功能 免費方案 適合誰
    Flint 中介視覺語言,幫 LLM 生高品質圖表 開源 需要報表 / 圖表自動化的開發者
    Data Formulator 可視化編輯 Flint 圖表的前端工具 開源 想在瀏覽器調整 AI 圖表的資料分析師
    VisionBridge1 讓純文字 LLM 具備視覺理解能力的代理 開源 想給本地 LLM 加上看圖能力的開發者

    你可以把它們組成一條完整流水線:VisionBridge 提供「看圖」能力、LLM 做推理與產生 Flint JSON、Flint+Data Formulator 負責「畫好圖」與人類微調。


    結語:先讓 AI「畫得出像樣的圖」再談自動化報表

    如果你已經在用 LLM 做資料分析、寫 BI 查詢,下一步就是讓結果不是只停在文字。Flint 幫你用很低的開發成本,把「專業圖表」變成 AI 回答的一部分,而且保留 JSON 規格,後續要改樣式、改資料源,都能持續演進。

    最實際的建議:花 30 分鐘跑起官方 Demo,拿文中的範例 JSON 改成自己的資料,先做出第一張「AI 自動生成、你看得順眼、同事也改得動」的圖表,再來思考要怎麼把它嵌進你的報表、內部工具或 Agent 流程裡。

    🚀 你現在可以做的事

    • 打開 https://microsoft.github.io/flint-chart/#/,跑起官方 Demo 並試著改用自己的資料
    • 在後端實作一個簡單的 /generate-chart 服務,讓 LLM 產生 Flint JSON 再交給 Flint 渲染
    • 部署 Data Formulator,讓資料分析同事用瀏覽器微調 LLM 生成的 Flint 圖表並存成報表模版
  • Plurality:在家自架你的 AI 中控台

    Plurality:在家自架你的 AI 中控台

    📌 本文重點

    • Plurality 是本地可自架的 AI 中控台
    • 同一介面整合聊天、腳本自動化與多代理協作
    • 透過沙盒與 MCP 打造安全可控的 AI Runbook 系統

    一句話定位:Plurality 是一個裝在你自己電腦或局域網裡的 AI 中控台,用同一個介面處理聊天、腳本自動化和多代理協作,而且完全開源、可本地部署。

    專案連結:https://github.com/azukaar/plurality (建議邊看文邊打開)


    核心功能:把「聊天 + 自動化 + 安全執行」塞進一個面板

    1. 一個介面同時管「聊天」和「背景自動化」

    Plurality 的定位很像「你自己架的 Slack + Jira + Runbook 執行器」,但全部交給 AI 來動。

    你可以在同一個 Web 介面裡:

    • 和 AI 助理聊天
    • 建立長期存在的 Agent(例如「專案助手」「報表助手」)
    • 為每個 Agent 配好自動化流程(Automation Flow),讓它在背景持續跑

    你可以這樣用:

    • 先在 Plurality 裡創一個「專案助理」Agent
    • 在聊天裡下達指令:「幫我建立一個每日 build 檢查流程」
    • 再把這段需求轉成 automation flow:每天定時跑腳本、整理結果、回報到同一個對話 Thread

    實際效果:你不再需要切來切去——一樣是在「跟 AI 聊天」,但對話可以變成「可重複、自動執行的任務」。

    💡 關鍵: 將常用對話轉成 automation flow,可把「會話」變成每天自動跑的固定任務,減少大量手動重複操作。

    行動建議:想像一下你現在最常對 ChatGPT 說的其中一件事(例如「整理日報」「幫我跑某個腳本」),這會是你在 Plurality 裡第一個要做成 Automation 的任務。


    2. 安全的 CLI + 檔案系統沙盒

    Plurality 支援讓代理在「沙盒環境」裡跑 CLI 命令、操作檔案,但重點是:

    • 可控制範圍:你可以只把某個專案資料夾掛載給該 Agent
    • 可審核:代理要執行敏感命令前,可以設成需要你點擊確認
    • 可記錄:所有命令和檔案操作都在介面裡看得到 log

    這意味著:

    • 開發者可以讓 Agent 幫忙跑測試、打包、整理 log
    • 知識工作者可以讓 Agent 在限定資料夾裡整理檔案、產出報告
    • 家用伺服器使用者可以讓 Agent 只碰 backup 資料夾,不碰其他東西

    你可以這樣設定:

    1. 在 Plurality 的設定中,新增一個「Project」或「Workspace」
    2. 把 /home/你/某個專案 或 NAS 的某個共享資料夾掛載給這個 Workspace
    3. 建立 Agent 並指定它只能使用這個 Workspace
    4. 開啟「命令前需要確認」(如果你怕它亂改東西)

    行動建議:先選一個「就算搞壞也不會心痛」的資料夾,當作 Agent 測試用沙盒,把 CLI 操作和檔案操作都限制在這裡。


    3. 搭配 MCP、多代理協作,變成你的「個人 Jira + Runbook 執行器」

    Plurality 支援 MCP(Model Context Protocol)等多代理協作生態,你可以把它當成一個統一入口,接上:

    • 不同工具的 MCP 伺服器(例如資料庫查詢、Issue 管理、監控系統)
    • 多個 Agent 各自負責不同任務

    用白話來說:

    • 「像 Jira 一樣」:你可以把每個自動化流程當成一個 Ticket / 任務
    • 「像 Runbook 一樣」:每個任務裡,是具體的步驟(腳本、API調用、檔案處理)
    • Plurality 的 Agent 負責:讀任務 → 選工具 → 執行 → 回報結果

    實際用法例子:

    • 一個「監控 Agent」:定時讀監控 API → 判斷是否異常 → 若異常就呼叫「Runbook Agent」
    • 「Runbook Agent」:按你寫好的流程,連線伺服器、跑腳本、紀錄在一個對話 Thread 裡

    行動建議:先想一個你現在「寫在 Notion / Wiki 的 Runbook」,例如「網站掛掉怎麼檢查」,把它拆成步驟,交給 Plurality Agent 來執行一次看看。


    適合誰用?三個具體場景

    1. 開發者:用 Plurality 管專案腳本

    適合這樣的人:

    • 手上有一堆 npm script / Makefile / shell script
    • 常常要:跑測試、打包、部署、整理 log

    實際流程可以長這樣:

    • 在 Plurality 裡建立一個「專案 Dev Agent」
    • 掛載你的專案資料夾(例如 /projects/my-app)
    • 讓 Agent:
    • 用 CLI 跑 npm test,把錯誤訊息整理貼回聊天
    • 根據你的指示修改設定檔或產出新腳本(在沙盒裡)
    • 定時跑 lint + test 並生成報告

    你每天要做的事情,就變成:開 Plurality → 問「今天 CI 有沒有紅?」→ 讓 Agent 調出 log 給你看。

    💡 關鍵: 讓 Agent 接管 npm test、lint 等例行腳本,可把日常 CI/開發檢查集中在單一對話介面完成。


    2. 知識工作者:整理檔案 + 做定時報告

    適合這樣的人:

    • 每週要交固定報告(營運簡報、數據摘要、內容整理)
    • 桌面 / NAS 上堆滿 PDF、Word、報表 CSV

    你可以這樣設計一個 Agent:

    • 掛載「報表資料夾」給它(例如 Reports/Weekly)
    • 每天或每週固定時間:
    • 掃描新檔案
    • 自動分類命名(根據檔名、內容)
    • 生成一份文字摘要(例如本週營運重點、會議紀錄整理)
    • 寄出 Email 或貼到公司內網

    整套流程變成:你只要把資料丟進資料夾,其它交給 Plurality。


    3. 自架家用伺服器:備份 + 監控

    如果你有自己的 NAS 或家用伺服器(例如和 Livinity 這種 homeserver OS 類似的架構),Plurality 很適合當成「AI 管家」。

    可以做的事情:

    • 每天半夜:
    • 檢查共享資料夾是否有新檔
    • 壓縮後備份到另一顆硬碟或雲端
    • 寫 log + 總結備份結果
    • 每小時:
    • 跑監控腳本(例如檢查 Docker 容器、硬碟空間)
    • 若異常,透過 Email / Telegram 通知你

    這些都可以用 Plurality 的 automation flow + CLI 沙盒來完成,而且所有設定都留在你自己的網路裡。

    💡 關鍵: 把備份與監控自動化放進局域網,能在不依賴外部服務的前提下,建立可審計又可控的「AI 管家」流程。


    15 分鐘入門:從 clone 到第一個 Automation Flow

    下面用一個具體目標來帶你:每天抓 RSS → 總結 → 寄信。

    步驟 0:準備環境(2 分鐘)

    需求:

    • 一台可以跑 Docker 的機器(你的電腦、NAS 或家用伺服器)
    • 至少一個可用的模型:
    • 本地:Ollama / LM Studio / 其他本地 LLM 伺服器
    • 雲端:OpenAI / Claude 等(有 API key)

    行動:先確認你有 Docker 和一個模型 API(或已裝好 Ollama)。


    步驟 1:拉 GitHub repo + 啟動(5 分鐘)

    1. 開啟 GitHub 專案:https://github.com/azukaar/plurality
    2. 在你的機器上:
    git clone https://github.com/azukaar/plurality
    cd plurality
    
    1. 使用 Docker(以官方 README 為準,但大致會是):
    docker compose up -d
    
    1. 打開瀏覽器,進入 http://你的機器 IP:PORT(通常 README 會寫預設 port)

    行動:先確認你能看到 Plurality 的 Web 介面,並完成初次設定帳號。


    步驟 2:連上本地或雲端模型(3 分鐘)

    在 Plurality 介面的設定裡(通常是「Models」「LLM Providers」之類):

    • 如果你用本地模型(例如 Ollama):
    • 填入 Ollama 的 URL(例如 http://host.docker.internal:11434)
    • 選一個模型(llama3 等)
    • 如果你用雲端模型:
    • 選 OpenAI / Anthropic 等
    • 貼入 API key

    接著:

    • 建立一個「預設 Agent」
    • 開一個新聊天,隨便問一個問題,確認模型回應正常

    行動:測一次聊天,確定模型接上沒問題,再往下做自動化。


    步驟 3:設定第一個 Automation Flow:RSS → 總結 → 寄信(5 分鐘)

    以概念步驟為主,實際操作依 Plurality 當前 UI 為準(版本更新可能略有差異):

    1. 建立一個 Agent(例如叫 RSS Reporter):
    2. 權限:允許網路請求(抓 RSS)
    3. 若需要寄信,先在設定裡填好 SMTP 或 Webhook(視官方檔案支援的方式)

    4. 建立 Automation Flow:

    5. 觸發條件:每日某個時間(例如 09:00)
    6. 步驟設計(可用自然語言描述給 Agent,再微調):

      1. 抓取指定 RSS(例如科技新聞、公司部落格)
      2. 解析最近 24 小時的新文章
      3. 用模型生成摘要:
        • 列出 3-5 則重點
        • 每則一段話說明「為什麼重要」
      4. 把摘要整理成一封 Email 內容
      5. 呼叫 SMTP/Email 工具寄給你
    7. 測試一次:

    8. 不用等明天,先在介面裡手動 Run 這個 Flow
    9. 檢查 log 和 Email 是否如預期

    行動:先用你最常看的其中一個 RSS 做範例,例如你公司部落格或常看的技術網站。


    小結:把「雜事」搬進你自己的局域網裡

    Plurality 的核心價值在於:

    • 一個介面聚合聊天 + 自動化 + 多代理
    • 可以讓 AI 真正「動手」跑 CLI、操作檔案,但仍在你可控的沙盒裡
    • 搭配 MCP、多代理協作,把原本散在各處的腳本、Runbook 和任務,集中到一個你自己掌控的中控台

    如果你本來就有自架 NAS、家用伺服器,或公司內網伺服器,Plurality 很適合直接變成「AI 操作台」;如果你只是想找個比 ChatGPT 更能「實際做事」的工具,也可以先在自己電腦上跑一個 Plurality,從那個 RSS → 總結 → 寄信的 Flow 開始。

    下一步行動:打開 https://github.com/azukaar/plurality,照本文的 15 分鐘流程做出你的第一個 Automation Flow,之後再慢慢把日常重複工作移進去。

    🚀 你現在可以做的事

    • 打開 Plurality 專案頁,用 git clone 把專案拉到本機或 NAS
    • 準備好一個可用模型(例如設定好 Ollama 或貼入 OpenAI / Claude API key),完成第一次聊天測試
    • 挑一個你每天重複做的流程(如 RSS 摘要、報表整理),在 Plurality 裡實作成第一個 Automation Flow
  • 把整個 Google 變成你的 AI Agent

    把整個 Google 變成你的 AI Agent

    📌 本文重點

    • google/skills 是 Google 產品專用的 AI Agent 工具箱
    • 透過現成 skills,LLM 可直接操作 Gmail / Calendar / Drive
    • 幾十行 Python 就能做出實用的 Workspace 自動化 Agent
    • 重視權限、安全與流程設計,才能放心在公司環境使用

    用一句話說清楚:google/skills 是一個專門替 Google 產品包好的「AI Agent 工具箱」,讓 LLM 不只會聊天,還能直接幫你操作 Gmail、Calendar、Drive 等服務。

    專案連結:https://github.com/google/skills


    google/skills 是什麼?可以幹嘛?

    用開發者的語言講:

    • 這是一組 Python 套件 + 一堆已實作好的「工具(skills)」
    • 每個 skill 就是一個可被 LLM 呼叫的函式,背後已幫你處理好 Google API 認證、資料結構、錯誤處理
    • 你只要把這些 skills 接到你熟悉的 Agent 框架(或自己寫個 loop),LLM 就能:
    • 在 Gmail 搜尋、讀取、回覆郵件
    • 在 Google Calendar 建立、更新、刪除行程
    • 從 Google Drive 找檔案、讀內容
    • 以及其他 Google 產品(例如 Docs / Sheets / Tasks 等)

    💡 關鍵: 把繁瑣的 Google API 細節封裝成 skills,讓你專注在設計 Agent 流程,而不是處理認證與資料結構。

    目前常見支援的產品與典型技能

    以 GitHub 專案內容與官方範例為主,目前重點集中在 Workspace 產品:

    • Gmail:搜尋郵件、讀取內容、標記已讀、建立草稿、送出郵件
    • Calendar:建立事件、更新時間/地點、取消會議、查詢空檔
    • Drive:列出檔案、搜尋、下載內容、讀取檔案文字(搭配 API 或其他工具)
    • Tasks / Docs / Sheets:視版本與模組更新擴充,作為實驗性 skills 提供

    你可以把它想成:「Google 幫你寫好一堆『LLM 可安全使用的 Google API wrapper』,你只要負責接到自己的 Agent。」


    核心功能:讓 LLM 真的「動手做事」

    下面用三個代表性技能,拆開來看它怎麼組成一條完整工作流。

    1. Gmail:搜尋 + 回覆郵件

    能做的事

    • 根據條件(發信人、標題關鍵字、時間)搜尋郵件
    • 讀取郵件主旨、內容、附件資訊
    • 由 LLM 生成人性化回覆,再用 skill 建草稿或直接寄出

    你可以怎麼用

    • 自動整理每日「待回覆」郵件清單
    • 給 Agent 一句自然語言指令:
    • 「幫我找這週所有含『報價』的客戶信,產出一封統一回覆草稿」

    2. Calendar:建立 / 修改行程

    能做的事

    • 建立新事件(時間、地點、參與者、線上會議)
    • 更新時間或加入備註
    • 查詢某段時間的空檔

    你可以怎麼用

    • 讓 LLM 從郵件裡抓出「時間 + 地點 + 主題」,自動變成 Calendar 事件
    • 用一句話:
    • 「把明天 3–5 點標成『專注工作』,不要排會議」

    3. Drive:從檔案抓資料

    能做的事

    • 依檔名、類型、擁有者搜尋檔案
    • 下載或讀取檔案(再交給 LLM 摘要)

    你可以怎麼用

    • 找到昨天產出的報表,請 LLM 摘要要點後寄給主管
    • 自動從會議紀錄整理 action items,寫回 Google Docs

    把它們串起來:一條完整工作流範例

    例子:自動從郵件抓會議資訊 → 建行程 → 建備忘錄

    1. Agent 用 Gmail skill 搜尋主題含「Meeting」「邀請」的未讀信
    2. LLM 解析郵件內容,抽出:會議主題、時間、地點、參與者
    3. 用 Calendar skill 建立事件,寫入摘要與會議連結
    4. 用 Drive/Docs skill 建一份「Meeting Notes」文件,寫入議程、預先問題

    你只要負責描述「整體目標」,LLM 會自己決定何時呼叫哪個 skill。你的程式碼變得像是在描述流程,而不是在寫一堆 API 呼叫細節。

    💡 關鍵: 一旦 workflow 串起來,同一套 skills 可以重複組裝出不同的自動化場景,大幅降低開發新 Agent 的成本。


    實戰場景:把散落在 Workspace 的動作串起來

    下面是幾個可以立即實作的場景,每一個都對應到你可以「今天就試做」的腳本。

    1. 個人行程助理

    需求:每天早上想知道今天有哪些會議、重要信件、待辦。

    可以怎麼做

    • Gmail:抓「星號」或加標籤的關鍵郵件
    • Calendar:列出今天所有會議與空檔
    • Tasks / Drive:列出今日到期的任務與文件
    • LLM 整理成一封「每日簡報」,寄到 Gmail 或 Slack

    👉 可行動:用本文後面的「每日早上報告 Agent」最小範例修改即可。

    2. 客服工單整理

    需求:客服信都在 Gmail,手工整理太慢。

    技能組合

    • Gmail:抓取特定 label(例如 support)的所有新信
    • LLM:
    • 自動分類(bug、退款、帳號問題)
    • 抽出關鍵欄位(客戶、產品、影響範圍)
    • Drive/Sheets skill:寫入 Google 試算表,讓團隊追蹤

    3. 銷售線索追蹤

    需求:商務開發信散落在 Gmail、會議安排在 Calendar、紀錄在 Drive。

    技能組合

    • Gmail:搜尋含「報價」「demo」關鍵字的信
    • Calendar:對應已有 / 尚未安排會議的線索
    • Drive:讀取對應的提案文件
    • LLM:產出「Sales pipeline 摘要」,再寄給業務團隊

    4. 團隊報表自動彙總

    需求:每週要整理多份 Google Sheets / Docs 的數據與摘要。

    技能組合

    • Drive:搜尋指定資料夾裡的所有報表
    • Sheets/Docs skill:抓出指定欄位/段落
    • LLM:彙整成一份「本週關鍵指標 + 亮點 + 風險」
    • Gmail:寄給管理層

    每個場景本質上都是:用 skills 拉資料 → LLM 處理 → 再用 skills 寫回 Google 生態。

    💡 關鍵: 只要 Workspace 流程是「讀資料 → 分類/摘要 → 回寫」,幾乎都能用同一套模式快速自動化。


    怎麼開始:從零到一的小 Agent(Python)

    這段寫給已經會基本 Python 的讀者。目標是做一個:

    「每日早上 9 點,整理今天的會議與重要郵件,寄一封報告給自己」

    步驟一:安裝套件與專案結構

    pip install google-skills openai  # 或你要用的 LLM 客戶端
    

    一個最小專案結構可以是:

    project/
      main.py          # 主程式,Agent 邏輯
      skills_config.py # Google skills 初始化
      .env             # 儲存 API Key 等環境變數
    

    步驟二:設定 Google API 憑證與權限

    1. 前往 https://console.cloud.google.com/
    2. 建立專案,啟用:
    3. Gmail API
    4. Calendar API
    5. (若需 Drive,就再開啟 Drive API)
    6. 建立 OAuth 用戶端 / Service Account 憑證
    7. 下載憑證 JSON,放進你的專案中,路徑寫在環境變數(例如 GOOGLE_APPLICATION_CREDENTIALS)

    google/skills 會讀這些設定,幫你處理 OAuth 流程。第一次執行會要你開瀏覽器認證,通過後就可以長期使用。

    步驟三:初始化 skills

    # skills_config.py
    from google.skills import GmailSkill, CalendarSkill
    
    gmail_skill = GmailSkill(scopes=[
        "https://www.googleapis.com/auth/gmail.readonly",
        "https://www.googleapis.com/auth/gmail.send",
    ])
    
    calendar_skill = CalendarSkill(scopes=[
        "https://www.googleapis.com/auth/calendar",
    ])
    
    TOOLS = {
        "gmail": gmail_skill,
        "calendar": calendar_skill,
    }
    

    (實際類名與參數以官方 GitHub 為準,這裡是示意寫法。)

    步驟四:寫一個最小「每日報告」 Agent

    下面示意一個 純 Python + LLM + skills 的簡易 loop:

    # main.py
    import datetime as dt
    from skills_config import TOOLS
    from openai import OpenAI
    
    client = OpenAI()
    
    
    def get_today_summary():
        today = dt.date.today().isoformat()
    
        # 1) 用 Gmail skill 抓今天重要信件(實際用法依官方 API)
        important_emails = TOOLS["gmail"].search_messages(
            query="label:STARRED newer_than:1d"
        )
    
        # 2) 用 Calendar skill 抓今天所有事件
        events = TOOLS["calendar"].list_events(
            time_min=today + "T00:00:00Z",
            time_max=today + "T23:59:59Z",
        )
    
        prompt = f"""
    你是一個助理,請用條列整理以下資訊:
    1. 今日重要郵件(寄件人 + 主題)
    2. 今日會議(時間 + 標題)
    
    重要郵件:{important_emails}
    今日行程:{events}
    """
    
        resp = client.chat.completions.create(
            model="gpt-4o-mini",  # 或你使用的其他 LLM
            messages=[{"role": "user", "content": prompt}],
        )
        return resp.choices[0].message.content
    
    
    def send_daily_report():
        summary = get_today_summary()
        TOOLS["gmail"].send_message(
            to="your_email@example.com",
            subject="今日工作總覽",
            body=summary,
        )
    
    
    if __name__ == "__main__":
        send_daily_report()
    

    接下來只要用 crontab 或任一排程工具,每天早上 9 點跑一次 python main.py,你就有一個真正會「用 Gmail + Calendar 幫你工作」的小 Agent 了。


    延伸玩法:接到 LangGraph / MCP / 自建 loop

    google/skills 本身只是一組工具,你可以自由接到任何 Agent 框架。

    常見接法比較

    名稱 核心功能 免費方案 適合誰
    LangGraph 圖形化定義 Agent workflow、狀態機 開源 要做複雜流程 / 多工具協作
    MCP 標準化「工具伺服器」協議 規格開源 想讓多個模型共用同一組工具
    Simple loop(自建) while-loop + tool call + LLM 只要有 LLM 即可 想快速測試、腳本導向

    怎麼接 google/skills?

    • LangGraph:把 Gmail/Calendar skill 包成「tool node」,用 graph 描繪整條流程(例如:先讀 mail → 判斷 → 建行程)。
    • MCP:把 google/skills 包成 MCP 工具伺服器,就像 Reddit 上有人把產品目錄接到 Claude 一樣,任何支援 MCP 的 Agent 都能呼叫這組 Google 工具。
    • 自建 loop:如前面的 send_daily_report(),自己在程式裡控制什麼時候 call 哪個 skill。

    實務注意事項:安全、權限與 rate limit

    在公司環境用 google/skills,這幾點非常重要:

    1. 最小權限原則:
    2. 只開啟必要的 scopes,例如只讀 Gmail 就不要給 send 權限
    3. 針對不同 Agent 建不同憑證,避免權限過大
    4. 審計與日誌:
    5. 記錄每次工具呼叫(誰、什麼時候、對哪個帳號)
    6. 公司內部可用 SIEM / 日誌系統統一管理
    7. Rate limit 與配額:
    8. Google API 有配額,批次任務要加上 sleep / retry
    9. 測試環境與正式環境要分開憑證,避免測試爆掉正式配額
    10. LLM 安全邏輯:
    11. 對「寫入」類操作(寄信、刪除事件)加上確認步驟
    12. 可用 rule-based filter:例如禁止刪除某些標籤信件

    總結:把「會聊天的 LLM」變成「會用 Google 的助理」

    如果你已經每天活在 Gmail、Calendar、Drive 裡,google/skills 的價值很單純:

    • 你不用再對著 Google API 文件苦讀,只要調用現成的 skills
    • LLM 能真的幫你「按按鈕、拉資料、寫回去」,而不是只給你建議
    • 從個人行程助理,到團隊報表自動化,都可以在幾十行 Python 內完成第一個版本

    先從一個小腳本開始:「每日早上發報告」,跑通一次之後,你就會自然開始想把更多 Workspace 工作交給你的 Agent。

    🚀 你現在可以做的事

    • 打開 google/skills GitHub 專案,瀏覽支援的 skills 清單與範例程式
    • 依照文中的「每日報告 Agent」範例,在本機建立一個最小 Python 專案跑通一次
    • 在你的 Workspace 工作流中,挑一個「讀資料 → 整理 → 寄出」流程,試著用 google/skills + LLM 自動化它
  • 用 Claude.md 做一個不會爛掉的長跑代理

    用 Claude.md 做一個不會爛掉的長跑代理

    📌 本文重點

    • 用 CLAUDE.md 嚴格約束代理行為,避免長跑爛掉
    • 核心原則是「行動+證據」,禁止空談與無限迴圈
    • 透過上下文壓力自查與簡潔憲法,讓代理長時間穩定運作

    用一份不到 100 行的 CLAUDE.md,就能讓你的 Claude 代理連跑幾小時都不會開始胡言亂語、卡住不動或重複修同一個 bug。

    參考原作者在 Reddit 的分享:
    – 長跑 Claude Code 代理的設定檔開源文:https://www.reddit.com/r/ClaudeAI/comments/1tjy3sk/i_opensourced_the_operating_file_that_keeps_my/
    – 100 條個人 AI 代理實戰心得:https://www.reddit.com/r/ClaudeAI/comments/1thi6nh/100_tips_tricks_for_building_your_own_personal_ai/


    核心功能:這份 CLAUDE.md 到底做了什麼?

    1. 只允許「行動與證據」,禁止長篇空談

    長跑代理會爛掉,通常是這三個症狀:

    1. 開始寫「我將會…」「接下來我要…」但不真的執行工具
    2. 一直說「應該已修好」但沒有測試結果
    3. 花很多篇幅重複解釋計畫,實際變更很少

    CLAUDE.md 的核心規則,就是把這些行為全部關掉:

    • 輸出只允許三種型態:
    • 已完成的動作(例如:檔案修改、指令執行、API 呼叫)
    • 具體問題 / 需要決策的提問
    • 極短的進度摘要
    • 聲稱「完成」前要附證據:如測試輸出、報表截圖路徑、命令列結果

    💡 關鍵: 將輸出限制為「行動+證據」,能大幅減少長篇空談與無效迴圈,讓長跑代理真正持續推進任務

    你可以做的事:
    – 在你的專案根目錄放一份 CLAUDE.md,明確寫出:
    – 「不要描述你要做什麼,只要直接做並回報結果」
    – 「任何『應該已修好』前,必須貼出測試輸出」

    2. 內建「上下文壓力」自我檢查

    長跑幾小時後,對話上下文會變超長,Claude 開始:

    • 忘記早期需求
    • 無法把握目前專案狀態
    • 回答變模糊或重覆

    原作者在 CLAUDE.md 裡加了一條關鍵原則:

    代理要定期自查上下文壓力:發現自己搞不清狀態,就主動整理摘要、刪除多餘上下文、或要求人類幫它重設現狀。

    具體做法通常包含:

    • 每完成一個階段任務,就輸出一個「短摘要 + 關鍵檔案清單」
    • 長度過大時,優先保留:
    • 最新的決策
    • 目前版本的檔案 / 結構
    • 尚未完成的待辦

    你可以做的事:
    – 在 CLAUDE.md 寫明:
    – 「當你感覺自己不確定目前狀態時,先輸出一份 10 行內的現況摘要,再繼續工作。」
    – 「如需要,可要求人類提供『目前唯一真實狀態』說明,並用這份說明覆蓋舊假設。」

    3. 任務憲法:不靠「一長串 Prompt」,靠幾條簡潔原則

    多數人用代理會寫一大段 prompt,結果 Claude 讀不完、也記不住。CLAUDE.md 的思路是:

    • 用 10–20 條簡短規則,定義這個代理的「憲法」
    • 每條都要能對應到實際行為約束,例如:
    • 「若有工具可以做某事,優先用工具,不要手寫模擬輸出」
    • 「對同一錯誤連續嘗試 3 次仍失敗,就停下來請人類決策,不要無限迴圈」

    💡 關鍵: 把 10–20 條行為規則寫成固定「憲法」,比灌輸一大段單次 prompt 更能在長跑中維持穩定行為

    參考 Reddit 另一篇實戰文:https://www.reddit.com/r/ClaudeAI/comments/1thi6nh/100_tips_tricks_for_building_your_own_personal_ai/

    你可以做的事:
    – 先列出你的代理最常「爛掉」的 3 個行為,逐條寫進 CLAUDE.md,用「禁止 / 應改為」的格式:
    – 「禁止:連續兩次貼出幾乎相同的錯誤訊息。應改為:第二次失敗時,整理你已試過的方法,請人類選下一步。」


    適合誰用:3 個實戰場景

    1. 單機腳本型代理:排程任務、批次資料處理

    你有這些需求時,很適合:

    • 每晚跑一次報表轉檔腳本
    • 每週整理一批 CSV / Excel 檔,把欄位標準化
    • 定期爬某個網站的資料、存到本地或資料庫

    做法:

    1. 用 Claude Code 或本地腳本,讓代理可以:
    2. 讀寫特定資料夾
    3. 執行 shell 指令(或以 PowerShell / bash 包一層)
    4. 把 CLAUDE.md 放在專案根目錄,寫清楚:
    5. 允許改動哪些檔案
    6. 批次任務完成的判定方式(例如輸出檔案數量、檔名規則)
    7. 用排程工具觸發:
    8. macOS / Linux:cron 或 systemd timer
    9. Windows:排程工作排程器 + 命令列啟動代理腳本

    2. 長連線開發代理:Claude Code / VS Code / Cursor 類工作流

    如果你常用 Claude 來寫程式、改大型專案,長時間開著一個 session,很容易出現:

    • 忘記三小時前的設計決定
    • 重複修同一支檔案
    • 一直在講解架構,但實際 commit 很少

    這時 CLAUDE.md 非常好用:

    實際操作:

    1. 在 VS Code 專案根目錄新增 CLAUDE.md,內容包含:
    2. 專案簡述
    3. 允許的工具(例如:跑測試、執行 npm test、pytest 等)
    4. 「行動 > 敘述」與「證據 > 猜測」等規則
    5. 在 Claude Code / Cursor 內重新開啟專案,確保代理會讀到這個檔案
    6. 開發時明確下指令:
    7. 「請遵守 CLAUDE.md,連續工作直到完成以下任務…」
    8. 「每完成一個子任務,產出最多 5 行的進度摘要」

    進階:也可以搭配多代理流程,參考:https://www.reddit.com/r/ClaudeAI/comments/1thi16y/how_i_built_a_9agent_team_where_my_agents/

    3. 自建小型自動化服務:抓報表、清理資料

    你想做一些「半自動」小工具,例如:

    • 每週自動登入內部系統下載報表
    • 讀取資料夾裡的新檔案,做資料清洗 / 格式標準化
    • 根據最新資料,產出簡短摘要寄 Email

    可用的整合方式:

    • MCP / shell 指令:
    • 透過 Model Context Protocol 暴露一組工具給 Claude,例如:
      • list_files, read_file, run_command
    • 規則寫進 CLAUDE.md:

      • 「處理檔案時,一律用工具列出檔名,不要從記憶猜」
    • Power Automate:

    • 由 Power Automate 排程觸發 HTTP / CLI,呼叫你的 Claude 代理後端
    • 回傳的結果可再串 Outlook 寄信、寫入 Excel、更新 SharePoint

    你可以做的事:
    – 先選一個最小自動化任務,例如「每週整理銷售報表」,只把這一個流程寫入 CLAUDE.md,確保跑穩,再慢慢加其他任務。


    10 分鐘上手:從 fork 到跑起你自己的代理

    以下是一條「10 分鐘內能動起來」的最短路徑,你可以依你使用的工具微調。

    Step 1:fork 開源專案

    1. 前往 Reddit 原文查看作者提供的 repo(通常會在貼文內):https://www.reddit.com/r/ClaudeAI/comments/1tjy3sk/i_opensourced_the_operating_file_that_keeps_my/
    2. 在 GitHub 上 fork 到自己的帳號
    3. 本地 git clone 下來

    Step 2:複製 CLAUDE.md 到你的專案

    1. 打開作者的 CLAUDE.md,通讀一遍規則
    2. 複製到你自己的專案根目錄
    3. 只做三種修改:
    4. 把專案描述改成你的任務(例如:財報整理、數據清洗、網站爬蟲)
    5. 調整允許使用的工具(例如是否允許 rm / 刪檔)
    6. 加上 2–3 條你最在意的「不准爛掉」條款

    💡 關鍵: 只動專案描述、工具白名單與 2–3 條關鍵禁令,能在 10 分鐘內把通用 CLAUDE.md 變成專屬代理憲法

    Step 3:綁定你常用的工作環境

    依你用的平台選一條:

    • Claude Code / VS Code / Cursor:
    • 在這個專案資料夾內開啟編輯器
    • 確認工具(跑測試、shell、檔案操作)已啟用
    • 對 Claude 說:「請讀 CLAUDE.md 並照裡面的規則長時間工作」

    • MCP + shell 指令:

    • 建立一個 MCP server,提供 run_shell, read_file, write_file 等工具
    • 在 CLAUDE.md 明確寫出「所有系統操作一律經由 MCP 工具」
    • 用你偏好的前端(例如自寫 CLI、簡單 Web)呼叫 Claude

    • Power Automate / 其他自動化:

    • 建一個小型後端服務(可用 Python FastAPI / Node.js)包住 Claude API
    • 後端每次呼叫 Claude 時,都把專案檔案+CLAUDE.md 帶入 context
    • 用 Power Automate 定期觸發這個 API

    Step 4:跑一個「能觀察的」任務,調整規則

    1. 選一個 30–60 分鐘的任務給代理連續跑(例如重構某一個資料夾的程式碼)
    2. 觀察:
    3. 什麼時候開始廢話變多?
    4. 哪種情況會卡在同一個錯誤?
    5. 直接把這些「失敗模式」寫回 CLAUDE.md 變成新條款

    重複兩三輪,你會得到一份專屬於你工作流、而且真的能「長跑不爛」的代理憲法。


    小結:先管好行為,再管工具

    長跑 AI 代理很容易越跑越爛,通常問題不在模型,而在缺乏清楚的行為規則。透過一份設計良好的 CLAUDE.md:

    • 把輸出限制在「行動+證據」
    • 讓代理主動監控上下文壓力
    • 用幾條簡單原則當作「憲法」

    你可以在單機腳本、開發環境、多工具自動化裡,得到一個穩定得多的 Claude 代理。

    建議從今天開始:先為你最常用的一個專案寫一份 CLAUDE.md,跑一個完整任務,看看它能連續跑多久還保持專注。那會是你感受到「長跑代理真的可用」的第一步。

    🚀 你現在可以做的事

    • 在一個常用專案根目錄新建 CLAUDE.md,寫入「行動+證據」與上下文自查規則後實際跑一次長任務
    • 從 Reddit 原文 fork 作者 repo,閱讀並複製其中 CLAUDE.md,依你的工作流做 2–3 處客製調整
    • 列出你代理常見的 3 個「爛掉模式」,逐條轉寫成禁止條款加進 CLAUDE.md,並在下一次工作中觀察效果
  • 96 個 Gemini Agent 幫你寫系統?

    96 個 Gemini Agent 幫你寫系統?

    📌 本文重點

    • 多 Agent 可複製「多人分工」開發流程
    • Runtime 設計比單純換更大模型更關鍵
    • 用開源工具就能打造迷你版 Antigravity

    用一群 Agent 代替「一個工程師慢慢寫」,解決的是:複雜專案要靠多人分工,AI 也可以用 Runtime + 多代理系統做到同樣的協作和自動化。

    核心觀念先講白:模型戰爭差不多打完了,現在比的是誰的 Agent Runtime 能把「模型能力」變成可落地的、多步驟的自動化工作流。

    Google 在 I/O 上展示的 Antigravity 2.0 + Gemini 3.5 Flash 是一個很極端的例子:

    • 96 個子代理分工
    • 12 小時寫完一套從零開始的作業系統
    • Token 成本不到 1,000 美金
    • OS 還能跑《Doom》

    💡 關鍵: 多代理 + 強 Runtime 已經能在「12 小時、不到 1,000 美金」內完成從零開發 OS,顯示關鍵瓶頸不再是模型本身,而是協作與流程設計。

    這不是叫你明天也去做一個 OS,而是提供一個「如何設計多 Agent 開發流程」的範本。下面我們拆成三件你可以直接抄的事:

    1. 多代理分工設計:任務 → 子任務 → Agent 編隊
    2. 強健 Runtime:重試、檢查點、錯誤恢復
    3. 平價版本實作:在你自己的專案做一個「迷你 Antigravity」

    核心功能:Antigravity 2.0 給開發者的三個啟示

    1. 多代理分工:任務 → 子任務 → Agent 編隊

    Antigravity 的做法,其實很像你帶一個遠端工程團隊:

    • 架構師 Agent:決定 OS 的模組切分(檔案系統、排程、驅動、UI…)
    • 模組作者 Agent:各自負責某一個模組的程式碼生成
    • 測試員 Agent:寫測試、跑測試、收斂錯誤
    • 整合者 Agent:把各模組組合、處理相依性、打包成可啟動的系統

    對你來說,可直接套用成一個通用流程:

    1. 寫一個頂層任務描述
      例:建立一個 RESTful CRUD 服務,管理任務(待辦事項),含 API、DB schema、簡單前端。

    2. 讓「架構師 Agent」自動拆解:

    3. API 設計與 OpenAPI spec

    4. 後端框架與資料庫層
    5. 前端 UI
    6. 測試與 CI script

    7. 為每個子任務設計 Agent 角色:

    8. api-architect-agent:只產出 API spec

    9. backend-agent:根據 spec 產生程式碼
    10. frontend-agent:負責 UI
    11. tester-agent:生成並執行測試
    12. integrator-agent:檢查專案結構、跑 build / lint

    13. 在 Runtime 中定義工作流:

    14. 任務圖(DAG):架構師 → 模組作者 → 測試員 → 整合者

    15. 每個節點定義輸入/輸出檔案、工具(Git、DB、HTTP client)

    可行動步驟:

    • 選一個你熟的框架(例如 FastAPI / Next.js)
    • 用自然語言寫清楚「最終可交付物」
    • 為這個專案定義 3–5 個 Agent 角色,明確限制各自輸入輸出

    2. Runtime 比模型重要:90% 成功率在多步任務會變災難

    多步任務有一個殘酷數學:

    • 假設每一步成功率 90%
    • 要跑 20 步,整體成功率 ≈ 0.9^20 ≈ 12%

    💡 關鍵: 即使單步有 90% 成功率,20 步工作流成功率只剩約 12%,所以不加 Runtime 管控,多步任務幾乎註定失敗。

    這就是為什麼像 Forge 這種開源 guardrails 會被重視:作者實測,一個 8B 模型在多步代理任務上,從 53% 提到 99% 成功率,完全不改模型,只改 Runtime。

    你在自己的「迷你 Antigravity」裡,要做三件事:

    1. 重試與 nudging

    2. 為每個步驟設 max_retries(例如 3 次)

    3. 失敗時自動加上「修正提示」,例如:上一步測試失敗,錯誤訊息如下,請修正而不是重寫整檔。

    4. 檢查點(checkpoint)

    5. 每完成一個重要子任務,就把中間產出存到 Git / DB

    6. 失敗時從最近的檢查點重跑,而不是重頭來

    7. 錯誤恢復流程

    8. 專門的 debug-agent:只看錯誤訊息 & log,產出修復建議

    9. Runtime 層做:自動建立 bug report、開 issue、指派給對應 Agent

    如果你用 Forge,它已內建:

    • Tool-agnostic 重試策略
    • 步驟執行強制與錯誤恢復
    • VRAM-aware context 管理(對本地模型很重要)
    • 評估套件與 Dashboard,可量化成功率

    可行動步驟:

    • 先把現有「單 Agent 自動流程」改成有重試與 checkpoint
    • 對每個任務記錄:總步數、失敗點、重試次數,在 Dashboard 裡看瓶頸

    3. 平價版本:你也能做一個「迷你 Antigravity」

    你不需要 Gemini 3.5 Flash + Google 內部 Runtime 才能玩多 Agent。下面這些工具可以在自家專案做一個縮小版:

    名稱 核心功能 免費方案 適合誰
    Forge 多步代理 guardrails、重試、Dashboard 開源 想提升本地 / 自架 LLM 可靠性的工程師
    llama.cpp + Qwen 本地 Agent 在個人電腦跑本地模型 + 簡易工具調用 開源 想省雲端費用、在內網跑 Agent 的團隊
    MCP 生態(如 OpenAI MCP、各種 server) 統一的工具協議,讓 Agent 調用資料庫、API 等 多數開源 / 免費 想把既有系統暴露為 Agent 工具的後端工程師

    一個實用組合示例:

    • 模型:Qwen 2.5 7B / 14B(透過 llama.cpp 或 Ollama 跑)
    • Runtime:Forge 當 guardrails
    • 工具層:一組 MCP server(例如 PostgreSQL、HTTP、Filesystem)

    你可以先做一個「自動搭建 CRUD 服務」的迷你 Antigravity:

    1. 使用者輸入需求(自然語言)
    2. architect-agent 產出設計 + 任務拆解
    3. backend-agent + frontend-agent 寫程式碼
    4. tester-agent 自動開發 & 執行測試
    5. integrator-agent 跑 build 並回報狀態

    適合誰用:三種典型場景

    1. 後端 / 全端工程師:自動化 CRUD 小專案

    你可以把「打造新微服務」變成一個表單:

    • 輸入資料模型 + 幾個業務規則
    • 多 Agent 流程負責 scaffold、API、測試、docker-compose

    行動:從一個只需要 3–5 小時就能手刻完的小服務開始,先讓多 Agent 幫你做到 70–80%,你只負責 code review。


    2. 資料團隊:資料管線與 ETL 任務

    • planner-agent:解析需求、拆成抽取/轉換/載入步驟
    • sql-agent:產生查詢與 view
    • check-agent:比對 row count、品質指標

    行動:挑一個每天都在重複手動跑的 ETL 任務,做成標準流程,讓 Agent 幫你自動生成 SQL + 驗證報表。


    3. 產品 / PM:快速驗證 Side Project

    • 搭配 Gemini 3.5(雲端)或本地 LLM
    • 定義一個「最小可行功能」(例如 landing page + 簡單 API)
    • 用多 Agent 完成第一版,再丟給工程師接手

    行動:每次新點子,給自己一個規則:「先讓多 Agent 寫一版 Demo,我只在最後 2 小時調整。」


    怎麼開始:一個最小可行範例

    這裡給一條「3–5 小時內可完成」的路線,你可以直接照做:

    步驟 1:選模型 + Agent 框架

    • 模型:
    • 想省錢/本地:Qwen 2.5 7B(透過 llama.cpp 或 Ollama)
    • 想雲端無痛:Gemini 3.5 Flash(透過 Google AI Studio)
    • Runtime / 框架:
    • 想要 guardrails:裝 Forge
    • 想用現成 MCP:選一個支援 MCP 的 Agent 框架(如 OpenAI 官方 Agent SDK)

    步驟 2:挑一個小系統

    條件:

    • 單服務、沒有第三方整合
    • 你自己寫大約 3–5 小時能完成

    例:任務管理 CRUD API + 簡單 React 前端

    步驟 3:設計任務拆分與 Agent 角色

    1. 任務描述寫成一個 markdown 檔(會給 architect-agent 看)
    2. 在 Runtime 中註冊 4 個 Agent:
    3. architect
    4. backend
    5. frontend
    6. tester/integrator
    7. 為每個 Agent 明確:
    8. 可用工具(Git、Filesystem、HTTP…)
    9. 輸入(上一個 Agent 的輸出 / 檔案)
    10. 必須產出什麼檔案

    步驟 4:加上監控 Dashboard

    • 如果用 Forge:直接啟用它的 Dashboard,看每次工作流的步驟成功率
    • 若自己實作:
    • 為每個步驟記錄:開始時間、結束時間、是否重試
    • 每次失敗時存 log + 輸入輸出到一個資料夾

    步驟 5:只做一件事的迭代

    • 第一版只要求「能跑起來」,不追求漂亮結構
    • 每次失敗,你只調整:
    • 任務拆分是否太粗/太細
    • Agent 提示是否太模糊
    • 重試與 checkpoint 是否設太少

    等到這個小系統穩定後,你才讓 Runtime 去碰更大的專案。


    小結:Runtime 是你的「AI 開發主管」

    Antigravity 2.0 用 96 個 Gemini Agent 寫出一套能跑《Doom》 的 OS,看起來很遠,但背後用到的概念其實都可落在你今天的 side project 上:

    • 把任務拆成 Agent 可接手的小單位
    • 用 Runtime 管控流程,而不是寄望模型每次都猜對
    • 利用開源工具(Forge、llama.cpp、MCP)做出自己的「迷你 Antigravity」

    💡 關鍵: 關鍵不是再換一個更大的模型,而是把現有模型放進可靠的 Runtime,讓它真的「交付」可用產物。

    關鍵不是再換一個更大的模型,而是先把你手上的模型,放進一個可靠的 Runtime 裡,讓它真的幫你「交付」東西。

    🚀 你現在可以做的事

    • 在 GitHub 上看看 Forge 專案,了解多步代理的 guardrails 怎麼設計
    • 挑一個 3–5 小時能手刻完的 CRUD 小服務,照文中的 4 個 Agent 角色拆任務實作一次
    • 把既有的單 Agent 自動化腳本,加上 max_retries 和簡單 checkpoint 機制,量化成功率變化
  • Argyph:在本機幫 AI 裝上程式碼大腦

    Argyph:在本機幫 AI 裝上程式碼大腦

    📌 本文重點

    • Argyph 把你的專案變成本機「程式碼大腦」
    • 三層索引:檔案、symbol graph、向量檢索完全離線
    • 可接 Claude / MCP,協助 debug、refactor、大型專案導覽

    你可以把 Argyph 想成「替你的 AI 助理裝一個本機程式碼大腦」,讓它在大專案裡不再只會 grep 和亂抓檔案。

    Argyph GitHub 專案連結|原始 Reddit 介紹


    為什麼需要一個「程式碼大腦」?

    一般 AI 助理(包含 Claude、各種 MCP 代理)在大專案裡常見幾個痛點:

    • 只會用關鍵字搜尋(grep),找不到真正關鍵的函式或類別
    • 動不動就把整個檔案塞進 context,還是看不懂整個呼叫鏈
    • 要用語義查詢,就得把程式碼丟上雲端向量庫,卡在隱私與延遲

    Argyph 解決的是:在完全本機的前提下,讓 AI 可以精準定位「哪個函式、在哪個檔、被誰呼叫」,再搭配向量檢索補上語義理解。

    💡 關鍵: Argyph 讓 AI 在本機就能理解整個專案結構,不必依賴雲端向量庫或大量 context 塞資料。


    核心功能:三層索引的本機程式碼大腦

    1. 檔案索引:先搞清楚專案長什麼樣

    Argyph 的第一層是「檔案清單」,會掃描整個專案,把所有檔案路徑與基本資訊建成索引。

    你可以立刻拿來做這些事:

    • 問 AI:列出這個 monorepo 裡所有包含 payment 的資料夾與檔案,幫我分類前端 / 後端 / infra
    • 快速導覽:請 AI 幫你列出「所有 migration 檔」、「所有含 config 的檔案」,再逐步打開看

    這一層幾乎等於「強化版 tree + grep」,但 AI 不用自己亂找,它有一份完整的檔案地圖可以參考。

    2. Symbol Graph:函式、類別、呼叫鏈一次串起來

    第二層是重點:Argyph 用 tree-sitter 解析程式碼,建立一個 symbol graph(符號圖):

    • 每個函式、類別、變數變成一個節點
    • 誰呼叫誰、誰繼承誰、誰 import 誰,變成邊

    這代表 AI 不再只看到「文字」,而是有:

    • get_user() 在哪個檔、哪一行
    • 它被哪些 API handler 呼叫
    • 這個 class 的 method 被哪些 service 用到

    你可以這樣用:

    • 問:列出所有呼叫 process_payment 的函式,照檔案列出並解釋呼叫差異
    • 問:幫我畫出 UserService 相關的呼叫鏈,從 HTTP handler 到 DB 層

    這對 debug / refactor / 新人 onboarding 都很實用,因為 AI 能「走呼叫鏈」,不是只看單一檔案。

    💡 關鍵: 有了 symbol graph,AI 可以沿著呼叫鏈追蹤影響範圍,適合用在風險評估與大規模重構。

    3. 向量索引:在本機做語義搜尋

    第三層是向量索引:

    • Argyph 內建向量資料庫與嵌入模型
    • 完全離線,不需要任何 API key

    這允許你用自然語言查詢「概念」而不是關鍵字,例如:

    • 找出專案裡所有處理權限驗證的邏輯,依風險高低幫我摘要
    • 幫我找所有寫死 API key 或憑證的地方,並列出檔案與行號

    向量搜尋是建立在 symbol graph 之上的:AI 可以先找到語義上相近的函式,再搭配呼叫鏈,給出比較完整的分析。

    💡 關鍵: 語義搜尋結合 symbol graph,讓 AI 查的是「概念 + 實際呼叫點」,而不只是模糊的文字相似度。


    適合誰用?三個具體場景

    1. 大型專案導覽與理解舊 codebase

    如果你正在接手一個幾萬行、幾百個檔的專案:

    • 問 AI:幫我整理這個專案的主要模組結構,列出每個模組的 entry point
    • 問 AI:找出所有 user login 流程相關的函式與檔案,畫出流程順序

    實際效果:你不用一個一個資料夾展開找,只要問問題,AI 會用 Argyph 的索引幫你拉出結構化的地圖。

    2. 搭配 Claude / MCP 做 refactor 或 bug trace

    Argyph 是一個 MCP server,可以直接接在支援 MCP 的代理上,例如:

    • Claude Desktop / Claude for Web(啟用 MCP)
    • 其他支援 MCP 的本機代理

    實際操作可以是:

    • 問:這個 bug 是某個 API 回傳格式變了,幫我找出所有依賴該 API 回傳結果的地方,評估改動風險
    • 問:我要把舊的 logging library 換成新的,列出所有使用舊 library 的呼叫點,並給我一個逐步 refactor 計畫

    AI 會:

    1. 用 symbol graph 找到所有相關函式與呼叫點
    2. 用向量搜尋補充語義相似的地方(例如命名不一致的 logging)
    3. 把結果給你看,或協助生成 patch(視你的代理能力而定)

    3. 公司內部需要嚴格保護原始碼

    很多團隊不願意把全專案丟上雲端向量庫(法遵 / NDA / 產業規範等):

    • Argyph 是單一 binary,本機跑、不會把程式碼傳到任何外部服務
    • 只做只讀索引:不會幫你修改、commit 或執行程式碼

    適合:

    • 金融、醫療等需嚴格控管原始碼的公司
    • 只允許在內網跑工具的團隊
    • 想先在個人機器上試驗「AI + codebase」的工程師

    你可以放心地讓 AI 在專案裡查來查去,但知道一切都留在你自己的機器或公司網路。


    和一般 AI 助理 / 雲端向量庫怎麼比?

    如果你現在已經在用「AI + 專案」的工具,可以參考這個比較。

    名稱 核心功能 免費方案 適合誰
    一般 AI 助理(無) 單純依靠上下文 + grep 視服務而定 小專案、單檔問題
    雲端向量檢索工具 把程式碼上傳雲端做語義搜尋 多有免費層級 不介意程式碼上雲端的團隊
    Argyph 本機三層索引(檔案 + symbol + 向量) 開源免費 想要本機、隱私保護又要強檢索的工程師

    怎麼開始:從安裝到接上 Claude / MCP

    以下是一條「最快能跑起來」的路徑,你可以照著做。

    步驟 1:安裝 Argyph(Rust 單一 binary)

    1. 前往 GitHub Releases
    2. 下載對應你系統的 binary(macOS / Linux / Windows)
    3. 將檔案改名為 argyph(可選),並移到你的 $PATH 例如:
    chmod +x argyph
    mv argyph /usr/local/bin/
    

    若你有 Rust 環境,也可以選擇 cargo install(以官方 README 為準)。

    步驟 2:對你的專案建立索引

    在專案根目錄執行:

    cd /path/to/your/project
    argyph index
    

    接著會發生:

    1. 立即建立檔案索引(可用來問檔案結構)
    2. 持續建立 symbol graph(可用來問呼叫鏈)
    3. 背景生成向量索引(可用來做語義搜尋)

    你可以邊等邊用,因為 Argyph 的設計是每一層建好就能用,不必等全部完成。

    步驟 3:在 Claude / MCP 代理中啟用 Argyph

    以 Claude(支援 MCP)為例,整體步驟大致如下(細節以官方文件為準):

    1. 打開 Claude 的 MCP 設定檔,例如 mcp.config.json
    2. 加入一個 Argyph server 設定:
    {
      "servers": {
        "argyph": {
          "command": "argyph",
          "args": ["server"],
          "env": {
            "ARGYPH_PROJECT_ROOT": "/path/to/your/project"
          }
        }
      }
    }
    
    1. 重新啟動 Claude 或重新載入 MCP 設定

    之後在 Claude 裡,你可以直接用自然語言要求它「用 Argyph 的 context」來回答與專案相關的問題(多數 MCP 代理會自動挑選需要的工具)。


    實用查詢範例:馬上能用的 prompt

    你可以照抄以下查詢,稍微改一下專案名就能套用。

    範例 1:找出所有調用某 API 的地方並總結風險

    「請用 Argyph 的索引幫我:
    1. 找出專案裡所有呼叫 createPaymentSession 的地方,列出檔案路徑與行數。
    2. 對每個呼叫點,說明它在什麼情境被呼叫(例如:checkout、訂閱續費)。
    3. 總結如果我修改這個 API 的回傳格式,可能影響的功能與風險。」

    範例 2:整理某個 domain 的完整呼叫鏈

    「這個專案是單一體 monolith,請用 Argyph 的 symbol graph 幫我:
    1. 找出所有跟 user onboarding 相關的函式與 class。
    2. 以『從 HTTP endpoint → service layer → DB layer』的順序,列出呼叫鏈。
    3. 幫我總結每一層主要職責,方便我之後 refactor。」


    總結:把 AI 當「懂專案的夥伴」,而不是「會寫程式的 autocomplete」

    Argyph 的價值在於:讓 AI 真正理解你的專案結構,而不是在一堆檔案裡瞎猜。

    如果你有一個中大型 codebase,又想保持程式碼只待在本機或公司內網,建議可以:

    1. 把 Argyph 裝起來
    2. 對你的主專案掃一輪索引
    3. 在 Claude / MCP 代理裡接上它,從「幫我畫出這個專案的主要模組」這種問題開始試

    你會發現,AI 從「會寫程式」變成了「懂這個專案的同事」。

    🚀 你現在可以做的事

    • 去 Argyph GitHub Releases 下載並安裝 argyph binary
    • 在你主要的專案根目錄執行 argyph index 建立三層索引
    • 打開你的 mcp.config.json,加入 Argyph server 設定並在 Claude / MCP 裡實際問幾個專案問題