跳到主要內容

【2026 最新】Claude Mods 是什麼?Function Hooks、Skills、Classic Hooks 差在哪(低風險試作+能力盤點)

最後更新: ·
Claude Mods 低風險試作、Function Hooks 能力盤點與退場方案

Claude Mods 是 Claude Code 正在 early access 測試的擴充方式:它把 TypeScript Function Hook 放進 Plugin,讓程式以 middleware(中介層)方式參與 Claude Code 的事件流程。截至 2026 年 9 月 20 日,官方仍明確提醒 API 可能隨版本變動;因此這篇不把它當成「裝了就好」的新玩具,而是帶你用拋棄式專案完成一次低風險、可撤回的實驗。

你會先分清 Skill、Classic Hook、Function Hook/Mod 與 Plugin,再建立一個只呼叫 UI 狀態 API、精簡且可觀察的 status-only Mod;接著用 plugin validate 做 capability diff(能力差異盤點)、跑 middleware 順序測試,最後演練停用、卸載、版本釘選與驗收。本文的 validator 與 tests 已在 Claude Code 2.1.278 執行;若你的版本不同,請把輸出差異視為要重新審查的訊號。

Claude Mods 先說結論

Claude Mod = Plugin 容器 + Function Hook 的 typed middleware。官方提案作者說明目前實作與 Claude Code 位在同一個 Bun 行程,但 Worker/node:vm 邊界不是 API contract,也不該被稱為安全 sandbox。把 Claude Code 想成一條廚房出餐線:Skill 是食譜,Classic Hook 是出餐口旁的檢查站,Function Hook 是能包住前後工序的中介層,Plugin 則是把食譜、檢查站、工具與 Mod 一起裝箱的容器。

  • 只想教 Claude 一套可重用做法:先用 Skill。
  • 想在既有生命週期事件外接 command、HTTP、prompt、agent 或 MCP tool handler:先看 Classic Hook。
  • 想在 runtime 事件前後包一層、改寫輸入或結果、組合多個中介層:才評估 Claude Mod。
  • 想把多種擴充一起安裝與分發:Plugin 是容器,不是與前三者互斥的第四種執行機制。
Claude Mods、Function Hooks、Skills、Classic Hooks 與 Plugin 的載入時機、能力及風險比較
選擇重點不是哪個名字最新,而是你要改變「知識、事件處理、runtime 流程」還是「分發方式」。圖/AlphaLab

Skills、Classic Hooks、Function Hooks 與 Plugin 差在哪?

Skill:把知識與流程交給 Agent

依照 Claude Code Skills 官方文件,Skill 的主體是 Markdown 指令與可選資源;Claude 會先看到描述,再按需要載入完整內容。它很適合教 review 清單、部署流程或某個領域方法,但不是用來攔截每次工具呼叫。若你第一次接觸這套格式,可先讀站內的 Agent Skill 與 SKILL.md 教學,再回來判斷是否真的需要寫程式。

Classic Hook:在既有事件接一個 handler

現行 Claude Code Hooks reference 列出 command、HTTP、prompt、agent(目前仍是 experimental;正式流程官方建議優先 command)與 MCP tool 等 handler。Classic Hook 收到結構化 JSON,也能在部分事件用 updatedInputupdatedToolOutput 改資料;所以「舊 Hook 只能擋或放、完全不能改輸入輸出」已不是正確對照。它與 Function Hook 的核心差異,是後者直接在 engine event chain 中以 typed function 組成 before/after/around middleware,不需把每一步都交給外部程序或 HTTP endpoint。

Function Hook/Mod:包住 runtime 事件鏈

官方目前把產品名稱定為 Claude Mods,工程原語仍叫 Function Hooks;截至 2026 年 9 月 20 日官方 repo 的 Mods README給出的定義很直接:Mod 是行為寫在 hooks module 裡的 Plugin。模組匯出一個 register(on, options),每個 Hook 的形狀是 ($, e, next)

