iT邦幫忙

2026 iThome 鐵人賽

DAY 17
0
AI Engineering

30天拆Agent:從Repo看設計系列 第 17 篇

Day 17|OpenClaw 的 Tool、Skill、MCP:真正不同的是誰能用、何時觸發,以及怎麼學

  • 分享至 

  • xImage
  •  

第一次看 OpenClaw,很容易覺得:

不也是讓 Agent 接 Tool,再用 SKILL.md 告訴它怎麼做事嗎?

但 OpenClaw 比較值得看的是它多做了一層 Runtime 管理:

哪些 Tool 可以被看到?
哪些 Skill 可以被載入?
這次由 Model 自己挑 Skill,還是 User 強制指定?
MCP 接進來之後,哪些 Agent 可以使用?
User 糾正一次之後,要不要真的修改 Skill?

這些事情並不是全部交給 Model,OpenClaw反而把責任切得很清楚:

Tool / MCP 權限
→ Runtime Config

Skill 是否能載入
→ Skill metadata + Runtime Config

這次要不要使用 Skill
→ Model / User

Skill 要不要因為經驗被修改
→ Model + Skill Workshop + Runtime Policy

這一篇就從這四層來看 OpenClaw 的 Tool、Skill 與 MCP。


1. Tool:不是叫 Model「不要用」,而是 Runtime 先把 Tool 拿掉

假設現在要建立一個航空客服 Agent:

flight-support

它需要:

booking__search
booking__check_rule
booking__update

但不應該使用:

exec
browser
booking__delete_booking

最簡單的方法當然是在 Prompt 寫:

你只能查詢與修改訂位。
不要使用 shell,也不要刪除訂位。

但這不是 OpenClaw Tool Policy 的主要做法。

OpenClaw可以直接在 openclaw.json 設定:

{
  agents: {
    entries: {
      "flight-support": {
        tools: {
          allow: [
            "booking__search",
            "booking__check_rule",
            "booking__update"
          ],
          deny: [
            "exec",
            "browser",
            "booking__delete_*"
          ]
        }
      }
    }
  }
}

這裡的重點是:

所有候選 Tool
        ↓
Tool Policy
        ↓
留下允許的 Tool
        ↓
才交給 Model

OpenClaw 官方文件明確說明,Model 最後只會看到通過 profile、allow/deny、provider restriction、sandbox、channel permission 與 plugin availability 等條件的 Tool。Tool Policy 的各層限制只能繼續縮小能力,後面的設定不能把前面已禁止的 Tool 再開回來;如果明確的 allowlist 最後讓 Agent 一個 Tool 都沒有,OpenClaw甚至會在 Model call 前直接停止。

主要程式在src/agents/tool-policy.ts,裡面有:

collectExplicitAllowlist(...)
collectExplicitDenylist(...)

collectExplicitAllowlist() 會把多層 Tool Policy 裡明確設定的 allow 項目整理出來,而 collectExplicitDenylist() 則整理 deny 項目;同一個檔案也處理 Plugin Tool group 與 MCP server namespace。

透過聊天修改Config JSON

正式設定檔仍然是:

~/.openclaw/openclaw.json

但 OpenClaw也支援從聊天介面修改 config。

例如先開啟:

{
  commands: {
    config: true
  }
}

之後 owner 可以在聊天介面執行:

/config set agents.entries.flight-support.tools.deny=["exec","browser"]

/config 會真的修改 openclaw.json,而且設定會跨 restart 保留;這個 command 預設關閉,而且是 owner-only。

這裡要特別區分「聊天設定」與「自然語言設定」。

User 說:

/config set ...

這是明確 Config。

但 User 只是說:

以後客服 Agent 不要使用 browser。

不能因此假設 OpenClaw 一定會自動修改 Tool Policy。


2. Skill:能不能載入,和這次要不要使用,是兩件不同的事

