理解 Agent 中的 Slash Command:从概念到自定义命令实践

一、为什么要单独理解 Slash Command

用 Agent 做事时,经常会遇到以 / 开头的输入:

text 复制代码
/help
/new
/model
/skill markdown-to-wechat-richtext

这类输入就是 Slash Command。

它看起来像一句聊天消息,但本质上更接近"命令"。普通消息通常会进入大模型推理流程,由模型理解意图,再决定是否使用工具;Slash Command 则会先被 Agent 的命令系统拦截和解析,然后按命令名触发固定逻辑。

这也是我觉得它值得单独讲清楚的原因:Slash Command 不是 Prompt 的另一种写法,而是 Agent 系统里的一个控制入口。

理解这个入口后,很多问题就容易解释了:

  • 为什么 /help 不需要模型推理,也能直接显示帮助信息?
  • 为什么 /new 可以直接开启新会话?
  • 为什么有些开源项目安装后,会在 Claude Code、Gemini CLI、Hermes 这类 Agent 里多出自己的命令?
  • 为什么 Hermes 可以通过配置新增 /greet/wechat-gzh 这样的自定义命令?

这篇文章围绕这些问题展开,重点放在 Slash Command 本身,而不是 Skill 的基础概念。

二、Slash Command 到底是什么

Slash Command 是 Agent 会话中的一种"命令式输入"。它通常以 / 开头,后面跟命令名和可选参数。

例如:

text 复制代码
/help
/model gpt-5.1
/skill markdown-to-wechat-richtext
/wechat-gzh abc/def.md

一条 Slash Command 通常可以拆成两部分:

text 复制代码
/wechat-gzh abc/def.md
└─────────┘ └────────┘
  命令名       参数

也就是:

text 复制代码
命令名:/wechat-gzh
参数:abc/def.md

Agent 收到这类输入后,一般不会马上把整句话当作自然语言丢给模型,而是先执行类似下面的流程:

text 复制代码
用户输入一条以 / 开头的消息
    ↓
Agent 判断这是 Slash Command
    ↓
解析命令名和参数
    ↓
查找命令注册表、Quick Command、插件命令或 Skill 命令
    ↓
执行对应逻辑
    ↓
返回结果,或者改变当前会话状态

所以 Slash Command 的关键点不是"让模型理解得更好",而是"让系统更确定地触发一个动作"。

举个简单例子:

text 复制代码
帮我开一个新会话

这是自然语言,Agent 需要理解你的意图。

而:

text 复制代码
/new

这是命令,系统可以直接把它识别为"开启新会话"。

三、Slash Command 解决了什么问题

Slash Command 的价值,是把常用操作变成短小、稳定、可重复的入口。

在 Agent 使用过程中,有些事情不适合每次都用自然语言描述。比如:

  • 查看帮助
  • 新建会话
  • 清理上下文
  • 切换模型
  • 加载 Skill
  • 执行固定脚本
  • 给已有能力起一个短别名
  • 在聊天平台里触发运维检查

如果每次都用自然语言表达,容易出现两个问题。

第一个问题是啰嗦。比如"帮我重新开启一个新的上下文,并且不要继承当前对话历史",不如 /new 直接。

第二个问题是歧义。自然语言要经过模型理解,模型可能会解释、追问、或者做出和预期不一致的判断;Slash Command 的命令名和参数结构更固定,适合控制类动作。

我通常把 Slash Command 分成四类来看。

会话控制命令

这类命令改变当前会话状态,例如:

text 复制代码
/new
/clear
/retry
/undo
/compress
/quit

它们不是用来完成业务任务的,而是用来管理会话本身。

配置和状态命令

这类命令用于查看或修改 Agent 运行状态,例如:

text 复制代码
/model
/config
/tools
/status
/usage

它们的特点是:用户希望得到一个确定的系统行为,而不是一段开放式回答。

能力加载命令

这类命令用于加载某种能力或工作流,例如 Hermes 中的:

text 复制代码
/skill markdown-to-wechat-richtext

也可以是某个 Skill 被注册成动态命令后直接调用:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

这里的重点是:Slash Command 只是入口,真正执行任务的可能是 Skill、工具、插件或 Agent 工作流。

用户自定义命令

用户自定义命令是本文后面重点讨论的部分。比如希望输入:

text 复制代码
/greet

直接输出:

text 复制代码
Hello, nice to meet you!

或者希望输入:

text 复制代码
/wechat-gzh abc/def.md

实际调用本地已有的:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

