在本章中,我们将讨论人类如何与计算机进行交流。我们将向您介绍您的 AI 助手 GitHub Copilot,这是一个使用人工智能(AI)帮助人们编写软件的神奇工具。更重要的是,我们将向您展示 Copilot 如何帮助您学习编程。我们并不期望您之前已经编写过任何程序。如果您已经编写过,请不要跳过本章,即使您已经对编程有一些了解。每个人都需要知道,现在我们有了像 ChatGPT 和 Copilot 这样的 AI 助手后,编写程序的方式有所不同,我们需要具备不同的有效编程技能。正如我们将看到的,我们还需要保持警惕,因为有时像 ChatGPT 和 Copilot 这样的工具会撒谎。
如果我们先请您阅读并理解下面的代码,您会感到高兴吗?
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年代电脑游戏中最需要速度的部分,如《毁灭战士》和《地震》等,都是用类似前面的代码示例中的汇编语言编写的。否则,根本不可能制作这些游戏。
好的,不再说那个了。让我们继续吧。你会更喜欢阅读下面的代码吗?
for num in range(0, 9):
print(num)
这段代码是用 Python 语言编写的,这是现在许多程序员使用的语言。与低级语言汇编语言不同,Python 被认为是一种高级语言,因为它更接近自然语言。即使你还不了解 Python 代码,你可能能猜到这个程序试图做什么。第一行看起来是在处理从 0 到 9 的数字范围。第二行正在打印一些东西。很难相信这个程序,就像汇编语言的怪物一样,应该打印从 0 到 9 的数字。不幸的是,它出了些问题,实际上并没有打印出从 0 到 9 的数字(而是打印出了 0 到 8)。
虽然这段代码更接近英语,但它并不是英语。它是一种编程语言,就像汇编语言一样,有着特定的规则。就像前面的代码一样,对这些规则的细节误解可能导致程序出错。
与计算机进行自然语言交流是沟通的圣杯,比如使用英语。在过去的 70 年里,我们一直在使用各种编程语言与计算机交流,不是因为我们想要,而是因为我们必须这样做。计算机对于英语这样的语言的变幻莫测和特殊性来说,简直没有足够的能力。我们的编程语言有所改进——从符号混乱的汇编语言到 Python,例如——但它们仍然是计算机语言,而不是自然语言。这正在改变。
使用 AI 助手,我们现在可以用英语提出我们想要的东西,并得到计算机代码作为回应。为了得到一个正确的 Python 程序,能够打印出从 0 到 9 的数字,我们可以用普通的英语语言向我们的 AI 助手(Copilot)提问,就像这样:
# Output the numbers from 0 to 9
Copilot 可能会通过生成类似以下内容来回应这个提示:
for i in range(10):
print(i)
与我们之前展示给你的例子不同,这段 Python 代码实际上是可行的!
AI 编码助手可以用来帮助人们编写代码。在这本书中,我们将学习如何使用 Copilot 来为我们编写代码。我们将用英语提出我们想要的内容,然后我们将得到 Python 代码的返回。
此外,我们将能够将 Copilot 作为我们工作流程的无缝一部分使用。没有像 Copilot 这样的工具,程序员通常会打开两个窗口:一个用来编写代码,另一个用来询问 Google 如何编写代码。这第二个窗口中有 Google 的搜索结果、Python 文档或程序员讨论如何编写代码来解决特定问题的论坛。他们经常将这些结果中的代码粘贴到自己的代码中,然后根据自己的上下文稍作调整,尝试其他方法等等。这已经成为程序员的一种生活方式,但你可以想象这种效率低下。据估计,程序员有多达 35% 的时间用于搜索代码[1],而找到的大部分代码并不容易使用。Copilot 通过帮助我们编写代码极大地改善了这种体验。
我们将在本书中使用两种主要技术:Python 和 GitHub Copilot。
Python 是一种编程语言。它是与计算机进行交流的一种方式。人们使用它来编写各种有用的程序,如游戏、交互式网站、可视化、文件组织应用程序、自动化例行任务等等。
在撰写本文时,它与 Python 的配合效果非常好。与许多其他语言(尤其是汇编语言)相比,Python 代码更容易编写。更重要的是,Python 易于阅读。毕竟,我们不会亲自编写Python 代码。我们的 AI 助手会!
计算机实际上不知道如何读取和运行 Python 代码。计算机能理解的只有一种叫做机器码的东西,它看起来比汇编代码更荒谬,因为它是汇编代码的二进制表示(是的,只是一堆 0 和1!)。在幕后,你的计算机会在运行之前将你提供的任何 Python 代码转换为机器码,如图 1.1 所示。
什么是 AI 助手?AI 助手是一个人工智能(AI)代理,可以帮助您完成工作。也许您在家里有一个 Amazon Alexa 设备,或者一台带有 Siri 的 iPhone——这些都是 AI 助手。
它们可以帮助你订购杂货、了解天气,或者确认在《哈利·波特》电影中扮演贝拉特里克斯的女演员确实出演了《搏击俱乐部》。AI助手只是一个计算机程序,它可以以类似人类的方式回应正常的人类输入,比如语音和文本。
Copilot 是一个具有特定工作的AI助手:它将英语转换为计算机程序。(正如我们很快会看到的那样,它还可以做很多其他事情。)还有其他像 Copilot 这样的 AI 助手,包括CodeWhisperer、Tabnine和Ghostwriter。我们选择 Copilot 作为本书的助手,是基于我们能够产生的代码质量、稳定性(它从未崩溃过!)和我们自己的个人偏好。当你感到舒适时,我们鼓励你也去尝试其他工具。
你可以将 Copilot 视为你和你正在编写的计算机程序之间的一层。你不需要直接编写Python 代码,只需用文字描述你想要的程序,这被称为提示,Copilot 会为你生成程序。
Copilot 背后的智慧是一个名为大型语言模型(LLM)的高级计算机程序。LLM 存储了关于词语之间关系的信息,包括哪些词在特定语境中有意义,并利用这些信息来预测最佳的词语序列以回应提示。
想象一下,我们问你这个句子中下一个词应该是什么:“这个人打开了________。” 这里有很多词可以填入,比如“门”或“盒子”或“对话”,但也有很多词不适合填入,比如“the”或“it”或“open”。LLM 会考虑到单词的当前上下文来生成下一个词,并且会一直这样做,直到完成任务。
请注意,我们并没有说 Copilot 对自己所做的事情有任何理解。它只是利用当前的上下文来继续编写代码。在你的旅程中要记住这一点:只有我们知道生成的代码是否按照我们的意图执行。很多时候是这样的,但你应该始终保持健康的怀疑态度。图1.2 给出了Copilot 从提示到程序的过程。
你可能会想为什么 Copilot 为我们编写 Python 代码而不是直接编写机器代码。现在 Python 不是一个可有可无的中间步骤吗?嗯,不是这样的,原因是 Copilot 会犯错。如果它会犯错,我们需要修复,使用 Python比 使用机器代码要容易得多。
实际上,几乎没有人检查从 Python 生成的机器码是否正确。这部分是因为 Python 语言规范的确定性。可以想象未来 Copilot 的对话如此准确,以至于检查Python 代码是不必要的,但我们离那个目标还有很长的路要走。
为了说明在有 AI 助手的情况下学习编程的变化,我们想向您展示 Copilot 在 解决一个通常在编程课程中或编程书籍中给学生的编程任务时的强大能力。
在过去学习编程时,学习者通常会花费大部分时间来处理程序的语法和基本结构。像我们接下来要展示的这个程序一样,从头开始编写程序(逐行编写)被视为他们所有学习的巅峰。在我们深入探讨这个问题之前,我们需要明确一点:尽管大多数编程教师(和书籍作者)认为新手程序员应该能够解决这个问题,但许多新手程序员实际上无法编写解决这个问题的代码。以下是这个问题的一个版本的说明[6]:
编写一个程序,用于读取每天的降雨量。负值的降雨量应该被拒绝,因为这是无效和不可接受的。程序应该打印出有效记录天数的数量,下雨天数的数量,该时期的降雨量以及任何一天降雨量的最大值。使用终止程序的哨兵值 9999。
如果你之前尝试过学习编程,这种问题描述可能对你来说很熟悉,你可能曾经努力解决过这样的问题。但是现在,如果我们将这个准确的提示输入给 Copilot,我们会得到以下的 Python 代码作为结果。(请记住,根据前面的介绍,Copilot 是非确定性的,所以如果我们再次询问它,可能会得到不同的代码!)
清单1.1 解决经典降⾬问题的 Copilot 代码
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 助手从根本上改变了学习编程所需的技能,你将学会如何更快地编写更大、更有意义的软件。
正如我们所见,我们可以使用 Copilot 根据我们想要的英文描述来编写 Python 代码。程序员使用术语“语法”来指代在给定语言中有效的符号和单词。因此,我们可以说 Copilot接受英文语法的描述,并将其转换为 Python 语法的代码。这是一个巨大的优势,因为学习编程语法一直是新手程序员的主要障碍。我应该在这里使用哪种括号——[、( 还是 {?我需要在这里缩进吗?我们应该按照什么顺序编写这些东西:先是 x 再是 y,还是先是 y再是 x?
这样的问题很多,说实话:这些都是无聊的东西。当我们只想编写一个能实现某种功能的程序时,谁会在意这些呢?Copilot 可以帮助我们摆脱语法的乏味。我们认为这是帮助更多人成功编写程序的重要一步,我们期待着这个人为的障碍完全消除的那一天。目前,我们仍然需要Python 的语法,但至少 Copilot 可以帮助我们。
但这还不是 Copilot 能做的全部。以下是一些相关且同样重要的任务,Copilot 可以帮助我们完成:
现在我们对于让 Copilot 为我们编写代码感到非常兴奋,但我们需要讨论使用 AI 助手所固有的危险。有关这些观点的详细说明,请参考参考相关文献。
如果 Copilot 能够编写我们的代码、解释它并修复其中的错误,那我们就完成了吗?我们只需告诉 Copilot 该做什么,然后庆祝我们的卓越成就?
不。程序员所依赖的一些技能(例如编写正确的语法)的重要性确实会降低。但其他技能仍然至关重要。例如,你不能对 Copilot 提出一个庞大的任务,比如“制作一个视频游戏。哦,还要让它有趣。” Copilot 会失败。相反,我们需要将这样一个庞大的问题分解成 Copilot 可以帮助我们的小任务。那么我们如何分解这样的问题呢?事实证明,这并不容易。人类需要在与 Copilot 等工具进行对话时培养这种关键技能,我们在整本书中都会教授这种技能。
其他技能,信不信由你,可能在 Copilot 中变得更加重要。测试代码一直是编写可运行代码的关键任务。我们对于测试人类编写的代码了解很多,因为我们知道在哪里寻找典型问题。我们知道人类在数值边界处经常犯编程错误。例如,如果我们编写一个程序来相乘两个数字,很可能大多数数值都是正确的,但当一个值为 0 时可能不正确。那么关于由 AI 编写的代码呢?20 行无瑕疵的代码中可能隐藏着一行如此荒谬的代码,以至于我们不太可能在那里预料到它。我们对此没有经验。我们需要比以前更加仔细地测试。
最后,一些必需的技能是全新的。其中一个主要的技能是称为即时工程的技能,它涉及如何告诉 Copilot 该做什么。当我们要求 Copilot 编写一些代码时,我们使用提示来发出请求。虽然我们可以使用英语编写提示并要求我们想要的东西,但这还不够。如果我们希望 Copilot 有任何机会做正确的事情,我们需要非常精确。即使我们很精确,Copilot可能仍然会做错事。在这种情况下,我们需要首先确定 Copilot 确实犯了一个错误,然后调整我们的描述,希望能将其引导到正确的方向。根据我们的经验,对提示进行看似微小的更改可能会对 Copilot 产生巨大的影响。
在教程中,我们将教给你所有这些技能。
目前社会上对于像 Copilot 这样的 AI 代码助手存在不确定性。我们想以一些问题和我们目前的答案来结束这一章节。也许你自己也在思考一些这样的问题!我们的答案可能最终被证明是极其错误的,但它们确实捕捉到了我们作为两位教授和研究人员,致力于教授编程的思考。
问:有了 Copilot,技术和编程工作会减少吗?
答:可能不会。我们预计会发生变化的是这些工作的性质。例如,我们认为Copilot能够帮助完成许多通常与初级编程工作相关的任务。这并不意味着初级编程工作会消失,只是随着程序员能够利用越来越复杂的工具完成更多工作,这些工作会发生变化。
问:Copilot 会扼杀人类的创造力吗?它只会不断循环和重复人类已经编写的代码,限制新思想的引入吗?
答:我们怀疑不是这样的。Copilot 帮助我们在更高的层次上工作,远离底层的机器代码、汇编代码或 Python 代码。计算机科学家使用抽象这个术语来指代我们能够与计算机的低级细节断开联系的程度。自计算机科学诞生以来,抽象一直在发生,而我们似乎并没有因此而受到伤害。相反,它使我们能够忽略已经解决的问题,专注于解决更广泛的问题。事实上,更好的编程语言的出现促进了更好的软件——那些支持谷歌搜索、亚马逊购物车和 macOS 的软件不是在我们只有汇编语言时编写的(而且很可能无法编写)。
问:我一直听说 ChatGPT。它是什么?它和 Copilot 一样吗?
答:它和 Copilot 不一样,但是它是基于相同的技术构建的。不过,ChatGPT 的重点不是代码,而是一般的知识。因此,它在各种任务中的应用范围比 Copilot 更广。例如,它可以回答问题、写作文,甚至在沃顿 MBA 考试中表现出色[7]。教育将因此需要改变:我们不能让人们通过 ChatGPT 获得 MBA学位!我们花时间的有价值的方式可能会改变。人类是否会继续写书,如果会,以何种方式?人们是否愿意阅读那些部分或完全由人工智能撰写的书籍?这将对包括金融、医疗保健和出版业在内的各行各业产生影响[8]。与此同时,现在存在着无限夸大的炒作,所以很难分辨真实与虚构。这个问题还因为一个简单的事实而变得更加复杂,即没有人知道长期来看会发生什么。 事实上,有一句由罗伊·阿马拉(被称为阿马拉定律)创造的古老格言,它说:“我们往往高估技术在短期内的影响,低估其在长期内的影响。”因此,我们需要尽力关注讨论,以便相应地进行调整。
在下一章中,我们将帮助您在计算机上开始使用Copilot,以便您可以开始编写软件。