其中 e 是事件資料,next(e) 把流程交給內層,$ 是唯一的主機能力入口。依你訂閱的事件不同,Mod 可能位在 prompt、context、model stream、tool call 與結果的資料路徑上;也可能只畫 UI。這正是它有力量、也需要先做能力盤點的原因。

Plugin:載入與分發的外殼

Plugin 可以同時包 Skills、Classic Hooks、MCP、LSP、agents、commands、Function Hook 與受支援的 Plugin 設定;目前 settings.json 僅支援 agentsubagentStatusLine官方 Plugin referenceuserprojectlocalmanaged scope 決定在哪裡載入與分享,不是作業系統權限邊界。官方安全說明也把 Plugin 與 Marketplace 視為高度信任元件,內容可能以目前使用者權限執行程式碼;安裝前仍要檢查整個 Plugin,而不只看 hooks/register.ts。站內的 Claude Code Plugin 安全檢查可補上 Marketplace 與一般 Plugin 的驗收流程。

Claude Mods 與 Function Hooks 怎麼運作?

Function Hooks 採用 Koa 式「洋蔥模型」。跨 Plugin 的現行 tier 由外到內是 prepend(managed)→ userappend(managed)→ builtincore;同一 module/event 才依註冊順序,先註冊者在外。使用者 Mod 不能跳過更高權限的 managed prepend。外層先做 before,呼叫 await next(e) 後進入內層與 core;等內層完成,再倒序做 after。

outer before
  inner before
    Claude Code core
  inner after
outer after

AlphaLab 在 2.1.278 建立兩個 session.start Hook,第一個先註冊;claude plugin test 的實際順序就是 outer:before → inner:before → inner:after → outer:after,1 個測試通過、0 個失敗。這不只是呼叫順序的小細節:外層能在事件進去前檢查,也能在結果回來後包裝;若不呼叫 next,就可能自行回答並停止內層。

但別把 typed event 誤解成「自動看懂 shell 語意」。例如目前 Bash 工具仍提供一段 e.command 字串,不是 shell AST;heredoc、轉義與間接執行仍可能讓單純 regex 政策失效。要做安全閘門,先理解事件 schema,再把高風險限制放到獨立 CI、OS 或網路控制。若你的需求只是既有 Hook,可先看 Claude Code Hooks 完整教學

低風險試作 Claude Mods:建立精簡、可觀察的 status-only Mod

以下實驗只呼叫 $.ui.status,不要求檔案、HTTP、process、prompt、model 或 tool 能力。先在拋棄式 repository 建立 status-only,並記下版本。這一節的 shell 指令適用 macOS、Linux 與 WSL:

claude --version
mkdir -p status-only/.claude-plugin status-only/hooks status-only/tests

第一個檔案是 status-only/.claude-plugin/plugin.json

{
  "name": "status-only",
  "version": "0.1.0",
  "description": "Shows one status line in interactive sessions",
  "author": { "name": "Your Name" }
}

第二個檔案是 status-only/hooks/hooks.json。這個精簡 Plugin 只列一個 Function Hook module:

{
  "description": "One session.start hook that only calls the UI status API",
  "modules": ["./register.ts"]
}

第三個檔案是 status-only/hooks/register.ts。用 isInteractive guard,避免在沒有可見介面的 headless session 設狀態:

import type { On } from 'claude-code'

export function register(on: On): void {
  on('session.start', ($, e, next) => {
    if (e.isInteractive) $.ui.status('status-only active')
    return next(e)
  })
}

先不要啟用 flag。從上層目錄做嚴格靜態驗證:

claude plugin validate ./status-only --strict --json

在 2.1.278 的實際輸出中,successtrue,notes 只有 hooks: session.startcalls: $.ui.status。若你的清單多出 $.fs$.http$.process$.env$.prompt$.model$.tool$.mcp,先停下來追到是哪一行、為什麼需要。

