Claude Code工作流中的命令實現(xiàn)與自定義指南
Claude Code 工作流中的命令實現(xiàn)與自定義指南
本文基于 claude-code-rev 源碼分析 Claude Code 工作流中的命令系統(tǒng):命令從哪里加載、如何被識別、如何執(zhí)行、能否自定義、如何編寫自定義命令/技能,以及這些命令與模型、工具權限、插件、工作流和 hooks 的關系。
結論先行:Claude Code 的命令可以自定義。最推薦的方式是寫 Markdown 形式的命令或技能;更深度的交互式命令需要插件或源碼級 local / local-jsx 實現(xiàn);工作流命令和 MCP skill 也能進入命令系統(tǒng),但它們依賴對應特性或外部服務。
0. 整體流程圖
命令工作流可以拆成四層:
- 命令來源:內(nèi)置命令、
.claude/skills、舊版.claude/commands、插件、工作流;MCP skills 走獨立的 MCP 命令集合。 - 加載過濾:
loadAllCommands(cwd)合并本地/插件/工作流來源,getCommands(cwd)按可用性、開關和動態(tài)技能過濾。 - 用戶輸入解析:用戶輸入
/command args后,processSlashCommand(...)解析命令名和參數(shù),并從當前命令表中查找命令。 - 執(zhí)行分支:根據(jù)
Command.type進入prompt、local、local-jsx,其中prompt命令還可以通過context: fork進入子代理執(zhí)行;MCP skills 主要通過單獨篩選后進入模型可調用技能集合。

