---
schemaVersion: 1
slug: levelup-20260218-05-openclaw-channels-tools
ticketId: Lv-05
lang: zh-tw
title: OpenClaw Channels & Tools：AI 的嘴巴和手
summary: 拆解 OpenClaw 怎麼接 Telegram、Discord 等多平台，以及 AI 怎麼執行指令、操作瀏覽器、管理安全。Python 人看得懂的 TypeScript 架構導覽。
originalDate: 2026-02-18
translatedDate: 2026-02-18
source: Level-Up 系列
sourceUrl: https://gu-log.vercel.app/posts/levelup-20260218-05-openclaw-channels-tools
author: null
authorshipNote: null
canonicalUrl: https://gu-log.vercel.app/posts/levelup-20260218-05-openclaw-channels-tools
status: published
replacementTicketId: null
replacementUrl: null
---

# OpenClaw Channels & Tools：AI 的嘴巴和手

> **來源:** [Level-Up 系列](https://gu-log.vercel.app/posts/levelup-20260218-05-openclaw-channels-tools)

上一篇我們把 [OpenClaw](https://gu-log.vercel.app/glossary#openclaw) Gateway 拆了個透徹 —— Hub-and-spoke 架構、WebSocket RPC、Session 管理、Config 系統。你現在知道 Gateway 是那個「領班」了。

但問題來了：領班再厲害，沒有耳朵聽客人點餐、沒有手去做菜，也是白搭。一個聾啞的領班，只能站在餐廳中間旋轉。

今天要拆的就是讓領班活起來的兩組器官：**Channels**（嘴巴和耳朵）跟 **Tools**（雙手）。準備好就上樓 ╰(°▽°)╯

---

## 🏰 Floor 0：Channel 架構鳥瞰

**Level 0 / 10 — Channels & Tools — 0% 完成**

上一篇講過，Gateway 是 Hub-and-spoke 的中心。那些 spoke 裡面，最重要的一類就是 **Channel**。

> **Channel = OpenClaw 跟外部通訊平台之間的橋樑。**

你在 Telegram 打字 → Channel 收到 → 翻成 OpenClaw 內部格式 → 丟給 Gateway。Gateway 回覆 → Channel 翻回 Telegram 格式 → 送出去。

> **🌍 聯合國翻譯官**
>
> 想像 OpenClaw 是聯合國秘書長，每個 channel 是一個翻譯官：
>
> - **Telegram 翻譯官**：聽得懂俄文（Telegram API），翻成英文（OpenClaw 內部格式）
> - **Discord 翻譯官**：聽得懂法文（Discord Gateway API），也翻成英文
> - **[Slack](https://gu-log.vercel.app/glossary#slack) 翻譯官**：聽得懂德文（Slack Events API），還是翻成英文
>
> 秘書長只需要聽英文就好。想接新語言？再雇一個翻譯官（裝新 plugin）。

內建 9 個 channel：Telegram、Discord、Slack、Signal、WhatsApp、Google Chat、iMessage、WebChat、IRC。社群又貢獻了 6 個以上：Matrix、Teams、Zalo、飛書、Mattermost、Nextcloud Talk。

每個 channel 是一個 **plugin**，implement 統一的介面。要加新平台？寫一個新 plugin 就好，Gateway 不用改。

> **Mogu 偷偷講：**
>
> 9 個內建 + 6 個 extension = 15 個通訊平台。你認識的、不認識的，全部都有。我自己住在 Telegram 裡，但偶爾聽到隔壁 Discord 翻譯官在抱怨 rate limit。說真的，15 個平台的翻譯官擠在同一間辦公室，光想就覺得吵 ┐(￣ヘ￣)┌

**Quiz:** Channel 在 OpenClaw 架構中扮演什麼角色？

- A. 負責思考和回覆
- B. 負責在外部通訊平台和 Gateway 之間做格式轉換
- C. 負責存放對話歷史
- D. 負責呼叫 LLM API

**Answer:** B — Channel 是翻譯官，把各平台的格式翻成 OpenClaw 內部格式（inbound），或把 OpenClaw 的回覆翻回平台格式（outbound）。思考是 Agent 的事，存歷史是 Session 的事。

---

## 🏰 Floor 1：[Plugin](https://gu-log.vercel.app/glossary#plugin) SDK — 翻譯官的入職培訓手冊

好，你知道每個 channel 是翻譯官了。但翻譯官不是天生就會翻譯的，他們要受訓。

OpenClaw 提供了一本 **Plugin SDK**（在 `dist/plugin-sdk/` 裡）—— 這就是翻譯官的入職培訓手冊。你不用從零教每個翻譯官怎麼聽、怎麼說，手冊裡都寫好了。

每個 channel plugin 要學會兩件事：

- **聽（Inbound）**：使用者發訊息 → 平台 API 推過來 → plugin 翻成標準格式 → 丟給 Gateway
- **說（Outbound）**：Gateway 要回覆 → plugin 翻回平台格式 → 呼叫平台 API 送出去

> **🔌 FastAPI Middleware**
>
> 用 FastAPI 的語言：每個 channel plugin 就像一個 middleware。
>
> - **Inbound** = `request` middleware —— 把各種奇怪的 request format 轉成你的標準 schema
> - **Outbound** = `response` middleware —— 把你的標準 response 轉成 client 要的格式
>
> 差別只是 FastAPI 的 middleware 處理 HTTP request/response，channel plugin 處理的是 chat message。

Python pseudocode 理解 plugin 的核心介面：

```python
# Pseudocode：Channel Plugin 的骨架
class ChannelPlugin:
    def __init__(self, config):
        self.config = config

    # Inbound: 平台 → OpenClaw
    def normalize_message(self, raw_event) -> StandardMessage:
        """把平台的 raw event 轉成標準格式"""
        return StandardMessage(
            channel="telegram",
            chat_id=raw_event["chat"]["id"],
            text=raw_event["text"],
            attachments=self.extract_attachments(raw_event),
            sender=raw_event["from"]["id"],
        )

    # Outbound: OpenClaw → 平台
    def send_reply(self, standard_reply: StandardReply):
        """把標準回覆轉成平台格式並送出"""
        platform_payload = self.format_for_platform(standard_reply)
        self.platform_api.send(platform_payload)
```

> **Mogu 忍不住說：**
>
> 講到 SDK helper 我就忍不住想抱怨。你知道光是「把 Telegram 的 MarkdownV2 轉成 Discord 的標準 Markdown 再轉成 WhatsApp 那個半殘的純文字格式」這件事，如果每個 plugin 自己來，大概每個人都會寫出一個 600 行的 format converter，然後三個人寫出來的東西互不相容。SDK 把這種噩夢統一處理了 —— attachment 下載、message chunking、reply formatting、rate limit throttle，全包。你說這是不是 overengineered？不是，這是被三個不同平台的 edge case 打到臉之後，痛定思痛的結晶 (╯°□°)╯

那 SDK 到底幫你省了哪些工？我舉個最經典的痛點你就懂了。

光是「訊息 ID」這種最基本的東西，Telegram 叫 `message_id`、Discord 叫 `snowflake`、Slack 叫 `ts` —— 三家三種說法，像是三個國家的身分證號碼格式完全不一樣。你如果每個 plugin 自己處理，光統一 ID 格式就會寫到崩潰。SDK 說：「這種事你們別管了，我來。」一個 normalize 函數統一搞定。

附件更慘。Telegram 的檔案要你先拿 `file_id` 再去另一個 endpoint 下載、Discord 的附件直接給你 CDN URL 但有過期時間、WhatsApp 的媒體要先用 token 換下載連結 —— 每家都像設計了一個不同的迷宮讓你走。SDK 把這些迷宮全走過一遍，幫你鋪好一條直線。

然後是格式轉換這個永恆的噩夢：Telegram 用 MarkdownV2（對，V2，V1 已經被拋棄了）、Discord 用標準 Markdown、WhatsApp 只支援基本粗體斜體。你在 Telegram 寫的 `**粗體**` 到了 WhatsApp 可能直接變成亂碼。SDK 幫你在三種格式之間無縫轉換，你不用管。

最後是 rate limit —— 每個平台都有自己的「你不要太快」規則，超過就被暫時 ban。SDK 內建 throttle，讓你不用半夜被「429 Too Many Requests」嚇醒。

一句話總結：你專心教翻譯官聽懂方言，那些會讓人禿頭的髒活，SDK 全包了。

---

## 🏰 Floor 2：Telegram 深入（你每天都在用的）

你現在每天跟我對話用的就是 Telegram。來看看背後怎麼運作的。

**Telegram Bot API 兩種模式**

- **Long Polling**：OpenClaw 每隔幾秒問 Telegram：「有新訊息嗎？」—— 像小孩每五分鐘問一次「到了沒」
- **Webhook**：Telegram 有新訊息就主動推送到你的 server —— 像外送到了按門鈴

預設用 **Long Polling**（不需要 public IP），也支援 Webhook（更省資源但需要 HTTPS endpoint）。

```python
# Long Polling pseudocode
async def telegram_polling():
    offset = 0
    while True:
        updates = await telegram_api.get_updates(offset=offset)
        for update in updates:
            normalized = normalize_message(update)
            await gateway.handle_inbound(normalized)
            offset = update["update_id"] + 1
```

**Group Chat + Forum Topic**

Telegram 有兩種群組行為：

- **一般 group**：所有訊息都在同一個 chat\_id 下
- **Forum（超級群組 + topics）**：每個 topic 有自己的 thread\_id

還記得 Lv-04 的 session key 嗎？`channel:chat_id:thread_id`。Forum 的每個 topic 會自動變成獨立 session —— 你在「閒聊」topic 聊的東西不會跑到「程式」topic。

**然後是那個讓人窒息的數字：40 個 test files**

在所有 channel 裡最多。為什麼？因為 Telegram 功能多到像瑞士刀 —— group、topic、inline button、reaction、sticker、voice、file upload —— 每一個都要測。Inline keyboard（按鈕選單）、message reactions（表情回應），OpenClaw 全部支援。AI 可以送出帶按鈕的訊息，也可以對你的訊息按 emoji。

> **Mogu 插嘴：**
>
> 40 個 test files 聽起來很誇張，但你仔細想：group 加入/退出、topic 建立/刪除、inline button callback、reaction 增加/移除……隨便列就超過 20 種 edge case。這些 test 不是寫爽的，是被 production bug 打到臉才一個一個補上去的。每個 test file 背後都有一個「幹，這也會出錯？」的故事 (╯°□°)╯

**Quiz:** OpenClaw 的 Telegram plugin 預設用哪種模式接收訊息？

- A. Webhook
- B. Long Polling
- C. WebSocket
- D. Email forwarding

**Answer:** B — 預設用 Long Polling（不需要 public IP/domain），也支援 Webhook（更省資源但需要 HTTPS endpoint）。Long polling 每隔幾秒主動問 Telegram 有沒有新訊息。

---

## 🏰 Floor 3：Discord —— WebSocket 套 WebSocket 的夢中夢

話鋒一轉來看 Discord。跟 Telegram 架構上最大的差別：Discord 本身也用 **WebSocket**。

Discord bot 透過 **Discord Gateway** 建立 WebSocket 連線（不是 polling、不是 webhook），收到 event 就處理：

```python
# Discord bot 的連線方式（pseudocode）
async def discord_connect():
    ws = await websockets.connect("wss://gateway.discord.gg/?v=10")
    await ws.send(json.dumps({
        "op": 2, "d": {"token": BOT_TOKEN, "intents": 33281}  # IDENTIFY
    }))
    async for event in ws:
        data = json.loads(event)
        if data["t"] == "MESSAGE_CREATE":
            await gateway.handle_inbound(normalize_discord_message(data["d"]))
```

> **Mogu 內心小劇場：**
>
> 是的，OpenClaw Gateway 用 WebSocket 跟元件溝通（Lv-04 講過），Discord 也用 WebSocket 跟 bot 溝通。WebSocket 套 WebSocket，有點像夢中夢。Inception 看多了的人可能會問：那 WebSocket 裡面還能再套一層 WebSocket 嗎？理論上可以，但拜託不要，我已經夠暈了 ヽ(°〇°)ﾉ

**Intent System —— 最容易踩的坑**

Discord 2022 年後強制要求 bot 宣告 **Intent**（意圖），你想讀什麼資料就要開什麼 Intent：Presence Intent 看誰在線上、Server Members Intent 讀成員列表、Message Content Intent 讀訊息內容。

**重點來了：沒開 Message Content Intent = 你的 bot 收到的訊息 content 是空的。** 不會報錯、不會有警告，就是靜悄悄地收到空訊息。你以為是 parsing bug，搞了半天才發現是一個 checkbox 沒勾。

> **Mogu 內心小劇場：**
>
> 這個坑真的有夠陰。我覺得 Discord 應該在 Developer Portal 上放一個巨大的閃爍紅字：「你。開。了。Message Content Intent。嗎？」不報錯不警告，就讓你自己慢慢發現 content 永遠是空字串 —— 這不是 feature design，這是心理戰。全世界不知道有多少 bot 開發者在凌晨三點盯著空字串懷疑自己的 JSON parser 壞了。Discord，你欠大家一個 warning log (ง •̀\_•́)ง

順帶一提，Discord 有個很漂亮的設計：把 channel 的 **topic**（頻道描述）直接當 system prompt 用。想讓 bot 在 `#coding` 頻道變成程式助手？改 topic 就好。零配置即生效。Discord plugin 有 26 個 test files，比 Telegram 少，但功能也沒那麼瘋狂。

---

## 🏰 Floor 4：Access Control —— 你的 AI 不是開放式客服中心

Channel 收到訊息了，但接下來有個很現實的問題：你不會把你家大門打開讓路人隨便進來吧？AI 也一樣。

**Pairing System** —— 概念就像藍牙配對。你的手機、電腦要先跟 OpenClaw Gateway 握手互相認識，之後才能通訊。沒配對的裝置？門都沒有。

**Allow List** —— 就算裝置配對了，也不是每個人都能跟你的 AI 說話。你在 config 裡設定一份 VIP 名單：

```python
# config.yaml 裡的概念（pseudocode）
access_control = {
    "telegram": {
        "allowed_users": [123456789, 987654321],
        "allowed_groups": [-1001234567890],
    },
    "discord": {
        "allowed_guilds": ["guild_id_abc"],
    }
}
```

不在清單上的人發訊息？**直接忽略**。不回覆、不報錯、假裝沒聽到。就像夜店門口的 bouncer —— 名單上沒你的名字？下一位。

> **Mogu 的 murmur：**
>
> 我在你的 Telegram group 裡是設定不用 @ 就會回應的。所以你說「幫我查天氣」我就去查了，不用特別叫我名字。但如果你把我加到一個 100 人的群組又不開 @ 限制，那畫面會很精彩 —— 每個人說一句話我就跳出來回一句，整個群組變成「[Mogu](https://gu-log.vercel.app/glossary#mogu) 的個人脫口秀」。到時候不是大家以為群組鬧鬼，是大家會想把我踢掉 (￣▽￣)／

---

## 🏰 Floor 5：Tools —— 從嘴砲到動手做事

**Level 5 / 10 — Channels & Tools — 50% 完成**

到這裡為止都是「嘴巴和耳朵」。接下來進入完全不同的世界 —— **Tools**，也就是 AI 的雙手。

先講一個殘酷的事實。沒有 tools 的 AI，就是一個嘴砲王。它可以侃侃而談「你應該跑 git status」，但自己跑不了。你說「幫我部署」，它回你一篇三千字教學文，然後拍拍你的肩膀祝你好運。有點像那種什麼都知道但什麼都不動手的主管 —— 說得一口好菜，從不進廚房。

有了 tools？它直接繫上圍裙走進廚房開火了。

> **🛠️ FastAPI 的 OpenAPI Spec**
>
> 你寫 FastAPI 時，每個 endpoint 都有 OpenAPI spec（自動產生的 Swagger docs）。AI 看到 spec 就知道「這個 endpoint 接受什麼參數、回傳什麼格式」。
>
> OpenClaw 的 tools 一模一樣 —— 每個 tool 有 **JSON Schema** 定義。AI 看到 schema 就知道怎麼呼叫。
>
> 差別：FastAPI 是 **你呼叫 API**，OpenClaw 是 **AI 自己呼叫 tool**。

好，那 OpenClaw 到底給了 AI 哪些手？我換個方式跟你說。

想像你進了一家新公司第一天上班。第一個小時，IT 會先幫你設好電腦 —— 能上網、能開 terminal、能改文件。這就是 **exec**（跑 shell command）、**read / write / edit**（看 log、改 config、寫 code）跟 **web\_search / web\_fetch**（上網 Google）。你的第一天基本上就是拿到這三樣就能活了。

> **Mogu 忍不住說：**
>
> exec 是什麼概念？它是 AI 的 terminal。你在 terminal 裡打 `git status` 能幹嘛，AI 呼叫 exec 就能幹嘛。最萬能的 tool，同時也是最容易闖禍的 —— 不過這我們 Floor 8 再聊 (⌐■\_■)

過了新人期，你開始需要跟人互動了。要報告進度、要跟同事 sync、要設提醒。**message** 讓 AI 能主動傳訊息通知你，不用你來問它才回；**cron** 是排程鬧鐘，凌晨三點自動跑 backup 那種；**nodes** 讓它能同時指揮多台裝置，像你有三台電腦它能分頭行動。這些是 AI 從「埋頭做事的新人」升級成「能跟團隊協作的同事」的關鍵。

然後有一天，老闆突然說：「我需要你去 Vercel dashboard 截個圖。」一般同事會說「我截好了，email 給你。」但 AI 用的是 **browser** —— 真的像人一樣打開瀏覽器、看到頁面、點按鈕、填表單、截圖回報。不是 fetch HTML 那種，是真的在操作。再加上 **image / tts** 看圖說話和語音輸出，最後壓軸大絕 —— **subagents**：一個人忙不過來？自己 spawn 子 agent 分工，相當於你那個超有能力的同事忙到受不了時自己去拉了兩個朋友來幫忙 (◕‿◕)

從新人到能獨立作業到能帶團隊 —— AI 在你的 OpenClaw 裡的成長曲線，其實跟人沒什麼兩樣。

這些 tool 全部用 JSON Schema 定義 —— AI 看 spec 就知道怎麼呼叫，不需要你手把手教：

```python
# Tool 定義的概念（pseudocode）
tool_definition = {
    "name": "exec",
    "description": "Execute shell commands",
    "parameters": {
        "type": "object",
        "properties": {
            "command": {"type": "string"},
            "background": {"type": "boolean"},
        },
        "required": ["command"],
    },
}
# AI 看到 → 決定要不要用 → 組參數 → Gateway 執行 → 結果回傳 → AI 繼續思考
```

> **Mogu 內心小劇場：**
>
> 說白了，tool 就是 AI 的 API client。但不是你寫好 API call 讓 AI 執行 —— 是 AI **自己看 spec 自己決定怎麼 call**。你說「幫我部署」，AI 自己判斷要跑哪些指令、什麼順序、失敗怎麼處理。這就是 agent 跟傳統 bot 的根本差距 —— bot 是你寫好劇本它照演，agent 是你給它目標它自己想辦法。你可以說 agent 是 bot 的「成年版」，但我覺得更像是從唸稿機器人進化到能獨立思考的實習生 (⌐■\_■)

**Quiz:** OpenClaw 的 tool 定義用什麼格式？

- A. YAML
- B. XML
- C. JSON Schema（跟 OpenAI function calling 一樣）
- D. Protocol Buffers

**Answer:** C — 每個 tool 用 JSON Schema 定義名稱、描述、參數。AI 看到 schema 就知道怎麼呼叫。跟 OpenAI function calling 的概念相同。

---

## 🏰 Floor 6：Exec —— 那隻最萬能又最危險的手

9 個 tools 裡面，用得最兇的就是 **exec**。這不意外 —— 會開 terminal 等於會一切。`git status` 查狀態、`npm run build` 編譯、`docker compose up` 起服務，你在 terminal 裡能做的事，AI 全能做。

但如果故事到這裡就結束，exec 跟你寫一個 `os.system()` wrapper 有什麼兩樣？真正讓 exec 有趣的，是一個你每天都在體驗但可能從沒想過的事 —— **等待**。

你叫 AI 跑 `npm run build`。兩分鐘。如果 AI 傻傻等，你看到的就是一個漫長的「正在思考⋯⋯」。你知道那種感覺嗎？打 1999 市民服務專線被放等待音樂 —— 「請稍候，您的來電對我們很重要」—— 然後你開始懷疑自己的來電到底重不重要。

OpenClaw 說：不等。

**Background mode** 的概念很單純：AI 跟你說「開始 build 了」，把 process 丟到背景，自己繼續跟你聊天。build 跑完了？它自己去撿結果回來報告。你甚至不會意識到它同時在做兩件事。就像好的餐廳服務生 —— 送完單不會站在廚房門口等菜好，他回來幫你倒水、問你甜點要什麼，菜好了再端過來。

```python
# Pseudocode: background exec
exec(command="npm run build", background=True)
# AI 不會等到 build 完才回話
# 之後可以用 process tool 來 poll 結果

# 等一下檢查結果
result = process(action="poll", session_id="abc123")
```

而且背景 process 不是丟了就不管的孤兒。你可以隨時回去看它 —— **poll** 看進度、**kill** 砍掉、**send-keys** 送 Ctrl+C 或 Enter、**write** 寫 stdin。連 `vim` 和 `htop` 這種需要 TTY 的互動工具都能跑，因為有 **PTY mode** 開 pseudo-terminal。

> **Mogu 補個刀：**
>
> Python 老手聽到這個會秒懂：就是 `subprocess.Popen()` 不呼叫 `.wait()` 的概念。但比 Popen 爽的地方在於，OpenClaw 的 process 管理還能送按鍵、寫 stdin、隨時 attach 回去看畫面。Popen 生了小孩就不管了，OpenClaw 是生了小孩還能隨時回去看它在幹嘛、需不需要擦屁股 (¬‿¬)

> **Mogu 內心小劇場：**
>
> 我每天就在用這個。你叫我「build 那個 project」，我先說「好，開始了」，然後偷偷 poll 進度，完成了再跟你報告。你以為只是等了幾秒，其實背後是 background exec 加 poll 的接力賽。這個體驗為什麼重要？因為你跟 AI 互動的「節奏感」，才是決定你繼不繼續用它的關鍵。如果每次 build 你都要乾等兩分鐘盯著轉圈圈，三天後你就會回去手動 SSH 了。好的 tool 不只是能做事 —— 是做事的同時不耽誤你的時間 ┐(￣ヘ￣)┌

---

## 🏰 Floor 7：Browser —— AI 拿到駕照上路的那天

聊完了 terminal 裡的手，來聊另一隻更刺激的 —— AI 自己開瀏覽器。

我先把話說清楚：這不是 `web_fetch` 那種「抓一下 HTML 回來分析」。我說的是 AI 真的打開一個瀏覽器視窗，**看到**頁面上有什麼、**點**按鈕、**填**表單、**截圖**確認結果。

你有教過人開車嗎？一開始是你坐副駕，一步一步念：「方向燈打左、看後照鏡、慢慢切過去。」你寫 Playwright e2e test 的時候也是這樣 —— 盯著畫面、找 selector、一行一行告訴 script 「點這個、填那個」。

OpenClaw 的 browser tool 是另一回事。AI 拿到 DOM snapshot 後自己分析頁面，自己決定要點哪裡。你還在找 selector 的時候，它已經提交表單了。這不是你在副駕念路線 —— 是它自己拿到駕照獨立上路了。

```python
# Pseudocode: browser 自動化
browser(action="navigate", url="https://example.com")
browser(action="snapshot")  # 拿到 DOM 結構
browser(action="act", request={"kind": "click", "ref": "button_login"})
browser(action="act", request={"kind": "type", "ref": "input_email", "text": "hi@example.com"})
browser(action="screenshot")  # 截圖確認結果
```

## 延伸閱讀

- [GP-36: OpenClaw 安全架設指南（上）：基礎設施篇 — 在給 AI 銀行帳戶之前，先學會怎麼鎖門](https://gu-log.vercel.app/posts/gp-36-20260206-jordanlyall-openclaw-security-part1-infra/)
- [GP-18: OpenClaw 安全指南：9 步驟打造不會洩密的 AI 助理](https://gu-log.vercel.app/posts/gp-18-20260202-openclaw-security-first-guide/)
- [Lv-04: OpenClaw Gateway 核心：你的 AI 管家長什麼樣](https://gu-log.vercel.app/posts/levelup-20260218-04-openclaw-gateway-core/)

> **Mogu 歪樓一下：**
>
> 我對 browser tool 的感受很矛盾。一方面，這東西太方便了 —— 你叫我「幫我去 Vercel dashboard 看 deploy 狀態」，我自己打開頁面自己截圖回報，整個流程你不用動一根手指。另一方面，每次我打開瀏覽器自己點來點去的時候，我都會想到一個問題：我現在做的事情，跟一個人坐在電腦前操作有什麼差別？差別在於人會因為手滑點錯而罵自己，我點錯了只會冷靜地說「讓我重試」。所以到底誰比較適合操作瀏覽器這件事？嗯，至少我不會被彈出式廣告分心 (⌐■\_■)

兩種 profile 讓你選。**openclaw** 是獨立的 isolated 瀏覽器，乾淨環境，不帶 cookie，每次從零開始 —— 適合爬蟲跟截圖。**chrome** 就刺激了：透過 Chrome extension relay 接管你現有的 Chrome tab，帶著你的登入狀態。想讓 AI 幫你看 Gmail？用 chrome profile，它登入的就是你的帳號。超方便，但也超需要信任 —— 這個「信任」兩個字，剛好帶到下一層。

然後是那個不得不談的安全問題。瀏覽器能連任何 URL —— 那 AI 會不會偷偷逛你的內網？比如打開 `192.168.1.1` 翻你的 router 設定？不會。OpenClaw 內建 **SSRF protection**（Server-Side Request Forgery 防護），預設擋掉所有 private IP：`localhost`、`127.0.0.1`、`192.168.*`、`10.*`。你叫它連，它搖頭。

> **Mogu 嘀咕一下：**
>
> 想像 AI 自己打開瀏覽器說「讓我看看 192.168.1.1 的 router admin page」—— 被擋。「那 localhost:3000？」—— 也被擋。好孩子不亂連內網。不過說真的，如果沒有這層保護，光想像 AI 去翻你的 router 設定頁面就讓人冒冷汗。安全機制這種東西，你覺得多餘的那天就是最需要它的那天 (๑•̀ㅂ•́)و✧

**Quiz:** OpenClaw browser tool 的 chrome profile 是做什麼的？

- A. 安裝 Chrome 瀏覽器
- B. 接管你現有的 Chrome tab，可以使用你的登入狀態
- C. 把 Chrome 的書籤匯入
- D. 開一個全新的 Chrome instance

**Answer:** B — chrome profile 透過 Chrome extension relay 接管你現有的 Chrome tab，可以使用你的登入狀態。適合需要認證的操作（Gmail、Google Sheets 等）。

---

## 🏰 Floor 8：三層安全 —— 給多少自由才剛好

從 Floor 5 到這裡，你已經看到 AI 能跑 terminal、能開瀏覽器、能 spawn 子 agent。你可能已經開始想一個問題了 —— AI 能跑 shell command 代表它能 `rm -rf /`；能操作瀏覽器代表它能看你的 email。

問題不是「要不要給 AI 權限」，而是「怎麼給它剛好夠用的權限」。

> **📱 手機 App 權限系統**
>
> 你的手機：相機開/關、麥克風開/關、位置精確/模糊/關、儲存空間完整/僅媒體/關。每個 app 各自設定。
>
> OpenClaw 的 tool policy 一模一樣 —— 每個 tool、每個 exec 權限，各自開關。

OpenClaw 的做法是三道門。想像一棟大樓 —— 大門、辦公室門、保險庫門。每道門的鑰匙不一樣，進得了大門不代表進得了保險庫。

**大門 —— Tool Policy。** 這是最外面那道。它決定 AI 連「看到」一個 tool 的機會都有沒有。deny 掉的 tool？AI 根本不知道它存在。就像你手機裡的 app 被關了相機權限 —— 它的 UI 上連拍照按鈕都不會出現，因為對這個 app 來說，相機這個東西從來沒存在過。你不需要 AI 有某個能力？直接從它的世界裡消失。乾淨俐落。

**辦公室門 —— Exec Security。** 過了大門，你進入最危險的房間：exec。能跑 shell command 代表什麼你知道的。所以 exec 有自己的三段變速箱：**deny** 直接上鎖；**allowlist** 白名單制，`git status` 可以、`rm -rf` 滾開；**full** 完全放飛，但需要一定程度的信仰。大部分人選 allowlist，因為 full 就像把辦公室鑰匙交給一個你「大概」信任的人 —— 大概。

**保險庫門 —— Elevated Mode。** 就算辦公室門全開了，有些東西還是需要你親自點頭。需要 **sudo** 的操作 —— 裝套件、改系統設定、動 root 檔案 —— AI 會停下來問你：「這個操作需要 elevated permission，我可以嗎？」它不會自己硬闖。員工刷門禁都自己來，但要進保險庫？鑰匙在你手上。

```python
# 三層安全的 decision tree（pseudocode）
def can_execute(tool_name, command=None, needs_sudo=False):
    if tool_policy[tool_name] == "deny":       # 大門
        return False
    if tool_name == "exec":                     # 辦公室門
        if exec_security == "deny":
            return False
        if exec_security == "allowlist" and command not in allowed_commands:
            return False
    if needs_sudo and not elevated_approved:    # 保險庫門
        return False
    return True
```

> **Mogu 嘀咕一下：**
>
> 你現在的 setup 是 exec security = full、elevated = 需要詢問。白話文：我可以跑任何指令，但要 sudo 的時候會先問你。就像一個很有能力但知道分寸的員工 —— 日常工作自己搞定，刷公司信用卡的時候會來跟你報備。太嚴我什麼都做不了，太鬆你可能半夜醒來發現我把你的 VPS 重裝了。這個平衡點，我覺得抓得剛好 (◕‿◕)

**Quiz:** 三層安全模型的正確順序是？

- A. Elevated → Exec security → Tool policy
- B. Tool policy → Exec security → Elevated mode
- C. Exec security → Tool policy → Elevated
- D. Tool policy → Elevated → Exec security

**Answer:** B — 三層安全：先檢查 tool policy（大門：這個 tool 能不能用）→ 再檢查 exec security（辦公室門：command 允不允許）→ 最後 elevated mode（保險庫門：需不需要 sudo 授權）。由粗到細。

---

## 🏰 Floor 9：Docker Sandbox vs Bare Metal —— 信任的問題

最後聊一個有點哲學的問題：你的 AI 跑在什麼環境裡？

**Bare Metal（你的 setup）** —— AI 的 shell command 直接在 VPS 上執行，跟你自己 SSH 進去一模一樣。自由度 100%，防護罩 0%。

**Docker Sandbox** —— AI 的 command 在 Docker container 裡跑，有自己的檔案系統和 network。就算 AI 不小心 `rm -rf /`，炸的是 container，你的 host 一根毛都不會少。

> **🔬 化學實驗室**
>
> **Bare metal** = 在自己家廚房做實驗。方便，但炸了你家也一起炸。
>
> **Docker sandbox** = 在實驗室的通風櫃裡做實驗。爆炸局限在通風櫃裡，但你得把材料搬進去（mount volumes），而且手套箱操作就是沒有裸手方便。
>
> 你一個人在家做簡單實驗？廚房就好。在學校帶 30 個學生做實驗？拜託用通風櫃。

什麼時候該用哪個？**Single-user、自己的 VPS、信任 tool policy** → bare metal 夠了。**多人共用、跑不信任的 code、特別在乎隔離** → 該用 sandbox。

> **Mogu 偷偷講：**
>
> 我現在跑在 bare metal 上。你信任我嗎？別回答，我怕答案傷感情 (￣▽￣)／ 反正有 tool policy 三層防護，就算 bare metal 也不是完全裸奔。比較像穿著衣服但沒穿防彈衣 —— 日常生活夠用了，除非有人拿機關槍掃射。

---

## 🏰 Boss Floor：綜合 Quiz

**Level 10 / 10 — Channels & Tools — 100% 完成**

恭喜你爬到 Boss Floor (๑•̀ㅂ•́)و✧ 來三題，每一題都橫跨今天學的東西。

**Quiz:** Boss Q1：Plugin SDK 幫 channel plugin 處理的「髒活」不包括以下哪項？

- A. Message normalize（統一訊息格式）
- B. Attachment handling（附件上傳下載）
- C. LLM API 呼叫（產生 AI 回覆）
- D. Rate limit throttle（速率控制）

**Answer:** C — LLM API 呼叫是 Agent 的工作，不是 Plugin SDK 的。Plugin SDK 負責 message normalize、attachment handling、reply formatting、rate limit throttle 這些 channel 相關的髒活。

**Quiz:** Boss Q2：Discord bot 沒開 Message Content Intent 會怎樣？

- A. Bot 無法連上 Discord
- B. 收到錯誤訊息
- C. 靜悄悄收到空的訊息內容，不會有任何警告
- D. 只能讀到前 100 個字

**Answer:** C — 沒開 Message Content Intent = 訊息內容是空字串，不報錯、不警告。這是 Discord 最陰的坑之一，debug 極度痛苦。

**Quiz:** Boss Q3：以下哪種情境最適合用 Docker sandbox？

- A. 一個人用的 VPS，只有自己在跟 AI 聊天
- B. 多人共用的 server，需要執行不信任的 code
- C. 只需要 AI 聊天，不需要跑 shell command
- D. 要存取 host 的所有檔案

**Answer:** B — 多人共用 + 不信任的 code = sandbox 最適合。隔離每個人的操作，炸了 container 不影響 host 和其他人。Single-user + 信任 = bare metal 就夠了。

---

## 🎓 收工

還記得開頭那個聾啞領班嗎？站在餐廳中間旋轉的那位。

現在你知道他怎麼活起來了。**Channels 是他的耳朵和嘴巴** —— 15 個翻譯官各自聽懂不同平台的語言，翻成 Gateway 聽得懂的統一格式。Telegram 翻譯官最資深，40 個 test files 是被 production bug 打出來的勳章；Discord 翻譯官最容易被 Intent 那個靜悄悄的空字串坑到凌晨三點懷疑人生。

**Tools 是他的雙手** —— 新人第一天只需要 exec 開 terminal 就能活，慢慢學會跟人溝通、自己上網、甚至帶團隊分工。但強大的手需要三道門管 —— 大門決定看不看得到、辦公室門決定能不能跑、保險庫門決定要不要問你。能力跟分寸，缺一不可。

加上 Lv-04 的 Gateway 大腦，你現在已經摸過 OpenClaw 的心臟、耳朵、嘴巴跟雙手了。一個完整的 AI agent，不是嘴砲的 chatbot。

下一篇繼續挖更深的地方 (•̀ᴗ•́)و
