本文不是理论堆砌,而是用一个真实可用的案例——在 Claude Code 里自定义 /codex 命令,把编码任务一键委派给 WSL 里的 OpenAI Codex CLI——完整演示自定义命令的写法、原理与踩坑点。
在这里插入图片描述

一、为什么要自定义命令

Claude Code 是 Anthropic 官方的终端 AI 编程助手,内置了 /clear/review/permissions 等斜杠命令。但实际工作中你总有一些高频、固定的诉求,比如:

  • 把任务交给另一个 AI CLI(Codex / DeepSeek)去做
  • 固定的代码审查流程
  • 每次开会前的项目状态汇报
  • 一键初始化新模块的目录结构

如果每次都手动复述一堆提示词,又累又容易漏。自定义斜杠命令就是解决这个问题的:把一个 Markdown 文件变成一个命令,输入 /命令名 即可触发。

二、原理:命令就是一个 Markdown 文件

Claude Code 的斜杠命令本质是一个 Markdown 文件(经典 commands 格式;并入 Skills 后,入口同样是 Markdown + YAML frontmatter),分为两部分:

1. Frontmatter(元数据)

--- 包裹的 YAML,声明命令的描述、参数提示、可用工具等:

---
description: 命令在 / 菜单里的说明文字
argument-hint: 提示用户该输入什么参数
allowed-tools: 允许 Claude 使用的工具,如 Bash(*)
model: 指定该命令使用的模型
---

2. 正文(给 Claude 的指令)

Markdown 正文是注入给 Claude 的提示词,里面有特殊的占位符:

占位符作用
$ARGUMENTS你输入 /命令 内容 中的"内容"整体替换进来
$1 $2按空格切分的位置参数:第一个是 $1、第二个是 $2,支持 ${3:-默认值} 缺省写法
$ARGUMENTS[N]0 起算的索引写法,$ARGUMENTS[0] 即第一个参数
${CLAUDE_SESSION_ID}当前会话 ID
!`命令`注入命令输出,如 !`git status`

⚠️ 网上流传的 $JSON_ARGS$PROMPT_FILE 等变量未见于官方文档,不要依赖。

工作流程:你输入 /codex 帮我重构这个模块 → Claude Code 读取 codex.md 内容,把 $ARGUMENTS 替换为"帮我重构这个模块" → 作为指令注入 Claude → Claude 按指令执行。

三、命令放在哪里?

位置作用范围
.claude/commands/xxx.md(项目目录内)仅当前项目可用,可随仓库提交共享
~/.claude/commands/xxx.md(用户主目录)所有项目全局可用

版本提示:commands/ 目录是兼容的旧格式。Claude Code 已把自定义命令并入 Agent Skills 标准,当前推荐写法是 .claude/skills/<命令名>/SKILL.md(项目级)或 ~/.claude/skills/<命令名>/SKILL.md(用户级)。frontmatter 与正文写法一致,还支持 disable-model-invocationcontext: fork 等新字段。本文案例基于经典 commands 格式,同样适用于 Skills。

个人建议:通用的工具类命令放用户目录(全局),业务相关的放项目目录。

四、实战案例:自定义 /codex

下面是我机器上的真实配置。分工很简单:开发任务全部在宿主机 Claude Code 里完成,/codex 只做代码评审、不做代码修改。 输入 /codex 评审下刚才的修改,Claude 会自动调用 WSL 里的 Codex CLI 以另一个模型视角审查改动,再把结果汇报回来(命令模板本身也支持写码模式,但那是备用能力,不是我的日常用法)。

4.1 前提

Windows 上安装了 WSL,并在 WSL 里装好 Codex CLI、完成登录鉴权:

npm install -g @openai/codex
codex login        # 或配置 OpenAI API Key
codex --version    # 确认可执行(本文验证环境:codex-cli 0.144.4)

4.2 创建文件

新建 ~/.claude/commands/codex.md,内容如下:

---
description: Review code changes with OpenAI Codex CLI running in WSL (read-only by default)
argument-hint: [your coding task]
allowed-tools: Bash(*)
---

Execute the following task using **Codex CLI** installed in WSL.

## Instructions

