技术速递|为 Copilot 编写更佳自定义指令的 5 个技巧
要是连一款应用是做什么的都不知道,根本没法为它写代码!GitHub Copilot 也是如此——而项目概述指令文件,恰好能在这一点上发挥关键作用。你的指令文件开头,应当像“电梯演讲”一样概括应用。比如:这款应用是什么?目标用户是谁?核心功能有哪些?内容无需冗长,只需用几句话搭建好背景框架即可。以下是指令文件中项目概述的示例:本网站为宠物领养机构提供支持服务。机构可入驻平台,管理自身线下站点、待领养
作者:Christopher Harrison
排版:Alan Wang
本指南提供了编写有效的 GitHub Copilot 自定义指令的 5 个关键技巧,内容涵盖项目概述、技术栈、编码规范、结构和资源,旨在帮助开发者获得更优质的代码建议。
如果你读过我的文章,或者听过我的演讲,你很可能已经听过我那个带点调侃的玩笑:“别对 Copilot 搞消极对抗那一套。”
不过,这个玩笑背后其实有个认真的观点:Copilot 在得到合适的上下文时才能发挥最佳效果。它就像一个新加入的队友,并不能读心(尽管有时看起来像能读心一样)。
Copilot 通常能大致推断出你在做什么以及怎么做,但如果你能把关键点说明清楚——比如你在构建什么、使用的技术栈有哪些、需要遵循什么规则等等——就能避免很多误解和错误。
这也是为什么指令文件如此重要。它能为 Copilot 提供你团队成员通过项目经验才掌握的背景信息和知识。
其中的核心就是 copilot-instructions.md
文件。每一次 Copilot 的对话或 Agent 请求,都会读取它。
那么,这个文件应该怎么写呢?
为了帮你避免“面对空白文件无从下手”的困境,我整理了每个指令文件都应该包含的五个要点(还会额外附赠一个小技巧——让 Copilot 自己帮你写这个文件)。
在开始之前
在深入更多细节之前,我想先分享一个重要建议:别想太多。撰写说明文档并没有一套固定的 “标准流程”。生成式 AI 的本质是概率性的 —— 这意味着即便是相同的请求,实际输出的结果也可能不同。你的目标不是追求 “绝对正确”,而是 “优化概率”:尽可能引导 Copilot,让它更频繁地给出你期望的答案。
下面提到的 5 部分内容(以及附赠技巧)并非 “强制要求”,而是 “参考建议”。根据我的经验,只要你的指令文件中包含了这些内容,或者至少涵盖了这些内容所指向的关键信息,Copilot 给出的建议质量就会大幅提升。
你可以把这些内容当作 “起点”,再结合自身项目特点、使用的模型类型,以及与 Copilot 的互动经验,不断尝试和调整优化。
为 GitHub Copilot 提供项目概述
要是连一款应用是做什么的都不知道,根本没法为它写代码!GitHub Copilot 也是如此——而项目概述指令文件,恰好能在这一点上发挥关键作用。
你的指令文件开头,应当像“电梯演讲”一样概括应用。比如:这款应用是什么?目标用户是谁?核心功能有哪些?内容无需冗长,只需用几句话搭建好背景框架即可。
以下是指令文件中项目概述的示例:
Contoso Companions
本网站为宠物领养机构提供支持服务。机构可入驻平台,管理自身线下站点、待领养宠物信息,并发布相关活动;潜在领养者则能搜索所在地区的可领养宠物、了解各类领养机构,还可提交领养申请。
上述示例清晰、直接且简洁。你无需写出一份“大宪章”,但关键在于,要让 Copilot 从宏观层面了解你正在推进的项目目标。顺便提一句,这个示例应用绝不是我用来说服自己领养新宠物的借口(说真的,真不是,我可没在自我暗示)。
明确你在项目中使用的技术栈
在确定你要构建的内容之后,下一个关键点就是明确你是用什么来构建它的。这包括你使用的后端与前端技术、调用的 API,以及目标测试套件。毕竟,用来创建网站的框架数量本就不断增长。举个例子,或许在你读完这篇博文的时间里,已经有三个新的 JavaScript 框架发布了!
在编写指令文件时,你不需要化身 George RR Martin,写出成段成段的技术细节。相反,可以考虑列出你所使用的技术栈,并加上一两条关于它们用法的简要说明。这将帮助 Copilot 理解它要生成代码的环境。
以下是我工作中使用的一个快速示例,供参考:
## 使用的技术栈
### 后端
- 使用 Flask 作为 API
- 数据存储在 Postgres 中,使用 SQLAlchemy 作为 ORM
- 为开发、测试和生产环境分别配置了数据库
- 在端到端测试中,会新建并填充一个数据库,测试完成后再删除
### 前端
- 使用 Astro 管理核心站点与路由
- 使用 Svelte 实现交互功能
- 使用 TypeScript 编写所有前端代码
### 测试
- 使用 Unittest 进行 Python 测试
- 使用 Vitest 进行 TypeScript 测试
- 使用 Playwright 进行端到端测试
明确你的编码规范
在创建第一个 Pull Request 之前,你需要清楚应该遵循哪些编码规范。其中一部分是关于代码应该如何编写的。比如说,我们在 JavaScript 或 TypeScript 中是否使用分号?Python 是否使用类型提示?使用 Tab 还是空格?(唯一正确答案是:使用分号、使用类型提示,以及——用空格。不接受反驳。)
根据你的项目结构,你可以把编码规范写进技术栈指令文件中。但我通常更倾向于单独设立一个规范部分,因为很多规范会适用于多个语言。我发现这样更便于阅读,而可读性对于可维护性至关重要,而且不同语言和框架之间往往存在共通的指导原则。
你也可以考虑为特定类型的文件使用单独的 .instructions 文件来定义规范,例如所有 .astro
或 .jsx
文件,或者遵循 /tests/test_*.py
命名模式的单元测试文件。
专业提示
人们很容易陷入一种循环,不断尝试去寻找给 Copilot 编写提示词或构建指令文件的“完美方式”。但实际上,一个“不完美”的指令文件也远比完全没有文件的效果要好得多。指令文件也应该随着时间演进,就像文档一样。(当然,我们的文档都是随时保持更新的,对吧?)我强烈建议你多做尝试,找出最适合的方法,不要让“完美”成为“良好”的敌人。
这是我自己工作中的另一个示例:
## 项目与代码规范
- 在任何支持类型提示的语言中,始终使用类型提示
- JavaScript/TypeScript 必须使用分号
- 必须编写单元测试,并且在提交 PR 前必须全部通过
- 单元测试应聚焦于核心功能
- 必须编写端到端测试
- 端到端测试应聚焦于核心功能
- 端到端测试应验证可访问性
- 始终遵循良好的安全实践
- 遵循 RESTful API 设计原则
- 在可行时使用脚本来执行操作
解释你的项目结构
正如编写代码有无数种框架和方式一样,项目结构也有看似无限的组织方法。比如,在一个 monorepo 结构中,你的前端代码可能放在名为 frontend
的文件夹里。或者叫 front-end
。或者 front_end
。或者 client
。甚至 web
……
你大概已经明白我要说什么了。
虽然 Copilot 大概率能自己推断出来,但一次简单的 ls
命令就能得出答案。不过,在自定义指令文件中列出项目结构,既能帮 Copilot 省点功夫,也给了你一个机会去提供更多关于文件夹内容的上下文信息。
以下是一个示例:
## 项目结构
- server/ :Flask 后端代码
- models/ :SQLAlchemy ORM 模型
- routes/ :按资源组织的 API 端点
- tests/ :API 的单元测试
- utils/ :工具函数与辅助方法,包括数据库调用
- client/ :Astro/Svelte 前端代码
- src/components/ :可复用的 Svelte 组件
- src/layouts/ :Astro 布局模板
- src/pages/ :Astro 页面与路由
- src/styles/ :CSS 样式表
- scripts/ :开发、部署与测试脚本
- docs/ :项目文档(需始终保持同步)
指引 GitHub Copilot 使用可用资源
几乎每个项目都有一套可用的脚本或资源来辅助开发。这些可能是用于简化环境搭建或运行测试的脚本,也可能是用于生成代码或模板的软件工厂。特别是随着 VS Code 中 MCP 支持以及 Copilot 编码 Agent 的引入,为 Copilot 的 Agent 提供了更多可用工具。
我们已经确认 Copilot 能够发现可用资源,但通过自定义指令文件提供一些指向正确方向的提示,可以提升其准确性和运行速度。
下面是一个示例:
## 资源
- scripts 文件夹
- start-app.sh:安装所有依赖库并启动应用
- setup-env.sh:安装所有依赖库
- test-project.sh:安装所有依赖库,并运行单元测试和端到端测试
- MCP 服务器
- Playwright:用于生成 Playwright 测试或与网站交互
- GitHub:用于与代码仓库和待办事项(backlog)交互
额外提示:让 GitHub Copilot 帮你创建自定义指令文件
创建指令文件没有一种完美的方法,有总比没有好。但我们都希望尽量做得正确,或者尽量接近正确。希望上面的指南已经给了你一些灵感!
然而,实际去写文件仍然是一个问题,这可能会让你再次面对“面对空白文件无从下手”的困境。
幸运的是,Copilot 可以帮助你更好地帮助自己!
你可以在 IDE 中使用 Copilot Agent 模式,或者在 GitHub 仓库中为 Copilot 分配一个 Issue,请它帮你生成指令文件。生成的文件可以直接使用,也可以根据需要进行编辑。我们的 Copilot 官方文档中甚至提供了推荐的提示语,用于生成指令文件!精简版的推荐提示如下:
你的任务是通过添加 .github/copilot-instructions.md 文件,将此仓库“接入”编码 Agent。文件应包含信息,说明当智能体首次接触该仓库时,如何能够最高效地工作。
每个仓库只需执行一次此任务,做好这项工作可以显著提升 Agent 的工作质量,因此请慢慢来,仔细思考,并在撰写指令前进行充分搜索。
## 目标
- 文档化现有项目结构和技术栈
- 确保遵循既定的开发规范
- 尽量减少 bash 命令和构建失败
## 限制
- 指令文件不得超过 2 页
- 指令应适用于整个项目
## 指南
请确保包含以下内容:
- 应用功能概述
- 使用的技术栈
- 编码规范
- 项目结构
- 已有工具和资源
## 步骤
- 对代码库进行全面盘点,查找并查看:
- README.md、CONTRIBUTING.md 及其他所有文档文件
- 搜索代码库中类似 HACK、TODO 等标记的解决方案
- 所有脚本,尤其是与构建、仓库或环境设置相关的脚本
- 所有项目文件
- 所有配置文件和 lint 文件
- 记录其他任何可以帮助智能体减少探索或尝试失败的 bash 命令时间的步骤或信息
## 验证
使用新创建的指令文件实现一个示例功能。利用在构建新功能过程中遇到的失败或错误经验,进一步完善指令文件。
使用上述提示语可以帮助你节省时间,但更重要的是,它还能帮助你理清对任意项目的思路和目标。
关于指令文件的最后说明
需要说明的是,提供指令并不能保证生成的代码完美无缺。但拥有一个良好的指令文件,是提升 Copilot 代码建议质量重要的第一步。如果你问我,对于任何使用 Copilot 的项目,拥有一个 copilot-instructions.md 文件都是必备的。
再次强调——它不需要完美。以以下几个部分为起点,就能打下坚实的基础:
- 你正在构建内容的简要介绍
- 使用的框架和技术栈
- 编码规范及其他项目指南
- 项目结构及资源位置
- 可用于自动化和任务处理的资源
从这里出发,你可以进一步探索 .instructions 文件,来为 Copilot 提供更具体的指导。但这一切都始于 copilot-instructions.md。
阅读官方文档,了解更多关于 GitHub Copilot 自定义指令的信息 >
更多推荐
所有评论(0)