本章涵盖了
- AI 助⼿如何改变新程序员的学习⽅式
- 为什么编程永远不会再⼀样了
- AI 助⼿如 Copilot 的⼯作原理
- Copilot 如何解决⼊⻔级编程问题
- AI 辅助编程的潜在危险
在本章中,我们将讨论人类如何与计算机进行交流。我们将向您介绍您的 AI 助手 GitHub Copilot,这是一个使用人工智能(AI)帮助人们编写软件的神奇工具。更重要的是,我们将向您展示 Copilot 如何帮助您学习编程。我们并不期望您之前已经编写过任何程序。如果您已经编写过,请不要跳过本章,即使您已经对编程有一些了解。每个人都需要知道,现在我们有了像 ChatGPT 和 Copilot 这样的 AI 助手后,编写程序的方式有所不同,我们需要具备不同的有效编程技能。正如我们将看到的,我们还需要保持警惕,因为有时像 ChatGPT 和 Copilot 这样的工具会撒谎。
1.1 我们如何与计算机交流
如果我们先请您阅读并理解下面的代码,您会感到高兴吗?
assembly
section .text
global _start
_start:
mov ecx, 10
mov eax, '0'
l1:
mov [num], eax
mov eax, 4
mov ebx, 1
push ecx
mov ecx, num
mov edx, 1
int 0x80
mov eax, [num]
inc eax
pop ecx
loop l1
mov eax, 1
int 0x80
section .bss
num resb 1
那个怪物打印出从 0 到 9 的数字。它是用汇编语言编写的,一种低级编程语言。正如你所看到的,低级编程语言并不是人类能够轻松阅读和编写的语言。它们是为计算机设计的,而不是为人类设计的。
没有人愿意编写那样的程序,但特别是在过去,有时是必要的。程序员可以使用它来准确地定义他们希望计算机执行的操作,甚至到每个指令的细节。这种控制水平是为了从性能较差的计算机中挤取出每一点性能而必需的。例如,1990年代电脑游戏中最需要速度的部分,如《毁灭战士》和《地震》等,都是用类似前面的代码示例中的汇编语言编写的。否则,根本不可能制作这些游戏。
1.1.1 使它变得稍微容易⼀些
好的,不再说那个了。让我们继续吧。你会更喜欢阅读下面的代码吗?
python
for num in range(0, 9):
print(num)
这段代码是用 Python 语言编写的,这是现在许多程序员使用的语言。与低级语言汇编语言不同,Python 被认为是一种高级语言,因为它更接近自然语言。即使你还不了解 Python 代码,你可能能猜到这个程序试图做什么。第一行看起来是在处理从 0 到 9 的数字范围。第二行正在打印一些东西。很难相信这个程序,就像汇编语言的怪物一样,应该打印从 0 到 9 的数字。不幸的是,它出了些问题,实际上并没有打印出从 0 到 9 的数字(而是打印出了 0 到 8)。
虽然这段代码更接近英语,但它并不是英语。它是一种编程语言,就像汇编语言一样,有着特定的规则。就像前面的代码一样,对这些规则的细节误解可能导致程序出错。
与计算机进行自然语言交流是沟通的圣杯,比如使用英语。在过去的 70 年里,我们一直在使用各种编程语言与计算机交流,不是因为我们想要,而是因为我们必须这样做。计算机对于英语这样的语言的变幻莫测和特殊性来说,简直没有足够的能力。我们的编程语言有所改进------从符号混乱的汇编语言到 Python,例如------但它们仍然是计算机语言,而不是自然语言。这正在改变。
1.1.2 使其变得更加容易
使用 AI 助手,我们现在可以用英语提出我们想要的东西,并得到计算机代码作为回应。为了得到一个正确的 Python 程序,能够打印出从 0 到 9 的数字,我们可以用普通的英语语言向我们的 AI 助手(Copilot)提问,就像这样:
python
# Output the numbers from 0 to 9
Copilot 可能会通过生成类似以下内容来回应这个提示:
python
for i in range(10):
print(i)
与我们之前展示给你的例子不同,这段 Python 代码实际上是可行的!
AI 编码助手可以用来帮助人们编写代码。在这本书中,我们将学习如何使用 Copilot 来为我们编写代码。我们将用英语提出我们想要的内容,然后我们将得到 Python 代码的返回。
此外,我们将能够将 Copilot 作为我们工作流程的无缝一部分使用。没有像 Copilot 这样的工具,程序员通常会打开两个窗口:一个用来编写代码,另一个用来询问 Google 如何编写代码。这第二个窗口中有 Google 的搜索结果、Python 文档或程序员讨论如何编写代码来解决特定问题的论坛。他们经常将这些结果中的代码粘贴到自己的代码中,然后根据自己的上下文稍作调整,尝试其他方法等等。这已经成为程序员的一种生活方式,但你可以想象这种效率低下。据估计,程序员有多达 35% 的时间用于搜索代码[1],而找到的大部分代码并不容易使用。Copilot 通过帮助我们编写代码极大地改善了这种体验。
1.2 关于技术
我们将在本书中使用两种主要技术:Python 和 GitHub Copilot。
Python 是一种编程语言。它是与计算机进行交流的一种方式。人们使用它来编写各种有用的程序,如游戏、交互式网站、可视化、文件组织应用程序、自动化例行任务等等。
在撰写本文时,它与 Python 的配合效果非常好。与许多其他语言(尤其是汇编语言)相比,Python 代码更容易编写。更重要的是,Python 易于阅读。毕竟,我们不会亲自编写Python 代码。我们的 AI 助手会!
计算机实际上不知道如何读取和运行 Python 代码。计算机能理解的只有一种叫做机器码的东西,它看起来比汇编代码更荒谬,因为它是汇编代码的二进制表示(是的,只是一堆 0 和1!)。在幕后,你的计算机会在运行之前将你提供的任何 Python 代码转换为机器码,如图 1.1 所示。
1.2.1 Copilot,你的⼈⼯智能助⼿
什么是 AI 助手?AI 助手是一个人工智能(AI)代理,可以帮助您完成工作。也许您在家里有一个 Amazon Alexa 设备,或者一台带有 Siri 的 iPhone------这些都是 AI 助手。
它们可以帮助你订购杂货、了解天气,或者确认在《哈利·波特》电影中扮演贝拉特里克斯的女演员确实出演了《搏击俱乐部》。AI助手只是一个计算机程序,它可以以类似人类的方式回应正常的人类输入,比如语音和文本。
Copilot 是一个具有特定工作的AI助手:它将英语转换为计算机程序。(正如我们很快会看到的那样,它还可以做很多其他事情。)还有其他像 Copilot 这样的 AI 助手,包括CodeWhisperer、Tabnine和Ghostwriter。我们选择 Copilot 作为本书的助手,是基于我们能够产生的代码质量、稳定性(它从未崩溃过!)和我们自己的个人偏好。当你感到舒适时,我们鼓励你也去尝试其他工具。
1.2.2 Copilot 在幕后的⼯作⽅式------30 秒内
你可以将 Copilot 视为你和你正在编写的计算机程序之间的一层。你不需要直接编写Python 代码,只需用文字描述你想要的程序,这被称为提示,Copilot 会为你生成程序。
Copilot 背后的智慧是一个名为大型语言模型(LLM)的高级计算机程序。LLM 存储了关于词语之间关系的信息,包括哪些词在特定语境中有意义,并利用这些信息来预测最佳的词语序列以回应提示。
想象一下,我们问你这个句子中下一个词应该是什么:"这个人打开了________。" 这里有很多词可以填入,比如"门"或"盒子"或"对话",但也有很多词不适合填入,比如"the"或"it"或"open"。LLM 会考虑到单词的当前上下文来生成下一个词,并且会一直这样做,直到完成任务。
请注意,我们并没有说 Copilot 对自己所做的事情有任何理解。它只是利用当前的上下文来继续编写代码。在你的旅程中要记住这一点:只有我们知道生成的代码是否按照我们的意图执行。很多时候是这样的,但你应该始终保持健康的怀疑态度。图1.2 给出了Copilot 从提示到程序的过程。
你可能会想为什么 Copilot 为我们编写 Python 代码而不是直接编写机器代码。现在 Python 不是一个可有可无的中间步骤吗?嗯,不是这样的,原因是 Copilot 会犯错。如果它会犯错,我们需要修复,使用 Python比 使用机器代码要容易得多。
实际上,几乎没有人检查从 Python 生成的机器码是否正确。这部分是因为 Python 语言规范的确定性。可以想象未来 Copilot 的对话如此准确,以至于检查Python 代码是不必要的,但我们离那个目标还有很长的路要走。
1.3 Copilot 如何改变我们学习编程的⽅式
为了说明在有 AI 助手的情况下学习编程的变化,我们想向您展示 Copilot 在 解决一个通常在编程课程中或编程书籍中给学生的编程任务时的强大能力。
在过去学习编程时,学习者通常会花费大部分时间来处理程序的语法和基本结构。像我们接下来要展示的这个程序一样,从头开始编写程序(逐行编写)被视为他们所有学习的巅峰。在我们深入探讨这个问题之前,我们需要明确一点:尽管大多数编程教师(和书籍作者)认为新手程序员应该能够解决这个问题,但许多新手程序员实际上无法编写解决这个问题的代码。以下是这个问题的一个版本的说明[6]:
编写一个程序,用于读取每天的降雨量。负值的降雨量应该被拒绝,因为这是无效和不可接受的。程序应该打印出有效记录天数的数量,下雨天数的数量,该时期的降雨量以及任何一天降雨量的最大值。使用终止程序的哨兵值 9999。
如果你之前尝试过学习编程,这种问题描述可能对你来说很熟悉,你可能曾经努力解决过这样的问题。但是现在,如果我们将这个准确的提示输入给 Copilot,我们会得到以下的 Python 代码作为结果。(请记住,根据前面的介绍,Copilot 是非确定性的,所以如果我们再次询问它,可能会得到不同的代码!)
清单1.1 解决经典降⾬问题的 Copilot 代码
python
rainfall = 0
total_rainfall = 0
num_rainy_days = 0
num_valid_days = 0
max_rainfall = 0
rainfall = int(input(
"Enter the amount of rainfall for the day: "))
while rainfall != 9999:
if rainfall < 0:
print("Invalid rainfall amount. Please try again.")
rainfall = int(input(
"Enter the amount of rainfall for the day: "))
else:
num_valid_days += 1
total_rainfall += rainfall
if rainfall > 0:
num_rainy_days += 1
if rainfall > max_rainfall:
max_rainfall = rainfall
rainfall = int(input(
"Enter the amount of rainfall for the day: "))
print("Number of valid days:", num_valid_days)
print("Number of rainy days:", num_rainy_days)
print("Total rainfall over the period:", total_rainfall)
print("Maximum amount of rain that fell on any one day:", max_rainfall)
我们不指望你现在对这段代码有任何直觉,但它是好的。作为计算机科学教授,我们会给这段代码高分。
学习编程的人过去需要花费几周甚至几个月的时间才能达到能够编写像这样的程序的水平。现在,Copilot 可以立即提供代码。正如本书的其余部分所述,我们仍然需要验证这段代码是否正确,因为 Copilot 可能会出错。然而,我们不再需要从头开始编写代码。我们相信与 Copilot 的成功互动标志着我们过去教授和学习编程的方式的终结。
作为一个对学习编程感兴趣的人,你根本不需要为了以前编写这样的代码而苦苦挣扎于语法、控制流和其他 Python 概念。当然,在本书中我们会学习这些概念,但不是为了你能够从头开始编写 Copilot 可以轻松生成的代码来展示你的理解能力。不,我们学习这些概念只是因为它们帮助我们解决有意义的问题,并与 Copilot 进行有效的交互。相反,由于 AI 助手从根本上改变了学习编程所需的技能,你将学会如何更快地编写更大、更有意义的软件。
1.4 Copilot 还能为我们做什么?
正如我们所见,我们可以使用 Copilot 根据我们想要的英文描述来编写 Python 代码。程序员使用术语"语法"来指代在给定语言中有效的符号和单词。因此,我们可以说 Copilot接受英文语法的描述,并将其转换为 Python 语法的代码。这是一个巨大的优势,因为学习编程语法一直是新手程序员的主要障碍。我应该在这里使用哪种括号------[、( 还是 {?我需要在这里缩进吗?我们应该按照什么顺序编写这些东西:先是 x 再是 y,还是先是 y再是 x?
这样的问题很多,说实话:这些都是无聊的东西。当我们只想编写一个能实现某种功能的程序时,谁会在意这些呢?Copilot 可以帮助我们摆脱语法的乏味。我们认为这是帮助更多人成功编写程序的重要一步,我们期待着这个人为的障碍完全消除的那一天。目前,我们仍然需要Python 的语法,但至少 Copilot 可以帮助我们。
但这还不是 Copilot 能做的全部。以下是一些相关且同样重要的任务,Copilot 可以帮助我们完成:
- 解释代码------当 Copilot 为我们生成 Python 代码时,我们需要确定该代码是否符合我们的要求。正如我们之前所说的,Copilot 会犯错误。虽然我们不打算教你 Python 的每一个细微之处(那是旧的编程模式),但我们会教你如何阅读 Python 代码,以获得对其整体功能的理解。我们还将使用 Copilot 的代码解释功能来向你解释代码。当你完成本书和我们的解释后,你仍然可以使用 Copilot 来帮助你理解它给出的下一段复杂代码。
- 使代码更易于理解------有不同的方法来编写代码以完成相同的任务。有些方法可能比其他方法更容易理解。Copilot 有一个工具,可以重新组织您的代码,使其更易于使用。例如,易于阅读的代码通常在需要时更容易改进或修复。
- 修复错误------错误是在编写程序时犯的错误,可能导致程序执行错误的操作。有时候,你的 Python 代码几乎可以工作,或者几乎总是可以工作,但在某种特定情况下却不能正常工作。如果你听过程序员的谈话,你可能听过一个常见的故事,程序员花了几个小时,最后才发现一个等号符号导致程序失败。这几个小时可不好玩!在这些情况下,你可以尝试使用 Copilot 功能,它可以帮助自动查找和修复程序中的错误。
1.5 使⽤ Copilot 时的⻛险和挑战
现在我们对于让 Copilot 为我们编写代码感到非常兴奋,但我们需要讨论使用 AI 助手所固有的危险。有关这些观点的详细说明,请参考参考相关文献。
- 版权------Copilot 通过使用人类编写的代码来学习编程。(当谈论像 Copilot 这样的 AI工具时,你会听到人们使用"训练"这个词。在这个背景下,训练是学习的另一个词。)更具体地说,它是通过使用包含开源代码的数百万个 GitHub 存储库进行训练的。一个担忧是 Copilot 会"窃取"那些代码并给我们。根据我们的经验,Copilot 并不经常建议使用别人的大块代码,但这种可能性是存在的。即使 Copilot 给我们的代码是其他人代码的融合和转换,仍然可能存在许可问题。例如,谁拥有 Copilot 生成的代码?目前对这个问题还没有共识。Copilot 团队正在添加一些功能来帮助解决这个问题;例如,Copilot 可以告诉你它生成的代码是否与已有代码相似,以及该代码的许可证是什么。自己学习和实验是很好的,我们鼓励这样做------但是如果你打算将这些代码用于家庭以外的目的,请注意必要的注意事项。 我们在这里有些模糊,这是有意的:法律可能需要一些时间来适应这项新技术。在这些辩论在社会中进行时,最好保持谨慎。
- 教育------作为我们自己的入门编程课程的教师,我们亲眼目睹了 Copilot 在我们过去给学生的任务上的出色表现。在一项研究中,Copilot 被要求解决 166 个常见的入门编程任务。它的表现如何呢?在第一次尝试中,它解决了近 50% 的问题。给 Copilot 更多的信息,这个数字可以提高到 80%。你已经亲眼见证了 Copilot 如何解决一个标准的入门编程问题。在 Copilot 这样的工具出现后,教育需要做出改变,教师们正在讨论这些改变可能会是什么样子。学生是否可以使用 Copilot,如果可以,以何种方式使用?Copilot 如何帮助学生学习?编程任务现在会是什么样子?
- 代码质量------我们需要小心不要完全依赖 Copilot,特别是对于敏感代码或需要保密的代码。例如,为医疗设备编写的代码或处理敏感用户数据的代码必须始终被彻底理解。向Copilot 请求代码、对它生成的代码感到惊叹并且不经过仔细审查就接受这些代码是很诱人的。但是那些代码可能是完全错误的。在本书中,我们将处理的代码不会被大规模部署,因此虽然我们将专注于获取正确的代码,但我们不会担心使用这些代码的广泛目的。我们将开始构建你需要独立确定代码是否正确的基础。
- 代码安全性------与代码质量一样,从 Copilot 获取的代码绝对不能保证安全。例如,如果我们正在处理用户数据,仅仅从 Copilot 获取代码是不够的。我们需要进行安全审计并具备专业知识来确定代码是否安全。然而,我们不会在真实场景中使用 Copilot 的代码。因此,我们不会关注安全问题。
- 不是专家------成为专家的标志之一是意识到自己知道什么,同样重要的是,意识到自己不知道什么。专家通常能够表达自己对回答的自信程度;如果他们不够自信,他们会进一步学习,直到确信自己知道。然而,Copilot 和更一般的 LLMs 不会这样做。你问他们一个问题,他们就会直接回答。如果必要,他们会混合真实的部分和垃圾的部分,组成一个听起来合理但整体上毫无意义的回答。例如,我们曾经看到 LLMs 为活着的人编写讣告,这毫无意义,但这些"讣告"确实包含了关于人们生活的真实元素。当被问到为什么算盘可以比计算机更快地进行数学运算时,我们曾经看到 LLMs 提出了各种回答,包括关于算盘是机械的,因此必然是最快的。在这个领域还有一些正在进行的工作,让LLMs 能够说:"对不起,我不知道",但我们还没有达到那个程度。他们不知道自己不知道什么,这意味着他们需要监督。
- 偏见------LLMs 将复制在其训练数据中存在的偏见。如果你要求 Copilot 生成一个名字列表,它会主要生成英文名字。如果你要求生成一个图表,它可能会生成一个不考虑人类感知差异的图表。如果你要求生成代码,它可能会生成类似于主导群体编写代码的风格的代码。(毕竟,主导群体编写了世界上大部分的代码,而 Copilot 是在这些代码上进行训练的。)计算机科学和软件工程长期以来一直缺乏多样性。我们不能再进一步压制多样性,事实上我们需要扭转这一趋势。我们需要让更多的人参与进来,并允许他们以自己的方式表达自己。如何处理像 Copilot 这样的工具目前正在研究中,并且对于编程的未来来说至关重要。然而,我们相信 Copilot 有潜力通过降低进入该领域的门槛来改善多样性。
1.6 我们需要的技能
如果 Copilot 能够编写我们的代码、解释它并修复其中的错误,那我们就完成了吗?我们只需告诉 Copilot 该做什么,然后庆祝我们的卓越成就?
不。程序员所依赖的一些技能(例如编写正确的语法)的重要性确实会降低。但其他技能仍然至关重要。例如,你不能对 Copilot 提出一个庞大的任务,比如"制作一个视频游戏。哦,还要让它有趣。" Copilot 会失败。相反,我们需要将这样一个庞大的问题分解成 Copilot 可以帮助我们的小任务。那么我们如何分解这样的问题呢?事实证明,这并不容易。人类需要在与 Copilot 等工具进行对话时培养这种关键技能,我们在整本书中都会教授这种技能。
其他技能,信不信由你,可能在 Copilot 中变得更加重要。测试代码一直是编写可运行代码的关键任务。我们对于测试人类编写的代码了解很多,因为我们知道在哪里寻找典型问题。我们知道人类在数值边界处经常犯编程错误。例如,如果我们编写一个程序来相乘两个数字,很可能大多数数值都是正确的,但当一个值为 0 时可能不正确。那么关于由 AI 编写的代码呢?20 行无瑕疵的代码中可能隐藏着一行如此荒谬的代码,以至于我们不太可能在那里预料到它。我们对此没有经验。我们需要比以前更加仔细地测试。
最后,一些必需的技能是全新的。其中一个主要的技能是称为即时工程的技能,它涉及如何告诉 Copilot 该做什么。当我们要求 Copilot 编写一些代码时,我们使用提示来发出请求。虽然我们可以使用英语编写提示并要求我们想要的东西,但这还不够。如果我们希望 Copilot 有任何机会做正确的事情,我们需要非常精确。即使我们很精确,Copilot可能仍然会做错事。在这种情况下,我们需要首先确定 Copilot 确实犯了一个错误,然后调整我们的描述,希望能将其引导到正确的方向。根据我们的经验,对提示进行看似微小的更改可能会对 Copilot 产生巨大的影响。
在教程中,我们将教给你所有这些技能。
1.7 社会对 Copilot 等 AI 代码助⼿的关注
目前社会上对于像 Copilot 这样的 AI 代码助手存在不确定性。我们想以一些问题和我们目前的答案来结束这一章节。也许你自己也在思考一些这样的问题!我们的答案可能最终被证明是极其错误的,但它们确实捕捉到了我们作为两位教授和研究人员,致力于教授编程的思考。
问:有了 Copilot,技术和编程工作会减少吗?
答:可能不会。我们预计会发生变化的是这些工作的性质。例如,我们认为Copilot能够帮助完成许多通常与初级编程工作相关的任务。这并不意味着初级编程工作会消失,只是随着程序员能够利用越来越复杂的工具完成更多工作,这些工作会发生变化。
问:Copilot 会扼杀人类的创造力吗?它只会不断循环和重复人类已经编写的代码,限制新思想的引入吗?
答:我们怀疑不是这样的。Copilot 帮助我们在更高的层次上工作,远离底层的机器代码、汇编代码或 Python 代码。计算机科学家使用抽象这个术语来指代我们能够与计算机的低级细节断开联系的程度。自计算机科学诞生以来,抽象一直在发生,而我们似乎并没有因此而受到伤害。相反,它使我们能够忽略已经解决的问题,专注于解决更广泛的问题。事实上,更好的编程语言的出现促进了更好的软件------那些支持谷歌搜索、亚马逊购物车和 macOS 的软件不是在我们只有汇编语言时编写的(而且很可能无法编写)。
问:我一直听说 ChatGPT。它是什么?它和 Copilot 一样吗?
答:它和 Copilot 不一样,但是它是基于相同的技术构建的。不过,ChatGPT 的重点不是代码,而是一般的知识。因此,它在各种任务中的应用范围比 Copilot 更广。例如,它可以回答问题、写作文,甚至在沃顿 MBA 考试中表现出色[7]。教育将因此需要改变:我们不能让人们通过 ChatGPT 获得 MBA学位!我们花时间的有价值的方式可能会改变。人类是否会继续写书,如果会,以何种方式?人们是否愿意阅读那些部分或完全由人工智能撰写的书籍?这将对包括金融、医疗保健和出版业在内的各行各业产生影响[8]。与此同时,现在存在着无限夸大的炒作,所以很难分辨真实与虚构。这个问题还因为一个简单的事实而变得更加复杂,即没有人知道长期来看会发生什么。 事实上,有一句由罗伊·阿马拉(被称为阿马拉定律)创造的古老格言,它说:"我们往往高估技术在短期内的影响,低估其在长期内的影响。"因此,我们需要尽力关注讨论,以便相应地进行调整。
在下一章中,我们将帮助您在计算机上开始使用Copilot,以便您可以开始编写软件。
概要
- Copilot 是一个 AI 助手,它是一个人工智能(AI)代理,可以帮助您完成工作。
- Copilot 改变了人类与计算机的互动方式,以及我们编写程序的方式。
- Copilot 改变了我们需要磨练的技能的重点(更少关注语法,更多关注提示工程和测试)。
- Copilot 是不确定性的;有时它会生成正确的代码,有时则不会。我们需要保持警惕。
- 代码版权、教育和职业培训以及 Copilot 结果中的偏见问题仍需解决。