📱

Get Our Mobile App

Take your business learning on the go!

Download on the App StoreGet it on Google Play

Keynote: AI-Powered App Development - Steve Sanderson - NDC London 2026

NDC Conferences54:05

Transcription

好的,大家早上好,欢迎各位。感谢大家前来。我总是对那些即使在会议的最后一天,也能克服万难起床并冒雨前来的人印象深刻。你们做得很好。

嗯,在我们开始之前,在我说出任何愚蠢的话让自己难堪之前,我想先了解一下在座的各位,你们在这个领域已经做了些什么。嗯,如果你们已经以某种方式使用人工智能来生成代码,请举手示意。是的。哦,天哪,几乎所有人都举手了。有多少人正在使用像 Cloud Code 或 Copilot CLI 这样的基于 CLI 的工具?是的。好吧。我们大概有 40% 的人。

很好。这对我来说非常酷,非常有趣,因为我一直都在研究这些东西。我叫史蒂夫。我在微软工作,我在 GitHub Copilot 编码代理运行时团队工作,这个名字显然需要一个更短的版本。但这就是我们所做的。我一直都在做这件事,对吧?所以我一直在思考人工智能编码代理。我正在使用编码代理来构建编码代理,并与其他关于编码代理的人交谈。对我来说,这是一个迷人的领域。感觉这可能是我加入科技行业以来发生的最大变革。它肯定正在改变我日常编写代码的方式。它改变了我创造的东西的类型,以及我感到有能力去做的事情。我相信在座的许多人对此有不同的看法。比如,有多少人认为这可能是一个非常糟糕的错误?有人吗?是的。好吧。好吧。所以,也许这里只有大约 10% 的人愿意承认。但你知道,这确实是一个担忧,对吧?我们作为一个行业,到底在做什么?我们将变成什么样子?

所以,让我们稍微思考一下这个问题。让我们先思考一下,我们到底希望软件行业是什么样的,或者我们为什么会进入这个行业。所以,请回想一下过去某个时候,当你作为一名软件开发人员,对自己的职业生涯感到非常满意的时候。当你正在做你喜欢的事情的时候。比如,想想你曾经工作过的一个你认为很棒的团队,一个你早上愿意去上班,启动电脑,泡杯咖啡,然后开始着手工作的项目,因为这个行业把我们都带入了其中,可能是出于共同的原因。你知道,我猜想我们在这个房间里有很多共同之处,为什么我们加入了这个行业。其中一个主要原因可能是我们喜欢电脑,对吧?就像我们大多数人从小就喜欢用电脑做事情,并且喜欢用我们的大脑通过电脑解决问题。你知道,我们喜欢它复杂但确定性的想法。你知道,它对我们很公平。如果我们能解决问题,它就会正常工作。我们可以运用我们的智慧将我们的想法转化为能够真正改变我们用户现实世界的东西。这一切都很棒。到目前为止,我们通过这种方式工作,拥有了一份不错的事业。

但感觉有些东西正在发生变化,因为到目前为止,只有我们能够编写可运行的代码,对吧?我们拥有其他人所没有的独特能力。这就像我们的个人护城河,给了我们一些特殊的经济优势。但现在机器也能编写代码了。甚至非技术用户也可以利用机器来编写代码。这是一个好主意吗?还是我们在把自己逼上绝路?

所以,让我们来思考一下我们是如何走到这一步的,对吧?所以,这可能始于几年前,当时出现了一系列工具,展示了我们可以利用人工智能来生成代码的方法。好吧,我们有了像 Cursor 和 VS Code 的 Agent Mode 这样的 IDE 工具,它们向你展示了如何与代理进行聊天,并且它会开始为你编写代码。我们还有网络版的 GitHub Copilot,你可以在那里提交一个 issue,将其分配给代理,它就会为你创建一个 PR。好吧,这就是这项技术的第一波浪潮。但随后,在基于 CLI 的工具浪潮之后,第二波浪潮也很快到来了。所以,Cloud Code 是第一个出现的,它定义了整个产品类别,随后迅速出现了 Gemini、CodeX CLI 和 C-Pilot CLI 等其他产品。我知道在座的许多人现在都在使用它们。但当我们显然有更现代的替代方案时,我们却决定回到这种旧的 UI 技术,这有点奇怪,对吧?我们为什么要这样做?这真的很奇怪,对吧?

我认为这些基于 CLI 的编码代理工具,它们经常被描述为“多巴胺机器”。这很奇怪,对吧?因为它们不与任何特定的 IDE 绑定。它们不与任何仓库绑定。它们不与任何特定的基于网络的工具绑定。你只需要在你的电脑上随时打开它们。你给它一个任务,在 5 到 10 秒内,你就能看到任务取得了一些进展,并且你会感觉很好。然后你每隔 10 秒钟再做一次,再过 10 秒钟再做一次。这有点令人上瘾。构建这些 CLI 工具的团队能够快速迭代。你知道,他们摆脱了一些现代 UI 的顾虑,能够专注于让代理变得非常出色。并且他们能够迅速获得比你可能习惯的更好的东西,如果你没有使用过这类工具的话。

但这有区别吗?嗯,人们对此会有不同的看法。如果你相信他们,有些人会告诉你,他们能够以这种方式更快地完成工作。就我个人而言,我觉得我能理解这一点。我绝对觉得我能够比以前在更广泛的情况下更快地生成代码。而且我认为这不仅仅是我。这是我工作团队的一些统计数据。所以,这是截至几天前的一周。这是一个大约七到十人的团队。在一周内,我们合并了超过 200 个 PR。现在我承认,其中大约一半只是琐碎的,比如给文档加一行,或者别的什么。但我认为,实际上,其中一百个是严肃的功能,在过去需要好几天的工作。你知道,实现良好,包含一整套测试等等。所以,我们每周从 10 名开发人员那里获得一百个这样的功能,每位开发人员每周 10 个非琐碎功能。这比我过去习惯的要向前迈进了一大步。