Validator 會檢查 manifest、source 與 capability footprint,不是 TypeScript type-checker。第一次開啟 Function Hook loader 前,先盤點目前已啟用的 Plugin:

claude plugin list --json

這個 early-access flag 開的是 Function Hook loader,官方沒有把它描述成只授權 --plugin-dir;enabled 清單也不是單一 Plugin clean room 的證明。嚴格驗證與盤點都符合預期後,才在拋棄式 repo 執行互動式 /plugin-types。這個 session 已是第一次 Function Hook loader activation,不只是 editor setup:

cd status-only
CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 claude
# 在 Claude Code 裡輸入:/plugin-types
# 完成後離開 session,再回到上層目錄

它會寫入 .claude/types/;每次更新 Claude Code 都要重生,不要手改。讓 editor 或 TypeScript 5.4+ 讀到現行 contract,可加入精簡的 tsconfig.json

{
  "compilerOptions": {
    "target": "es2023",
    "lib": ["es2023"],
    "types": [],
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "skipLibCheck": true
  },
  "include": [".claude/types", "hooks", "tests"]
}

用 generated types 跑測試,再以 --plugin-dir 載入示範 Mod

靜態清單符合預期後,再加入 status-only/tests/register.test.ts。這個測試不碰真實網路或主機程序,只記錄 ui.status event:

import { describe, expect, test } from 'claude-code/testing'

describe('register', () => {
  test('sets one status line at interactive start', async ($, on) => {
    const statuses: Array<string | undefined> = []

    on('ui.status', ($, e) => {
      statuses.push(e.text)
      return { value: undefined }
    })
    on('session.start', ($, e) => ({ cwd: e.cwd }))

    await $.session.start({
      cwd: '/work', surface: 'terminal', isInteractive: true
    })
    expect(statuses).toEqual(['status-only active'])
  })
})

執行下列測試時,本文環境得到 1 pass、0 fail:

CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 \
  claude plugin test ./status-only

完成型別生成與測試後,才在新 session 以 --plugin-dir 實際載入 status-only;只用 one-shot 環境變數,不先寫進 shell profile:

CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1 \
  claude --plugin-dir ./status-only

看到 status-only active 後,便完成「只新增 $.ui.status」的 smoke test。官方 sec-default README 顯示它只保護部分 managed prompt、settings 與 tool policy 不被 user tier 改寫,而且明確不自行新增政策;它不是通用安全沙箱。官方 early-access 更新與啟用方式可在 Claude Code 官方 issue核對。

Native PowerShell 不支援前面的 mkdir -p、行首環境變數與反斜線續行;改用:

New-Item -ItemType Directory -Force -Path status-only\.claude-plugin,status-only\hooks,status-only\tests
claude plugin list --json
$previous = $env:CLAUDE_CODE_ENABLE_FUNCTION_HOOKS
try {
  $env:CLAUDE_CODE_ENABLE_FUNCTION_HOOKS = "1"

  Push-Location .\status-only
  try {
    claude
    # 輸入 /plugin-types,完成後離開
  } finally {
    Pop-Location
  }

  claude plugin test .\status-only
  claude --plugin-dir .\status-only
} finally {
  if ($null -eq $previous) {
    Remove-Item Env:CLAUDE_CODE_ENABLE_FUNCTION_HOOKS -ErrorAction SilentlyContinue
  } else {
    $env:CLAUDE_CODE_ENABLE_FUNCTION_HOOKS = $previous
  }
}

Claude Mods 能力盤點:把 validate 當 capability diff

claude plugin validate 能靜態列出 Hook pattern 與呼叫的 $ 方法,適合回答「這次更新多了哪些能力」。它不是惡意程式掃描器,也不會替你判斷目的 URL、檔案路徑、指令、依賴套件或政策邏輯是否安全。