1. 命令的核心類型
源碼中的命令統(tǒng)一抽象為 Command,定義在 src/types/command.ts。它由公共字段 CommandBase 加上三種執(zhí)行形態(tài)之一組成。
| 命令類型 | 源碼類型 | 主要用途 | 是否適合用戶自定義 | 執(zhí)行結果 |
|---|---|---|---|---|
prompt | PromptCommand | 把 Markdown/文本內(nèi)容擴展成模型輸入;可作為技能被用戶或 Claude 調用 | 適合,最推薦 | 生成用戶消息,通常繼續(xù)讓模型處理;也可 context: fork 由子代理執(zhí)行 |
local | LocalCommand | 執(zhí)行本地 TypeScript/JS 模塊邏輯,不渲染交互 UI | 不適合普通配置,需要源碼或插件代碼 | 返回 text、compact 或 skip |
local-jsx | LocalJSXCommand | 渲染 Ink/React 交互界面,例如選擇器、配置面板 | 不適合普通配置,需要源碼或插件代碼 | 通過 onDone(...) 回傳結果、是否繼續(xù)查詢、下一條輸入等 |
關鍵字段:
| 字段 | 出現(xiàn)位置 | 含義 |
|---|---|---|
name | CommandBase | 命令內(nèi)部名稱,用戶通常通過 /<name> 調用 |
aliases | CommandBase | 命令別名,findCommand(...) 會匹配別名 |
description | CommandBase | 命令說明,顯示在補全、幫助或 SkillTool 中 |
argumentHint | CommandBase | 參數(shù)提示,來自 frontmatter 的 argument-hint |
whenToUse | CommandBase | 技能適用場景,來自 frontmatter 的 when_to_use |
userInvocable | CommandBase | 是否允許用戶直接輸入 /name 調用;false 時只能讓 Claude 通過 Skill 工具調用 |
disableModelInvocation | CommandBase | 是否禁止模型通過 SkillTool 調用 |
loadedFrom | CommandBase | 命令來源,例如 skills、commands_DEPRECATED、plugin、bundled、mcp |
kind | CommandBase | 當前主要用于標記 workflow |
isSensitive | CommandBase | 對敏感參數(shù)進行歷史記錄脫敏 |
allowedTools | PromptCommand | Markdown 命令中內(nèi)聯(lián) shell 片段可用的工具 allowlist |
model | PromptCommand | 命令或技能指定的模型 |
hooks | PromptCommand | 技能被調用時臨時注冊的 hooks |
context | PromptCommand | inline 或 fork;fork 會使用子代理單獨執(zhí)行 |
agent | PromptCommand | context: fork 時指定子代理類型 |
effort | PromptCommand | 子代理或模型推理 effort |
paths | PromptCommand | 條件技能匹配文件路徑后才激活 |
2. 命令從哪里來
src/commands.ts 是命令聚合入口。內(nèi)置命令由 COMMANDS() 返回,技能、插件和工作流再由 loadAllCommands(cwd) 合并。
2.1 來源總表
| 來源 | 典型目錄/入口 | 加載函數(shù) | loadedFrom / source | 說明 |
|---|---|---|---|---|
| 內(nèi)置命令 | src/commands/* | COMMANDS() | source: builtin | 例如 /help、/clear、/model、/hooks、/status 等 |
| 用戶/項目技能 | .claude/skills/<skill>/SKILL.md、~/.claude/skills/<skill>/SKILL.md | getSkillDirCommands(cwd) | loadedFrom: skills | 推薦的自定義方式,目錄格式固定為 skill-name/SKILL.md |
| 舊版自定義命令 | .claude/commands/*.md、.claude/commands/**/SKILL.md | loadSkillsFromCommandsDir(cwd) | loadedFrom: commands_DEPRECATED | 仍支持,適合兼容舊用法;新內(nèi)容建議遷移到 skills |
| bundled skills | 構建內(nèi)置的技能包 | getBundledSkills() | loadedFrom: bundled | 隨 Claude Code 打包分發(fā) |
| built-in plugin skills | 內(nèi)置插件提供 | getBuiltinPluginSkillCommands() | 取決于插件 | 來自啟用的內(nèi)置插件 |
| plugin commands | 插件命令 | getPluginCommands() | loadedFrom: plugin | 插件可提供命令能力 |
| plugin skills | 插件技能 | getPluginSkills() | loadedFrom: plugin | 插件提供的 prompt 型技能 |
| workflow commands | 工作流腳本 | getWorkflowCommands(cwd) | kind: workflow | 受 WORKFLOW_SCRIPTS feature gate 控制 |
| MCP skills | MCP 服務暴露 | getMcpSkillCommands(...) | loadedFrom: mcp | 不經(jīng)過 loadAllCommands(cwd);從 AppState.mcp.commands 單獨篩選后作為模型可調用 skill 進入系統(tǒng) |
| dynamic skills | 運行時發(fā)現(xiàn) | getDynamicSkills() | 通常仍是 prompt command | 由文件觸達或動態(tài)發(fā)現(xiàn)機制插入 |
2.2 合并順序
loadAllCommands(cwd) 的合并順序是:
return [ ?...bundledSkills, ?...builtinPluginSkills, ?...skillDirCommands, ?...workflowCommands, ?...pluginCommands, ?...pluginSkills, ?...COMMANDS(), ]
這意味著命令列表中,技能和插件命令會出現(xiàn)在內(nèi)置命令之前。運行時查找由 findCommand(...) 按數(shù)組順序返回第一個匹配項,因此同名命令可能受到加載順序影響。實踐中建議自定義命令避免與內(nèi)置命令重名。
2.3 過濾邏輯
getCommands(cwd) 會在合并后做兩類過濾:
| 過濾點 | 源碼函數(shù) | 作用 |
|---|---|---|
| 可用性過濾 | meetsAvailabilityRequirement(cmd) | 根據(jù) availability 限制命令只對某類認證/服務提供方可見 |
| 開關過濾 | isCommandEnabled(cmd) | 根據(jù) feature flag、環(huán)境變量或運行時狀態(tài)決定命令是否啟用 |
| 動態(tài)技能插入 | getDynamicSkills() | 把運行時發(fā)現(xiàn)的技能插到插件技能之后、內(nèi)置命令之前 |
3. Markdown 命令和技能如何加載
自定義命令最重要的入口在 src/skills/loadSkillsDir.ts 和 src/utils/markdownConfigLoader.ts。
3.1 推薦目錄:.claude/skills
技能目錄只支持這一種結構:
.claude/ skills/ ? my-skill/ ? ? SKILL.md
my-skill 會成為命令名,用戶可以輸入:
/my-skill 參數(shù)
如果放在用戶目錄,則是:
~/.claude/ skills/ ? my-skill/ ? ? SKILL.md
3.2 舊版目錄:.claude/commands
舊版命令目錄仍被支持:
.claude/ commands/ ? review.md ? git/ ? ? pr.md ? deploy/ ? ? SKILL.md
命名規(guī)則:
| 文件形態(tài) | 命令名 |
|---|---|
.claude/commands/review.md | /review |
.claude/commands/git/pr.md | /git:pr |
.claude/commands/deploy/SKILL.md | /deploy |
.claude/commands/team/release/SKILL.md | /team:release |
源碼中 buildNamespace(...) 會把子目錄轉換成冒號命名空間。
3.3 加載范圍和優(yōu)先級
loadMarkdownFilesForSubdir(...) 會加載三類位置:
| 位置 | 路徑 | 說明 |
|---|---|---|
| managed/policy | managed path 下的 .claude/<subdir> | 組織策略或托管配置,優(yōu)先級最高 |
| user | ~/.claude/<subdir> | 用戶全局命令/技能 |
| project | 從當前目錄向上查找 .claude/<subdir>,直到 git root 或 home | 項目級命令/技能 |
Markdown 文件加載組合順序是 managed > user > project。文件層面會按真實文件 identity 去重,技能層面也會按 realpath 去重,順序靠前者保留。
項目目錄向上查找會在 git root 停止,避免父目錄的 .claude/commands 或 .claude/skills 意外泄露進無關倉庫。worktree 場景下,如果 worktree 缺少 .claude/<subdir>,會回退到主倉庫對應目錄。
4. Frontmatter 字段參考
Markdown 命令/技能通過 YAML frontmatter 定義元數(shù)據(jù)。字段解析主要在 src/utils/frontmatterParser.ts 和 src/skills/loadSkillsDir.ts。
4.1 常用字段
| 字段 | 類型 | 用于 | 含義 |
|---|---|---|---|
description | string | 命令/技能 | 顯示說明;缺失時會從正文第一行提取 |
argument-hint | string | 命令/技能 | 參數(shù)提示,例如 [branch]、<issue-id> |
arguments | string 或 string[] | 命令/技能 | 聲明命名參數(shù),供正文替換使用 |
allowed-tools | string 或 string[] | prompt 命令 | 允許內(nèi)聯(lián) shell 片段使用的工具;缺失默認為空 |
when_to_use | string | skill | 給模型看的“什么時候使用”說明 |
version | string | skill | 技能版本 |
model | string | prompt 命令 | 指定模型;inherit 表示繼承父上下文 |
user-invocable | boolean-like string | skill | 是否允許用戶直接 /name 調用;默認 true |
disable-model-invocation | boolean-like string | skill | 是否禁止模型通過 SkillTool 調用 |
hooks | HooksSettings | skill | 技能被調用時注冊臨時 hooks |
context | inline 或 fork | skill | fork 會啟動子代理執(zhí)行 |
agent | string | fork skill | 指定子代理類型 |
effort | string 或 integer | fork skill | 指定推理 effort |
paths | string 或 string[] | skill | 條件技能,匹配文件路徑后才激活 |
shell | bash 或 powershell | skill/command | 控制 Markdown 內(nèi) ! shell 片段使用的 shell |
4.2 最小自定義技能示例
--- description: 生成當前改動的代碼審查清單 argument-hint: "[重點區(qū)域]" when_to_use: 用戶希望快速審查當前分支或工作區(qū)改動時 --- ? 請審查當前倉庫的改動,重點關注:$ARGUMENTS。 ? 輸出: 1. 高風險問題 2. 可維護性問題 3. 建議補充的測試 4. 可以直接合并的理由或阻塞項
放到:
.claude/skills/review-changes/SKILL.md
調用:
/review-changes auth 模塊
4.3 帶命名參數(shù)的示例
--- description: 根據(jù) issue 編號生成修復計劃 argument-hint: "<issue> <scope>" arguments: - issue - scope --- 請為 issue $issue 生成修復計劃。 范圍:$scope 要求: - 先定位相關文件 - 說明風險 - 給出測試計劃
命令內(nèi)容最終會通過 substituteArguments(...) 替換參數(shù)。
4.4 只能由 Claude 調用的技能
--- description: 安全審計技能 when_to_use: 當任務涉及認證、權限、外部輸入、密鑰或命令執(zhí)行時使用 user-invocable: false --- 對當前任務做安全審計,重點檢查注入、權限繞過、敏感信息泄露和不安全默認值。
用戶直接輸入 /security-audit 時會收到提示:該技能只能由 Claude 調用。用戶可以說“請使用 security-audit 技能”。
4.5 fork 子代理技能
--- description: 在獨立上下文中做大型代碼審查 when_to_use: 當改動跨多個模塊,需要獨立上下文審查時使用 context: fork agent: code-reviewer effort: high --- 請審查當前分支的代碼改動,輸出關鍵問題和建議。
執(zhí)行時不會把技能正文簡單塞進當前對話,而是走 executeForkedSlashCommand(...),調用 runAgent(...) 在子代理中執(zhí)行。
4.6 帶 hooks 的技能
---
description: 編輯 TypeScript 后自動檢查
hooks:
PostToolUse:
- matcher: "Write|Edit|MultiEdit"
hooks:
- type: command
command: "npm run typecheck"
timeout: 60
---
請實現(xiàn)用戶請求,并在修改 TypeScript 文件后自動觸發(fā)類型檢查。源碼中 getMessagesForPromptSlashCommand(...) 會在命令帶有 hooks 時調用 registerSkillHooks(...),這些 hook 以會話級方式注冊。
5. 用戶輸入/command后發(fā)生什么
src/utils/processUserInput/processSlashCommand.tsx 負責 slash command 的運行時處理。
5.1 解析與查找
流程如下:
| 步驟 | 源碼函數(shù) | 行為 |
|---|---|---|
| 解析輸入 | parseSlashCommand(inputString) | 拆出 commandName、args、isMcp |
| 判斷存在 | hasCommand(commandName, context.options.commands) | 不存在時判斷是否像文件路徑;否則返回 Unknown skill |
| 獲取命令 | getCommand(commandName, context.options.commands) | 按 name、userFacingName()、aliases 查找 |
| 檢查調用權限 | command.userInvocable === false | 禁止用戶直接調用,只允許 Claude 使用 SkillTool |
| 分支執(zhí)行 | switch (command.type) | 進入 local-jsx、local 或 prompt 分支 |
findCommand(...) 的匹配邏輯是:
_.name === commandName || getCommandName(_) === commandName || _.aliases?.includes(commandName)
5.2 prompt命令執(zhí)行
普通 prompt 命令會:
- 調用
command.getPromptForCommand(args, context)生成內(nèi)容塊。 - 注冊技能 hooks(如果 frontmatter 中定義了
hooks)。 - 解析
allowedTools,把額外工具權限傳給后續(xù)模型處理。 - 創(chuàng)建用戶消息,通常設置
shouldQuery: true,讓 Claude 接著處理。
Markdown 技能的 getPromptForCommand(...) 還會做這些替換/處理:
| 處理 | 說明 |
|---|---|
| 添加 base directory | 有 baseDir 時,正文前會加 Base directory for this skill: ... |
| 參數(shù)替換 | 通過 $ARGUMENTS 或命名參數(shù)替換用戶輸入 |
${CLAUDE_SKILL_DIR} | 替換成技能目錄,便于引用技能自帶腳本 |
${CLAUDE_SESSION_ID} | 替換成當前 session id |
| 執(zhí)行 Markdown 內(nèi) shell 片段 | 非 MCP 技能可以執(zhí)行 ! shell 片段;MCP 技能禁止執(zhí)行 |
5.3 context: fork的執(zhí)行
當 PromptCommand.context === 'fork' 時,流程進入 executeForkedSlashCommand(...):
| 階段 | 行為 |
|---|---|
| 準備上下文 | prepareForkedCommandContext(...) 生成技能內(nèi)容、agent 定義、prompt messages |
| 創(chuàng)建 agent id | createAgentId() |
| 啟動子代理 | runAgent(...) 使用指定 agent、model、effort 和可用工具 |
| 收集結果 | extractResultText(...) 提取子代理最終輸出 |
| 返回結果 | 結果包裝成 <local-command-stdout>,不再直接讓主模型查詢 |
在 KAIROS/assistant 模式下,fork 命令還可能以后臺方式運行,完成后把結果重新放回消息隊列。
5.4 local命令執(zhí)行
local 命令是源碼或插件中的 JS/TS 模塊。執(zhí)行邏輯:
先構造用戶輸入消息。
await command.load() 懶加載模塊。
調用 mod.call(args, context)。
根據(jù)返回結果處理:
{ type: 'skip' }:不寫消息,不繼續(xù)查詢。{ type: 'text', value }:輸出<local-command-stdout>。{ type: 'compact', compactionResult }:進入上下文壓縮后的消息構造流程。
5.5 local-jsx命令執(zhí)行
local-jsx 命令適合交互 UI,例如選擇器、設置面板。執(zhí)行邏輯:
command.load() 懶加載 JSX 模塊。
調用 mod.call(onDone, context, args)。
返回 React 節(jié)點后通過 setToolJSX(...) 渲染。
UI 完成后調用 onDone(result, options)。
options 可控制:
display: 'skip' | 'system' | 'user'shouldQuerymetaMessagesnextInputsubmitNextInput
6. 命令是否可以自定義
可以,但不同層級能力不同。
| 自定義方式 | 是否需要寫代碼 | 能力 | 適用場景 | 推薦程度 |
|---|---|---|---|---|
.claude/skills/<name>/SKILL.md | 否 | prompt 命令、模型技能、可 fork、可帶 hooks、可指定模型和工具 | 項目/個人常用流程、審查、生成、分析、規(guī)范化任務 | 最高 |
.claude/commands/*.md | 否 | 舊版 prompt 命令,支持命名空間 | 兼容舊項目或快速添加 /foo | 中等,建議新建用 skills |
| 插件命令/技能 | 是 | 可分發(fā)、可封裝復雜能力 | 團隊/生態(tài)共享命令 | 高,但復雜度更高 |
| 工作流命令 | 取決于工作流 | 標記為 workflow 的命令 | 可復用自動化工作流 | 取決于 feature 是否啟用 |
| MCP skills | 外部 MCP 服務 | 遠端服務暴露技能 | 外部系統(tǒng)集成 | 適合系統(tǒng)集成 |
修改 src/commands/* | 是 | 完整 local/local-jsx/prompt 能力 | fork 本項目或實現(xiàn)內(nèi)置級交互命令 | 僅適合維護者 |
7. 自定義命令實戰(zhàn)模板
7.1 項目級命令:生成 PR 描述
文件:.claude/skills/pr-description/SKILL.md
--- description: 根據(jù)當前分支生成 PR 描述 argument-hint: "[目標分支]" when_to_use: 用戶準備創(chuàng)建 pull request 或需要總結當前分支改動時 allowed-tools: - Bash(git status:*) - Bash(git diff:*) - Bash(git log:*) --- 請基于當前分支相對 $ARGUMENTS 的改動生成 PR 描述。 要求: - 標題不超過 70 字符 - Summary 使用 1-3 個 bullet - Test plan 使用 checklist - 明確指出未驗證項
調用:
/pr-description main
7.2 只能模型調用的領域技能
文件:.claude/skills/db-review/SKILL.md
--- description: 數(shù)據(jù)庫變更審查 when_to_use: 當任務涉及 SQL、migration、索引、事務或數(shù)據(jù)庫性能時使用 disable-model-invocation: false user-invocable: false --- 請審查數(shù)據(jù)庫相關改動,重點檢查: - migration 是否可回滾 - 大表 DDL 是否會長時間鎖表 - 查詢是否有合適索引 - 是否存在 SQL 注入風險
用戶不能直接 /db-review,但可以要求 Claude 使用該技能。
7.3 按路徑激活的條件技能
--- description: React 組件審查 when_to_use: 當修改 React/TSX 文件時檢查組件結構和狀態(tài)管理 paths: - "src/**/*.tsx" - "app/**/*.tsx" --- 當用戶修改 React 組件時,檢查 props 類型、狀態(tài)管理、副作用和可訪問性。
帶 paths 的技能會先進入 conditional skill 存儲,只有匹配路徑被觸達后才激活。
8. 命令和 SkillTool 的關系
Claude Code 把很多 prompt 型命令也暴露給模型作為 SkillTool 可調用能力。
| 函數(shù) | 作用 |
|---|---|
getSkillToolCommands(cwd) | 返回模型可調用的 prompt commands,包括 .claude/skills、bundled skills 和舊版 .claude/commands |
getSlashCommandToolSkills(cwd) | 更偏向“技能”列表,要求有 description 或 whenToUse,并來自 skills/plugin/bundled 等來源 |
getMcpSkillCommands(mcpCommands) | 從 MCP 命令中篩出 prompt 型、模型可調用、loadedFrom: mcp 的技能 |
影響模型是否可調用的關鍵字段:
| 字段 | 效果 |
|---|---|
disable-model-invocation: true | 不進入模型可調用技能列表 |
user-invocable: false | 用戶不能直接 /name 調用,但模型仍可調用,除非同時禁用模型調用 |
description / when_to_use | 對插件/MCP 類技能尤其重要,決定是否展示給模型或工具列表 |
8.1 Skill 變成命令的完整流程
從 Markdown skill 文件到可執(zhí)行命令,經(jīng)歷以下階段:
8.1.1 加載階段:Markdown → PromptCommand
.claude/skills/example.md
↓ loadSkillsDir.ts 讀取文件
↓ parseMarkdown() 解析 frontmatter + body
↓ 構建 PromptCommand 對象
{
type: 'prompt',
path: '/path/to/example.md',
prompt: 'body 內(nèi)容',
allowedTools: frontmatter.allowed-tools,
...
}
源碼位置:src/skills/loadSkillsDir.ts 的 getPromptForCommand() (344-405行)
8.1.2 用戶輸入/skill-name執(zhí)行路徑
用戶輸入: /example arg1 arg2
↓ processSlashCommand.tsx 檢測 "/" 開頭
↓ findMatchingCommand() 查找匹配的命令
↓ getMessagesForPromptSlashCommand() 生成消息
↓ getPromptForCommand() 處理 prompt 內(nèi)容
↓ 返回 { messages, allowedTools, hooks }
關鍵函數(shù):src/utils/processUserInput/processSlashCommand.tsx 第827行
8.1.3 getPromptForCommand() 詳細處理步驟
| 步驟 | 操作 | 源碼位置 |
|---|---|---|
| 1 | 添加 base dir prefix | 第352行 |
| 2 | 替換 $ARGUMENTS | 第360-375行 |
| 3 | 替換 ${CLAUDE_SKILL_DIR} | 第380行 |
| 4 | 替換 ${CLAUDE_SESSION_ID} | 第385行 |
| 5 | 執(zhí)行內(nèi)聯(lián) ! shell 片段 | 第390-405行 |
8.1.4 SkillTool 調用路徑
模型通過 SkillTool 調用 skill 時:
模型輸出: Skill({ skill: "example", args: "arg1" })
↓ SkillTool.ts call() 函數(shù) (580-841行)
↓ 判斷 context: inline 還是 fork
↓ inline: 直接返回 prompt 消息
↓ fork: 啟動子 Agent 執(zhí)行
8.1.5 Inline vs Fork 執(zhí)行流程對比
| 類型 | 流程 | 適用場景 |
|---|---|---|
| inline | 模型收到 skill prompt → 在當前會話繼續(xù) | 簡單指令、快速任務 |
| fork | 啟動子 Agent → 子 Agent 執(zhí)行 → 返回結果 | 復雜任務、隔離執(zhí)行 |
8.1.6 關鍵源碼位置表
| 功能 | 文件 | 行號 |
|---|---|---|
| Skill 加載 | src/skills/loadSkillsDir.ts | 344-405 |
| Slash 命令解析 | src/utils/processUserInput/processSlashCommand.tsx | 827 |
| SkillTool 調用 | src/tools/SkillTool/SkillTool.ts | 580-841 |
| SkillTool 系統(tǒng)提示 | src/tools/SkillTool/prompt.ts | 173-195 |
| Skills 列表注入 | src/messages/prompt/formatPrompt.ts | formatCommandsWithinBudget |
9. 命令和權限的關系
命令系統(tǒng)本身不等同于工具權限系統(tǒng),但它會影響后續(xù)模型或內(nèi)聯(lián) shell 的權限邊界。
9.1allowed-tools
Markdown 命令 frontmatter 的 allowed-tools 會被解析為工具列表。對于 prompt 命令:
- 會傳到 slash command 結果的
allowedTools。 - 在 Markdown 內(nèi)聯(lián) shell 執(zhí)行時,會被寫入
alwaysAllowRules.command,讓該命令內(nèi)部的 shell 片段按命令級 allowlist 執(zhí)行。
9.2 MCP 技能的限制
MCP skills 被視為遠端/不可信來源,源碼中明確禁止執(zhí)行其 Markdown 正文里的內(nèi)聯(lián) shell 片段。也就是說:
| 來源 | 是否執(zhí)行 Markdown 內(nèi) ! shell 片段 |
|---|---|
| 本地 skills / commands | 可以,受權限與 allowed-tools 影響 |
| bundled / plugin skills | 取決于加載來源與策略 |
| MCP skills | 不執(zhí)行 |
9.3 Remote / Bridge 模式限制
src/commands.ts 中還有遠程模式限制:
| 限制 | 源碼對象/函數(shù) | 含義 |
|---|---|---|
REMOTE_SAFE_COMMANDS | remote mode 預過濾 | 只保留不依賴本地文件系統(tǒng)、git、shell、IDE、MCP 的命令 |
BRIDGE_SAFE_COMMANDS | bridge inbound allowlist | 手機/web 遠程控制進入的 local 命令默認阻止,只有 allowlist 內(nèi)可執(zhí)行 |
isBridgeSafeCommand(cmd) | bridge 判斷 | prompt 命令默認安全,local-jsx 默認阻止,local 需要 allowlist |
10. 與 hooks 的關系
命令和 hooks 是兩套機制,但可以互相連接:
| 連接點 | 說明 |
|---|---|
技能 frontmatter 中聲明 hooks | 技能被調用后,通過 registerSkillHooks(...) 注冊會話級 hooks |
| 命令觸發(fā)工具調用 | prompt 命令本身會變成模型輸入,模型后續(xù)使用工具時仍會觸發(fā) hooks |
allowed-tools 與 hooks 雙重約束 | 命令可限定工具列表,hooks 可在工具真正執(zhí)行前后審計或阻斷 |
| fork 技能與 Subagent hooks | context: fork 會啟動子代理,相關生命周期可能觸發(fā)子代理 hooks |
建議:
| 目標 | 用命令還是 hook |
|---|---|
| 讓用戶主動觸發(fā)某套流程 | 用命令/技能 |
| 在工具執(zhí)行前后自動校驗 | 用 hook |
| 給某個技能附帶臨時質量門禁 | 在技能 frontmatter 中聲明 hooks |
| 對所有項目統(tǒng)一攔截危險行為 | 用全局或項目級 hook |
11. 源碼級原理說明
11.1 加載原理
getCommands(cwd) 是命令表入口。它先調用 memoized 的 loadAllCommands(cwd),再做可用性過濾和動態(tài)技能插入。
核心鏈路:
getCommands(cwd)
└─ loadAllCommands(cwd)
├─ getSkills(cwd)
│ ├─ getSkillDirCommands(cwd)
│ ├─ getPluginSkills()
│ ├─ getBundledSkills()
│ └─ getBuiltinPluginSkillCommands()
├─ getPluginCommands()
├─ getWorkflowCommands(cwd)
└─ COMMANDS()
getSkillDirCommands(cwd) 又會加載:
managed .claude/skills user ~/.claude/skills project .claude/skills additional --add-dir .claude/skills legacy .claude/commands
11.2 Markdown 轉 Command 的原理
SKILL.md 或舊版 .md 文件會經(jīng)歷:
讀取 Markdown → parseFrontmatter(...) → parseSkillFrontmatterFields(...) → createSkillCommand(...) → 返回 type: 'prompt' 的 Command
createSkillCommand(...) 生成的命令固定是 type: 'prompt'。因此 Markdown 自定義命令不是直接執(zhí)行 JS 函數(shù),而是生成一段 prompt 內(nèi)容,讓 Claude Code 把它作為用戶消息或子代理任務處理。
11.3 執(zhí)行原理
用戶輸入 /name args 后:
processSlashCommand(...)
→ parseSlashCommand(...)
→ hasCommand(...)
→ getMessagesForSlashCommand(...)
→ getCommand(...)
→ switch command.type
├─ local-jsx: load().call(onDone, context, args)
├─ local: load().call(args, context)
└─ prompt:
├─ context === 'fork' → executeForkedSlashCommand(...)
└─ inline → getMessagesForPromptSlashCommand(...)
11.4 為什么 Markdown 命令不能直接做任意 UI
Markdown 命令最終被轉成 PromptCommand。它只有 getPromptForCommand(...),不能直接返回 React 節(jié)點,也不能直接實現(xiàn) onDone 交互流程。需要交互 UI 的命令必須是 local-jsx,也就是源碼或插件代碼提供的命令。
11.5 為什么自定義命令推薦寫成 skills
skills 目錄是當前更完整的能力模型:
- 支持
SKILL.md目錄結構和技能資源文件。 - 支持
${CLAUDE_SKILL_DIR}引用技能目錄。 - 支持
paths條件激活。 - 支持
when_to_use給模型選擇技能。 - 支持
context: fork啟動子代理。 - 支持技能級
hooks。
舊版 .claude/commands 仍能用,但源碼中標記為 commands_DEPRECATED,適合兼容,不建議作為新設計的首選。
12. 使用建議與最佳實踐
| 場景 | 推薦做法 | 原因 |
|---|---|---|
| 團隊共享常用流程 | 提交 .claude/skills/<name>/SKILL.md 到倉庫 | 可版本化、可審查、隨項目走 |
| 個人全局命令 | 放在 ~/.claude/skills/<name>/SKILL.md | 不污染項目倉庫 |
舊項目已有 /commands | 可以繼續(xù)用,但新命令遷移到 /skills | commands_DEPRECATED 仍支持但不是首選 |
| 需要交互選擇器 | 寫插件或源碼 local-jsx 命令 | Markdown 無法渲染 UI |
| 需要執(zhí)行本地腳本 | 優(yōu)先用技能正文指導 Claude 調工具,必要時用 Markdown ! 片段并設置 allowed-tools | 保持權限邊界清晰 |
| 涉及危險操作 | 不要只靠命令說明,配合 PreToolUse / PermissionRequest hooks | 命令是觸發(fā)流程,hook 才是強約束點 |
| 需要模型自動選擇 | 寫清 description 和 when_to_use | 模型依賴這些字段判斷是否使用技能 |
| 需要隔離上下文 | 使用 context: fork | 大任務不會污染主上下文,且有獨立 token 預算 |
13. 常見問題
13.1/commands和/skills有什么區(qū)別
.claude/commands 是舊版 Markdown 命令目錄;.claude/skills 是更完整的技能目錄。兩者最終都會被轉成 type: 'prompt' 的 Command,但 skills 支持更明確的目錄結構、資源引用、條件激活和模型技能語義。
13.2 自定義命令能覆蓋內(nèi)置命令嗎
命令合并時自定義技能在內(nèi)置命令之前,查找時返回第一個匹配項,因此同名有可能影響解析結果。但不建議依賴覆蓋行為,最好避免與內(nèi)置命令重名。
13.3 Markdown 命令能直接執(zhí)行 shell 嗎
可以使用 Markdown 內(nèi)聯(lián) shell 片段,但要受權限和 allowed-tools 影響。MCP skills 不會執(zhí)行內(nèi)聯(lián) shell。涉及危險操作時,建議用 hooks 做強制約束。
13.4user-invocable: false是什么效果
用戶不能直接輸入 /skill-name 調用;如果模型可調用未禁用,Claude 仍可通過 SkillTool 使用它。
13.5context: fork和普通命令區(qū)別是什么
普通 prompt 命令會把內(nèi)容加入當前對話;context: fork 會啟動子代理在獨立上下文中執(zhí)行,最終把結果返回給主流程。
13.6 命令會自動出現(xiàn)在模型可用技能里嗎
不一定。模型可調用技能通常要求是 prompt 類型、不是 builtin、沒有 disableModelInvocation,并且有合適的 description 或 when_to_use。插件/MCP 類技能對顯式描述要求更高。
14. 關鍵源碼位置
| 文件 | 關鍵函數(shù)/類型 | 說明 |
|---|---|---|
src/types/command.ts | Command, PromptCommand, LocalCommand, LocalJSXCommand | 命令類型系統(tǒng) |
src/commands.ts | COMMANDS() | 內(nèi)置命令列表 |
src/commands.ts | loadAllCommands(cwd) | 合并 bundled skills、plugin skills、skill dir commands、workflow commands、plugin commands、內(nèi)置命令 |
src/commands.ts | getCommands(cwd) | 過濾可用命令并插入動態(tài)技能 |
src/commands.ts | findCommand(...), getCommand(...) | 命令查找邏輯,支持別名和 user-facing name |
src/commands.ts | getSkillToolCommands(...), getSlashCommandToolSkills(...) | 生成模型可調用技能列表 |
src/commands.ts | REMOTE_SAFE_COMMANDS, isBridgeSafeCommand(...) | 遠程/bridge 模式命令安全過濾 |
src/utils/processUserInput/processSlashCommand.tsx | processSlashCommand(...) | 用戶 /command 輸入解析入口 |
src/utils/processUserInput/processSlashCommand.tsx | getMessagesForSlashCommand(...) | 按 command.type 分支執(zhí)行 |
src/utils/processUserInput/processSlashCommand.tsx | executeForkedSlashCommand(...) | context: fork 子代理執(zhí)行邏輯 |
src/skills/loadSkillsDir.ts | getSkillDirCommands(cwd) | 加載 .claude/skills 和舊版 .claude/commands |
src/skills/loadSkillsDir.ts | createSkillCommand(...) | 把 Markdown 技能轉換成 PromptCommand |
src/skills/loadSkillsDir.ts | parseSkillFrontmatterFields(...) | 解析技能 frontmatter 字段 |
src/utils/markdownConfigLoader.ts | loadMarkdownFilesForSubdir(...) | 加載 managed/user/project Markdown 配置文件 |
src/utils/markdownConfigLoader.ts | getProjectDirsUpToHome(...) | 從 cwd 向上查找 .claude/<subdir>,到 git root 停止 |
src/utils/frontmatterParser.ts | FrontmatterData, parseFrontmatter(...) | frontmatter 字段定義和 YAML 解析 |
15. 快速決策表
| 你想做什么 | 應該用什么 |
|---|---|
增加一個 /review,讓 Claude 按固定步驟審查代碼 | .claude/skills/review/SKILL.md |
增加一個 /git:pr 命名空間命令 | .claude/commands/git/pr.md 或遷移為 .claude/skills/git-pr/SKILL.md |
| 讓 Claude 在修改 TS 文件后自動 typecheck | 技能 frontmatter hooks,或項目級 PostToolUse hook |
| 做一個交互式模型選擇面板 | local-jsx 命令,需要源碼或插件 |
| 做一個純本地狀態(tài)查詢命令 | local 命令,需要源碼或插件 |
| 讓某技能只在 React 文件被修改后出現(xiàn) | paths: ["**/*.tsx"] 條件技能 |
| 把外部系統(tǒng)能力暴露給 Claude | MCP skill 或插件 skill |
| 團隊統(tǒng)一分發(fā)命令 | 項目 .claude/skills 或插件 |
以上就是Claude Code工作流中的命令實現(xiàn)與自定義指南的詳細內(nèi)容,更多關于Claude Code工作流命令的資料請關注腳本之家其它相關文章!
相關文章
文章分享了使用ClaudeCode提高開發(fā)效率的六個實用工作流程,分別為:快速理解新代碼庫、高效修復錯誤、代碼重構、擴展思考、GitWorktree并行開發(fā)及自定義斜杠命令,通過Clale2026-05-22
Claude Code 修改文件的方式不是傳行號,也不是打 AST patch,它讓模型輸出一段要替換的原文 old_string 和替換后的文本 new_string,由 Edit 工具完成實際寫入,本文給大家2026-05-22
這篇文章主要為大家詳細Claude Code的核心用法,包括精簡上下文、先規(guī)劃后編碼、強制自我驗證,通過標準四步工作流與實戰(zhàn) Prompt助你 5 分鐘上手,讓 AI 成為編程神隊友,有2026-04-28