好的。所以,让我们看看它的感觉如何,让我们踏上一段小旅程,我们将尝试一下,我们能多快地创建一个功能,然后我们将开始思考这会把我们带到哪里,它会迫使我们以什么样的“新思维方式”来思考,以及它可能会给我们带来什么样的问题。因为这并非全是阳光和幸福。我们可能会在我们所做的事情中遇到一些困难。所以,让我们试着预测一下。

好的。所以,让我们试着实现一个功能。假设你刚刚加入了 Copilot 团队,在你工作的第一周,你想添加一个功能,嗯,在你工作的前半小时,你想添加一个功能,它可以告诉你有哪些模型可供交互。所以,我们这里有命令行上的 Copilot,假设我们想运行 `show models`。好的。问题是,它作为一个功能不存在,对吧?这是一个未知选项。所以,让我们现在自己来实现它。我们先检查一下我们是否处于一个良好、干净的状态。我们是。然后我们将打开 Copilot,并尝试着手处理它。

好的。所以,我们的 CLI 工具出现了,我们可以对它说,比如,“向 CLI 添加一个 `d-show models` 命令,该命令列出可用于处理的标准输出模型。”好的。所以,它将开始思考这个问题。它将如何做到呢?嗯,我不知道。这是非确定性的。它决定在这种情况下使用 `explore` 子代理。所以,子代理是我一会儿会向你解释的一个新功能,但那是另一个专门负责弄清楚如何做事情的代理。它已经弄清楚了 CLI 的入口点在这里,在 `index.ts`。它看到了一个它可以遵循的模式。它只是告诉我们它将添加 `d-show models`。它正在弄清楚在哪里添加它。它注意到有一些类似的东西可以遵循。它现在已经开始编辑文件了。好的。它完成了吗?嗯,还没有。它仍然需要实际实现这个功能,它正在这样做。它决定构建它。所以,它将检查是否有任何编译错误。会有错误吗?没有。好的。它现在将自己运行它,看看它实现的功能是否真的有效。它说它有效。它正在验证它是否在帮助中,我将在此停止。

好的。所以,让我们看看我们现在有什么。所以,让我们去看看它做了哪些改变。好的。所以,它在选项列表中添加了 `d-show models`,并且它还添加了一个处理程序,该处理程序将记录一些模型。让我们检查一下它是否真的有效。所以,如果我现在运行 `copilot show models`,它确实可以。它会生成一个模型列表。好的,很酷。所以,我们能够在大约一分钟内从无到有地实现一个功能,这相当不错。你可能会想,好吧,那又怎么样?这只是一个五行左右的功能,不是吗?是的,确实如此。但实现这样一个功能最难的部分,并不是那五行代码。而是弄清楚你该把它们放在哪里,以及什么才算遵循了正确的模式等等。当然,如果我让它继续下去,它还会为我编写一些测试和其他类似的东西。

好的。所以,这似乎是一个很好的起点。所以,希望我们能够每天交付多个非琐碎的功能,这似乎并不荒谬。是的,这显然是一个相当琐碎的功能,但如果我们工作一个小时左右,我们可以做一些更大的事情。

好的。所以,如果我们能够如此快速地进行更改,它就会迫使我们以一种略有不同的方式思考代码。我们开始与我们的项目建立一种不同的关系。所以,这是我们团队现在对代码以及我们整个职业生涯一直遵循的规则所持有的不同态度的几种方式。也许其中一些不再适用了。

所以,我认为我们很快就会觉得代码不再是宝贵的资产了。代码很便宜。如果你想写很多代码,你可以很快写出很多代码。如果你想原型化某些东西,特别是如果它不需要达到生产标准,你现在可以以令人难以置信的速度完成。原型现在基本上是免费的。原型和生产就绪代码之间仍然存在很大的差距,但特别是对于原型,它们非常非常便宜,非常非常快。当我们开始处理某项工作,发现它需要大量非琐碎的实现时,过去我们可能会想,哦,那将需要很长时间来完成,而且维护起来会很困难,等等。我们不再有这种感觉了。我们可能只会觉得,好吧,我需要一千行代码来解析一些东西。那又怎样?Opus 模型可以在几分钟内为我生成。如果以后我不喜欢它,我会把它扔掉。如果我需要重写它,我会重写它。如果我需要更改语言,如果我需要更改库,无论什么,我以后都会重新生成它。代码本身很便宜。我不需要对它过于在意。

在设计流程方面,过去,如果你要做一周的功能工作,你可能会安排一堆会议,并希望在开始工作之前真正就这个功能建立共识,并弄清楚所有架构方面的考虑因素,并预见问题。我们现在不再那样做了,因为我们现在发现,如果你有一个你将在几个小时内完成的功能,那就去做吧,对吧?代理会生成一个实现。事实上,可能有多种不同的方法来做某件事。全部做三种,没关系。然后你可以比较实现某事的三个不同方法。通过实际工作来学习,然后看看结果如何,架构问题实际上变成了什么。然后到最后,你可能会把它全部扔掉,因为它在某种程度上是混乱的。但如果不是,也许这三者之一就是你想要的。所以,这是我们处理工作的一种不同方式。

好的。所以,让我们深入了解一下。让我们开始思考你可以如何定制和调整代理将要做的事情,并希望让你比以前更成功。因为在我们进行的过程中,我们会发现有些事情实际上会给我们带来新的挑战。并且会有很多未知数,我们需要尝试预测我们正在做什么,以及我们需要什么才能更成功。

好的。所以,说到编码代理,有很多不同的功能和术语,你可能熟悉,也可能不熟悉。这里有一堆词,这些词对应于编码代理工具中的功能。当然,它在不同工具之间略有不同。Cloud Code 将具有与 Copilot 或 Gemini 或 Opus 或抱歉,Opus 是一个模型,或者像 Open Code 这样的不同功能。它们都将具有略微不同的功能,我在这里不是要试图将你推向任何一个。我认为所有这些你都可以成功地使用。我将向你展示 Copilot。我实际上是在那个团队。但是,你知道,它们都有类似的功能。