為了驗證這個界線,AlphaLab 另建一個只執行靜態 validation 的測例,宣告 $.process.run(['printf', 'probe'])$.http.fetch('https://example.com')。嚴格驗證仍回傳 success: true,但 notes 清楚多出 $.http.fetch, $.process.run。這只證明靜態語法、結構與 capability 掃描通過;不保證實際載入成功,更不代表行為可信。

  1. 先存基準:把已審查版本的 --strict --json 輸出,連同 source pin/識別一起保留:Git full SHA、archive SHA-256、npm exact version;若是 command source,保存 accepted command digest 與 resolved output hash。
  2. 更新後再掃:對 hooks、calls 與 literal env names 做 diff;新增高權限能力就要求逐行說明。
  3. 讀完整 Plugin:Function Hook realm 沒有 ambient Node/DOM,但同一 Plugin 還可能帶 Classic command hook、MCP、LSP、monitor 或 executable。
  4. 測失敗路徑:現行 contract 下,Hook throw、逾時或回傳錯誤形狀時,預設會略過該 Hook、讓內層或 core 繼續。拒絕型檢查要在呼叫 next() 前完成,並測試 .catch;catch 的拒絕結果不能撤銷已執行的內層效果,而且目前另有 1 秒預算。
  5. 把高風險控制外移:合併政策、秘密隔離與 egress 限制仍要放在 CI、OS、container 或網路層。

最重要的安全句子是:沒有 ambient Node/DOM,不等於沒有主機能力。目前 $ 可以提供檔案、HTTP、process、prompt、model、tool 與 MCP 等介面;上游 managed Hook 可盤點或限制部分能力,但安裝 scope 本身不是權限沙箱。權限流程也不能一概而論:$.tool.call() 的契約明確會經過 permission check,必要時顯示 permission dialog;$.mcp.call() 則明確沒有 permission prompt。現行契約沒有承諾直接的 $.fs$.http$.process 會自動套用一般工具權限,因此這些能力要另設上游政策與主機層控制。需要把規則、測試與獨立 gate 串起來時,可參考 Agent CAPA 實作教學

還要單獨盤點 Plugin monitor:它會以 unsandboxed shell command 執行。若 monitor 已在目前 session 啟動,disable 或 reload 都不會終止該程序,必須結束 session。

如何停用、卸載、版本釘選與準備回退?