OpenClaw啟動 Agent run 時,會先解析目前 Agent 可以使用的 Skill,把 eligible Skill 整理進 prompt;Model 可以根據 Skill 的 name 與 description 判斷這次是否相關。OpenClaw同時會建立 Skill snapshot,並在 SKILL.md 變動或其他 refresh 條件發生後更新。

因此:

User:
「我要改明天下午的飛機」
        ↓
Model 看見:
flight-rebooking
        ↓
description 符合目前需求
        ↓
讀取 / 使用 Skill
        ↓
依 Skill 操作 Tool

這一層才是 Model-driven selection。


Skill 不是存在就一定會被載入

OpenClaw還有一個很實際的設計:Load-time gating。

假設 flight-rebooking 必須依賴:

booking-cli
BOOKING_API_KEY
flight.enabled

可以在 SKILL.md 裡宣告:

---
name: flight-rebooking
description: Handle flight rebooking.

metadata:
  openclaw:
    requires:
      bins:
        - booking-cli
      env:
        - BOOKING_API_KEY
      config:
        - flight.enabled
---

OpenClaw載入 Skill 時會先檢查:

booking-cli 是否存在?
BOOKING_API_KEY 是否存在?
flight.enabled 是否為 true?

條件不成立,這個 Skill 就不會成為這次 run 的 eligible Skill。

官方支援的 gating 包含:

requires.bins
requires.anyBins
requires.env
requires.config
os

而且 requires.bins 是在 Skill load time 檢查 host PATH;如果 Agent 另外跑在 sandbox,binary 還必須同時存在 sandbox 裡。

這個設計解決了一個很實際的問題:

沒有 booking-cli
        ↓
不要先讓 Model 選到 flight-rebooking
        ↓
做到一半才發現工具不存在

而是:

Runtime 啟動
   ↓
檢查 dependencies
   ↓
決定 Skill 是否 eligible
   ↓
再交給 Model

Runtime 還可以再控制 Skill Config

除了 SKILL.md,Operator也可以在:

~/.openclaw/openclaw.json

設定:

{
  skills: {
    entries: {
      "flight-rebooking": {
        enabled: true,
        apiKey: {
          source: "env",
          provider: "default",
          id: "BOOKING_API_KEY"
        },
        config: {
          environment: "production"
        }
      }
    }
  }
}

skills.entries 可以控制 Skill 是否啟用、需要注入的 env / credential,以及 Skill 自己需要的 config。Agent run 開始時,OpenClaw會解析 effective skill list,再把 eligible skills 編進 prompt。

因此 Skill 其實有兩層:

SKILL.md
→ 這個 workflow 是什麼、什麼情況使用

openclaw.json
→ 這個 Runtime 是否允許它、環境是否具備條件

3. 同一個 Skill 還可以有三種觸發方式

OpenClaw這裡有一個比「有 SKILL.md」更值得看的設計:

同一種能力,不一定都要讓 Model 自己判斷。

一般情況:

---
name: flight-rebooking
description: Handle flight rebooking.
---

代表 Model 可以根據自然語言自行選擇。

User:
「幫我改機票」
       ↓
Model 判斷
       ↓
flight-rebooking

但如果設定:

---
name: flight-rebooking
description: Handle flight rebooking.
user-invocable: true
disable-model-invocation: true
---

那這個 Skill 不會出現在 Model 正常的 Skill prompt 裡,Model不能自行選擇;但 User仍然可以明確指定它。

例如:

$flight-rebooking

或對支援 command 的 channel 使用對應 Skill command。

還有第三種:

---
name: flight-rebooking
description: Handle flight rebooking.

command-dispatch: tool
command-tool: booking_rebook
command-arg-mode: raw
---

這種情況甚至可以:

/flight-rebooking BR123 tomorrow
              ↓
不先讓 Model 決定流程
              ↓
直接 dispatch booking_rebook Tool

OpenClaw文件明確把 command-dispatch: tool 定義為直接送到指定 Tool、繞過 Model 的模式。


4. MCP:接進 OpenClaw 後,不是另一套權限系統