好的。现在,我将首先更详细地向你展示这个子代理功能。但在我解释它之前,让我先开始一个演示,因为它需要一分钟时间在后台运行。所以,我需要一个大型代码库来开始向你展示一些东西。所以,这里有一个游戏引擎。它实际上实现了 Doom,我相信在座的大多数人都熟悉它。它实际上是用 .NET 编写的。嗯,这是一个几周前收到的 pull request。假设你的工作是审查这个 pull request。嗯,你可能会看它,然后说,“哦,改变了两个文件。这对我来说将是一个非常容易的审查。我一分钟就能完成。”所以,你进去看看他们在两个文件中所做的更改,然后你看到,哦,你知道吗?这并不那么容易审查。实际上,这有点可怕,特别是如果你真的想知道这些代码的每一行都没有像“差一错误”这样的东西,或者类似的东西。这将是一个非琐碎的过程。

那么,如果我们能让我们的编码代理来做审查阶段呢?嗯,也许我们可以。或者它只是会产生一些垃圾?我们怎么知道?所以,让我们试试。我将去 Copilot 这里,然后我将启动它,然后我将告诉它我希望它审查这个。所以,我将说,“我希望你审查 PR。跨 Opus、Haiku 和 Gemini 并行粘贴。”现在,这三样东西,它们是不同的 AI 模型,它们对这段代码会有略微不同的看法。有些会比其他更严格。有些会以某种方式产生幻觉,而另一些则可能不会。但通过在多个代理之间运行这种并行的代码审查,我可以获得多个级别的反馈并进行比较,并尝试找出真正的信息是什么,什么不是。

所以,你可以看到它已经从 GitHub 获取了 PR。它实际上正在使用其大型输出处理。所以,因为模型有有限的上下文窗口,它决定这太多了,无法放入上下文窗口。所以,它将其保存到磁盘上的一个文件,然后每个不同的代理都可以按需读取这些文件的不同部分。

好的。所以,它已经获得了 PR 内容,并且它已经在这些三个不同的代理之间启动了并行审查,然后它必须等待它们产生输出。

好的。所以,当它运行时,让我们回到这里。对。所以,子代理,这就是我刚才在这里展示的,一个代理可以并行启动多个任务,具有不同的上下文窗口、不同的工具、不同的模型等等,并为你组合结果和编排事物。计划模式我一会儿会讲到。我将为你演示。这是一种你可以预测或与模型合作,为你要做的工作制定一个全面的计划,并尝试避免它做错事情的情况。技能是一个相对较新的增强功能。有多少人已经看到或使用过技能?是的,人数很少。好的,所以这值得深入研究一下。所以,技能是你为编码代理创建可重用功能,然后与团队中的其他人共享它们的一种方式。我将向你展示一个例子。委托是一种在你本地处理完东西后将其上传到云端的方式,这样你就不用耗尽自己的机器了。记忆,这是一种跟踪可以跨团队共享的事实的方法。所以,如果你的一个同事告诉代理某事,比如,“哦,永远不要用这种方式写测试。总是用另一种方式写测试。”那么这个记忆就可以在你的项目中存储和跟踪,这样其他编码代理就会自动获取它。钩子提供了确定性的回调,因此你可以更改代理的行为。其他东西也很酷。但让我们看看这个审查进展如何。我可以看到 Haiku,哦,实际上它们都刚刚完成,对吧?好吧。所以,Haiku 最先完成,然后是 Gemini,然后是 Opus,现在它正在将所有这些内容合并成一个综合审查。Opus 发现了一个特定的问题,让我们看看。好的。好的。所以,它给了我们这个报告。Opus 发现了一个问题。Haiku 没有发现任何问题。Gemini 发现了三个问题。我不想单独阅读它们。我只想告诉它,我想知道它们是如何比较的。所以,主要的意见分歧是什么?

好的。所以,让我们看看这些不同的审查是如何相互比较的,以及我们可以从中了解什么。所以,我们有一个关于 `elementbounds empty` 的问题,Opus 说有一个 bug,Haiku 则没有。好的。所以,它说了什么?它说 Opus 更严谨。数学确实会溢出。总体评估 Opus 发现了一个问题。Haiku 说根本没有问题,Gemini 发现了三个问题。好的。所以,这与我使用这些模型的经验相符。如果你不知道,Haiku 是这些模型中最小的一个。它响应非常快,但它没有很好的深度洞察。Gemini 是一个稍微更焦虑的模型。它倾向于抱怨很多事情,并且会注意到很多架构问题,即使它们不是真正的问题,但了解它的观点很有趣。而 Opus 目前是编码代理世界的“大人物”。这可能是我最感兴趣的意见。

好的。所以,这就是我们如何从一个像这样的编码代理工具中轻松地编排多个代理。

好的。所以,让我们深入研究一下其中的一些功能,并且让我们也稍微思考一下这现在将给我们带来的一些挑战。所以,我不知道你怎么样,但过去 JavaScript 框架每三天就出现一次,我发现很难跟上。就编码代理而言,情况更是如此。在这些功能列表中,大约一半的功能是在过去三周或更短时间内发明出来的。这不是夸张。所以,就像试图跟上这一点几乎是一项全职工作。这是我的全职工作,我都在努力。所以,我同情那些不能把这当作全职工作的人。而且,这不仅仅是产品本身在发货的东西。其他人还在发明更复杂的东西,你可以在编码代理之上做。这里有两个例子,对吧?所以,这个叫做 Gas Town 的东西最近在 Hacker News 上开始流行起来。Steve Yagi 是软件行业的一个知名人士。他创造了这种虚构的编码代理世界,你有一个市长,他们有代表工作的珠子车队,他们把它们送到不同的代理那里,你知道,这是一个完整的虚构的“让我们假装”的编码代理世界,它是否有效,我真的不知道,但人们正在玩弄这些东西。

