我认为“人工智能”模型(即大型语言模型)并没有被过度炒作。确实,任何新技术都会吸引一些投机取巧的人。许多公司喜欢宣称他们在“使用人工智能”,就像过去他们声称自己是由“区块链”驱动的一样。我们一次又一次地看到这种现象。尽管我们现在可能处在一个泡沫中,但互联网在2000年泡沫破裂后,其应用以前可是科幻小说里的东西。
我认为最近的进展不仅仅是炒作的原因,是我过去一年里每周至少花几个小时与各种大型语言模型互动,并一直对它们解决我给出的越来越难的任务的能力印象深刻。因此,我的研究项目和业余项目的代码编写速度至少提高了50%。
大多数我在网上看到讨论大型语言模型(LLM)实用性的人,要么极其乐观,声称所有工作将在三年内自动化,要么极其悲观,认为它们没有任何贡献,也永远不会有。在这篇文章中,我只是想提供一个更实际的讨论。
我不打算对未来做出任何预测。我只是想通过一个接一个的例子,列出我(一个研究机器学习的程序员和研究科学家)与不同大型语言模型进行的50次对话,这些对话显著提高了我的研究能力并帮助我完成了各种编程业余项目。其中包括:
使用我从未使用过的技术构建整个Web应用程序。
教我使用之前从未使用过的各种框架。
将数十个程序转换为C或Rust语言,以提高10-100倍的性能。
精简大型代码库,从而显著简化项目。
编写了我去年几乎所有研究论文的初始实验代码。
自动化了几乎所有单调的任务或一次性脚本。
几乎完全取代了为帮助我设置和配置新包或项目而进行的网页搜索。
大约50%地取代了为帮助我调试错误消息而进行的网页搜索。
如果我要将这些例子分为两大类,它们将是“帮助我学习”和“自动化无聊的任务”。帮助我学习显然很重要,因为这意味着我现在可以做以前觉得有挑战性的事情;但自动化无聊的任务对我来说同样重要,因为它让我可以专注于我最擅长的事情,并解决困难的问题。
最重要的是,这些例子是我实际使用LLM帮助我的真实方式。它们不是为了展示某种令人印象深刻的能力;它们源于我完成实际工作的需要。这意味着这些例子并不光鲜亮丽,但我每天做的很多工作也并不光鲜,而目前可用的LLM让我几乎可以自动化所有这些工作。
我在这篇文章中的希望是,让你通过我如何使用LLM提高生产力的例子,了解这些模型的实际价值。请知道,当你感到疲倦时——你肯定会——你只看到了我使用LLM帮助我的不到2%的例子。
我不会声称今天的LLM(大型语言模型)会接管世界。我也不会谈论未来的模型可能或不可能做到的事情。我只会讨论今天的模型是否对我有帮助。你可能会想——为什么有人会写整篇文章来证明语言模型是有用的?这不是显而易见的吗?!但是,似乎有一大群人——在学术文献中,在软件工程领域,甚至在媒体圈——他们广泛宣称LLM毫无贡献,只是又一个炒作周期,几年后就会在对世界毫无影响的情况下消亡。我将论证这些人是错误的,因为当前的LLM已经很有用了。但我觉得有必要对我所说的话进行一些说明,因为还有另一群人(同样声音很大)声称相反的观点:今天的模型可以取代所有程序员,人们不应该学习编程,因为明年他们都会失业。我不会明确反驳这些人的观点(这不是这篇文章的重点),但我要明确的是,我并不是在为他们的观点辩护。我也不会试图争辩“目的证明手段的正当性”,说我们应该训练这些模型,尽管它们有很多有害影响。我完全理解这些模型会带来负面(可能非常负面)的后果。从虚假信息到滥用、监控再到工作替代。(或者,如果你相信某些人的话,甚至人类灭绝??)我会在某个时间点写一整篇关于我对LLM有害影响的看法的文章。但这与语言模型是否有用的问题是分开的——正如我所说,这才是我想在这里讨论的。我也理解你可能不想使用语言模型的原因是它们容易产生幻觉、复述事实、并且由于缺乏鲁棒性而惨遭失败——我可能比你更了解这些限制。但这篇文章不会涉及这些问题。因为我认为,尽管有这些缺陷,模型仍然是有用的。我还进一步理解,训练这些模型的伦理问题至多是可疑的。也许你不喜欢它们在未经许可的情况下使用了人们的数据进行训练(我可能比你更了解这个问题)。或者你在考虑那些为了明确训练这些模型而拿着微薄报酬的人。我同意这些都是问题。但这篇文章也不会涉及这些问题。正如我多次强调的:我只会讨论模型是否有用。通常情况下,我不是一个容易相信事物的人。例如:尽管在十年前经历了安全社区中的加密货币热潮,但我完全避免写任何关于区块链的论文。我从未拥有过比特币。它们基本上没有用途——除了赌博和欺诈。日复一日,我对所有的主张都持怀疑态度。每当有人告诉我“[新技术]将改变世界”时,我的普遍反应是冷漠。因此,当我告诉你,当有人第一次告诉我这项人工智能技术将会非常有用并显著改变我处理日常工作的方式时,我的反应基本上是相同的:“眼见为实。”更重要的是,我还是一名安全研究员。在过去将近十年的日常工作中,我一直在展示人工智能模型在面对任何它们未经过训练的环境时是如何惨败的。我已经证明,稍微扰动机器学习模型的输入就能让它们产生极其错误的输出;或者,大多数机器学习模型会记住训练数据集中的特定示例,并在使用时重复它们。我完全理解这些系统的局限性。然而,我在这里说的是,我认为当前的大型语言模型是自互联网问世以来,对我的生产力提升最大的一项技术。老实说,如果今天你让我选择是使用互联网还是使用一个最先进的语言模型来解决我工作中的一个随机编程任务,我很可能会在超过一半的时间里选择语言模型。以下是我如何使用大型语言模型(LLM)来帮助我的方式:你可能不喜欢我的使用案例。你可能认为它们很愚蠢。这些使用案例也可能与你有关的事情毫无关系。我接受这可能是真的。但我只能代表自己说话。这些案例都是我从过去一年与某个LLM的聊天记录中直接提取出来的。(铭毅备注:代码部分参见原文博客)去年,我制作了一个测验让人们测试他们预测GPT-4解决一系列任务的能力准确度。最终这个测验非常受欢迎——它获得了超过一千万次的页面浏览量你猜怎么着?我几乎让GPT-4为我编写了这个应用程序的整个初始版本!我通过一系列问题来实现这一目标首先是询问应用程序的基本结构然后逐步构建各种功能整个对话总共长达3万字它确实考验了当时最先进的原始GPT-4模型的能力如果你仔细查看这段对话你会看到各种例子从我只用文字描述我想要的东西并要求模型提供完整实现的消息到我要求进行特定更改的消息再到我只要求简单的一次性答案的情况一般来说这之所以有效是因为语言模型擅长解决人们之前解决过的问题而这个测验的99%只是一些基本的HTML和一个Python后端服务器世界上任何人都可以写出来这个测验有趣且受欢迎的原因并不是因为背后的技术而是测验的内容因此将所有无聊的部分自动化使得我很容易就能完成这个测验事实上我可以自信地说如果没有语言模型的帮助我可能根本不会制作这个测验——因为我不想花时间从头编写整个Web应用程序而且我还是一个懂得编程的人!我相信即使是当前的模型也足以让绝大多数人解决他们以前无法解决的有意义的任务只需询问解决方案我还有类似的例子其中我让模型为我编写整个应用程序当它们上线时我会尽量明确说明这些是借助语言模型完成的曾几何时我总是紧跟新框架的步伐但是一个人的时间是有限的由于工作的关系我大部分时间都在跟踪最新的研究进展而不是最新的JavaScript框架这意味着当我要开始一个与我特定研究领域无关的新项目时我通常有两种选择首先我可以使用我已经知道的东西这些通常已经过时了十年或二十年但如果项目很小通常也够用了或者我可以尝试学习新的通常更好的做事方式这时语言模型就派上用场了因为对于我来说大部分新框架/工具比如Docker、Flexbox或者React对其他人来说并不新鲜世界上可能有几十万到几百万人彻底了解这些东西因此当前的语言模型也同样了解这些这意味着我不需要阅读一些静态的入门教程这些教程假设读者知道特定的事情并且想要实现特定的目标我可以与语言模型互动学习我需要解决任务的任何知识例如今年早些时候我在构建一个LLM评估框架时希望能够在一个受限环境中运行LLM生成的代码这样它不会删除我电脑上的随机文件之类的Docker是完成这项任务的完美工具但我以前从未使用过它现在重要的是这个项目的目标不是使用DockerDocker只是我为了实现目标需要的工具我只想理解Docker的10%以便能够自信地以最基本的方式安全使用它如果我在90年代做这件事我基本上得买一本关于如何从基本原理使用Docker的书读前几章然后尝试跳跃阅读找出我想要的内容在这之后情况有所改善如果我在过去十年做这件事我会在网上搜索一些描述如何使用Docker的教程尝试跟着做然后在网上搜索我遇到的错误信息看看是否有人遇到同样的问题但今天我只需要请语言模型教我Docker所以这里是我这样做的过程一旦我设置并运行了Docker我发现它在Linux上运行时存在一些权限问题我希望这些问题能够消失于是我就请模型帮我解决这个问题通过这个过程我了解了Podman并请模型将所有特定于Docker的代码改写成Podman版本然后当我想弄清楚如何在Docker容器中传递主机的GPU时我也向模型寻求帮助当我年轻时我的第一门编程语言是Java这可能是个错误我真的很喜欢编程但我绝对讨厌面对新项目的空白屏幕尤其是Java!甚至只是让它编译一个“Hello World”程序——“public static void main string args”是干什么的?括号应该放在哪里?哪些字母需要大写?为什么这里用花括号而那里用方括号?于是我做了我任何一个孩子都会做的事——我请我父亲帮我完成快进到二十年后我仍然不喜欢使用不熟悉的框架开始新项目仅仅是处理模板代码就需要花费很多时间而且我对自己在做什么没有任何了解例如最近我想尝试编写一些CUDA代码以在GPU上基准测试一些简单贪婪搜索的性能并将其与某人高效优化的CPU实现进行比较但我不知道如何编写CUDA程序我会写C语言我了解GPU的工作原理、内核的作用、内存布局等等但实际编写代码将任务发送到GPU?我不知道如何开始所以我请模型给我写一个初稿的CUDA程序它完美吗?绝对不!但这是一个开始而这正是我想要的你会注意到这里的代码经常是错误的!其实我完全可以接受这一点我并不寻求完美的解决方案我需要的是一个起点然后我可以从那里开始改进如果未来的模型能做得更好那就太棒了但即使是现在的模型已经对我有很大的帮助了另外完全不同于上面提到的项目对于我在家里进行的一些个人项目我使用了一块树莓派Pico W这是我第一次使用它我希望它能为我做一些事情特别是一些网络方面的事情现在我相信我可以在网上找到一些好的教程描述如何实现我想要的功能但是你最近有没有看过互联网?前五个搜索结果通常只是一些垃圾内容农场里面有2008年写的有bug的代码只是为了SEO而更新根本不起作用所以我只是请一个语言模型教我如何做我想做的事我以前使用过微控制器所以大致了解它们的工作原理但我从未使用过Pico W我只需要一些帮助来处理所有的依赖项然后我可以自己解决其余的问题我总是为新微控制器编写的第一个“Hello World”程序是让一个LED闪烁这让我可以测试我是否能够编译并上传代码到设备所有引脚是否设置正确并基本了解我在做什么所以我直接请求模型给我写一个闪烁程序再说一次:这在网上存在吗?几乎肯定存在但是我还得去搜索它一旦我把这段代码运行起来从这里开始我就知道该怎么做了我知道Python是如何工作的信不信由你!所以我可以直接从那里继续编辑内容已经把特别的Micro Python部分处理好了当我遇到另一个需要特别处理的问题时我可以再次请求模型帮助我比如在这里我继续请求模型为我写一个连接到WiFi的脚本然后我再次遇到困难这次需要连接到一个MQTT服务器我就请求模型帮我解决我现在经常这样做甚至这一节开头的例子也不是假设——这里是我询问如何使用Flexbox的方法因为上次我学习新的HTML布局方式还是用div替代表格的时候作为一名安全研究员我经常遇到这样的情况需要处理一个包含几千行代码的新仓库这是别人的研究项目我必须弄清楚它是如何工作的然后才能进行攻击这听起来不难如果每个人都写干净的代码这真的不应该难但现实并非如此研究人员没有动力发布干净的代码所以人们常常会发布他们手头能用的任何垃圾代码我也这样做我没有可以在这里分享的研究相关例子但我可以分享一个我正在进行的个人项目的例子据说我对康威的生命游戏有一种不健康的痴迷最近我尝试找到一种从Python快速评估一些生命模式的方法有一个很棒的C++工具叫golly可以做到这一点但我不想把我的Python代码改写成C++现在golly有一个CLI工具可以实现我想要的功能——我只需要找到正确调用它的方法第一步是处理支持大约50种不同命令行选项的C++代码只让它执行我想要的一个功能所以我把全部500行的C++代码丢给LLM并请求一个简化版的文件只做相同的事情你知道吗?它完美地完成了然后我请求为C++代码编写一个Python包装器结果也成功了这又是一个我觉得太麻烦以至于我自己可能永远不会去做的任务之一但是既然现在我可以请求别人帮我完成我就得到了一个比原来的Python代码快100倍的东西我发现自己经常这样做这里有另一个例子我在做同样的任务这次是用Python同样这些任务都不难但每次我这样做时我都节省了大量时间这是我认为现有LLM很棒的一个方面:这并不光鲜亮丽也不会因为你说“这里有一个无聊的方式我用LLM让我的生活更轻松”而得到很多网络赞誉但这是现实有很多事情我必须做但它们非常无聊不需要任何思考但却需要完成事实上我发现自己拖延任务的主要原因之一是因为我知道完成它们会感觉很烦人和痛苦LLM极大地减少了这种痛苦让我更容易开始工作因为我只需要解决有趣的问题因此我想介绍一些完全平凡的问题这些问题我通过请求LLM帮我解决了例如最近我不得不反汇编一些用Python 3.9编写的Python程序大多数Python反汇编器只适用于Python 3.7及以前版本但在我使用的3.9二进制文件上运行失败反汇编其实并不是很难的任务主要是避免在你跟随goto重构控制流时出错因此我没有花时间手动为几百行代码的几千个操作码执行这项转换而是请求LLM为我完成这效果非常好!比我预想的要好得多这里有三次不同的对话我让模型为我做了这件事另一个例子是当我需要将一些非结构化数据转换为结构化格式时例如我在做一个项目时需要获取带有作者姓名的书名列表所以我在网上找到了某种非结构化格式的数据并请求LLM为我格式化它或者最近我在写一篇关于如何突破某些防御的博客文章并且想展示我修改的完整代码差异所以我粘贴了代码差异和一个之前如何将差异转换为HTML格式的示例然后请LLM将这个差异按之前的格式输出再举一个例子作为我工作的一部分我经常需要生成我使用的资源的引用Google Scholar让引用论文变得很容易我只需复制粘贴正确的引用即可但引用网页稍微有些麻烦;最近我就直接请求LLM为我生成引用需要明确的是:我会检查这些引用是否正确!我可能还能举出至少一百个类似的例子但我想你已经明白我的意思了我完全理解这类任务可能有人会看了说“就这样??”但让我们记住五年前LLM还几乎无法串连起一个连贯的段落更不用说为你解决整个问题了如果你曾经看过某人在使用某个工具时比你熟练度低得多这可能会让人有些痛苦你会看到他们在一个可以通过某种宏或巧妙地使用并行应用程序自动化的任务上花费数分钟甚至数小时但是学习这些必要的“咒语”需要时间而且很有挑战性例如最近我试图编写一个Python程序来处理来自Apple Lisa键盘的键盘输入我在网上找到了一些人在C语言中编写的代码其中有许多像#define KEYNAME key_code这样的语句我想把这些语句转换成一个Python字典将整数代码映射到相应的字符串现在我是一个Emacs用户我知道如何在Emacs中解决这个问题这甚至不是很难以下是我刚刚录制的键捕获内容可以实现这一效果:虽然这对我来说几乎是自然的但我已经花了半辈子时间来使自己在Emacs中足够流畅以至于这变得自然但你知道现在我连接到编辑器上的LLM会让我输入什么吗?然后文本会突然在我眼前被重写正是在这种情况下我认为LLM的潜在实用性对于非专家甚至比专家更高模型提高了每个人的起点如果你以前什么都做不了现在突然你可以做很多事情真正的程序员想要了解一个工具的工作原理时会阅读参考手册但我是一个懒惰的程序员我只想要现成的答案所以现在我直接问语言模型当我向一些人展示这些例子时他们会有些防御地说:“LLM并没有做任何你不能用已有工具做到的事情!”你知道吗?他们是对的但是用搜索引擎你能做到的事情实际上你也可以用关于这个话题的书做到而你用书能做到的事情通过阅读源代码也能做到但每一步都比前一步更容易而当某件事变得更容易时你就会更频繁地去做并且以不同的方式去做所以这里是我问“什么$东西能给出所有剩余参数”并得到答案紧接着是另一个“我怎么使用这个东西”的问题!实际上这是我最常用LLM的方法之一我之所以不能给你提供更多这样的例子仅仅是因为我在Emacs和Shell中内置了一个查询LLM的工具所以90%的情况下当我想做这些事情时甚至不需要离开我的编辑器过去在互联网上搜索内容是一项需要技巧的技能查询中需要包含哪些特定词汇?应该是复数形式还是单数形式?过去式吗?哪些词汇你希望页面上不要出现?我需要的是X和Y还是X或Y?现在情况不同了我记不起上次在谷歌中使用OR进行查询是什么时候了也记不起上次使用减号(-)来排除部分结果是什么时候了大多数情况下现在你只需写下你想找到的内容搜索引擎就会为你找到但是搜索引擎仍然不是100%的自然语言查询它仍然有点像在玩反向危险游戏试图使用答案中会出现的关键词而不是问题我认为几乎所有人都忘记了我们学会这项技能的过程对于一些简单的任务随着时间的推移越来越多语言模型今天表现得更好我可以直接输入“我知道+对应__add__但对应什么?”它会直接告诉我答案是__inv__这是用标准搜索引擎很难搜索到的东西是的我知道有一种方法可以找到答案可能如果我输入“python documentation metaclass "add"”,然后在页面上搜索我就能找到答案但你知道还有什么方法有效吗?直接向LLM提问这样做每次只能节省几秒钟但当你正忙于解决某个编码任务同时试图记住无数事情时能够直接抛出你要解决的问题并得到连贯的答案是非常棒的这并不是说他们今天在这方面表现得完美语言模型只知道那些在网上被反复提及的事情“反复提及”到底意味着什么取决于模型所以我确实需要花一些脑力思考是该问模型还是问互联网但模型只会变得越来越好或者每当我遇到随机崩溃时我会把看到的内容输入模型并请求解释比如在这里我输入zsh no matches found "Remote wildcard transfer issue"时的做法或者作为一个完全不同的例子去年我在写一篇博客文章时想让第一个词的首字母变大并让其余的文本围绕它排版就像我刚刚在这个句子中所做的那样现在这种效果被称为首字下沉但我当时并不知道这一点我只知道我想要的效果所以我问语言模型“我想让它看起来像一本华丽的书文字围绕着O”它给了我正是我想要的效果:这项任务又属于“我只因为有LLM才做的”类别——我不会认为花费大量时间来弄清楚如何做到这一点是值得的但是因为我可以直接问模型我就问了这让我的文章变得更好看了一些有两种程序第一种是你希望做得好的程序;这些程序会存在一段时间并且代码的整洁性很重要因为你需要维护它们好几年第二种是存在仅仅25秒的程序;它们帮助你完成某个任务然后立即被丢弃在这些情况下我完全不关心代码质量程序是完全独立的现在我几乎只用LLM来为我编写这些程序请注意:这些案例大多数是那种你看了会说“就这样?”的例子但就像我之前说的我每天只有这么多时间来处理一个特定项目如果我能省下写一个再也不会用到的程序的时间和精力我会选择这样做最常见的例子可能是帮助我生成可视化一些研究实验结果数据的图表我有几十个这样的例子可能更接近一百个而不是零它们看起来基本一样所以这里只展示一个:或者另一个类似的例子是当我有一种格式的数据并想将其转换为另一种格式的数据时通常这是我只需要做一次的事情一旦完成我就会把生成的脚本扔掉但我可以给你举出成千上万这样的例子很多时候当我想编写一个足够简单的脚本时我会直接请求LLM为我编写一个完整的脚本例如这里我请求LLM为我编写一个脚本能把我的论文读给我听以确保它们没有愚蠢的语法问题在很多情况下当我不完全知道自己想要什么时我会从请求模型提供一些初始代码开始然后从那里进行迭代例如这是一个一次性任务我只需要快速处理一些数据在2022年我会花两分钟用Python编写这个脚本然后等上几个小时运行因为它只运行一次——优化它所花的时间比Python程序运行的时间还要长但现在呢?我当然会花同样的两分钟请求一个Rust代码来为我处理数据或者这里是另一个例子我请求模型为我下载一个数据集并对其进行一些初步处理对我来说容易吗?是的可能很容易但这不是我想要思考的任务;我想要思考的是我将用这个数据集进行的研究消除干扰非常有价值远不止节省的几分钟时间还有一次我在编写一个程序以便能够用小方块3D打印一些像素化的图像为此我想将一个PNG文件转换为STL文件;但这不是项目的重点这只是必须要完成的一件事所以我请求LLM为我解决这个问题或者另一个例子是我最近想用Docker Compose来设置一个新项目我遇到了问题只是想尽快让它运行然后再弄清楚出了什么问题