GitHub Copilot是GitHub开发的最新工具,在OpenAI的帮助下自动完成代码。
Copilot通过上下文生成智能代码建议,如文档字符串、代码注释、函数名称,甚至文件名称。然后,它使用所有这些信息来建议代码片段,开发人员可以通过按下键盘上的Tab键轻松接受。
根据Copilot网站,它了解Python、JavaScript、TypeScript、Ruby和Go,以及其他几十种语言,因为它 "在数十亿行公共代码上受过训练"。虽然它目前仍处于有限的技术预览阶段,但有兴趣的人可以注册加入一个等待名单来试用它。
在这篇文章中,我们将探讨Copilot的主要功能,如何只用Copilot建立一个简单的应用程序,以及它的优点和缺点。
Copilot的主要功能
Copilot的主要功能是它的自动完成功能。例如,当输入一个功能描述时,Copilot会在用户完成之前完成整个功能。虽然这种自动完成功能与其他一般的自动完成功能相似,但Copilot的功能更胜一筹。
当继续写代码并添加更多注释时,Copilot开始通过其人工智能能力理解代码的整个上下文。有了上下文,它就能在句子中间自动完成注释。
例如,通过添加一个函数,它生成了整个注释和一个函数;在这种情况下,它想出了最后一个函数应该是一个乘法函数,如下图所示。
Copilot的另一个很酷的功能是能够看到10个整页的建议,而不是一个单行的建议,并选择最适合的代码。
要做到这一点,在Mac键盘上按^ + Return ,或在Windows上按Ctrl + Enter ,就可以打开建议列表,如下图所示。
你能只用GitHub Copilot来构建一个应用程序吗?
利用Copilot的功能,我想挑战一下自己,只用Copilot构建一个小型的应用程序。在这个挑战中,我想创建一个简单的随机报价应用,同时显示报价的情绪。
要做到这一点,我需要遵循一些规则,看看我可以从Copilot中获得多少好处。
首先,如果我遇到问题,我不能在网上搜索,包括使用Stack Overflow或文档。这让我看到是否有可能完全依靠Copilot的建议来创建工作代码。
第二条规则是,我不能自己写任何新的代码。然而,我可以写注释、变量、名称和函数名称来触发Copilot的建议。同样地,我也可以对建议的代码进行小的编辑。
最后,我可以触发Copilot的建议列表并接受其中一个,因为这是一个内置功能。
设置项目
我选择Next.js和React来建立这个项目,因为它们是我最熟悉的工具,可以帮助我更好地评估Copilot的性能。
由于React让开发者在构建应用程序时相当省事,而我想看看Copilot如何管理React组件。
对于Next.js来说,它提供了一个很好的起点,我不需要花很多时间来设置一切,而且它有内置的后端功能,使得它在调用不同的API端点时不会引发CORS错误。
虽然Next.js对于这个小项目来说似乎太强大了,但不需要事先安装其他依赖项,其集成的、易于使用的API功能使它成为这个挑战的好选择。
开发API端点
从开发API端点开始,我想要一个在GET 请求上返回随机报价的报价生成器和一个情感分析端点。情感分析端点需要接收一个字符串作为查询参数,并返回一个情感。
因为我不知道返回值是什么格式,所以我让Copilot来写,看看它能返回什么。
/api/get_quote GET 请求端点
为了使用Next.js创建两个端点,我在api 文件夹中创建了两个文件:get_quote.js 和get_sentiment.js 。Next.js就可以根据文件名来创建这些端点。剩下的就是在这些文件中定义处理函数,我让Copilot为我做这些。
对于get_quote 端点,我写了一个评论并选择了一个好的建议。
// get random quote from random API
点击评论,Copilot就会回应一个不同的选项列表,供我挑选。
我选择的建议是以下内容。
const getQuote = async () => {
const response = await fetch('https://quotes.rest/qod.json')
const quote = await response.json()
return quote.contents.quotes[0].quote
}
这个建议起了作用。我检查的其他建议几乎都是坏的,或者需要一个我没有的API密钥。这可能是因为Copilot是在GitHub的开源代码上培训的,有些端点可能已经过时了,这可能会让人感到沮丧。
此外,这个端点返回当天的报价,这意味着每次调用,我都会收到当天的相同报价,这不是我所期望的。相反,对于每个端点的调用,我想收到一个不同的随机报价。
对于这个端点的第二部分,我需要为这个端点创建一个处理程序,调用Copilot已经生成的函数。该处理程序是Next.js在客户端请求端点时调用的函数。
为了做到这一点,我声明了这个函数的名称,看看Copilot是否会建议正确的实现。
而Copilot又给了我一个惊喜。一切似乎都是正确的。
首先,它调用了getQuote 函数,并返回了从网络服务中收到的报价。然后,它将报价保存到常量中,并将检索到的报价返回给客户端的JSON。我唯一需要添加的是.status(200) ,以向客户端发送200 状态代码。
/api/get_sentiment GET 请求端点
对于get_sentiment 功能,我选择了Copilot的建议,不需要改变任何东西。
我输入了以下内容。
// determine if the text is positive or negative
然后,Copilot建议了以下代码,我使用了这个代码。
async function getSentiment(text) {
const response = await fetch(`http://text-processing.com/api/sentiment/`, {
method: "POST",
body: `text=${text}`,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
})
const json = await response.json()
return json.label
}
然而,对于端点部分,我不得不添加.status(200) ,类似于get_quote 端点。
以下是我提供给Copilot的内容。
export default async function handler(req
然后,Copilot建议如下,我选择了它。
export default async function handler(req, res) {
const sentiment = await getSentiment(req.query.text)
res.json({ sentiment })
}
Copilot又设法为我们提供了一个可行的解决方案,建议了正确的处理程序,并计算了get_sentiment 处理函数需要返回的内容。这个建议看起来与我们之前的建议相似。
接下来让我们看看Copilot如何处理React组件的生成。
React组件
对于前端,我需要几个指定的React组件和一个带有按钮的React控制器组件。这两个指定的组件需要显示文本:一个是报价文本,另一个是感言文本。
让我们看看Copilot如何处理创建这些React组件。
QuoteTextBox
我从QuoteTextBox 组件开始,它将展示一个简单的报价;我添加了以下评论,看看Copilot会有什么建议。
// React component to show a quote inside a div
const
Copilot推荐了一个简单的函数组件,我完全不需要修改。
const QuoteTextBox = (props) => {
const { quote } = props
return (
<div className="quote-text-box">
<p>{quote}</p>
</div>
)
}
export default QuoteTextBox
SentimentTextBox
为了建立情感文本框,我添加了以下评论。
// React component to show sentiment text inside a div
const
对于这个文本框,要找到合适的建议是比较麻烦的,我不得不滚动浏览大部分的建议,直到找到一个能与我的代码配合的建议。
const SentimentTextBox = (props) => {
// Get sentiment text from props
const sentimentText = props.sentimentText
// Return component
return (
<div className="sentiment-text-box">
{sentimentText}
</div>
)
}
// Export component
export default SentimentTextBox
清楚地了解对Copilot的期望很重要,因为它只是一个工具,开发者不能只依赖它给出的第一个建议。
我仍然需要回到这个组件中,将API返回的内容映射成可读的文本。例如,如果网络服务返回neg ,我需要将其映射为Negative 。
带有按钮的控制器组件
我还需要一个控制器组件来管理所有的逻辑。我创建的前两个React组件只是接收数据并将其呈现在屏幕上,但控制器组件需要管理API调用。
我首先输入了以下内容。
// React component that uses QuiteTextBox and SentimentTextBox and APIs to show quotes and sentiment with a button to generate new quotes.
const
然后,Copilot带来了这个建议。
const QuoteGenerator = ({quote, sentiment, onClick}) => {
return (
<div>
<QuoteTextBox quote={quote} sentiment={sentiment} />
<button onClick={onClick}>Generate New Quote</button>
<SentimentTextBox sentiment={sentiment} />
</div>
)
}
export default QuoteGenerator
Copilot建议的控制器组件似乎很基本;它缺乏API调用,没有使用正确的道具SentimentTextBox 。然而,Copilot确实提供了正确的结构,它只是需要一些调整来完成它。
然后,我只需要给控制器组件添加功能。我没有传递quote 、sentiment 、onClick ,而是要求Copilot生成它们。我还需要一些Hooks来存储从调用API得到的情感和报价数据。
对于Hooks,Copilot马上就知道我需要什么了。为了触发第一个Hook的建议,我开始输入一个评论,Copilot建议了正确的Hook。
然而,对于第二个Hook,我甚至不需要输入评论。我接受了第一个Hook的建议,移到下一行,Copilot立即建议第二个Hook。
虽然端点是正确的,但我仍然需要做一些改变来使它们发挥作用。我必须非常具体地询问我想要什么,否则,Copilot开始建议不同的网络服务。
我希望它只是调用已经创建的端点。此外,当我收到报价时,我需要特别调用getSentiment 端点,并将情感映射为人类可读的文本。
这就是我的最终版本,在我这边做了一些小改动之后。
const QuoteGenerator = () => {
// Hook to store text in state
const [quoteText, setQuoteText] = React.useState('')
const [sentimentText, setSentimentText] = React.useState('')
// Function to get quotes from API /api/get-quote
const getQuote = () => {
fetch('/api/get-quote')
.then(response => response.json())
.then(json => {
setQuoteText(json.quote)
getSentiment(json.quote)
})
}
// Function to get sentiment from API /api/get-sentiment\
const getSentiment = (text) => {
fetch('/api/get-sentiment?text=' + text)
.then(response => response.json())
.then(json => {
setSentimentText(json.sentiment)
})
}
// Function to be called when user clicks on button to generate new quote
const onClick = () => {
getQuote()
}
const mapSentimentToText = {
'neg': 'Negative',
'pos': 'Positive',
'neutral': 'Neutral'
}
return (
<div>
<QuoteTextBox quote={quoteText} />
<SentimentTextBox sentimentText={mapSentimentToText[sentimentText]} />
<button onClick={onClick}>Generate New Quote</button>
</div>
)
}
export default QuoteGenerator
最终的应用程序
在对我的简单的报价生成应用程序进行实验后,我发现Copilot提供了足够的帮助来创建一个简单的应用程序。
我的期望值并不高,最初以为我需要修改大量的代码才能使应用程序正常运行。
然而,Copilot让我吃惊。在一些地方,它给我的建议是无稽之谈,但在另一些地方,这些建议是如此之好,以至于我不敢相信Copilot会做出这些建议。
Copilot的优点和缺点
为了总结我使用Copilot的经验,我整理了使用它的优点和缺点,这样你就可以决定Copilot是否是你可以每天使用的东西。
Copilot的优点
使用Copilot的主要优点是它提供了类固醇的自动完成功能。作为一个自动完成工具,我相信它是目前市场上最好的;没有任何东西能像Copilot一样有用。
Copilot还向开发者展示了解决不同问题的多种方法,这些问题可能不是那么明显。当需要一个代码片段时,10个建议的功能是非常好的,通常可以用来代替Stack Overflow,以提高效率。
总而言之,Copilot使用起来很有趣。对于所有的技术极客来说,这是一个可以玩耍的新东西,它使日常工作变得更加有趣。
Copilot的缺点
虽然它的功能提供了更高的效率,但用户必须记住它是一个工具,而不是人类开发者的替代品。因为Copilot不是万能的,用户不能完全依赖它来完成他们所有的代码。它的大多数建议都需要修改以适应特定的需求。
最后,我注意到Copilot建议将React类用于逻辑性不强的小型组件,而不是使用Hooks的功能组件。因为它是根据GitHub上公开的代码进行训练的,所以Copilot可能会提供一些贬值的编码建议。
总结
GitHub Copilot并不是一个可以听从项目想法并为你编码的东西。它也不会取代开发者的工作。但它可以使编码变得更容易。
GitHub Copilot擅长处理小任务;当你开始要求它处理更复杂的任务时,你往往会得到一些废话。尽管如此,它对于初学者和有经验的开发者来说都是一个非常好的工具。
The post1 week with GitHub Copilot:只用Copilot建立一个应用程序,首先出现在LogRocket博客上。