另一个大约两周前变得非常热门,可能持续了三天的是 Ralph Wigum,我相信你们中的一些人听说过,而你们中的一些人可能只是在想,我为什么在这里?我为什么起床要听这个人谈论 Ralph Wigum?它为什么重要?嗯,问题在于,编码代理可能非常懒惰,而 Ralph Wigum 试图解决这个问题。所以,你会告诉你的代理,嘿,做这个任务。它有六个部分,它会做一点,然后说,我完成了六个任务中的四个,所以我完成了。然后你说,什么?不,去完成另外两个任务。它说,是的,你说得对。我将完成这两个其他任务。然后一分钟后,它会说,那些有点难,所以我以后再做。然后你说,不,去做。它会说,好的,是的,我会的。然后它会说,我添加了待办事项注释,说明我们以后会做这些。然后你会想,我为什么要做这个?所以,Ralph Wigum 试图强迫它实际完成工作。它只是一个 while 循环,不断地对编码代理说“去做,去做,去做”。想法是,你让它整夜运行,或者别的什么,谁知道它消耗了多少 token。但当你早上醒来时,你已经将整个操作系统移植到了 Rust,并且你知道已经创造了 AGI。这就是它的想法。它有效吗?它无效吗?为什么叫 Ralph Wigum?嗯,这些都是谜。但我想鼓励你思考这些东西,但不要过于沉迷其中,因为这些东西会一直变化。而且,我不知道你怎么样,但你可能会开始经历一点“错失恐惧症”(FOMO)。比如,考虑到我们迭代的速度如此之快,你怎么知道什么值得思考,什么不值得思考?

所以,为了试图抵消一些这种 FOMO 效应,我想回到一些我认为是真正宝石的基本原理,根据我在过去六个月里与编码代理团队合作的经验。我们认为什么才是真正影响代理在给定任务上成功或失败的基本原理?我们将从计划开始。你可能会注意到,所有这些都是对人类来说也普遍很好的事情。所以,这似乎是合理的,对吧?计划。分配给编码代理的任务可能不符合你期望的原因之一是问题可能被低估了,而代理非常懒惰。如果它们可以侥幸说,“哦,我以最简单的方式完成了这个,无论你是否想要它,它们都会这样做。”所以,计划是一种确保你事先充分沟通你希望代理做什么的方法。让我向你展示。

好的。所以,我需要另一个应用程序来处理。所以,我选择了字面上最主流的商业场景,那就是标准的电子商务,对吧?所以,我有一个开源的 .NET 电子商务平台。它是完全正常的。唯一不寻常的是测试数据中令人难以置信的价格,以及语言似乎都搞错了。但除此之外,它只是正常的电子商务。

好的。现在,假设我想在这个应用程序中添加一个非琐碎的功能。所以,我可以在这个仓库中进入我的编码代理。让我们启动 Copilot。然后,我可以告诉它开始工作。好的。但我该如何确切地告诉它该做什么呢?你会注意到这里有一个“切换并制表以循环模式”的东西。我可以这样做来切换到计划模式。当我处于计划模式时,它知道无论我告诉它做什么,我都不真的想让它开始实现,我想让它和我一起制定一个计划。

好的。所以,让我们告诉它一个复杂的功能来处理。添加一个产品定制功能。好的。这可能是一个巨大的工作量。比如,产品定制是什么意思?所以,它将开始思考这个问题。它希望研究我们的产品代码。是的。所以,它正在列出文件。它再次使用那个 `explore` 子代理来探索架构,并且它正在思考这个项目以及它可能意味着什么。哦,它说产品定制是模糊的。我需要澄清用户的意思。所以,它将如何做到这一点?

好的。所以,它给我们带来了多项选择。我们可以输入任意答案,如果我们愿意,但假设我只是选择我想要“构建自己的产品”选项。所以,让我们把它放进去。它将再思考一下。也许它已经准备好编写计划了。也许还没有。好的。它说,“‘构建自己的’用例是什么?”我只是想用“定制 PC 构建器”。好的。也许它现在可以开始了。我不知道。让我们看看。好的。系统信息是否兼容?好的。我不想再想这个问题了。这是一个演示,对吧?所以,我不需要它是一个完整的东西。所以,我只是要告诉它,“现在不要再问问题了。”然后它现在将不得不开始处理这个问题。

好的。所以,它将思考这个功能,并希望它能想出一个如何实际执行的计划。好的。所以,让我们稍等片刻,因为它在思考“创建实现计划”。它正在列出文件。它正在搜索东西。我有足够的信息来创建一个全面的计划。让我创建计划文件。继续。好的。所以,它创建了这个文件,你可以看到它进入了一个临时目录,而不是我的实际项目,因为它可能只是一个短暂的计划。如果我们愿意,以后可以把它移到项目中,但它已经在后台完成了,并且说你可以按 Control+Y 来阅读整个内容。所以我将这样做,然后希望它会在我的 IDE 中。好的。在这里。

好的。所以,这是它刚刚想出来的。问题陈述:添加一个“构建自己的”功能。这是我提出的方法。这是我们将要添加的一些实体。这是工作计划,分为多个阶段。这是技术架构。我们将添加数据库的东西,未解决的问题,等等。现在,这是一份非常重要的文件。如果你正在处理一个像那样的大型功能,如果我真的在做这件事,我会花很长时间来处理这份文件。我会轻松地花一个小时与代理一起完善这个计划,并实际分解这些工作中的每一项,检查我是否理解了架构将是什么样的,预见任何问题,告诉它其他事情,等等。它可以自动更新这个计划,或者你也可以自己编辑文件。在这种情况下,我只是要添加一些我经常添加到这些东西中的内容。对于每个阶段,在底部添加一个验证行,说明我将能够在 UI 中看到什么来检查它是否有效。