这就是 Slash Command 作为"快捷入口"的典型用法。

四、开源项目为什么安装后能提供自己的命令

很多开源项目安装后,可以在某个 Agent 里使用自己的 Slash Command。这里容易产生一个误解:好像所有 Agent 都有一套统一的 Slash Command 插件标准。

实际情况不是这样。

不同 Agent 的实现方式差别很大。一个项目能提供命令,通常是因为它适配了某个 Agent 的扩展机制。

常见方式有几种。

文件型命令

有些 Agent 会约定一个命令目录。项目只要把 Markdown 文件放进去,Agent 就会把这些文件识别成命令。

典型形式类似:

text 复制代码
.claude/commands/xxx.md
~/.claude/commands/xxx.md

这种模式下,Markdown 文件往往不是普通文档,而是一个 Prompt 模板。用户输入 /xxx 后,Agent 加载对应模板,再把参数拼进去执行。

这种方式很适合开源项目分发自己的工作流,例如:

text 复制代码
/spec-create
/spec-implement
/spec-review

但要注意:这是某些 Agent 的约定,不代表所有 Agent 都支持同样的目录结构。

注册表型命令

有些 Agent 在源码里维护一张命令注册表。每个命令都有名字、说明、参数、handler。

用户输入 /help/model/new 时,系统会查注册表,然后调用对应处理函数。

Hermes 的内置 Slash Command 就属于这种思路。命令注册表是核心入口之一,CLI、自动补全、帮助信息、部分平台映射都可以基于这张表生成。

这种方式更适合系统级命令,因为它需要修改 Agent 本身的代码。

插件型命令

插件型命令介于"用户配置"和"修改源码"之间。

项目提供一个插件,插件安装后向 Agent 注册新的 Slash Command。用户不需要改 Agent 源码,但命令仍然可以拥有比较完整的逻辑。

这类方式适合可分发、可复用、功能较完整的扩展。

MCP 或工具型入口

还有一些项目并不直接提供 Slash Command,而是提供 CLI、MCP Server 或工具集。Agent 通过工具发现机制拿到这些能力后,再用某种命令或自然语言触发。

这种情况下,用户看到的可能像 Slash Command,但底层并不一定是命令文件或命令注册表,而是工具调用。

所以判断一个项目为什么能提供命令,不能只看"有没有 /xxx",还要看它适配的是哪一种扩展机制。

五、Hermes 里自定义 Slash Command 的几种方式

在 Hermes 中,自定义 Slash Command 可以从简单到复杂分成几层。

Quick Command

最简单的是 Quick Command。

它写在 Hermes 配置文件里:

text 复制代码
~/.hermes/config.yaml

Quick Command 支持两种类型:

text 复制代码
exec
alias

exec 用来执行本地 shell 命令,适合固定输出、系统检查、脚本执行。

alias 用来把一个短命令改写到另一个 Slash Command,适合给已有命令、Skill 命令或复杂命令起别名。

官方文档里的表达也很直接:Quick Commands 可以把一个短 Slash Command 映射到 shell 命令,或者映射到另一个 Slash Command。

内置 Slash Command

如果要做系统级命令,就需要改 Hermes 源码。

大体思路是:

  1. 在命令注册表里增加命令定义。
  2. 在 CLI 或 Gateway 的命令处理逻辑里增加 handler。
  3. 如有必要,补充帮助信息、自动补全、平台映射和测试。

这种方式适合真正属于 Hermes 核心能力的命令,例如会话控制、配置管理、工具管理等。

普通用户只是想加一个快捷命令时,不建议直接走这条路。

插件命令

插件命令适合可分发扩展。

如果一个能力不应该进入 Hermes 核心,但又希望安装后自动多出命令,就可以做成插件。

插件方式比 Quick Command 更重,但比直接改核心源码更适合分发。

Skill 动态命令

Hermes 还支持把已安装 Skill 当作动态命令来调用。

例如本地有一个 Skill:

text 复制代码
markdown-to-wechat-richtext

它可以用于把 Markdown 文章转换成微信公众号编辑器友好的富文本 HTML 片段。

如果这个 Skill 可以作为动态命令调用,那么原始调用可能是:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

这里 /markdown-to-wechat-richtext 是入口,abc/def.md 是传给这个 Skill 的文件路径参数。

后面要做的 /wechat-gzh,本质上就是给这条较长的 Skill 命令起一个短别名。

六、实践一:用 Quick Command 实现 /greet

先从最简单的例子开始:实现一个 /greet 命令。

目标效果是:

text 复制代码
/greet

