GitHub Copilot 教程:提示词、技巧和用例
本文是一篇关于 GitHub Copilot 提示词的指南,重点是向大家展示如何与 AI 结对程序员沟通,获得预期的结果。

生成式 AI 编码工具正在改变开发人员处理日常编码任务的方式。从记录代码库到生成单元测试,这些工具都有助于加快工作流程。但是,对新兴技术的学习总不可避免会遇到各种各样的困难,比如 AI 编码助手输出的代码不符合要求。

例如,我们让 GitHub Copilot 使用 p5.js(一个基于 JavaScript 编程语言的创意编程库)绘制一个冰淇淋甜筒,却只得到无意义的建议,有时甚至没有建议。为什么呢?通过进一步了解 GitHub Copilot 处理信息的方式,就会发现我们的沟通方式需要调整。

在下面示例中, GitHub Copilot 生成了无意义的解决方案:

调整提示词后,就可以获得更准确的结果:

我们既是开发人员,也是 AI 爱好者。Rizel 曾使用 GitHub Copilot 构建了一个浏览器扩展,剪刀石头布游戏以及发送推文。Michelle 在 2016 年创办了一家 AI 公司。我们都是 GitHub 开发的拥护者,喜欢分享使用 GitHub Copilot 的心得。


本教程包括以下内容:

  • 提示词是什么?提示词工程是什么?(区别在于你的沟通对象是开发人员还是机器学习研究者)
  • 编写 GitHub Copilot 提示词的三个最佳实践以及三个技巧。
  • 使用 GitHub Copilot 构建浏览器扩展的示例。


保持进步

虽然我们都使用过 AI,但整体仍处于生成式 AI 技术的试错阶段。另外,模型不同导致的问题也各不相同,因此很难制定通用的提示词创建方法。因此,本文并不是一篇通用指南,只是一篇提示词制作经验的分享和集体学习。


提示词是什么?提示词工程又是什么?

答案因沟通对象而异。

在生成式 AI 编码工具中,提示词有不同含义,具体取决于与你沟通的是正在构建和微调这些工具的机器学习(ML)研究人员,还是在 IDE (集成开发环境)中使用这些工具的开发人员

本教程将以在 IDE 中使用生成式 AI 编码工具的开发人员的角度定义这些术语。另外,为方便读者了解全貌,我们也在图表中添加了 ML 研究人员定义。

提示词提示词工程上下文
开发人员代码块、单行代码或开发人员编写的自然语言注释,目的是让 GitHub 生成特定的建议;在 IDE 中提供指令或注释,以生成特定的编码建议;开发人员提供的详细上下文信息,目的是让生成式 AI 编码工具按照要求输出内容;
ML 研究人员IDE 代码和相关上下文(IDE 注释、打开文件中的代码等)的编译,由算法持续生成,并发送到生成式 AI 编码工具的模型中;创建算法,为大型语言模型生成提示词(IDE 代码和上下文的编译)算法作为代码的附加信息发送到大型语言模型(LLM)的细节(如打开文件中的数据以及在你在光标之前和之后编写的代码)。


编写 GitHub Copilot 提示词的三个最佳实践

1. 设定一个高层次目标。🖼

如果你有一个空白文件或空代码库,会非常有帮助。换句话说,如果 GitHub Copilot 不知道你想要构建什么,那么最好为 AI 结对程序员设定一个框架。先给 GitHub Copilot 一个大的框架说明,再补充具体细节,就可以让它生成你想要的代码。

给 GitHub Copilot 提示词时,要像与人对话一样思考——怎么先把大问题拆分为小问题,然后一起解决问题?如何与他/她结对编程?

例如,在 Next.jst 中创建 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. 给出简单具体的要求,以获取简洁的输出为目标。

向 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']


了解更多 AI 训练的常见方法,例如零样本学习、单样本学习和少样本学习


编写 GitHub Copilot 提示词的三个技巧

下列是与 GitHub Copilot 沟通的三个技巧。

1. 多试验提示词

对话是一门艺术而非科学,提示词也是如此。因此,如果你在第一次尝试时没有得到想要的结果,请按照上述最佳实践,重新编写提示词。

例如,下列提示词比较模糊,没有为 GitHub Copilot 提供上下文或限制。

# 为 grades.py 写一些代码

我们反复修改提示词,但仍然没有得到想要的结果,由此可见想把提示词修改得更具体并没有那么容易。因为往往在一开始,我们并不知道结果应该包含哪些细节。这也是我们鼓励大家多尝试的原因。

下面的提示词比上面的更具体,但没有明确定义输入和输出的要求。

# 在 grades.py 中执行一个函数来计算平均成绩

我们设置限制并概述希望函数做的任务,再次试验提示词。同时,我们还改写了注释,让函数更加清晰(让 GitHub Copilot 有明确的验证目标)。

这一次终于得到了我们想要的结果。

# 在 grades.py 中执行函数 calculate_average_grade,把成绩列表作为输入, 并以浮点数的形式返回平均成绩。

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 没有生成建议代码,而是生成了一个建议:“Code goes here”。

def rndpwd(l):
    # Code goes here

认真审查 AI 生成的代码

生成式 AI 编码工具背后的 LLM 旨在从训练数据中发现和推断模式,将这些模式应用于现有语言,然后生成遵循这些模式的代码。因为这些模型的规模非常庞大,它们生成的代码序列甚至可能还不存在。所以,你要像审查同事的代码一样,始终认真评估、分析和验证 AI 生成的代码。


实践案例 👩💻

试着用 GitHub Copilot 构建一个浏览器扩展

首先,要在 IDE 中安装并打开 GitHub Copilot。我们还可以使用 GitHub Copilot 聊天工具的早期预览版。每次当我们对代码有疑问时,就会使用它。如果你还没有 GitHub Copilot 聊天功能,可以注册并加入候补名单。在此之前,你可以将 GitHub Copilot 与 ChatGPT 配对使用。


更多生成式 AI 提示词编写指南



原文作者:Rizel Scarlett,Michelle Mannering
原文链接:https://github.blog/2023-06-20-how-to-write-better-prompts-for-github-copilot/
推荐阅读
相关专栏
开发者实践
182 文章
本专栏仅用于分享音视频相关的技术文章,与其他开发者和声网 研发团队交流、分享行业前沿技术、资讯。发帖前,请参考「社区发帖指南」,方便您更好的展示所发表的文章和内容。