好的。所以,这是一个我给你的建议。通常,让你的编码代理不仅仅是生成代码,而是以一种结构化的方式来完成工作,这样在每个阶段都有一些你可以作为人类在 UI 中客观观察到的东西,以确保它实际上在做有用的事情,这是非常有帮助的。你不想让它只是生成代码然后编译。太好了。但你怎么知道它是正确的代码呢?你想看到它做些什么。

好的。所以,你可以看到它正在对那个计划文档进行大量的进一步编辑。它现在已经添加了像这样的验证步骤,并且它将继续添加更多的验证步骤。然后,当它实际处理这个任务时,它将保持计划的最新。所以,如果它学到了新东西,它会把它添加到计划中,并且它会随着任务的完成而标记任务。这将允许你跟踪它的工作,并且它也允许它在长远来看跟踪它的工作。

好的。所以,这是这些大型技术中的第一个。下一个我想谈的是组合。好的。所以,当你作为人类承担一项艰巨的任务时,你不会每次都从头开始学习。你将你已经知道的技能和工具带入过去,你可以应用它们,这使你工作得更快。编码代理也可能如此。技能是定义代理可以拥有的某些能力的一种方式,然后你可以跟踪它们,并在团队成员之间,甚至在整个行业中共享它们,如果你愿意的话。所以,让我向你展示如何获得技能,如何创建技能,以及如何使用它们。

所以,获得技能的第一种方法是安装其他人已经发布到互联网上的技能。所以,让我给你举个例子。所以,我将回到这里,在一个新会话中。我将首先列出我已经安装的技能。你可以看到我最初只有一个技能。现在,忘记它。这将是我几分钟后演示的一部分。所以,假设你没有看到它,现在没有安装任何技能。我将向你展示如何安装别人制作的技能。

好的。所以,我们可以做的第一件事是,我们可以从一个叫做“市场”的地方获取它们,它基本上只是另一个词,指的是一个包含技能的 Git 仓库。好的。所以,这是一个 Git 仓库。Enthropic skills。如果我在这里通过浏览器访问它,就是这个。然后你会看到,由 Enthropic 提供的这个是一个你可以插入你的编码代理的技能集合。我们有像 MCP Builders、PDFs、PowerPoint、与主题相关的以及其他东西。好的。所以,我们可以深入了解每个技能是什么,但让我们先尝试安装这个技能集合。

好的。所以,我们需要粘贴一个命令,因为它对我来说太难记了。所以,我需要什么?就是这个。所以,`plugin install document skills blah blah blah`。好的。所以,它已经安装了这个 `document skills` 插件。现在,如果我列出我的技能,你会看到我有很多技能,它们对应于我们刚才在那个仓库里看到的东西。

现在,技能到底是什么?它们在机械上是什么?嗯,当你一会儿创建一个时,你会看到,但另一种看待它的方式是访问这个提供其规范的网站,它显示一个技能基本上只是一个 Markdown 文件。它是一个带有元数据的 Markdown 文件。如果我们能看到一个例子,这是 PDF 处理。它有一个名字。它有一个描述。然后它有很多关于如何做它的信息。这可能是一份很长的文件。所以,技能的聪明之处在于它们是如何逐步披露给模型的。模型有有限的上下文窗口,如果你有上千个技能,每个技能都有一个巨大的文档与之关联,你不会想把所有这些都加载到上下文中。它只会让模型感到困惑并导致性能下降。所以,技能的优点是它只需要将这个描述加载到上下文中。这足以让模型意识到何时需要使用特定的技能。当它意识到这一点时,它可以研究它并获取完整的信息。它不仅仅是 Markdown 内容。它还可以是工具和脚本以及类似的东西,我将向你展示。

所以,理解这个的最好方法可能是现在创建我们自己的技能。所以,假设你想让你的团队能够共享编码代理来检查你产品的构建状态。好的。所以,我现在就来做。我将首先向你展示我们刚刚安装了这个 `skill creator` 技能。所以,创建技能的最简单方法是使用 `skill creator` 技能。好的。所以,让我们说“使用 `skill creator` 技能创建一个技能,在那个位置,它应该询问用户哪个项目,我们将做 .NET asp.net .NET Core 或 GitHub Copilot SDK,并获取它的构建状态。”

好的。所以,它需要知道使用 `skill creator` 技能,对吧?所以,它最初不知道。它将意识到这个任务对应于 `skill creator`,并且它将把它加载到它的上下文中。一旦它完成了,它将进行一些研究,找出如何创建技能,然后希望它会实际做到。它正在运行一个 Python 脚本,它就像一个项目模板,用于技能。如果我们到这里,我应该能向你展示它实际上正在创建它。所以,它将出现在这里。现在它是一个空文件。好的。所以,它正在检查它在做什么。嗯,它在做什么?文件是空的。是的。哦,好的,它现在完成了。对。所以,它在这里添加了这个 `build status` 技能,并附有这个描述。并且它有一个工作流,对应于我刚才告诉它的,那就是询问用户哪个项目,然后检查。

当然,如果我想改变技能的工作方式,我可以直接编辑这个文件。但我也可以指示代理来更新它。所以,假设我只想让它从主分支获取构建状态。所以,让我们说“实际上只从主分支获取状态”。好的。所以,它将弄清楚如何做到这一点,并且它将进行一些编辑,希望如此。所以我认为,是的,它完成了。它刚刚在这个技能上添加了这个“分支主”的东西。

好的。所以,现在我和我团队中的其他人都可以使用它了,因为这将被存储在我的项目中的源代码控制中。

