凛冬已至,疯王犹在炉边添野火
为什么要单独理解 Slash Command用 Agent 做事时经常会遇到以/开头的输入/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 会话中的一种“命令式输入”。它通常以/开头后面跟命令名和可选参数。例如/help /model gpt-5.1 /skill markdown-to-wechat-richtext /wechat-gzh abc/def.md一条 Slash Command 通常可以拆成两部分/wechat-gzh abc/def.md └─────────┘ └────────┘ 命令名 参数也就是命令名/wechat-gzh 参数abc/def.mdAgent 收到这类输入后一般不会马上把整句话当作自然语言丢给模型而是先执行类似下面的流程用户输入一条以 / 开头的消息 ↓ Agent 判断这是 Slash Command ↓ 解析命令名和参数 ↓ 查找命令注册表、Quick Command、插件命令或 Skill 命令 ↓ 执行对应逻辑 ↓ 返回结果或者改变当前会话状态所以 Slash Command 的关键点不是“让模型理解得更好”而是“让系统更确定地触发一个动作”。举个简单例子帮我开一个新会话这是自然语言Agent 需要理解你的意图。而/new这是命令系统可以直接把它识别为“开启新会话”。三、Slash Command 解决了什么问题Slash Command 的价值是把常用操作变成短小、稳定、可重复的入口。在 Agent 使用过程中有些事情不适合每次都用自然语言描述。比如查看帮助新建会话清理上下文切换模型加载 Skill执行固定脚本给已有能力起一个短别名在聊天平台里触发运维检查如果每次都用自然语言表达容易出现两个问题。第一个问题是啰嗦。比如“帮我重新开启一个新的上下文并且不要继承当前对话历史”不如/new直接。第二个问题是歧义。自然语言要经过模型理解模型可能会解释、追问、或者做出和预期不一致的判断Slash Command 的命令名和参数结构更固定适合控制类动作。我通常把 Slash Command 分成四类来看。会话控制命令这类命令改变当前会话状态例如/new /clear /retry /undo /compress /quit它们不是用来完成业务任务的而是用来管理会话本身。配置和状态命令这类命令用于查看或修改 Agent 运行状态例如/model /config /tools /status /usage它们的特点是用户希望得到一个确定的系统行为而不是一段开放式回答。能力加载命令这类命令用于加载某种能力或工作流例如 Hermes 中的/skill markdown-to-wechat-richtext也可以是某个 Skill 被注册成动态命令后直接调用/markdown-to-wechat-richtext abc/def.md这里的重点是Slash Command 只是入口真正执行任务的可能是 Skill、工具、插件或 Agent 工作流。用户自定义命令用户自定义命令是本文后面重点讨论的部分。比如希望输入/greet直接输出Hello, nice to meet you!或者希望输入/wechat-gzh abc/def.md实际调用本地已有的/markdown-to-wechat-richtext abc/def.md这就是 Slash Command 作为“快捷入口”的典型用法。四、开源项目为什么安装后能提供自己的命令很多开源项目安装后可以在某个 Agent 里使用自己的 Slash Command。这里容易产生一个误解好像所有 Agent 都有一套统一的 Slash Command 插件标准。实际情况不是这样。不同 Agent 的实现方式差别很大。一个项目能提供命令通常是因为它适配了某个 Agent 的扩展机制。常见方式有几种。文件型命令有些 Agent 会约定一个命令目录。项目只要把 Markdown 文件放进去Agent 就会把这些文件识别成命令。典型形式类似.claude/commands/xxx.md ~/.claude/commands/xxx.md这种模式下Markdown 文件往往不是普通文档而是一个 Prompt 模板。用户输入/xxx后Agent 加载对应模板再把参数拼进去执行。这种方式很适合开源项目分发自己的工作流例如/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 配置文件里~/.hermes/config.yamlQuick Command 支持两种类型exec aliasexec用来执行本地 shell 命令适合固定输出、系统检查、脚本执行。alias用来把一个短命令改写到另一个 Slash Command适合给已有命令、Skill 命令或复杂命令起别名。官方文档里的表达也很直接Quick Commands 可以把一个短 Slash Command 映射到 shell 命令或者映射到另一个 Slash Command。内置 Slash Command如果要做系统级命令就需要改 Hermes 源码。大体思路是在命令注册表里增加命令定义。在 CLI 或 Gateway 的命令处理逻辑里增加 handler。如有必要补充帮助信息、自动补全、平台映射和测试。这种方式适合真正属于 Hermes 核心能力的命令例如会话控制、配置管理、工具管理等。普通用户只是想加一个快捷命令时不建议直接走这条路。插件命令插件命令适合可分发扩展。如果一个能力不应该进入 Hermes 核心但又希望安装后自动多出命令就可以做成插件。插件方式比 Quick Command 更重但比直接改核心源码更适合分发。Skill 动态命令Hermes 还支持把已安装 Skill 当作动态命令来调用。例如本地有一个 Skillmarkdown-to-wechat-richtext它可以用于把 Markdown 文章转换成微信公众号编辑器友好的富文本 HTML 片段。如果这个 Skill 可以作为动态命令调用那么原始调用可能是/markdown-to-wechat-richtext abc/def.md这里/markdown-to-wechat-richtext是入口abc/def.md是传给这个 Skill 的文件路径参数。后面要做的/wechat-gzh本质上就是给这条较长的 Skill 命令起一个短别名。六、实践一用 Quick Command 实现/greet先从最简单的例子开始实现一个/greet命令。目标效果是/greet输出Hello, nice to meet you!这个命令不需要读取文件不需要调用 Skill也不需要让大模型参与推理。它只是返回一句固定文本所以最适合用 Quick Command 的exec类型。配置写法打开 Hermes 配置文件~/.hermes/config.yaml加入下面配置quick_commands: greet: type: exec command: printf Hello, nice to meet you!\n