接下來看 MCP。

假設現在航空公司已經有一個 MCP Server:

booking-mcp

提供:

search
check_rule
update
delete_booking

Operator可以把它加入 OpenClaw 管理的 MCP registry。

例如從聊天介面:

/mcp set booking={"command":"booking-mcp","args":["serve"]}

但 /mcp 預設也是關閉的,需要:

{
  commands: {
    mcp: true
  }
}

而且同樣是 owner-only。

這些設定會寫入 OpenClaw 的:

mcp.servers

不是只存在目前 conversation。


MCP Tool 進來後,仍然走 Tool Policy

這裡才是 OpenClaw MCP 設計比較有意思的地方。

Configured MCP Tool 會使用 canonical name:

<server>__<tool>

例如:

booking__search
booking__check_rule
booking__update
booking__delete_booking

然後前面第一節的 Tool Policy 可以直接寫:

{
  agents: {
    entries: {
      "flight-support": {
        tools: {
          allow: [
            "booking__search",
            "booking__check_rule",
            "booking__update"
          ],
          deny: [
            "booking__delete_*"
          ]
        }
      }
    }
  }
}

也就是:

Built-in Tool ─┐
Plugin Tool ───┤
MCP Tool ──────┼─→ Tool Policy → Model
其他 Tool ─────┘

OpenClaw文件直接規定 configured MCP tools 使用相同 policy surface;MCP server 如果經過 policy 後沒有任何允許的 Tool,該 server 可以直接從該 run 的有效 capability 中被省略。

src/agents/tool-policy.ts 也真的讀取 MCP server names,並和 Plugin Tool group 一起處理。


OpenClaw甚至同時扮演 MCP Client 與 MCP Server

openclaw mcp 有兩種不同方向。

第一種:

OpenClaw
   ↓
MCP Client
   ↓
booking-mcp

也就是前面設定的:

mcp.servers

第二種則是:

openclaw mcp serve

方向變成:

Codex / Claude Code / 其他 MCP Client
               ↓
              MCP
               ↓
           OpenClaw
               ↓
      OpenClaw channel conversation

官方 CLI 文件明確把這兩個角色分開:

openclaw mcp serve
→ OpenClaw 當 MCP Server

openclaw mcp list / add / set / probe ...
→ 管理 OpenClaw 要連出去的 MCP Server

因此 OpenClaw 的定位已經不只是:

Agent + MCP Client

而比較接近:

           External MCP
                ↓
                │
          ┌─────▼─────┐
          │ OpenClaw  │
          │  Gateway  │
          └─────┬─────┘
                │
      ┌─────────┴─────────┐
      ↓                   ↓
OpenClaw Agent      External MCP Client

這也是它作為 Gateway Runtime 和一般 Agent SDK 很不一樣的地方。


5. Self-learning 才是真的讓 Agent 改變能力

假設原本 Skill 寫:

1. cancel 舊航段
2. 找新航班
3. rebook

實際執行時 User 糾正:

不對。

這種票不能先 cancel。
要先 rebook 新航段成功,
才能取消舊航段。

如果這只是一般 Memory,可能只會變成:

這個 User 曾說過要先 rebook。

但 OpenClaw 的 Self-learning 想處理的是另一件事:

這是不是一個未來還會重複使用的 procedure?

如果答案是,是,那它應該修改 Skill。

Skill Workshop:Agent 不是直接偷偷改 SKILL.md

OpenClaw在src/agents/skill-workshop-prompt.ts有buildSkillWorkshopPromptSection()

其中直接建立一段 Skill Workshop system prompt,要求 Agent 對自己主動發現的 durable、reusable skill / workflow 改進走 skill_workshop,而不是直接改 Workshop proposal 或 Workshop-owned Skill。它同時區分 User 明確要求修改自己擁有的 workspace/project Skill 時,可以直接使用一般 file tools。

而:

src/agents/system-prompt.ts

會先判斷:

availableTools.has(SKILL_WORKSHOP_TOOL_NAME)

只有這次 run 真的有 skill_workshop Tool 時,才把 Workshop 的 prompt section 加進 system prompt。

也就是:

這次 Runtime
有 skill_workshop
       ↓
System Prompt 加入
Skill Workshop routing rule
       ↓
Agent 發現 durable procedure
       ↓
skill_workshop

User 糾正後,有兩種 Learning 路徑

OpenClaw現在的 Self-learning 有兩種值得區分的情況。

第一種:Agent 當下就發現剛剛使用的 Skill 有錯

例如:

Agent 使用 flight-rebooking
        ↓
做錯順序
        ↓
User 糾正
        ↓
Agent 按新順序成功完成

OpenClaw可以做 Immediate Repair。

但不是任意 Skill 都能改。

Runtime會用 usage receipt 確認這次 run 真的使用過該 Skill,才允許 foreground repair;修正仍會經過 proposal storage、hash binding、安全掃描與 rollback capture。

最後是否直接套用,由skills.workshop.autonomous.mode決定。

例如:

openclaw config set skills.workshop.autonomous.mode propose

代表:

發現可重用修正
     ↓
建立 proposal
     ↓
等待人工確認

如果:

openclaw config set skills.workshop.autonomous.mode auto

則允許通過相關檢查後自動維護 Workshop Skill。

如果:

openclaw config set skills.workshop.autonomous.mode off

則停用 autonomous learning。

目前文件中的預設值是:

auto

第二種:User 沒叫它學,但這次工作值得回頭檢查

這叫:

Experience Review

假設一個客服 case 是:

Agent 嘗試 A
      ↓
失敗
      ↓
User 修正
      ↓
嘗試 B
      ↓
成功
      ↓
User:「好,謝謝」

User 完全沒有說:

請記住

或:

請修改 Skill

OpenClaw仍可能在 foreground work 結束後安排一次 detached review。

它也不是每一句對話都做。

目前 Self-learning 文件列出的 troubleshooting 條件包含:

至少 10 次 model iterations

不是 provider / prompt error

屬於 eligible foreground work

Runtime 確實回報 model 與 skill_workshop 可用

Gateway 在 30 秒 quiet period 內保持運作與 idle

符合條件後,Review Model再根據真實 conversation evidence 判斷:

這裡有沒有值得長期保存的 procedure?

沒有就 abstain。

不是每次都硬生一個 Skill。

所以流程比較像:

Conversation
      ↓
複雜工作完成
      ↓
Experience Review
      ↓
Model review evidence
      ↓
┌───────────────┐
│值得形成 Skill?│
└───────┬───────┘
        │
    ┌───┴───┐
    ↓       ↓
   No      Yes
    ↓       ↓
 abstain   Workshop

這才是真正接近我們前面一直討論的 Autolearning。

User 也可以明確要求「從這次工作學」

如果 User 不想等 Runtime 自己判斷,可以直接/learn或/learn docs/flight-runbook.md; focus on recovery

這條路徑會以目前 conversation 或指定資料作為 learning evidence。

但有一個很重要的差別:

/learn 不會因為 autonomous mode 是 auto 就偷偷直接套用。

官方設計是先找 matching pending proposal 或 matching live Skill;如果沒有適合的 Skill 才建立新的 pending proposal,而且 explicit /learn 不會 auto-apply。

因此可以把 OpenClaw 的 Skill learning 簡化成三種:

User 當下糾正
        ↓
Immediate Repair


User 沒要求學
但完成一段複雜工作
        ↓
Experience Review


User 明確要求學
/learn
        ↓
Explicit Learning

References


上一篇
Day 16|OpenClaw 的 Agent 怎麼組成?從小航一路看到跨 Agent 委派
下一篇
Day 18|OpenClaw 怎麼記住人?從 Memory Promotion 到多人記憶隔離
系列文
30天拆Agent:從Repo看設計 共 18 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言