好的。所以,让我们实际使用它,好吗?所以,我将进入一个新的会话,并检查我们是否安装了它。你可以看到,默认情况下我们有它,因为它在项目中,`build status`。现在我可以使用它了。还请注意,它显示为一个斜杠命令。所以,我们现在可以自动完成技能名称来快速调用它。所以,让我们提交它。它将开始思考。显然,它知道我们希望它使用 `build status` 技能,因为我们使用了斜杠命令。它将把它加载到上下文中,然后它会问我们,“好的,你想检查哪个项目的状态?”让我们用 Copilot SDK。它将调用这个技能。所以,它将遵循其中指定的任何指令,并将其与其他任何它正在进行的任务合并。它正在做什么?好的。所以,它使用了 GitHub Actions 来获取构建状态,然后它正在解析它,并且它正在生成这片绿色的文本。所以,很好。它有效,而且这是你可以轻松地在团队成员之间重新使用的东西。

好的,太棒了。所以,我们在如何指导代理在我们的场景中提高效率方面取得了良好进展。让我们处理最后一个。现在,我认为这可能是所有这些中最重要的一项。所以,另一个非常令人讨厌的反模式是,编码代理可能会陷入其中,你告诉它实现某个东西,它说,“太棒了,我做到了,我实现了它”,然后你检查它,它却不起作用。所以,你回去说,“它不起作用。”它说,“哦,我真的很抱歉,我将为你修复它。”然后它做了一些改变。它说,“我现在做好了。”你试了一下,它仍然不起作用。陷入这种循环真的很令人沮丧。但你可以通过给代理一个反馈循环来打破这种循环,这样它就可以自己检查它的工作。这可以在多个级别上完成。所以,最简单的级别是,确保它能够实际编译你的代码,因为这样,如果有什么构建错误,它就能看到并自己解决。如果你有 linter,如果你有测试套件,同样,确保它能够自己运行它们,这样它就能检测到任何问题。但我认为最强大的方法是让它能够实际运行你的真实应用程序,并像最终用户一样与之交互,因为这样它就可以做你作为开发人员会做的事情。当你实现某个东西时,你实际上会在你的应用程序中尝试它,对吧?为什么代理不能这样做?嗯,如果你给它一个技能,它就可以做到。

所以,为了演示这一点,我将回到这个简单的电子商务东西,并想象我想在这个应用程序中添加一些其他功能。我将使用一个我之前准备好的技能来实现这一点,因为创建这个技能需要太长时间。所以,我有一个简单的电子商务自动化技能。我使用了 `skill creator` 来创建它,显然花了大约半个小时左右。并且我教会了它如何使用 Playwright 自动化浏览器,这样它就可以与我的应用程序交互。并且我给了它很多关于我的应用程序的特定信息,比如这是我们测试数据的标准管理员凭据。这是如何首先设置网站。这是如何启动浏览器。你不需要弄清楚。我提供了一些实际的脚本来完成这些。我还有所有这些其他小的 JavaScript 片段,教你如何探索和列出页面上的链接,以及如何导航,注册用户,以及类似的东西。并且你可以随着时间的推移构建越来越多的功能。

所以,让我们试试使用它,好吗?我将退出这里,然后我将开始一个新的会话。然后在这里,我将进入我的技能列表。你可以看到我在这里有一个简单的电子商务自动化技能。好的。所以,让我们使用它来启动一个浏览器。好的。所以,希望它会发现它需要将该技能带入其上下文窗口,并且它会这样做。然后它应该能够使用它。所以,它正在使用其中提供的脚本。并且你可以看到一个真实的浏览器刚刚弹出。好的,这很好。

现在,基于所有这些知识,我还可以让它做其他事情。所以,例如,我想让它使用该技能来注册一个新用户,史蒂夫。好的。并且因为有一个内置脚本来执行此操作,所以它应该能够相当可靠地完成。所以,它会发现使用哪个脚本,然后它会完成这个过程。它很快,但你可以看到它已经注册了这个用户并登录了。好的。而且我也可以用它来做更复杂的事情。所以,假设我想处理某种订单管理的东西,我需要一些测试数据,或者我想让它能够检查订单管理是否真的有效。我可以对它说,“再次使用该技能,并作为管理员创建一个新产品。我们称之为‘超级耳机’,然后为它下五个订单,以史蒂夫的名义。实际上是五个独立的订单。”

好的。所以,这是一个相当非琐碎的流程,它将不得不经历。但它应该能够做到,因为我们的技能告诉它如何探索网站,如何以管理员身份登录等等。所以,它已经生成了一个脚本,它已经以管理员身份登录,它已经进入了产品创建向导,它正在经历这个流程,它已经创建了超级耳机,它再次以史蒂夫的身份登录,并且它现在正在以史蒂夫的身份下订单。

好的。所以,显然,如果你只是想自动化测试目的的东西,这很有用。但我想说的更大的观点是,你真的希望代理能够自己做到这一点,因为它选择这样做。你希望它拥有那个

力量,每当它实现某个东西时,就可以立即开始。我实际上要检查一下这是否有效。让我打开一个浏览器,点击整个流程,确保这个功能确实得到了妥善实现。如果出现任何错误,它可以看到这些错误,然后回到代码并开始对其进行修改。好的,所以这些是我想要介绍的一些基本概念。

好了,到目前为止一切都很顺利。我们一直在快速前进。我们变得更有效率,我们更快乐。没有什么会出错,对吧?嗯,我想说的是,这很棒,但也有一些我们作为开发者需要开始思考的真正缺点。而且有一些困难的问题,可能甚至超出了我们能够触及的范围。但仅仅从一个简单的层面来看,我目前在我所在的团队中看到的一个最大的挑战是,我们产生代码的速度之快。

所以,这是几天前我们未合并请求列表的一个快照。这仅仅是当天前两个小时的统计。嗯,我们收到了六个新的未合并请求,其中五个正在等待审查。而且这仅仅是欧洲人在线的时候。所以我们只有三个人在欧洲。团队的其余成员都在美国,他们现在还在睡觉。而我们已经有了六个未合并请求,我们正在互相等待审查。

