iT邦幫忙

2026 iThome 鐵人賽

DAY 18
0

開場故事

有些東西看起來像檔案,其實比較像能力說明書。

skill.md 就是這種東西。

你可以把它想成:

  • 不是一段要直接執行的程式
  • 也不是單純的說明文字
  • 而是一份讓 OpenClaw 知道「這個 workspace 現在有哪些可用技能」的能力描述

更重要的是,OpenClaw 不會每次都把它當成普通文字重新亂讀一遍。
它會把這些技能整理成 snapshot,讓當下的 turn 能穩定使用。

這也是第 18 天我想看的地方:

OpenClaw 怎麼找到並讀進 skill.md

今天要解的問題

  • skill.md 到底是什麼,不只是什麼?
  • OpenClaw 怎麼決定哪些 skills 要被納入?
  • 為什麼要做 snapshot,而不是每次現場重掃?
  • skills snapshot 會去哪裡?
  • skill.md 怎麼變成模型看得到的 prompt?

架構總覽

這條流程可以先簡化成五步:

  1. 先決定這個 agent 的 skill filter
  2. 讀 workspace 裡有哪些可用 skills
  3. 根據條件建立 reusable skill snapshot
  4. 如果需要,寫回 session / store
  5. 把 snapshot 的 prompt 併進這次 turn 的 developer instructions

也就是說:

skill.md 不是直接「被執行」,而是先被整理,再被注入到 turn 的語境裡。

這點很重要,因為它把 skill 從「檔案」變成了「能力上下文」。

原始碼節錄

先看 OpenClaw 怎麼在入口附近把 skills snapshot 拉出來。

📄 原始碼:src/agents/agent-command.ts:1400-1428

const skillFilter = resolveEffectiveAgentSkillFilter(cfg, sessionAgentId);
const currentSkillsSnapshot = sessionEntry?.skillsSnapshot;
const [{ getRemoteSkillEligibility, resolveReusableWorkspaceSkillSnapshot }, { canExecRequestNode }] = await Promise.all([
	loadSkillsRuntime(),
	loadExecDefaultsRuntime()
]);
const skillSnapshotState = resolveReusableWorkspaceSkillSnapshot({
	skillFilter,
	currentSkillsSnapshot,
	workspaceDir,
	agentDir,
	agentId: sessionAgentId,
	canExecRequestNode,
	getRemoteSkillEligibility
});
const skillsSnapshot = skillSnapshotState.snapshot;
if (skillsSnapshot && sessionStore && sessionKey && needsSkillsSnapshot && !suppressVisibleSessionEffects) {
	sessionStore[sessionKey] = {
		...sessionStore[sessionKey],
		skillsSnapshot
	};
}

這段透露了幾件事:

  • skills 不是現場臨時查表
  • 它先被轉成 snapshot
  • snapshot 可以被重用
  • 必要時還會寫回 session store

這種做法很像把工具箱先整理好,再交給上工的人。

再看 skills snapshot 怎麼進入 turn 的 developer instructions。

📄 原始碼:extensions/codex/src/app-server/thread-lifecycle.ts:3062-3062

function buildDeveloperInstructions(params) {
	return [
		"Running inside OpenClaw. Use dynamic tools for messaging, cron, sessions, media, gateway, and nodes when available.",
		"Use Codex native `spawn_agent` for Codex subagents. Use OpenClaw `sessions_spawn` only for OpenClaw or ACP delegation; if it is not already loaded, search for `sessions_spawn` in the `openclaw` dynamic tool namespace before calling it.",
		"Preserve channel/session context. Visible channel replies: use `message`, do not describe would-reply.",
		renderCodexRuntimePromptOverlay(params),
		params.extraSystemPrompt,
		params.skillsSnapshot?.prompt
	].filter((section) => typeof section === "string" && section.trim()).join("\\n\\n");
}

這一段就把答案講得很直白了:

  • skills snapshot 不是丟去某個神秘地方
  • 它會直接成為 developer instructions 的一部分
  • 也就是說,模型真的看得到它

這就是 skill.md 的第一個關鍵轉換:

從檔案,變成 prompt。

白話拆解

1. skill.md 比較像能力卡,不像單純說明文件

如果把 OpenClaw 當成一個團隊,那 skill.md 比較像是每個成員的技能卡:

  • 這個人會什麼
  • 這個人在哪些情況該出場
  • 這個人會受到哪些限制

它不是用來「讀爽的」。
它是用來決定這個 turn 能不能做、能做哪些事、怎麼做的。

2. 為什麼要 snapshot

因為 skill 不是永遠不變。

如果每次 turn 都重新掃整個 workspace 去找 skill:

  • 成本高
  • 行為不穩
  • 版本不好追
  • debug 很痛

snapshot 的意思就是:

把某一時點的可用技能集合固定下來,讓這一輪先用穩定版本跑。

這對長流程系統非常重要。

3. skill.md 不是獨立執行體

很多人看到 skill 會直覺以為它像 plugin 一樣有自己的 runtime。

其實不是。

在這個階段,它比較像:

  • 被讀入
  • 被篩選
  • 被版本化
  • 被放進 prompt

真正執行它的,是後面的模型和工具調用流程。

4. 為什麼要先看 skill filter

不是所有 skill 都該出現在所有 agent 身上。

OpenClaw 先算 skillFilter,就等於先決定:

  • 哪些技能屬於這個 agent
  • 哪些技能要排除
  • 哪些技能可能要遠端 eligibility 判斷

這樣後面 snapshot 出來的東西才不會亂。

5. skillsSnapshot?.prompt 是真正進到模型腦袋的那段

這一點很關鍵。

如果 skill 只是存著不用,那它只是資料。

但當 skillsSnapshot?.prompt 被併進 developer instructions 之後,它就變成模型真的會看見、會受影響的指令背景。

這就是 skill 和純設定檔最大的差別:

它不是只被保存,而是被注入到推理上下文。

設計取捨

  • 好處是 skill 有版本感,不會每次 turn 都亂飄
  • 好處是 prompt 內容可追蹤,debug 也比較容易
  • 好處是 skill filter 可以先擋掉不該出現的能力
  • 好處是模型真的會收到對應的 skill 語境
  • 代價是多了一層 snapshot 的心智負擔
  • 代價是 skill 文件更新後,不一定馬上反映到當下 session

但我覺得這個代價是值得的。
因為能力上下文如果不穩,整個 agent 行為就會飄。

今天的結論

  • skill.md 是能力描述,不是單純文件
  • OpenClaw 會先用 skillFilter 決定可用技能範圍
  • resolveReusableWorkspaceSkillSnapshot() 會把 skills 整理成可重用 snapshot
  • skillsSnapshot 可以寫回 session store,保留當下能力集合
  • params.skillsSnapshot?.prompt 會進到 developer instructions
  • 這表示 skill 不是被「執行」,而是被「注入」到 turn 的上下文

下一步

如果上一天是在看 cron 怎麼進來,那這一天就在看 skill.md 怎麼變成可用能力。
下一篇我會繼續往下走:

skill 從定義到執行,OpenClaw 到底怎麼處理它?


上一篇
第 17 天:cron 是怎麼被 OpenClaw 掛進來的
下一篇
第 19 天:skill 從定義到執行,OpenClaw 怎麼處理它
系列文
30 天走進 OpenClaw:一個 AI Agent 的誕生、掙扎與進化23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言