输出:

text 复制代码
Hello, nice to meet you!

这个命令不需要读取文件,不需要调用 Skill,也不需要让大模型参与推理。它只是返回一句固定文本,所以最适合用 Quick Command 的 exec 类型。

配置写法

打开 Hermes 配置文件:

text 复制代码
~/.hermes/config.yaml

加入下面配置:

yaml 复制代码
quick_commands:
  greet:
    type: exec
    command: "printf 'Hello, nice to meet you!\n'"

这里有几个细节需要注意。

greet 是命令名,不需要写成 /greet。用户输入时带 /,配置里只写命令名。

type: exec 表示这是一个执行 shell 命令的 Quick Command。

command 里的内容是实际执行的 shell 命令。这里用 printf 输出固定文本。

保存配置后,在 Hermes 会话里输入:

text 复制代码
/greet

预期看到:

text 复制代码
Hello, nice to meet you!

如果当前会话没有立即生效,可以重启 Hermes CLI,或者开启一个新会话再测试。

为什么这里不用 Skill

/greet 这种命令没有复杂流程,也没有可复用的任务经验。为了输出一句固定文本去写 Skill,会把问题复杂化。

这里用 exec 的好处是:

  • 不调用 LLM
  • 不消耗 token
  • 配置简单
  • 行为稳定
  • 很适合做系统检查、固定脚本、状态查询

比如下面这些命令也适合 exec

yaml 复制代码
quick_commands:
  disk:
    type: exec
    command: "df -h /"

  uptime:
    type: exec
    command: "uptime"

exec 的边界也很清楚:它适合执行明确的 shell 命令,不适合承载复杂的 Agent 工作流。

七、实践二:用 /wechat-gzh abc/def.md 调用本地 Skill

第二个例子更接近真实工作流。

本地已经有一个 Skill:

text 复制代码
markdown-to-wechat-richtext

它的用途是把 Markdown 文章转换成微信公众号编辑器友好的富文本 HTML 片段。

原始调用可以写得比较完整:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

但这个命令名偏长。日常写文章时,更希望输入一个短命令:

text 复制代码
/wechat-gzh abc/def.md

达到同样效果。

目标映射关系是:

text 复制代码
/wechat-gzh abc/def.md
    ↓
/markdown-to-wechat-richtext abc/def.md

这里推荐使用全小写字母和连字符的命令名:

text 复制代码
wechat-gzh

这种命名方式更符合 Slash Command 的使用习惯,也更不容易遇到大小写匹配带来的困扰。

配置写法

~/.hermes/config.yaml 中配置:

yaml 复制代码
quick_commands:
  wechat-gzh:
    type: alias
    target: /markdown-to-wechat-richtext

如果已经有前面的 /greet,可以放在同一个 quick_commands 下:

yaml 复制代码
quick_commands:
  greet:
    type: exec
    command: "printf 'Hello, nice to meet you!\n'"

  wechat-gzh:
    type: alias
    target: /markdown-to-wechat-richtext

注意这里用的是 alias,不是 exec

原因很简单:/wechat-gzh 不是要执行一条本地 shell 命令,而是要转发到另一个 Slash Command,让 Hermes 继续按 Skill 命令处理。

参数到底是怎么传过去的

这一段最容易困惑。

用户输入的是:

text 复制代码
/wechat-gzh abc/def.md

Hermes 先把它拆成两部分:

text 复制代码
/wechat-gzh abc/def.md
└─────────┘ └────────┘
  命令名       参数文本

也就是:

text 复制代码
命令名:/wechat-gzh
参数文本:abc/def.md

然后 Hermes 查 quick_commands,发现配置里有:

yaml 复制代码
wechat-gzh:
  type: alias
  target: /markdown-to-wechat-richtext

接下来,alias 会把原命令后面的参数文本追加到 target 后面:

text 复制代码
/markdown-to-wechat-richtext + 空格 + abc/def.md

最终得到:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

也就是说,abc/def.md 不是写死在配置里的,也不需要在配置里写 ${1}$ARGUMENTS 这类占位符。

它来自用户实际输入中跟在命令名后面的剩余文本。

Hermes CLI 的处理逻辑也能印证这一点。alias 分支里会取出原始命令中 base_cmd 后面的内容:

python 复制代码
user_args = cmd_original[len(base_cmd):].strip()
aliased_command = f"{target} {user_args}".strip()
return self.process_command(aliased_command)

这段逻辑表达的意思就是:

text 复制代码
目标命令 + 原命令参数 = 改写后的新命令

