用过 ChatGPT 的人都知道,AI 对话能力再强,每次都要重复敲一段冗长的提示词也是件烦人的事。在 OpenCode 这个终端 AI 编程助手里,这个问题被一套强大的 Commands(斜杠命令) 系统优雅地解决了。你在 TUI 界面里只需要输入 / 加一个命令名,OpenCode 就会把一段预置的提示词发送给大模型,省去反复复制的麻烦。
更重要的是,这套系统远不止"快捷短语"这么简单:它支持参数注入、shell 输出嵌入、文件内容引用,还能绑定特定的 Agent、模型,甚至强制以子代理(subagent)的方式执行。本篇文章将带你从零掌握 OpenCode 的命令系统,让你的日常编程工作流实现"一键复用"。
在 OpenCode 的 TUI 中输入 /,就会弹出命令列表。这些命令分为两类:
/init(生成 AGENTS.md 规则文件)、/undo(撤销上一步)、/redo(重做)、/share(分享会话)、/help(查看帮助)等。/命令名 触发。自定义命令的本质,是把一段"高质量的固定提示词"与当前的项目上下文结合起来,让 AI 按照你预设的套路执行任务。比如团队规范统一的"代码审查"、"测试覆盖率分析",都可以沉淀成一条命令。
在 opencode.jsonc 或 opencode.json 配置文件的 command 字段中定义:
{
"$schema": "https://opencode.ai/config.json",
"command": {
// 键名就是命令名
"test": {
// 发送给 LLM 的提示词(必填)
"template": "运行完整的测试套件并生成覆盖率报告,展示所有失败项。\n针对失败的测试给出修复建议。",
// TUI 中显示的描述
"description": "运行测试并生成覆盖率报告",
"agent": "build",
"model": "anthropic/claude-3-5-sonnet-20241022"
}
}
}
配置完成后,在 TUI 中输入 /test 即可执行。
更清爽的方式是把每个命令写成一个独立的 Markdown 文件,文件名即命令名:
~/.config/opencode/commands/.opencode/commands/例如创建 .opencode/commands/test.md:
--- description: 运行测试并生成覆盖率报告 agent: build model: anthropic/claude-3-5-sonnet-20241022 --- 运行完整的测试套件并生成覆盖率报告,展示所有失败项。 针对失败的测试给出修复建议。
frontmatter 中定义命令的元信息,正文就是提示词模板。相比 JSON 配置,文件方式更利于版本控制和多人协作——每个命令都是独立的文件,评审时一目了然。
命令系统的精髓在于模板里的特殊语法。
$ARGUMENTS用 $ARGUMENTS 占位符接收参数,让命令具备"可输入性":
--- description: 创建新的 React 组件 --- 创建一个名为 $ARGUMENTS 的 React 组件,需要 TypeScript 支持。 包含完整的类型定义和基础结构。
执行时输入:
/component Button
$ARGUMENTS 就会被替换为 Button。你还可以用位置参数 $1、$2、$3 精确控制每个参数:
--- description: 在指定目录创建文件 --- 在目录 $2 中创建名为 $1 的文件,内容如下:$3
/create-file config.json src "{ \"key\": \"value\" }"
!命令 `这是非常实用的能力——在模板中用 ` !bash 命令 ` 将命令执行结果动态拼进提示词。命令会在项目根目录执行,输出直接成为提示词的一部分。
比如创建一条分析测试覆盖率的命令:
--- description: 分析测试覆盖率 --- 以下是当前测试结果: !`npm test` 请根据这些结果,提出提升覆盖率的具体建议。
或者审查最近的代码变更:
--- description: 审查最近的代码变更 --- 最近的 git 提交记录: !`git log --oneline -10` 请审查这些变更并给出改进建议。
这意味着你的命令永远是"新鲜"的,反映的是当前项目的实时状态,而不是写死的一段静态文本。
@文件名用 @ 前缀把项目文件内容直接引入提示词,非常适合针对特定文件的审查类命令:
--- description: 审查指定组件 --- 请审查 @src/components/Button.tsx 这个组件。 检查性能问题并给出优化建议。
文件内容会被自动读取并作为上下文发送给模型,避免了让 AI 自己去找文件的额外步骤。
除了 template 和 description,还有几个影响执行行为的选项:
| 选项 | 作用 | 默认值 |
| ---- | ---- | ------ |
| template | 提示词模板(必填) | 无 |
| description | TUI 中显示的命令描述 | 无 |
| agent | 指定由哪个 Agent 执行 | 当前 Agent |
| subtask | 是否强制以子代理方式执行 | 取决于 agent |
| model | 覆盖该命令使用的模型 | 默认模型 |
{
"command": {
"review": {
"agent": "plan",
"subtask": true
}
}
}
当 agent 指向一个子代理时,命令默认会触发子代理调用。把 subtask 设为 true 可以强制命令以子代理方式执行,即使目标 Agent 的 mode 是 primary。这样做的好处是:子代理的运行不会污染主对话的上下文,适合"一键分析"这种只需要返回结论的场景。
{
"command": {
"analyze": {
"model": "anthropic/claude-3-5-sonnet-20241022"
}
}
}
有些命令(如复杂重构)需要更强的模型,有些(如简单的格式化)用便宜的模型就够了。用 model 选项按命令指定模型,是控制成本的好办法。
下面我给出几个可以直接抄作业的命令,组成一个实用的"开发工具箱"。
--- description: 生成规范的 Git 提交信息 --- !`git diff --stat` 基于以上变更内容,生成一条符合 Conventional Commits 规范的提交信息,只输出最终提交命令。
--- description: 为指定文件编写单元测试 --- 为 @$1 编写单元测试,使用项目现有的测试框架。 覆盖正常路径、边界情况和错误分支,测试要可以直接运行。
用法:/unittest src/utils/format.ts
--- description: 排查构建错误 --- 构建输出如下: !`npm run build` 请分析错误原因,定位相关源码文件,并给出修复后的代码。
自定义命令可以覆盖内置命令。如果你定义了同名命令,它会替换内置行为。这在想"魔改"内置命令时很好用,但也容易误伤,建议覆盖前先想清楚。
Slash Commands 是 OpenCode 里投入产出比极高的功能之一。它把"重复的提示词"抽象成可复用的命令资产,配合 $ARGUMENTS 参数、` !shell 动态输出和 @文件` 引用,几乎可以覆盖日常开发的所有重复场景。
记住这套心法:凡是你在项目里说过第二遍的话,都值得写成一条命令。试着从一条"运行测试并分析失败"的命令开始,逐步积累自己的命令库,你会明显感觉到在终端里写代码的流畅度上了一个台阶。