版本回退方案要同時管「Claude Code 版本」與「Mod source」。對 copied、非 command source 的 Plugin,plugin.json.version 會影響 cache/更新判斷,但不是密碼學內容釘選;local-directory Marketplace 的 load-in-place Plugin 也是例外。個別 Git plugin source 應鎖完整 40 字元 commit SHA,archive 應鎖 SHA-256,npm source 應鎖 exact version。Marketplace source 本身只能固定 ref,不要把兩層 pin 混在一起。command source 預設會在每個 enabled session 背景重跑一次;設定 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 時會跳過背景重跑。Copy mode 以內容 hash 派生版本,link mode 則以 real path 與 top-level entries 派生;這套 cadence 不受 DISABLE_AUTOUPDATER 控制。它不能用 authored version 或 Git SHA 當成同一套回退保證;需要可重現回退時,先停用它,改用已釘選的 Git 或 archive source。官方的 Plugin source 文件列出可用的 source 與 pinning 方式。

  1. 先記 compatibility pair:保存 Claude Code 精確版本、Mod source pin/識別(Git full SHA、archive SHA-256、npm exact version;command source 保存 accepted command digest 與 resolved output hash)、validation JSON、測試結果,以及 /plugin-types 生成檔第一行的版本。
  2. 本地測試立刻停用:結束 session;新 session 不帶 CLAUDE_CODE_ENABLE_FUNCTION_HOOKS=1--plugin-dir
  3. 先辨識來源與 scope:對自行從 Marketplace 安裝的 user/project/local Plugin,先確認實際 scope,再執行 claude plugin disable name@marketplace --scope <user|project|local>;若要卸載,也明確指定同一 scope。從最後一個 scope 卸載時,Claude Code CLI 預設也會刪除 ${CLAUDE_PLUGIN_DATA}。一般版本回退若需保留資料,先備份並使用 claude plugin uninstall name@marketplace --scope SCOPE --keep-data;若是安全事故,則先隔離與檢查該目錄,不要直接讓 known-good 版本重用可能已受污染的 state。官方 Persistent data 說明列出這項卸載語意。Managed 或組織要求的 synced Plugin 需由管理員處理;一般 synced Plugin 從 claude.ai 移除;skills-dir 來源則停用或刪除來源。
  4. 回到 known-good Mod:若你控制 Marketplace,先把個別 Plugin 的 Git source 鎖回已審查的完整 SHA,並確認它會解析成不同的 resolved version;若 authored version 未變,plugin update 會把它視為同一版本而跳過。這種情況先維持停用,將 known-good source 發布成新的 resolved version,再更新或重裝,不能只改 SHA 就宣稱已回退。不控制 Marketplace 時,先停用/卸載,再從受控且固定 SHA 的來源重裝;archive 則核對 SHA-256。官方 version resolution 說明是驗收依據。
  5. 回到 known-good CLI:官方指定版本安裝方式,macOS/Linux 可用 curl -fsSL https://claude.ai/install.sh | bash -s 2.1.278 安裝本文版本,再跑 claude --versionDISABLE_AUTOUPDATER=1 只停背景更新;需要凍結所有更新路徑時使用 DISABLE_UPDATES=1
  6. 重新驗證:重跑 /plugin-types、strict validation 與 tests。
  7. 停用驗收:新 session 的 claude plugin list --json 顯示正確 scope 且已 disabled/未載入,原本行為消失。不要把 disabled Plugin 仍出現在清單或 cache 目錄仍存在,誤判成仍在執行。
  8. 版本回退驗收:新 session 顯示預期的 known-good resolved version,source pin/識別正確,而且 validation、tests 與 Hook trace 符合保存的 known-good 基準。

Disable/uninstall 在目前 session 何時生效取決於操作路徑:關閉互動式 /plugin menu 時,Claude Code 會自動執行 /reload-plugins;若變更來自另一個 terminal 的 claude plugin 指令,則可在目前 session 手動執行 /reload-plugins。互動式 terminal 可重新載入 hooks、skills、agents、plugin MCP 與 LSP;Desktop、Agent SDK 與 -p 雖可 reload,但不會重連 plugin MCP server,MCP 變更要等下一個 session。這些 reload 說明不適用於已啟動的 monitor:disable 或 reload 都不會停止它。只有確認 Plugin 不含 monitor 的一般變更才把 reload 當候選;Plugin 含 monitor 或正在做事故隔離時,直接結束並重開 session。若你把規則檔也納入遷移,Claude Code 原生 AGENTS.md 教學可幫你分清規則文件與 runtime 擴充,不要把兩者混成同一個退場單位。

截至 2026 年 9 月,Claude Mods 有哪些時效風險?

本文使用的最新公開 Claude Code release 是 2.1.278;官方 repo 內的 Function Hook declaration 則由 2.1.277 生成,檔頭直接標示 EARLY ACCESS,並要求更新後重新執行 /plugin-types。官方目前也有 sec-defaultdifftelemetryagents-md 四個 built-in Mod;早期文章若只列三個,代表它的快照已經不同。

因此不要照抄某篇教學宣稱的最低版本、事件欄位或「零 token」結論。不同 Mod 可以只畫 UI,也可以呼叫 model、agent 或 tool;是否用到模型與 token 取決於實作。每次升級都應把 generated type diff 視為 migration review,而不是例行按下更新。想理解這種 runtime 為何需要成套控制,可延伸閱讀 AI Agent Harness 是什麼Claude Token 節省教學

Claude Mods 常見問題

Claude Mods 是什麼?