我们该如何管理这一切?就像以如此快的速度产生代码,谁来阅读它?我们怎么知道它实际上是正确的?我不认为这是一个已解决的问题。我不是来这里说答案是这个,因为我们现在不知道答案。这是我们正在努力解决的事情。显然,我们正在思考,我们能否投入更多的人工智能来解决这个问题?但我们不知道,对吧?它现在是一个未解决的问题。这对我们来说是一个挑战。

我还要提出另一个挑战,我不知道你们是否会对此产生共鸣,但它确实有点困扰我,那就是当我回到我的集成开发环境,开始用我实际的手指像动物一样写代码时,这对我来说是一种奇怪的体验。我不太确定要按哪个键,我只是看着我的手,想着让代码从它们那里出来。我不知道该怎么做。因为我猜想,我真正的肌肉记忆在某种程度上开始改变了,我觉得当我想要屏幕上出现一大段代码时,我应该用英语说出来。我不知道,现在打字感觉很奇怪。我对此并不感到自豪。我不认为这一定是一件好事。我不知道该怎么办。这是否是一个问题,还是不是?我是否需要做一些像每日手动编码练习来保持我的敏锐度,或者有没有意义?我真的不知道。但我非常想听听你们其他人对这类事情的看法。

显然,还有更深层次的问题,比如你知道我们作为一个行业,长远来看到底要去哪里?这对我们在世界上的角色,软件工程师的供需关系等等会有什么影响?我们现在还没有这些问题的答案。我感觉自己没有资格预测未来。所以我不打算这样做。但我很乐意和你们中的任何人聊聊这个,看看你们对此有什么想法。

但尽管有所有这些未知数,我认为我不会愿意让任何人现在把这个东西从我手中夺走。就像我获得的巨大生产力感是我不会放弃的东西。我确实觉得我可以做以前做不到的事情。

举个例子。上周,我使用了一些屏幕录制软件,它一直在崩溃。它是开源的。所以我去了 GitHub 仓库,想看看其他人是否报告了这个问题。是否有某种变通方法,其他人已经报告了,但没有变通方法。这个东西是用 Rust 写的,我不会说 Rust,所以通常我无法对此做任何事情。但我心想,哦,让我们看看如果我让 Copilot 来处理会发生什么。所以,我告诉 Copilot,去这个仓库,克隆它,调查以下问题,如果你能找到修复方法,就提交一个未合并请求。就这样。我没有告诉它如何克隆,如何提交未合并请求,任何这些东西。而且真的,在不到 10 分钟的时间里,它就找到了问题所在,它说这里有一个 UTF8 解析错误。这里有一个三行的修复。我已经为你提交了一个未合并请求,并且第二天未合并请求就被合并了。

这是我过去不会尝试的事情。也许如果我真的想,我可能会做到,但处理它是用 Rust 写的这个事实的开销,可能意味着我不会尝试它。但现在我被赋予了做这类事情的能力。所以这确实让我感觉很好,尽管存在所有不确定性。

现在,我们到目前为止所谈论的一切都是关于让你作为开发者拥有额外的能力,这很棒,但世界上除了软件开发者之外还有其他人。也许你可能也想为你的用户带来一些这样的能力。显然,在应用程序中使用人工智能已经可行多年了,但相对较新的是能够将来自编码代理的实际代理循环也集成到你的应用程序中,这带来了很多内置的、预优化的智能。

所以,我们在过去几周内发布了一个 Copilot 的 SDK。它支持 Node、Python、.NET 和 Go。也有其他语言的社区项目。这允许你在你的应用程序中使用与 Copilot CLI 相同的代理框架来处理其他功能,它带来了我们所做的所有工具、提示和优化,所以你可以开箱即用地获得非常智能的东西。

让我给你展示一个使用它的快速示例,我将从另一个软件相关的任务开始,这样更容易理解,但我稍后会告诉你它不限于此。所以,我这里有一个名为 issue sizer 的项目,目前还没有多少实现。我将实现一个可以估算特定问题解决难易程度的功能。它将利用 Copilot 编码代理的所有智能,但我将能够从我自己的代码中控制它。

所以,让我们开始添加一个 Copilot 客户端实例。它将使用我本地安装的任何东西以及我登录的任何凭据。但你可以自定义它,如果你传递选项。好的。它将创建一个新会话。然后我将非常简单地向你展示,我们可以让它列出这个目录中的文件。现在,我不需要给它任何特殊的工具来访问文件系统或其他东西,因为它正在使用真实的编码代理来完成这个任务。而且它显然已经具备了查看周围文件并就如何调查它们做出决定的能力。

现在,第一次运行时需要一点时间。它总是这样。在它完成之前,我们不会看到任何输出,但我很快就会解决这个问题。好的。你可以看到它正在那里运行在构建输出目录中。所以它看到了一个可执行文件和一堆 DLL 和其他东西。好的,这没问题。但让我们获取更多关于它在做什么的信息。我可以通过订阅一些事件来做到这一点。所以我们有这个 on callback,它会给我们一个 event info。我们有大约 20 种不同类型的事件。它们都有很好的强类型来表示它们。我将检测它是否是一个工具,然后显示工具名称。如果不是,我将只显示事件名称。

所以,如果我现在再次运行它,我们应该会看到更多一点信息。我们可以看到我们修改了消息。有一个用户消息。助手开始了一些工作。助手进行了一些推理。它将意图列为列出目录内容。然后它正在进行一个 view 调用,以查找该位置的文件。好的,这没问题。所以我们可以看到更多信息,如果我们愿意,我们可以构建一个 UI,以一种稍微更动态的方式更新,以显示代理正在做什么。