所以不同输入会得到不同的改写结果:

用户输入 Hermes 改写后
/wechat-gzh abc/def.md /markdown-to-wechat-richtext abc/def.md
/wechat-gzh posts/a.md /markdown-to-wechat-richtext posts/a.md
/wechat-gzh /home/sharpcj/blog/a.md /markdown-to-wechat-richtext /home/sharpcj/blog/a.md

target 是固定的:

text 复制代码
/markdown-to-wechat-richtext

参数是动态的:

text 复制代码
abc/def.md
posts/a.md
/home/sharpcj/blog/a.md

这就是带参数 alias 的核心。

Skill 接收到的是什么

alias 只负责改写命令,不负责解释参数含义。

/wechat-gzh abc/def.md 被改写成:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

后面的处理就交给 markdown-to-wechat-richtext 这个 Skill 命令。

这个 Skill 需要理解:

text 复制代码
abc/def.md

是一个 Markdown 文件路径,然后按自己的工作流去读取文件、转换内容,并生成微信公众号可复制使用的 HTML fragment。

所以职责边界是:

角色 负责什么
/wechat-gzh 提供短命令入口
Quick Command alias 把短命令改写成长命令,并保留参数
/markdown-to-wechat-richtext 加载并执行本地 Skill 工作流
Skill 理解文件路径,完成 Markdown 到微信富文本 HTML 的转换

这个边界很重要。不要期待 alias 自己去读文件、转换 HTML、处理 Mermaid 或输出结果文件。alias 只做"转发"。真正的任务执行在 Skill 里。

没有传参数会怎样

如果只输入:

text 复制代码
/wechat-gzh

alias 改写后会变成:

text 复制代码
/markdown-to-wechat-richtext

这时 Skill 没有拿到文件路径,就无法知道要转换哪篇文章。比较合理的结果是提示用户补充 Markdown 文件路径。

所以这个命令的推荐用法应该始终带上文件路径:

text 复制代码
/wechat-gzh path/to/article.md

如果路径里包含空格,最好避免这种路径命名;如果确实需要使用,建议先按当前 Hermes 命令解析行为测试引号是否符合预期。技术文章和工程文件里,我更建议直接使用不含空格的路径。

八、execalias 怎么选

理解 /greet/wechat-gzh 后,Quick Command 的两种类型就比较清楚了。

类型 做什么 是否调用 Agent 工作流 适合场景
exec 执行本地 shell 命令 通常不调用 固定输出、系统检查、脚本执行
alias 改写到另一个 Slash Command 取决于目标命令 缩短命令名、包装 Skill、复用已有命令

判断时可以问一个问题:这个命令最终要做的事情,是一条 shell 命令能完成,还是应该交给 Agent/Skill 继续处理?

如果是一条 shell 命令能完成,用 exec

例如:

yaml 复制代码
quick_commands:
  disk:
    type: exec
    command: "df -h /"

如果是调用另一个 Slash Command,用 alias

例如:

yaml 复制代码
quick_commands:
  wechat-gzh:
    type: alias
    target: /markdown-to-wechat-richtext

我不建议把复杂 Prompt 直接塞进 Quick Command。Hermes 文档也明确提到,string-only prompt shortcut 不是有效的 Quick Command。可复用 Prompt 工作流应该放进 Skill,再用 alias 指向这个 Skill 命令。

这也是 /wechat-gzh 这个例子的设计思路:

text 复制代码
复杂工作流放 Skill
短入口用 alias

九、排查命令不生效的问题

配置完 Slash Command 后,如果输入命令没有得到预期结果,可以从下面几个方向排查。

配置文件位置是否正确

Quick Command 写在:

text 复制代码
~/.hermes/config.yaml

不要写到项目目录里的普通 YAML 文件,也不要写到其他 profile 的配置里。

如果使用 Hermes profile,需要确认当前会话使用的是哪个 profile。不同 profile 有不同的配置、Skill 和记忆目录。

YAML 缩进是否正确

YAML 对缩进敏感。下面是正确写法:

yaml 复制代码
quick_commands:
  greet:
    type: exec
    command: "printf 'Hello, nice to meet you!\n'"

  wechat-gzh:
    type: alias
    target: /markdown-to-wechat-richtext

常见错误是缩进错位,例如把 type 写到和 greet 同一层,或者把第二个命令写到 greet 里面。

命令名不要带斜杠

配置 key 不写 /

yaml 复制代码
wechat-gzh:
  type: alias
  target: /markdown-to-wechat-richtext