1. No path conversion needed: WSL inherits the current Windows directory as its working dir.
2. Run Codex (choose the right mode):

   **For review/analysis tasks (read-only, no writes):**
   ```bash
   wsl bash -c 'codex exec --sandbox read-only --skip-git-repo-check "PROMPT"'
   ```

   **For coding tasks (writes code — reserved, not the default use):**
   ```bash
   wsl bash -c 'codex exec --sandbox workspace-write --skip-git-repo-check "PROMPT"'
   ```

3. Report the Codex output. If it modified files, summarize the changes.

## Task

$ARGUMENTS

注:示例相对作者的真实配置做了三处微调——read-only 提到首位、去掉 faster 表述、命令去掉嵌套的 cd $(wslpath ...)(原因见 4.3 避坑要点)。你的文件保持原样也能用,但建议按示例版本优化。

几个关键点逐一拆解:

  • allowed-tools: Bash(*):本次命令调用期间的免确认预授权,不是工具白名单——未列出的工具仍会按会话权限规则请求。Bash(*) 把任意 Bash 命令都免确认,风险较高,建议按实际命令精确匹配(用 /permissions 验证),不要图省事全放开。
  • 正文分 “Instructions”(怎么做)+ “Task”(做什么):$ARGUMENTS 放在最后,用户输入的任务会被替换到这里。指令部分写清步骤,Claude 才能稳定执行。
  • --sandbox 等参数属于 Codex CLI,不是 Claude Code 功能:--sandbox read-only 表示禁止写入、适合分析任务、风险更低(并不保证更快);--skip-git-repo-check 用于非 git 目录。
  • 两种模式,日常只用一种:模板同时给了 workspace-write(写码)和 read-only(评审)两种模式,但我的实际用法是评审专用——永远走 read-only,Codex 只出意见、不动文件。开发任务留在宿主机 Claude Code(DeepSeek)做。
  • 有副作用、仅手动触发的命令建议加 disable-model-invocation: true:否则在 Skills 机制下,Claude 可能因"看起来相关"而自动调用它。加上后只有你输入 /codex 才会触发。

4.3 实际执行链路

你输入 /codex 评审下刚才的修改
        ↓
Claude Code 读取 codex.md,替换 $ARGUMENTS
        ↓
Claude 执行 Bash(无需 cd——WSL 自动继承 Windows 当前目录):
  wsl bash -c 'codex exec --sandbox read-only --skip-git-repo-check "评审 main.py 的改动"'
        ↓
WSL 中的 Codex CLI 只读审查,输出分级意见
        ↓
Claude 把 Codex 意见汇报给你(评审不动任何文件)

可以看到,/codex 本质上是一个**“中继命令”**:Claude Code 负责接收任务、桥接 Windows 与 WSL、汇报结果,真正干活的是 Codex CLI。

Windows + WSL 双环境的避坑要点
  1. WSL 继承 Windows 当前目录:Claude Code 在 D:\projects\my-app 启动时,WSL 的 pwd 直接就是 /mnt/d/projects/my-app,不需要 cd,也就不需要路径转换。
  2. 确需切目录时,先在本机算好路径:wsl wslpath "D:/xxx" 得到 /mnt/d/xxx 再拼进命令,不要在命令里嵌套 $(wslpath ...)——Windows 侧 shell 可能吃掉内层引号导致失败(本案例实际踩过)。
  3. 警惕嵌套引号:wsl bash -c '... "PROMPT"' 叠加了单双引号,任务里出现 $、反引号、双引号时极易解析出错,提示词内尽量规避特殊字符。
  4. 更彻底的方案:直接在 WSL 里安装 Claude Code + Codex CLI,同环境运行,路径、目录、引号三类问题全部消失。

4.4 使用效果

# 评审专用(我的日常用法):让 Codex 以另一个模型视角审刚写完的代码
/codex 评审下刚才的修改

# 只读分析(read-only 禁止写入,风险更低)
/codex 分析一下这个项目的模块依赖,输出一份报告

# 模板里保留的 workspace-write 写码模式属备用能力,本文不展开——作者惯例:写码留在宿主机,/codex 不改码

实录:本文作者环境为 Windows 11 + Git Bash + WSL + codex-cli 0.144.4,输入 /codex 评审下 后,Codex 以 read-only 模式输出约 8.7 万 tokens 的分级评审,未改动任何文件。