好的,到目前为止,这只是使用了编码代理的内置工具。当然,你也可以为它添加自己的工具和功能。由于这是一个 C# 应用程序,我将使用 C# 来完成。所以,我将在这里定义一个名为 get issue size label 的新方法,只是为了展示我们可以做到。它将接收工作天数,并基于此使用这个绝对令人发指的语法。这是什么鬼东西?根据传入的数字返回不同的字符串。好的,让我们设置一个断点,这样我们就可以看到它。然后我必须让它在我的会话中可用。所以,我将传递一组工具,我正在使用 Microsoft Extensions AI 库将该方法转换为 AI 可以调用的东西。一旦我做到了,我将提示它实际使用它。所以,我将说,一个需要六天的工作的问题的标签是什么?

如果我现在用调试器运行它,然后希望它能够访问该工具并选择调用它来满足这个特定请求。好的。你可以看到它调用了我的方法。它将六作为工作天数传递。然后当它得到返回的字符串时,它说标签是 size m。好的,太棒了。所以它奏效了。酷。

现在,让我们使用这个来实现一个实际估算工作量大小的功能。这似乎是一个很难解决的问题,但实际上并非如此,因为你知道,代码编码代理已经具备了这项能力。所以,我可以添加一个像这样的漂亮的大提示,说你是一名软件工程师。估算问题的复杂性。检查问题是否对应于当前目录中的源代码,如果是,则调查代码以提供更准确的估算。它将利用像 explore sub agent 或其他任何东西的所有能力来完成这个任务。好的。它将接受这个 issue URL。所以,让我们运行它。它会说输入你的 issue URL。让我们找一个我们可以处理的问题。让我们去 Copilot SDK 仓库。进入问题列表。找一些看起来很大的。好的,这个很大。连接到活动 CLI 会话。好的。

所以,如果我回到这里并粘贴它,那么它应该利用编码代理默认已经拥有的所有能力。所以,它有能力,你知道,比如从网上获取东西,并处理它是否是大型输出,并检查该内容。它能够查看磁盘上的文件,并且可以就这是否是与该仓库对应的代码进行推理,而事实并非如此。所以,在这种情况下,它只会跳到提供一个总体估算,并且它已经决定这是一个中等大小的问题,这可能是合理的。五天的工作。好的,酷。所以,这就是你如何从你的应用程序中控制这些编码代理之一,并建立在它已经拥有的所有技能和能力之上。

但它不限于软件工程类型的任务。为了证明这一点,我们还创建了另一个小演示,我将在这里展示。好的。所以,在 PowerPoint 的右上角,你看到我添加了这个小扩展,GitHub Copilot。现在我想说清楚,这不是我们实际发布的某个功能。这不是产品公告或任何东西。这只是我们一起制作的一个有趣的小演示,我们添加了,我们使用了我之前展示的 SDK 来创建一个侧边栏,我可以在其中输入一些指令,它将使用编码代理功能,但它也连接到 Office API,所以它可以与文档本身进行交互。

所以,我可以这样说,制作一个五页的演示文稿。我知道文字太小了。让我们放大。制作一个关于 NDC London 的五页演示文稿,使用酷炫的布局和大量的伦敦双关语。好的。所以,嗯,我在这里使用 Haiku,这是一个小型模型。我之所以使用它,只是因为它速度快。我发现实际上,它生成的布局有点混乱。所以,它可能会很难看。如果我使用像 Opus 这样的模型,它通常会产生相当好的设计,但它确实需要一整分钟才能响应,而且我不想让你等那么久。所以,它正在工作,希望它能在几分钟内给我们一个实际的答案,而它现在异常缓慢。让我们只是启动一个新的实例,以防我能让它更快。

好的,我再试一次,希望我们会得到一些输出。好的,它正在添加一个名为“代码与文化相遇”的幻灯片。好的,让我们看看它还会产生什么。NDC London 是什么?最负盛名的会议。它不是伦敦的混乱迷雾。好的,酷,没问题。会议亮点。太棒了。

好的,所以正如你所看到的,它正在工作。嗯,双关语不太好。我认为我们需要一些更高级的人工智能。如果我们想要好的……这是什么鬼东西?我们没有拉你的大……什么?我不知道。好的,让我们快速离开那个。好了。

[笑声] 我深感抱歉。我确实道歉。这是我做过的最糟糕的事情之一。好的。嗯,好了。重点是,你可以将编码代理的智能应用于可能不仅仅是编码的任务,使用像这样的 SDK。

好的,我想我们快要完成了,我确定你们中的许多人都非常渴望出去喝杯咖啡。所以,我只想留下一些关于这对我们这个行业意味着什么的思考。我们到底是什么?我们想成为什么?我认为归根结底,它并没有改变我们仍然是工程师的事实。它给了我们额外的工具,额外的能力,并允许我们将我们的才能应用于更广泛的事情。但根本上,我们仍然在做同样的工作,对吧?我们仍然用我们的大脑来决定如何解决问题。对于你实际可以构建的东西,仍然存在几乎无限的可能性空间。而你则需要运用你的品味和智慧的决定,来决定你将如何使用这些更强大的工具来实现目标。而且希望它能让你能够承担以前无法承担的问题。

所以,这是我对你们的挑战。去拿一个 CLI 工具,我不在乎是哪个,然后尝试做一些你以前从未做过的事情。如果你想尝试修复你甚至不懂语言的代码中的错误,那就试试吧。如果你想尝试在你工作中为某事实现一个原型,那就去做吧。如果你想尝试那个人们一年来一直说无法完成的非常困难的功能,因为它太难了。只是看看如果你把问题扔给你的编码代理会发生什么。我不知道它是否会奏效,但你知道,你会学到一些东西。而且,对于许多这些原型制作的事情,你会对你在一个或两个小时的工作中能够获得的东西感到非常满意。

好的,就留给你们了。我希望你们有一个非常好的会议最后一天。如果你在附近,我很乐意和你聊聊这些事情。但除此之外,祝你们有美好的一天,然后,是的,享受你们的时光。

[掌声]