GitHub Copilot 使用指南:提示、技巧和用例
GitHub Copilot官方文档: https://docs.github.com/zh/copilot/using-github-copilot/prompt-engineering-for-github-copilot
在这份 GitHub Copilot 提示指南中,两位 GitHub 开发者倡导者 Rizel 和 Michelle 将分享向人工智能结对程序员传达所需结果的示例和最佳实践。
Rizel Scarlett & Michelle Duke
2023 年 6 月 20 日 | 2024 年 12 月 18 日更新
人工智能生成编码工具正在改变开发者处理日常编码任务的方式。从记录我们的代码库到生成单元测试,这些工具正在帮助我们加速工作流程。然而,正如任何新兴技术一样,总有一个学习曲线。因此,无论是新手还是经验丰富的开发者,当基于人工智能的编码助手无法生成他们想要的结果时,有时会感到沮丧。(这听起来熟悉吗?)
例如,当要求 GitHub Copilot 使用 p5.js 绘制一个冰淇淋🍦时,一个用于创意编码的 JavaScript 库,我们继续收到无关的建议,有时甚至没有任何建议。但当我们更多地了解了 GitHub Copilot 处理信息的方式后,我们意识到我们需要调整我们的沟通方式。
这里有一个 GitHub Copilot 生成无关解决方案的例子:
当调整我们的指令时,我们能够生成更精确的结果:
我们既是开发者也是 AI 爱好者。我,Rizel,使用 GitHub Copilot 构建了一个浏览器扩展;一个石头、剪刀、布游戏;以及发送推文。而我,Michelle,在 2016 年成立了一家 AI 公司。我们都是 GitHub 的 DevRel,喜欢分享我们使用 GitHub Copilot 的最佳建议。
在这个 GitHub Copilot 指南中,我们将涵盖:
- 什么是“提示”以及什么是提示工程(提示:这取决于你是在和开发者还是和自动学习研究员交谈)
- 三个最佳实践和三个额外建议,用于使用 GitHub Copilot 创建提示
- 这是一个你可以尝试使用 GitHub Copilot 来帮助你构建浏览器扩展的例子
进步胜于完美
即使我们有使用 AI 的经验,我们也认识到每个人在使用生成式 AI 技术时都处于试错阶段。我们还知道提供通用提示制作技巧的挑战,因为模型各不相同,开发者正在解决的问题也是如此。这并不是一个包罗万象的指南。相反,我们正在分享我们在提示制作方面所学到的知识,以加速在这个软件开发新时代的集体学习。
什么是提示以及什么是提示工程?
这取决于你跟谁交谈。
在生成式 AI 编码工具的背景下,提示(prompt)的含义可能因人而异,这取决于你是询问构建和微调这些工具的机器学习(ML)研究人员,还是询问在他们的集成开发环境(IDE)中使用这些工具的开发者。
为此指南,我们将从使用 IDE 中生成式 AI 编码工具的开发者视角定义术语。但为了给您一个全面的了解,我们还在图表中添加了机器学习研究者的定义。
提示 | 提示工程 | 上下文 | |
---|---|---|---|
开发者 | 代码块、单独的代码行或开发者编写的自然语言注释,用于从 GitHub Copilot 生成特定建议 | 提供 IDE 中的说明或注释以生成特定的编码建议 | 开发者提供的详细信息,以指定从生成式 AI 编码工具期望的输出 |
机器学习研究者 | 编译 IDE 代码及其相关上下文(IDE 注释、打开的文件中的代码等),这些上下文由算法持续生成并发送到生成式 AI 编码工具的模型 | 创建将生成提示(IDE 代码和上下文的汇编)的大语言模型算法 | 细节(如来自您打开的文件的数据以及光标前后您编写的代码)作为关于代码的附加信息发送到大型语言模型(LLM) |
GitHub Copilot 提示编写最佳实践 3 条
1. 以一个高层次的目标设定场景。
这非常有帮助,如果你有一个空白文件或空的代码库。换句话说,如果 GitHub Copilot 对你想要构建或完成的事情没有任何上下文,为 AI 配对程序员设定场景可能非常有用。在深入细节之前,先给 GitHub Copilot 一个大致的描述,帮助它生成你想要的内容是有益的。
programming with this person?翻译: 将这个过程想象成与某人交谈:我应该如何分解问题以便我们一起解决?我将如何与这个人进行结对编程?
例如,在 Next.js 中构建 Markdown 编辑器时,我们可以写一个这样的注释
/*
Create a basic markdown editor in Next.js with the following features:
- Use react hooks
- Create state for markdown with default text "type markdown here"
- A text area where users can write markdown
- Show a live preview of the markdown text as I type
- Support for basic markdown syntax like headers, bold, italics
- Use React markdown npm package
- The markdown text and resulting HTML should be saved in the component's state and updated in real time
*/
这将提示 GitHub Copilot 生成以下代码,并在不到 30 秒内生成一个非常简单、未加样式的但功能齐全的 Markdown 编辑器。我们可以用剩下的时间来美化组件:
注意:此级别的细节有助于您创建更符合期望的输出,但结果可能仍然是不确定的。例如,在注释中,我们提示 GitHub Copilot 创建默认文本,内容为“在此处输入 Markdown”,但它生成了“Markdown 预览”作为默认文本。
2. 让你的提问简单具体。目标是收到 GitHub Copilot 的简短输出。
一旦你向 AI 代码伙伴传达了你的主要目标,就要清晰地阐述它需要遵循的逻辑和步骤以实现该目标。GitHub Copilot 在你将目标分解时能更好地理解你的目标。(想象你正在写一个食谱。你会将烹饪过程分解成离散的步骤——而不是写一段描述你想要制作的菜肴的段落。)
让 GitHub Copilot 在每一步后生成代码,而不是一次性生成一大堆代码。
这里是一个我们为 GitHub Copilot 提供逐步反转函数指令的示例:
3. 给 GitHub Copilot 举一两个例子。
从示例中学习不仅对人类有用,也对您的 AI 编程伙伴有用。例如,我们想要从以下数据数组中提取名称并将其存储在新数组中:
const data = [
[
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 }
],
[
{ name: 'Bob', age: 40 }
]
];
当我们没有向 GitHub Copilot 展示一个示例时……
// Map through an array of arrays of objects to transform data
const data = [
[
{ name: 'John', age: 25 },
{ name: 'Jane', age: 30 }
],
[
{ name: 'Bob', age: 40 }
]
];
const mappedData = data.map(x => [x.name](http://x.name/));
console.log(mappedData);
// Results: [undefined, undefined]
它生成了错误的 map 使用:
const mappedData = data.map(x => [x.name](http://x.name/));
console.log(mappedData);
// Results: [undefined, undefined]
相比之下,当我们提供了一个例子……
// Map through an array of arrays of objects
// Example: Extract names from the data array
// Desired outcome: ['John', 'Jane', 'Bob']
const data = [
[{ name: 'John', age: 25 }, { name: 'Jane', age: 30 }],
[{ name: 'Bob', age: 40 }]
];
const mappedData = data.flatMap(sublist => sublist.map(person => person.name));
console.log(mappedData);
我们得到了我们想要的结果。
const mappedData = data.flatMap(sublist => sublist.map(person => person.name));
console.log(mappedData);
// Results: ['John', 'Jane', 'Bob']
了解更多关于人工智能训练的常见方法,例如零样本学习、单样本学习和少样本学习。
三个使用 GitHub Copilot 撰写提示的额外技巧
这里有三个额外的技巧,可以帮助您与 GitHub Copilot 进行对话。
1. 尝试你的提示。
仅仅对话比科学更像是艺术,提示制作也是如此。因此,如果你第一次尝试没有得到你想要的结果,请根据上述最佳实践重新制作你的提示。
例如,下面的提示很模糊。它没有为 GitHub Copilot 提供任何上下文或边界以生成相关建议。
# Write some code for grades.py
我们迭代了提示词以使其更具体,但仍然没有得到我们想要的确切结果。这提醒我们,在提示词中添加具体性比听起来更难。一开始就很难知道应该包含哪些关于你目标的细节,以便从 GitHub Copilot 生成最有用的建议。这就是为什么我们鼓励实验。
以下提示的版本比上面的更具体,但它并没有明确定义输入和输出要求。
# Implement a function in grades.py to calculate the average grade
我们再次通过设定边界和概述我们希望函数执行的操作来对提示进行了实验。我们还重新措辞了注释,使函数更加清晰(给 GitHub Copilot 一个明确的意图来验证)。
这次,我们得到了我们想要的结果。
# Implement the function calculate_average_grade in grades.py that takes a list of grades as input and returns the average grade as a floating-point number
2. 保持几个相关标签页打开。
我们没有确切的数量,你应该保持多少个标签页以帮助 GitHub Copilot 上下文化你的代码,但根据我们的经验,一个或两个是有帮助的。
GitHub Copilot 使用一种称为相邻标签的技术,允许 AI 配对程序员通过处理你 IDE 中打开的所有文件,而不是仅处理你正在工作的单个文件,来使你的代码具有上下文。然而,GitHub Copilot 并不保证将所有打开的文件视为你代码的必要上下文。
3. 使用良好的编码实践。
这包括提供描述性的变量名和函数,以及遵循一致的编码风格和模式。我们发现与 GitHub Copilot 合作鼓励我们遵循我们在整个职业生涯中学到的良好编码实践。
例如,这里我们使用了描述性的函数名,并遵循了代码库利用蛇形命名法的模式。
def authenticate_user(username, password):
因此,GitHub Copilot 生成了一个相关的代码建议:
def authenticate_user(username, password):
# Code for authenticating the user
if is_valid_user(username, password):
generate_session_token(username)
return True
else:
return False
与下面的例子进行比较,我们在其中引入了不一致的编码风格,并给我们的函数取了一个糟糕的名字。
def rndpwd(l):
而不是建议代码,GitHub Copilot 生成了一个注释,说:“代码在这里。”
def rndpwd(l):
# Code goes here
Stay smart 保持聪明
生成式 AI 编码工具背后的代码旨在从其训练数据中寻找和推断模式,将这些模式应用于现有语言,然后生成遵循这些模式的代码。鉴于这些模型规模庞大,它们可能会生成尚未存在的代码序列。就像您会审查同事的代码一样,您应该始终评估、分析和验证 AI 生成的代码。
一个实践示例
尝试提示 GitHub Copilot 构建一个浏览器扩展。
要开始,您需要安装并打开 GitHub Copilot 到您的 IDE 中。