用户输入时才写 /

text 复制代码
/wechat-gzh abc/def.md

这是很多人第一次配置时容易写错的地方。

修改配置后是否需要重启

有些配置在当前会话里不会立刻重新加载。稳妥做法是保存配置后重启 Hermes CLI,或者开启新会话再测试。

如果是在 Gateway 场景,比如 Telegram、Discord、Slack 里使用,也可能需要重启 Gateway。

Skill 是否真的存在

如果 /wechat-gzh 最终指向:

text 复制代码
/markdown-to-wechat-richtext

那本地就必须真的有这个 Skill,并且 Hermes 能识别到它。

可以用 Hermes 的 Skill 管理命令检查,或者在会话里直接测试原始命令:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

如果原始命令都不工作,/wechat-gzh 这个 alias 也不会工作。alias 只是改写命令,不会修复目标命令本身的问题。

十、什么时候需要更正式的 Slash Command

Quick Command 很方便,但它不是万能的。

如果只是给常用命令起别名、执行脚本、包装已有 Skill,Quick Command 足够好。

但如果需要下面这些能力,就应该考虑更正式的实现方式:

  • 命令需要复杂参数解析
  • 命令需要交互式确认
  • 命令要出现在完整帮助和自动补全体系里
  • 命令要跨平台稳定分发给很多用户
  • 命令需要访问 Hermes 内部状态
  • 命令需要完整测试和权限控制

这时更适合做内置命令或插件命令。

可以这样选择:

需求 推荐方式
自己用的短命令 Quick Command
执行一条固定脚本 Quick Command exec
给已有 Slash Command 起别名 Quick Command alias
包装已有 Skill Skill + Quick Command alias
给团队分发完整扩展 插件命令
进入 Hermes 核心能力 内置 Slash Command

对大多数个人工作流来说,最实用的组合是:

text 复制代码
Skill 承载复杂流程
Quick Command 提供短入口

/wechat-gzh 就是这个组合的例子。

十一、总结

Slash Command 是 Agent 里的命令入口,不是普通 Prompt。

它的作用是把常用动作变成明确、短小、可重复的输入。命令系统会先解析命令名和参数,再决定调用内置逻辑、Quick Command、插件命令、Skill 命令或其他扩展能力。

在 Hermes 中,普通用户自定义命令最适合从 Quick Command 开始。

固定输出或脚本执行,用 exec

yaml 复制代码
quick_commands:
  greet:
    type: exec
    command: "printf 'Hello, nice to meet you!\n'"

给已有 Skill 命令起短别名,用 alias

yaml 复制代码
quick_commands:
  wechat-gzh:
    type: alias
    target: /markdown-to-wechat-richtext

输入:

text 复制代码
/wechat-gzh abc/def.md

实际等价于:

text 复制代码
/markdown-to-wechat-richtext abc/def.md

这里最关键的是参数传递机制:abc/def.md 不写在配置里,而是来自用户输入中跟在命令名后面的剩余文本。alias 会把这段文本追加到目标命令后面。

理解这一点后,Slash Command 就不再只是一个"以斜杠开头的神秘命令",而是可以被设计、组合和复用的 Agent 交互入口。

相关推荐
深蓝AI9 小时前
NVIDIA 发布 Nemotron 3 Embed:开源嵌入模型登顶 RTEB,RAG 检索精度全面提升
aigc
TrisighT14 小时前
Skill 写成 2000 字说明书?Claude 根本不读——路由器思维与渐进式披露
aigc·ai编程·claude
食尘者15 小时前
MacBook Pro M5Max 本地大模型推理实践
macos·aigc
倾颜15 小时前
AI 聊天刷新后记录全丢?用浏览器本地存储给 AI Chat 加一层"离线记忆"
前端·aigc
刘棕霆16 小时前
企业测试造数为什么这么难?我把熟手经验做成了一个可交付的造数 Skill
aigc·agent·测试
武子康16 小时前
HunyuanVideo 全家族选型:原版 13B / I2V / Avatar / Foley / 1.5 8.3B 怎么分工
人工智能·llm·aigc
一孤程16 小时前
AI辅助测试用例生成实战——用大模型把测试设计效率提升300%
人工智能·测试工具·ai·aigc·测试用例·测试·测试覆盖率
怕浪猫17 小时前
AI Agent 应用开发实战封面大集合
aigc·openai·ai编程
wangruofeng1 天前
8 小时 10000 星,xAI 把内部编码 Agent 开源了:Grok Build 的架构拆解
开源·github·aigc