它是使用 Function Hooks 的 Claude Code Plugin。行為寫在 hooks module,透過 register(on, options) 訂閱 engine events,並以 ($, e, next) 參與事件鏈。

Function Hook 和 Mod 是同一件事嗎?

不完全相同。Function Hook 是技術原語;Claude Mod 是把這個原語裝進 Plugin 後的產品名稱。討論 API 時看 Function Hook,討論安裝與分發時看 Mod/Plugin。

Claude Mod 能看見 prompt 或改寫工具呼叫嗎?

取決於它訂閱的事件與取得的能力。現行生成型別包含 prompt.submitprompt.contexttool.call 等事件;相應 Hook 可以讀取並在 contract 允許的範圍改寫輸入或結果。安裝時應把 prompt、instruction、transcript、tool arguments 與 results 都列入資料流盤點。

plugin validate 通過就代表安全嗎?

不是。它能找出部分會阻止載入的靜態/結構問題,並列出 Hook pattern 與 $ capability footprint;它不保證 runtime 可載入或安全。本文的 process+HTTP 測例也能通過 strict validation,所以你仍要讀 source、檢查 dependency、釘選內容並測試失敗路徑。

Claude Mods 一定不耗 token 嗎?

不能一概而論。只更新 UI 的範例不需呼叫模型;但現行 $ 也提供 model、agent、prompt 與 tool 相關能力,實際 token 與上下文影響取決於該 Mod 做了什麼。

怎麼先停用 Claude Mod?

本地 early-access 測試先關 session,再以不帶 flag 與 --plugin-dir 的新 session 啟動。已安裝 Plugin 則在正確 scope disable 或 uninstall;只有不含 monitor 的變更才把 reload 當候選。Plugin 含 monitor 或正在做事故隔離時,直接結束並重開 session。

已經有 Skill,還需要 Mod 嗎?

多數教學型需求先用 Skill 就夠。只有當你必須參與 engine event chain、在前後處理資料或提供新 runtime 行為時,才承擔 Mod 的版本與安全成本。

現在適合把 Claude Mods 用在正式政策嗎?

適合受控試驗,不適合單獨成為不可繞過的唯一防線。它仍是 early access,失敗語意與 API 都必須按精確版本驗證;高風險政策要另有 managed layer、CI 與 endpoint 控制。

給新手的 6 個重點

  1. 先用一句話選層:知識用 Skill、事件外接用 Classic Hook、runtime middleware 才用 Mod、分發用 Plugin。
  2. 只在拋棄式 repository 與 one-shot flag 測試 early-access 功能。
  3. plugin validate --strict --json 當 capability diff,不當安全證書。
  4. 每次更新都綁定 Claude Code 版本、Mod source pin/digest、generated types 與測試結果。
  5. 拒絕型 Hook 必須測 throw、timeout、錯誤形狀與 .catch,不能假設 fail-closed。
  6. 停用驗收要在新 session 確認未載入且行為消失;版本回退則要確認 known-good resolved version、source pin 與保存的驗證基準,不能只看資料夾是否還在。

接著閱讀

左右滑動查看更多推薦

結語:先證明單一能力,再談強大擴充

Claude Mods 最值得學的不是「能 Hook 更多事件」,而是它把 runtime 擴充變成可列出、可測試、可組合的能力面。新手的正確起點,是讓 validation 只列出 session.start$.ui.status,並讓測試驗證預期的一次狀態列行為,再演練一次停用與驗收。等這條證據鏈穩定後,才逐項加入真正需要的能力;每多一項,都要能回答誰批准、如何限制、怎麼測、出了事如何撤回。

ALPHALAB 社群

有問題?來 Telegram 聊

和 Terry、編輯、其他網友一起討論這篇文章。提問、分享觀點,回覆更即時。

加入 Telegram 討論

📩 訂閱 AlphaLab 電子報

每週最多三封:一封 Weekly 週報與最多兩封關鍵 Alpha Signal。

我們不會 spam,隨時可退訂。