4.5 高频场景:写码交给 DeepSeek,评审交给 Codex

在我这里,/codex 是评审专用,不做代码修改——分工很明确:开发任务全部在宿主机 Claude Code(经网关路由到 DeepSeek)里完成,写完代码后输入:

/codex 评审下刚才的修改

Codex 以另一个模型、独立进程的身份在 WSL 里把改动过一遍。这不是炫技,而是实打实的"第二个工程师":Claude/DeepSeek 写码时有自己的思维惯性,Codex 的审查视角往往能发现前者没注意到的问题——两个模型互审,比单个模型自查靠谱得多

三个实操要点
  1. 先说清"刚才的修改"是什么。Codex 不会自己知道哪些文件是新改的,提示词里必须带上文件清单或 diff。在 git 仓库里,可以让 Claude 先跑 git diff --stat 把改动文件列进提示词;不在 git 仓库(比如本文写作目录),就直接在提示词里点名文件。更省心的做法是在 codex.md 正文里追加一条评审规则:
## Reviewing recent changes (optional)

If the task is to review recent changes:
1. First find out what changed: run `git diff --stat` (in a git repo), or ask the user for the file list
2. Include the file list / diff in the PROMPT so Codex knows what to review
3. Ask for findings ordered by severity (e.g. P0/P1/P2)
  1. 评审务必用 read-only:--sandbox read-only 禁止 Codex 改动文件,只输出意见。评审场景永远不该出现写操作。

  2. 让 Codex 分级输出。实测中 Codex 会按 P0(不修会翻车)/ P1(影响可信度)/ P2(可优化)输出,直接照着改即可。上文 4.4 的实录就是一次完整的交叉评审:它揪出了三个 P0 硬伤(嵌套代码块、未验证的占位符变量、嵌套引号坑),其中"嵌套引号"那条我们后来实机复现、确实会挂——这就是交叉评审的价值:你写完以为没问题,Codex 替你踩了一遍坑

五、进阶:一个命令文件 = 一个模型切换器

同目录下的 flash.mdpro.md 是更简化的玩法——只用 frontmatter 和一行占位符:

---
description: Quick, cost-efficient task
model: my-flash
argument-hint: [your prompt]
---

$ARGUMENTS
---
description: Deep reasoning task
model: my-pro[1m]
argument-hint: [your prompt]
---

$ARGUMENTS

效果:/flash 总结这个仓库 会用便宜的快模型快速跑,/pro 设计这个架构 会用更强的深度推理模型——用命令把模型选择固化成了肌肉记忆,不用每次手选。

⚠️ 前提说明:示例中的 my-flashmy-pro[1m] 不是官方模型名,是作者环境通过网关路由到第三方模型后配置的自定义 ID(已脱敏)。model 字段只能填当前 /model 里可见的模型名,普通官方账户请改用 claude-sonnet-5 等官方 ID,或先配置好自定义网关再照抄。

六、实用小贴士

  1. 描述要写清楚:description 会显示在 / 菜单里,这是你找命令的入口。
  2. 参数提示别省:argument-hint 提示用户输入格式,避免"不知道填什么"。
  3. 分步指令优于一句话:告诉 Claude"先做什么、再做什么、最后汇报什么",执行稳定性天差地别。
  4. allowed-tools 慎用 *:免确认授权范围太大有风险,建议按实际命令精确匹配,并在 /permissions 里验证生效情况。
  5. 生效时机:Skills 新格式支持会话内热加载;经典 commands 格式保存后新开会话,/ 菜单里即可看到新命令。
  6. 团队共享:把命令放进项目 .claude/commands/,提交到 Git 仓库,队友 clone 后即得。

七、总结

Claude Code 的自定义命令看似简单——就是一个 Markdown 文件——但它把"提示词 + 工具策略 + 环境桥接"封装成了一个语义化入口:

  • /codex:评审专用中继器——写码留在宿主机 Claude Code(DeepSeek),评审交给 WSL 里的 Codex,两个模型互审、Codex 永不改码
  • /flash/pro:模型切换器
  • 你的命令:任何你能想到的高频工作流

你给 AI 的不是一行提示词,而是一个可复用、可分享、可持续演进的"能力插件"。 这就是自定义命令的价值。


如果您觉得有用,欢迎 点赞、转发、评论、关注

更多推荐