前言
我刚开始用 Copilot Chat 时,基本都是直接打一整句自然语言。
比如解释这段代码、帮我修复这个错误、给这个函数写测试、优化一下这个方法。这样当然能用,但问题也明显:同样一类任务,每次都要重新组织提示词。尤其是在代码审查、补测试、修报错这些高频场景里,提示词写得不够具体,Copilot 的回答就容易发散。
Slash Commands 解决的就是这个问题。它把一些常见开发任务做成了斜杠命令,比如/explain、/fix、/tests、/doc。输入/后,Copilot Chat 会显示当前环境可用的命令。不同 IDE、不同上下文、不同扩展下能看到的命令会有差异,所以最稳的办法不是背一张固定命令表,而是在当前 Chat 输入框里输入/看可用项。
我更愿意把 Slash Commands 看成“任务意图快捷入口”。它不会替代清晰的问题描述,也不会自动理解所有项目规则。它的价值在于把常见动作变得更短、更明确,再配合#上下文引用、@workspace这类上下文能力,让 Copilot 更容易把回答落到当前代码里。
一、Slash Commands 适合处理高频小任务
Slash Commands 的用法很简单,在 Copilot Chat 输入框里输入/,再选择对应命令。它本质上是预设任务入口,帮你少写一大段提示词。
常见命令可以分成几类。
代码理解用/explain。当你打开一个陌生文件,或者接手一段别人写的逻辑时,它适合快速解释当前代码在做什么。
代码修复用/fix。当编辑器里已经有报错、类型错误或明显问题时,选中相关代码再执行/fix,比单纯问“这段代码怎么改”更聚焦。
测试生成用/tests。它适合围绕现有代码生成测试,尤其是已经有函数、类或模块时。需要注意的是,/tests更适合给已有代码补测试。如果你在做 TDD,还没有代码实现,直接用自然语言描述测试目标会更合适。
文档注释可以用/doc。它适合给函数、类或模块生成注释,尤其是公共 API、工具函数和复杂业务方法。
性能或可维护性问题可以尝试/optimize或/simplify。这两个命令并不是所有环境都一样可用,输入/时能看到就用,看不到就直接用自然语言描述你的优化目标。
这里有个使用习惯很重要:命令只负责说明任务类型,真正的质量还取决于上下文。
比如只写:
/fixCopilot 会根据当前文件和选中内容尝试修复,但它未必知道你希望保持 API 兼容、不能改数据库结构、不能引入新依赖。
更稳的写法是:
/fix 只修复当前 TypeScript 类型错误,不要改变函数签名,不要新增依赖。Slash Commands 不需要写得很长,但最好补上边界条件。尤其是修复类和优化类命令,少加一句限制,结果可能完全不同。
二、/explain 不只是解释代码,还适合接手旧项目
/explain是我最常用的命令之一。
接手一个旧项目时,真正费时间的地方通常不是某一行语法,而是搞清楚一段逻辑为什么这么写。这个函数处理了哪些边界?为什么失败时返回默认值?这里有没有隐含的业务规则?这些信息在代码里经常没有注释。
比如有这样一个函数:
functionparseUserPreferences(jsonString){constdefaults={theme:'light',language:'en',notifications:true};try{constparsed=JSON.parse(jsonString);return{...defaults,...parsed};}catch(e){returndefaults;}}如果只是问:
/explainCopilot 大概率会解释这个函数如何解析 JSON、如何合并默认配置、为什么使用try...catch。
但在真实项目里,我更建议继续补充问题:
/explain 重点解释这个函数的容错策略,以及哪些输入可能导致结果不符合预期。这样回答会更贴近开发判断。比如它可能指出:
如果 jsonString 是无效 JSON,会直接返回默认配置。 如果 parsed 里传入 theme: null,最终结果会覆盖默认 theme。 如果 parsed 里包含额外字段,这个函数不会过滤。这些才是维护代码时真正有价值的信息。很多旧代码表面上能运行,但隐含着“允许额外字段”“失败时静默降级”“默认值可被 null 覆盖”这类行为。/explain的价值不只是翻译代码,而是帮你更快找到这些行为边界。
它也适合代码审查前的预热。先选中关键函数跑一遍/explain,再问“这里有没有副作用”“这里是否可能破坏兼容性”,比直接从整个 PR 开始看更省力。
三、/fix 和 /tests 要配合约束使用
/fix很方便,但我不建议把它当成自动修复按钮随便点。
它适合处理范围明确的问题,比如类型错误、空值判断遗漏、异步调用没等待、明显的语法问题。遇到跨模块 Bug、业务状态错误、并发问题时,只靠/fix通常不够,需要先让 Copilot 分析调用链和上下文。
比如下面这个函数:
defcalculate_average(numbers):total=sum(numbers)returntotal/len(numbers)如果空列表进来,会出现除零错误。选中这段代码后使用:
/fix 处理空列表输入,保持返回值仍然是数字。得到的修复会更可控:
defcalculate_average(numbers):ifnotnumbers:return0total=sum(numbers)returntotal/len(numbers)如果不写“保持返回值仍然是数字”,Copilot 可能会选择抛异常、返回None,或者改成其他错误处理方式。它们不一定错,但可能和当前项目约定冲突。
/tests也一样。它能给已有函数生成测试,但最好告诉它测试框架、覆盖重点和命名风格。
比如这个函数:
defvalidate_email(email:str)->bool:ifnotemailor'@'notinemail:returnFalselocal,domain=email.split('@',1)ifnotlocalornotdomain:returnFalseif'.'notindomain:returnFalsereturnTrue可以这样写:
/tests 使用 pytest,为 validate_email 生成测试。重点覆盖空字符串、None、缺少 @、缺少域名、缺少本地部分、正常邮箱和带子域名邮箱。生成结果一般会比只写/tests更接近预期:
importpytestfromyour_moduleimportvalidate_emaildeftest_valid_email():assertvalidate_email("user@example.com")isTruedeftest_valid_email_with_subdomain():assertvalidate_email("user@mail.example.com")isTruedeftest_empty_string():assertvalidate_email("")isFalsedeftest_none_input():assertvalidate_email(None)isFalsedeftest_missing_at_symbol():assertvalidate_email("userexample.com")isFalsedeftest_missing_local_part():assertvalidate_email("@example.com")isFalsedeftest_missing_domain():assertvalidate_email("user@")isFalsedeftest_missing_dot_in_domain():assertvalidate_email("user@example")isFalse这段测试还有一个细节:原函数类型标注是email: str,但测试里传了None。如果项目严格使用类型检查,这个用例可能需要调整。也就是说,Copilot 生成的测试要审查,不能直接当成最终答案。它可以帮你补测试框架和覆盖思路,但边界条件是否符合项目设计,仍然要自己判断。
四、命令要和上下文引用一起用
Slash Commands 单独使用,适合当前选中代码很明确的场景。只要任务跨文件,就要补上下文。
VS Code 里可以用#明确引用文件、文件夹、符号、代码库、终端输出和工具结果。常见写法包括#file、#selection、#codebase、#terminalSelection。当前文件、当前选中内容、可见错误、Git 状态也会作为隐式上下文的一部分参与对话,但复杂问题最好显式引用。
比如你要解释当前选中的函数:
/explain #selection你要让 Copilot 从整个工作区找认证逻辑:
@workspace 这个项目的登录态是在哪里维护的?你知道问题涉及整个代码库,但不知道相关文件在哪里,可以写:
#codebase 找出订单状态从 pending 变成 paid 的完整调用链。你要让它结合终端错误输出修复问题,可以先选中终端里的报错,再写:
/fix #terminalSelection 结合当前项目结构分析这个测试失败原因。这里要注意不同 IDE 的上下文能力不完全一样。VS Code 支持#引用文件、文件夹、符号、代码库和终端输出,也支持@workspace、@terminal、@vscode这类参与者。Visual Studio、JetBrains、Xcode 里可用的命令和引用方式会有差异。实际使用时,以当前输入框弹出的候选项为准。(Visual Studio Code)
我现在的习惯是:小代码块用#selection,跨文件问题用#codebase,项目结构问题用@workspace,终端错误用#terminalSelection或@terminal。这样比单纯靠 Copilot 猜上下文稳定很多。
五、把项目规则写进自定义指令
Slash Commands 能告诉 Copilot 这次要做什么,但项目规则要靠自定义指令长期保存。
比如团队要求 React 组件必须用函数式组件,API 请求统一用fetch,禁止使用any,所有外部输入必须做 Zod 校验。如果每次都在提示词里重复这些规则,很快就会烦。更好的做法是放到.github/copilot-instructions.md。
一个简单示例:
# Project rules - This project uses React 18 and TypeScript. - Use functional components and React Hooks. - Use `fetch` for API requests. Do not introduce `axios`. - Avoid `any`. Use specific types or `unknown` with type narrowing. - Validate external input with Zod. - Keep API response shapes backward compatible. - Do not modify database migration files unless explicitly requested.如果不同文件需要不同规则,可以继续拆成.github/instructions/*.instructions.md,用applyTo指定适用范围。VS Code 会把仓库级指令和匹配到的文件级指令加入上下文。适合把 React、测试、API、数据库、GitHub Actions 这类规则分开维护。(Visual Studio Code)
例如测试文件可以单独写:
--- applyTo: "**/*.test.ts,**/*.spec.ts" --- - Use Vitest syntax. - Prefer explicit assertions over snapshot tests. - Cover success path, failure path, and boundary input. - Do not mock the module under test itself.这样再使用/tests时,Copilot 更容易生成符合项目风格的测试。
这里不要把自定义指令写成“写优雅代码”“遵循最佳实践”。这类话太宽,实际效果有限。更有用的是项目里不容易从语法推断出来的规则,比如“不要改 migration 文件”“API 响应字段必须兼容旧客户端”“后台任务日志必须包含 traceId”。
总结
Slash Commands 的价值,不是让 Copilot 变得更神,而是让常见操作更稳定。
/explain适合理解旧代码和复杂逻辑。真正有价值的用法,是让它解释设计意图、边界行为和潜在风险,而不是只翻译每一行代码。
/fix适合处理范围明确的问题。使用时最好补充约束,例如不改函数签名、不引入新依赖、不改变返回结构。越是业务代码,越要限制修改范围。
/tests适合给已有代码补测试。它能快速生成测试骨架和常见边界用例,但测试是否符合类型约束、业务预期和项目习惯,仍然要人工审查。
#上下文引用和@参与者能显著提升回答质量。选中代码就用#selection,跨文件问题用#codebase,项目结构问题用@workspace,终端问题用@terminal。
项目规则要放进自定义指令。Slash Commands 解决单次任务意图,自定义指令解决长期项目约束。两者配合起来,Copilot 的输出才会更贴近真实项目。
我的建议是先把最常用的三个场景跑顺:解释旧代码、修复当前错误、给关键函数补测试。等这三个流程稳定后,再加入#codebase、@workspace和.github/copilot-instructions.md。这样不会一下子把 Copilot 用得太复杂,也能慢慢形成自己的 AI 编码工作流。