Transcription
我们构建软件的方式将会改变。人工智能将能写出比我写得更好的提交信息。该代理可以检查其输出。它可以运行测试。如果测试失败,它可以直接读取失败测试的输出,然后继续进行,直到测试通过。>> 你有什么建议给那些想要学习这些东西的产品经理或相关人士吗?>> 人工智能不可能凭空为你思考并为你做出所有决定。你必须提供一定程度的关于你想构建的产品类型的背景信息。有些人已经开始使用一些较新的工具,他们构建了第一个版本并将其发布出去,然后他们不得不回去,像买一本教科书一样学习基础知识,然后才能进一步发展。如何从零开始用人工智能构建一个应用程序。所以,这里有几件事。好的,欢迎大家。我今天的嘉宾是 Lee Robinson,他现在在 Cursor 工作。Lee 之前在 Verscell 担任开发者体验负责人,在那里他帮助构建了 Vzero,而且坦率地说,他在开发者关系领域是一位传奇人物。所以,我非常兴奋能请他来谈谈如何从零开始用人工智能构建一个应用程序,以及现有工程师如何更好地利用这些人工智能工具。欢迎 Lee。>> 谢谢。是的,我非常兴奋能谈论这个。>> 是的。好的。那么,在我们开始构建之前,让我们谈谈,你能分享一下你为什么决定离开 Verscell 并加入 Cursor 吗?>> 是的。大约一年半前,我开始更多地使用人工智能进行编码,当时主要是自动补全。你知道我用过 GitHub Copilot,我觉得它很不错。但是,它开始变得好很多,不仅在 Cursor 中,而且在其他工具中,用于下一代或下一个动作的自动补全,这确实很有帮助,但我仍然没有完全信服。然后大约六个月前,我开始认真对待这件事,尝试了很多编辑器,并真正地在编码方面涉足人工智能领域,因为我听很多人谈论过它,但我仍然持怀疑态度。当我开始更多地了解人工智能代理并允许代理编写代码并给它们一个机会时,我非常惊讶于模型的质量已经跟上来了,而且工具也变得好多了,以至于我非常惊讶于人工智能能够编写的代码量,但我仍然需要审查它并确保它是正确的。但即使那样也足以让我震惊,我应该更认真地对待这件事。然后我开始使用从 Slack 启动的后台代理,无论是文档中的错别字还是用户界面中的错误,或者是一些非常非常小的我本可以切换上下文来处理的事情,但我只需通过 Slack 消息就可以启动它们。这真的让我退后一步思考,好吧,我们构建软件的方式将会改变。我想帮助人们,特别是现有的开发者,如何在这种旅程中导航,就像我当时在导航一样。这就是我加入 Cursor 的原因。>> 是的。感觉就像现在每个开发者都有一个团队,我不知道,初级工程师,或者就像一个工程经理可以指导人工智能一样,对吗?>> 是的,没错。>> 好的。那么,让我们来谈谈实际的。所以,也许我们先谈谈从头开始构建一个应用程序,对吧?嗯。>> 而且,我认为如今所有的角色都在融合。我是一名产品经理,但我认为现在的工程师也可以成为自己的产品经理。我认为很多人没有意识到初始设置阶段对于构建一个好的应用程序有多么重要。所以,也许你能展示一下你如何使用 Cursor 来设置这些东西。>> 是的。这里有几件事。一是,我觉得对于新进入软件工程领域的人来说,他们可能会收到很多关于如何开始和构建应用程序的冲突建议,因为人工智能可以使它看起来很容易,但实际上,构建高质量软件需要大量的范围和技术知识。有时,如果你向人工智能模型询问一个计划,如果你还没有花一点时间学习一些基础知识,它会输出一些东西,你会点头说,“是的,好的。Postgress 数据库,我想我知道那是什么。”然后它会描述模式,你会说,“是的,好的。”这似乎说得通。所以,我总是想强调,即使在我们讨论这个从零到一的阶段时,理解并询问关于计划的问题,比如那是什么?为什么我们需要那一部分?>> 对于那些刚刚开始编码之旅的人,或者可能在编码之旅的前几年的人,因为你正在作为一个单人开发者从零到一构建东西,这意味着你扮演着多个人的角色。有前端、后端、DevOps、产品经理、设计师。构建高质量软件需要很多角色,你想确保你至少能在其中一些方面做得很好。所以,我将打开 Cursor,我有一个我一直在为我们要构建的应用程序准备的提示。我想一步一步地讨论我是如何构建它的,然后我们会看看会发生什么。>> 听起来很棒。是的。>> 太好了。好的。所以,我已经打开了 Cursor,我刚刚将一个提示粘贴到一个 README 文件中,这样我们就可以在让代理执行任何工作之前先看一下。现在,我想一步一步地分解这些内容。你会注意到我带有一些知识和想法,关于我希望系统如何工作。所以,我想构建一个应用程序,我们可以跟踪音乐收听情况并报告关于热门艺术家和歌曲的统计数据。所以,过去,我曾经使用 Last FM,你可以收听你的热门艺术家,你可以看到你所有时间播放最多的歌曲。所以,我想为好玩而重建一个这样的东西。我想像与同事一样与人工智能合作,帮助我制定计划。而且,你是产品经理。我们正在观看的产品人员都知道 PRDS 以及如何将你的产品需求结构化成连贯的东西。我必须说,在人工智能领域,你作为指挥人工智能代理的驱动者,PRD 流程中有一些部分可能与这个领域不太相关。而且有一些新的部分是你需要引入的,比如拥有更多的技术基础来确切地了解你想要要求的需求。例如,在需求方面,我已知这个应用程序将需要一些身份验证,并且我对身份验证的类型有一个大致的了解。所以我知道 OAUTH。所以,我会说,让我们只做 Google OAUTH 或使用 Google 登录。他们将连接到他们的 Spotify 账户。我们将使用 Spotify API。所以,我需要知道 API 是什么。然后,我们将把这些信息存储在数据库中。所以,我之前构建过应用程序的经验,你知道,我与 API 通信,我得到一些数据,我需要存储这些数据并在将来使用它。所以,我们需要一个数据库。至关重要的是,我也想使用测试。所以,对于我的业务逻辑或应用程序的工作方式,端到端测试可以覆盖整个应用程序并测试用户流程。这很重要是因为它允许代理拥有一个自我验证的循环。代理可以检查其输出。它可以运行测试。如果测试失败,它可以直接读取失败测试的输出,然后继续进行,直到测试通过。所以,测试可能在过去被淘汰了,但它们又回来了。然后还有一些技术选择。我想使用 git,这样我们可以随着时间的推移进行快照。而且我对我的包管理器有自己的看法,并且在进行过程中会写下描述性的提交。然后,你知道,提前有一些想法以及你想要使用的东西以及你希望应用程序感觉如何,这很有帮助。我来自工程背景,所以我已经知道一些我想选择的技术栈,但如果我不知道,我可以问人工智能,来回交流并尝试理解其中一些东西。但这是随着你经验的增长,它将极大地帮助你了解哪些工具适合你,以及哪些工具也适合人工智能模型理解。所以我对应用程序的设计外观有一些想法。你知道,极简、功能性、有意识地使用颜色。我们正在观看的设计师们,他们可能会给模型提供更好的标记,更好的提示。然后是前端,我知道一些我想使用的技术栈。我想使用 React。我想使用 Tailwind 进行样式设计。Shad CN UI,然后是 ESLint,就像测试允许你向代理提供反馈一样,Linter 也可以向代理提供关于某些在 React 世界中可能不起作用的东西的反馈。如果人工智能生成了错误的代码,Linter 可以说,“嘿,顺便说一句,这在后端可能不起作用。”关于数据库,我想使用什么。关于基础设施,我想使用哪些工具。然后,我想做的是拥有这个计划。但这个计划可以是一个活的文件。所以,我们可以在里面放待办事项。它是一种非常轻量级的任务管理系统。现在,你也可以通过 MCP 模型上下文协议等方式集成外部系统。去和 Linear 谈谈。去和 Notion 谈谈。那是更高级的模式,如果你愿意的话。但你实际上可以走得很远,只需一个 Markdown 文件和一些待办事项,尤其是在单人模式下操作时。而最后这句我认为非常重要。就像如果模型有问题,请让人类参与进来。征求我的意见。在我没有提供足够的清晰度时提问。我确定我在这里遗漏了一些东西。所以,让我们实际采取这个。我只是会>>把它剪掉。我将打开 Cursor 中的代理侧边栏,我们将把它放大一点。然后我将把它粘贴在这里,然后我们将按 Enter。>> 制作我的计划。是的。而且,只是为了从一个技术水平不如你,可能更像我这样的人的角度来看,你也可以显然要求人工智能来制定需求和技术栈,然后你可以审查它,然后如果你不理解什么,你可以直接突出文本并说,“嘿,这有意义吗?或者这是什么意思?”对吧?就像也有办法做到这一点。>> 没错。是的。没错。所以,我们现在可以看到,它已经开始工作了。Cursor 代理可以为你做的一件事是,它可以内部管理一个待办事项列表,因为它正在逐步处理你的任务。所以,你有一个本地待办事项列表,这是代理正在管理的。然后你有一个全局待办事项列表,它可以是你的 Markdown 文件,也可以是外部任务管理系统。而且,我们也可以看到已更改的文件。所以,我们有了计划。所以,当这个过程进行时,我可以打开计划,我们可以看一下。而且,如果我愿意,它说,“嘿,顺便说一句,我们有了你的计划。我们还有很多其他待办事项要做,但在此之前,让我们先回顾一下,确保这个计划看起来是正确的。”所以,这个单一的聊天记录在我们历史中已经完成了。值得重新审视一些基础知识,那就是我有一个与代理的聊天。我正在与一个人工智能模型交谈。我在这里选择了那个人工智能模型,你可以只使用自动模式,或者在你开始了解什么最适合你之后选择一个特定的模型。而且,当我向这个对话中添加更多内容时,所有的消息都是追加历史记录。所以,当你继续与人工智能聊天时,它会积累更多的上下文。而且,我可以看到这里的百分比仪表,我已经使用了大约 2% 的可用上下文,或者说是人工智能的工作记忆。所以,我们有了计划。好的,我们要构建这个 Web 应用程序。它有我们的技术栈。看起来不错。基础设施包管理器。好的,所以,让我们看看它是如何决定将我的需求分解成块的。所以,第一个是设置项目。这看起来还可以。设置数据库,获取正确的表,而且,这很合理,我们必须先设置项目,然后再去设置数据库。好的,这都很合理。我们甚至还有可以验证此步骤是否正常工作的可交付成果。设置身份验证,这样我们就可以使用 Google 登录,通过 Spotify API 集成 Spotify,然后开始添加一些功能。现在,其中一些功能我们可能需要进一步分解。它们相当宽泛。测试,我们可能想更早地添加测试,这样当我们添加功能时,例如,我们可以使用测试来验证事物是否正常工作。部署,有点类似。我们可以等到最后,如果我们愿意,但我们也可以更早地部署并经常尝试获得一个 URL。而且,正如你记得的,我要求了反馈。所以,这里有一些开放性问题,比如数据多久同步一次?我们真正关心哪些统计数据?所有这些上下文我都没有提供给人工智能模型,这就是为什么它会提问是好的,因为它帮助你思考你实际上想让这个应用程序做什么?你实际上想构建什么?人工智能不可能凭空为你思考并为你做出所有决定。你必须提供一定程度的关于你想构建的产品类型的背景信息。让我们看看。然后,你基本上会给它一些反馈来更新计划,对吧?就像为了添加测试等等。>> 是的。而且,像成功标准。我认为这很有意义。我可能想把成功标准移到每个迭代中。所以,让我们做这些改变。让我们把成功标准移到每个迭代中。让我们更早地设置测试,这样我们就可以验证每个步骤,而且,也许我们可以回答其中一些问题。数据应该每天同步。而且,这很有趣,你可以有拼写错误。没关系。人工智能模型会理解你是否有拼写错误。你不必输入完美的语法或完美的拼写,它会弄清楚的。>> 是的,你可以根据我建议的一些事情来修改计划。太好了。>> 而且,我们在这里的 Cursor 中得到了这种差异视图,我们可以说,“是的,我们将保留这些更改。这看起来很棒。”而且,它将继续进行,并为计划的每个部分添加更多可交付成果和成功标准。然后,一旦完成,我们就可以让它开始执行并处理第一步或第一个迭代。所以,现在我们只有计划在我们的应用程序中。我们还没有代码。我们还没有真正开始。但这就是我们将开始进入有趣的部分,我们对这个计划感觉相当不错。我们喜欢它被分解的方式。我们可以现在要求代理实际启动这个过程。现在,值得停下来谈谈前台代理和后台代理。所以,前台代理是我现在正在与之合作的,我正在观看输出。我正在审查它在做什么。而且,正如你将在几分钟内看到的,我可以批准或拒绝代理执行的特定操作。也有一个世界,你可以启动后台代理。所以,当我们在这个项目上走得更远一些时,例如,你可能会在第二阶段看到,一旦我们让应用程序正常工作并且有多个待办事项列表,也许我们决定其中一个我们可以放到后台运行,我们可以并行处理多个事情。现在,这是一种更高级的管理和习惯的方式,但当你习惯了它,它可以帮助你分解不同的任务。现在,你也可以使用多个前台代理,但然后你有多个人工智能代理试图更新同一个代码库。所以,你必须有意识地去做。>> 看起来它完成了。Cursor 为我建议了一个记忆。所以,这是一种长期记忆,关于我们可能如何引导这个项目,它说成功标准应该被移到计划的每个迭代中,如果我们想继续更新计划,我们可以保留它。现在,我将丢弃它。关于记忆的事情是,它们将被注入到你的对话的上下文中。所以,如果你在记忆中输入,“我更喜欢非常简洁的回复”,它将在未来的对话中记住这一点。>> 就像跨项目一样,还是只在同一个项目中?>> 所以,这只是我目前所在的这个工作区。可能会有一种情况,你想要一些跨越你所有项目的东西。是的,那会很有趣。好的,看起来它完成了。我们仍然只有计划,但我们已经起草并准备好了多个待办事项,它想做下一个。所以,让我们继续做下一个待办事项。所以,我们有一个计划。看起来不错。它现在将开始实际执行这个列表并启动事情。然后,我们将能够沿途验证事情是否正常工作。现在,你会注意到的是代理,我将在这里稍微缩小一下,以便我们可以让它更大一点。代理只是在为我运行事情。发生这种情况的部分原因是,我已经有一个允许列表,我说代理可以运行特定的命令。所以,在我的机器上,代理正在使用终端,它正在运行一个命令来访问互联网并下载东西并安装东西。现在,如果这是一个我不想运行的命令,我可能每次都必须手动允许它,但我已经在我的全局设置中做出了决定。实际上,没关系。如果你运行 npx,你知道,那完全没问题。>> 嗯。>> 所以,它将继续进行,它将使这个应用程序变得很棒。这看起来都很好。它为我安装了所有依赖项。它把它放在一个子应用程序中,然后又把它移回主应用程序。它曾经像这样安装。所以,这比人工智能之前的日子好太多了,对吧?就像安装那些依赖项需要永远,伙计。你知道。>> 是的。而且,就像特别是当事情出错时,代理可以修复它。所以,这也有缺点,对吧?你必须介入并指导代理。但有时当你添加依赖项时,你会遇到一个奇怪的错误,因为你知道你应该使用某个 CLI 参数,而你不知道,它可以为你做到这一点,这真的很不错。所以,它安装了所有这些依赖项。它正在为我设置测试。它正在为我设置 Shaden。现在,你会注意到我们到了一个需要用户输入的地方。所以,它在等我。所以,我会说这看起来不错。我喜欢那个颜色。当然。然后,那个子终端完成了。它又回到了代理那里,说,太好了,这看起来不错。继续。继续。所以,它只是在为我安装和设置很多东西。现在,当这个过程进行时,我将把它拉回来。我们可以开始看到我们有一个正在成长的项目。如果你是新手开发者,这可能看起来有点令人生畏。所以,这也是一个时间,当这个过程进行时,我可以回到我的代理那里。我可以做 Command T。我可以打开一个新的聊天或一个新的标签页,也许我想要这个标签页,也许我不想要这个标签页。这是在询问问题时要包含在上下文中的附加文件。但我可以问,比如解释一下这个项目根目录下的文件。它们是什么?为什么需要它们?所以,这只是一个我们正在提出的问题,试图获得更多关于系统如何工作的知识。它将阅读所有这些内容并回来。所以,我们这里还在进行中。代理还在设置东西。而且,你刚刚看到了一些非常有趣的事情,那就是它已经设置并安装了所有测试,然后它知道如何运行测试。所以,它创建了一个测试,页面渲染而没有崩溃,并确认测试有效。它运行了服务器,并确保服务器正常工作,现在有一个测试失败了,这是好事。这意味着有些东西没有正常工作,代理正在一路修复。哦,你看它说了什么?它说我看到了问题。默认页面没有主元素,所以找不到。所有这些事情都在为你发生,这真的很不错,但它也生成了很多代码。所以,我们真的想确保我们退后一步,理解这里发生了什么。当然,所有这些更改都会有一个摘要,因为它只是吐出很多东西,这可能会让人感到不知所措。但就像,让我们回到这里看看它说了什么。>> 好的,所以我们有一个定义依赖项的 package.json 文件。我们有一个 lock 文件。好的,我们有 next.js 配置文件,如何配置 TypeScript 等等。而且,这将在你熟悉和了解这些东西时帮助你,也有助于你做出更好的技术决策,关于你想使用或不想使用的工具。例如,你可能会说,“不,我以前用过 Playwright,我实际上想用一个不同的测试库。”太好了,没问题。但你将获得这些练习,以便你可以确定你想要使用什么以及你喜欢什么。>> 是的,我的意思是,这就是你变得更具技术性并学习这些东西的方式,对吧?所以,>> 是的。>> 是的。所以,它还在进行。它看起来奏效了。而且,现在我的端到端测试实际上可以工作了。所以,它打开了一个浏览器。它确认浏览器可以渲染页面,然后将结果反馈回来。然后,因为我在计划中告诉它要进行提交,人工智能将写出比我写得更好的提交,那就是我设置好所有东西的提交。太好了,这看起来很棒。它提交了所有这些更改。然后,它还更新了计划。所以,它完成了第一阶段的所有工作。应用程序本地运行。Linting 通过。基本的测试结构。基本的测试套件通过。所以,现在我们在这里有一个总结。第一阶段,我们做了什么?我们设置了应用程序。我们安装了包管理器。我们获得了测试设置的所有管道。我们让 git 工作了。太棒了。而且,我们有一个运行的服务器。Linting 通过。测试通过。现在,如果我们愿意,我们就可以进入第二阶段了。所以,如果我对此感到满意,我可以保留所有更改,或者我也可以逐步查看每个文件。并手动验证它们并更多地了解我正在处理的内容。所以,因为我对这些工具有所了解,所以我可以逐步进行,进行抽查,并确保一切看起来都还可以。所以,让我们以这个为例。这是我们的主页。我们有这个 React 组件。这是一个音乐追踪器。太棒了。使用 Google 登录。连接 Spotify。然后,这是我们的测试。页面是否渲染而没有崩溃?它是否显示音乐追踪器标题?它是否显示登录和连接?这似乎是很好的测试。这似乎是正确的。>> 是的,我认为你这样做的方式和我通常尝试做这些事情的方式之间存在两种差异。>> 我没有包含让它编写测试的指令,这就像一个有经验的工程师会做的那样。所以,似乎仅仅是我写了测试这一事实,它就可以修复很多东西并测试很多东西,对吧?>> 是的,百分之百。就像,让我试着找一个很好的例子。现在,顺便说一下,你可以看到 Cursor 代理能够启动和运行终端。终端可以用来在本地启动应用程序。它也可以用来运行测试。所以,它可以并行运行这两件事。但我还想提到,我们有一个很长的变化。我们目前使用了 200,000 个 token 上下文窗口的 24%。>> 是的。>> 而且,记住代理的工作记忆,就像这个聊天中的所有内容,如果我让它做,“好的,现在做下一件事。”它将把所有这些之前的上下文带入下一次对话。而且,我们必须决定,我们想要它吗?或者它可能会分散代理的注意力并无益吗?现在,你可能会想,我的意思是,我只用了 24%。但即使你接近上下文限制的顶部,也有一些非常好的研究和早期研究表明,一旦你达到顶部,你就会遇到一个“大海捞针”的问题,当你使用 95% 的上下文时,你给了人工智能模型所有这些东西,你想让它在中间找到这一小部分相关信息。这很难做到。我的类比是,如果我们聊了 30 分钟的饮水机,然后最后你说,“哦,顺便说一句,我说的第一件事是什么?”我说,“呃,我已经忘了。你再说一遍?”你知道,这有点像人类的运作方式。所以,例如,我们已经进行了一次提交。我在源代码控制面板中可以看到,我没有那些更改。实际上,我将更新计划,因为我们已经提交了这些东西。所以,我现在处于一个全新的状态。所以,实际上我要做的是,我将按 Command N,然后我将开始一个新的聊天。因为我不需要所有之前的上下文。所以,让我们回到计划,看看我们是否可以设置一些可验证的东西。如果我做数据库,我将不得不去获取一个数据库并设置它。这可能比我们现在的时间要长。也许只是用一些虚拟的东西来构建前端。>> 抱歉,再说一遍。>> 也许只是让你用一些虚拟数据来构建前端,或者你知道。>> 是的,让我们做,让我们添加一个设置页面,来配置你的 Spotify 账户,即使我们还没有集成 API,而且我想确保它能正常工作。所以,添加测试。>> 是的,也许我们应该把添加测试的东西放到系统提示中,或者你知道。>> 是的。我喜欢操作的方式是,当我发现自己开始重复说同样的话时。这就像一个提醒我,“嘿,实际上,这可能是我想要放入 Cursor 规则的东西。”Cursor 规则基本上是你放在每次聊天、每次对话顶部的注释,以便将其放入与人工智能模型的对话上下文中。所以,例如,它可能会说,“始终使用此包管理器,始终运行测试,始终使用某种提交风格,并确保你尽早并频繁地提交。”这些都可以是你本质上编码到应用于你项目的规则中的工作方式。是的。而且,Cursor 规则只是为了让观看的人知道,它们就是标题,对吧?Cursor 说标题。规则就是这样。是的。所以,我只是说,让我们把运行测试和使用 git 作为我的项目中的 Cursor 规则。而且,我可以继续按 Enter,它会把它放入队列。而且,如果我说,“啊,实际上我不想这样做,”我可以删除它,或者我也可以把它推上去,并中断聊天,如果我愿意的话。所以,我们现在有几件事正在发生。我们创建了页面。我们添加了测试。我们将进行一些导航。太好了,我仍然会让他们做所有这些事情,因为为什么不呢?然后,我们将让他们更新 Cursor 规则。但现在,这是一个展示审查流程的好机会。所以我可以逐步进行。我们到目前为止已经更改了四个不同的文件。而且,我可以批准或拒绝。哦,顺便说一句,右边我们看到测试刚刚通过。所以,这是好事。进展。我们有一个指向设置的链接。这看起来不错。我会保留,或者我可以使用 Command Y。让我们看下一个文件。我们有设置页面。这是一个 React 组件。因为现在它实际上在做什么并不重要,所以我将把它略过,直到我们有更多功能。它现在只是被存根了,它实际上并没有做什么。当然,我们会保留这个。>> 转到下一个。我们有测试。这看起来还可以。所以,我们会保留它。而且,它通过了。所以,这是好事。哦,我们还有另一个测试。太好了。现在,我还看到了别的东西,那就是我看到了这个波浪线,波浪线正在给我一个错误。它说,“嘿,找不到这个东西。你可能错过了安装类型定义。”这很有趣,因为当我,你知道,开始时安装所有这些东西时,看起来它只是错过了设置一些类型定义,这在我在编辑器中工作时给了我更多的本地反馈。所以,让我们这样做。所以我将把它添加到聊天中,我们可以将它排入队列。而且,看起来它可能在这里卡住了,测试没有真正退出。所以,我们可以跳过它。我认为它看起来奏效了,但我们实际上没有退出,或者测试没有,终端命令没有退出信号。好的,设置页面正在通过。有一个 Lint 错误。好的,还在进行。太好了,它完成了。所以,现在这个完成了,它实际上可以从队列中提取东西,并继续处理我建议的事情。所以,它将创建一些 Cursor 规则。我将审查这些更改。这些看起来不错。然后,我将再次打开我的代码,你会看到这是我的项目目录结构。>> 而且,它将继续创建一些 Cursor 规则。现在,一件有趣的事情是,这是一个讨论人工智能模型如何工作的好时机,那就是它们是在某个时间点(称为知识截止日期)之前从互联网上的某些数据进行训练的,然后在那之后它们就不知道更改了。所以,你刚刚看到的是,它创建了一个 Cursor 规则,但它是在这个 Cursor 规则文件 Cursor 规则中完成的。现在,对于观看的 Cursor 用户来说,你会知道这是创建 Cursor 规则的旧方法,你把所有东西都塞进这个规则里。这没关系,它仍然有效,仍然支持。实际上有一个新的方法,我们可以把它分解成更小的部分,我们可以提供反馈说,我是否想在每次对话中都包含这个,或者我只想在某些对话中包含这个。所以,我实际上可以进去说,“实际上使用新版本的 Cursor 规则”,它们可以放在多个文件中,我们甚至可以标记,“Web”来在有任何关于“嘿,我不知道它确切如何工作”的困惑时搜索网络,或者我可以标记特定的文档,比如 Cursor 文档。所以,让我们这样做,而不是 Web。我也将把它放入队列。现在,当我在说话时,代理正在为我做事情,我提到聊天中有一个错误,它不知道如何描述,它去安装了这些东西的依赖项。现在,当我将鼠标悬停在它们上面时,我得到了所有这些来自类型定义的帮助我理解我正在看的东西的信息,这很好。嗯。>> 所以,它现在去删除了那个文件,它将为我的应用程序设置一些新的 Cursor 规则。所以,我有一个 doc Cursor,然后是一个 rules 文件夹,然后里面有不同的文件。所以,它将为我设置几个。太好了。一个是关于一般规则,另一个是关于 git 工作流程,开发工作流程。太棒了。而且,我可以进去修剪我喜欢和不喜欢的。我认为这些对我来说可能有点冗长,我可能会删除一些东西。>> 但,是的,这只是处理这个工作流程的一种方式,我们可以测试并确保事情正常工作。看起来不错。>> 你能试着让它加载吗?就像,实际的应用程序?>> 哦,是的,让我们这样做。让我,让我打开,我将停止共享,然后我将打开一个浏览器。我们可以看看它构建了什么。好的,这是它制作的“Hello World”应用程序。你知道,如果你的应用程序看起来不像这样,你就发布得太晚了。这是最>> 基础的“Hello World”页面。我们有按钮,但它们什么都不做。>> 是的。>> 哦,设置。实际上,这还不错。当我告诉它创建设置页面时,这看起来不错。它还没有真正考虑到我想要的那个设计,但它,我猜还可以。我需要对我想找的东西更具体。但你看到的一件事,这真的很不错,是因为我告诉它使用 Shad CN UI,这是我选择的设计系统和组件库构建器,我能够获得这些相当不错。我不太确定它是否完全使用了它们,但我将能够放入所有这些组件,这让事情,你知道,更容易一点,更容易访问一点,更可定制一点。所以,>> 是的,>> 它相当不错。>> 我的意思是,你知道,事实上,Chassis and UI 是 AI 喜欢构建的最喜欢的 UI。>> 是的。是的,它被所有主要的 AI 模型用来生成 UI。>> 嗯。所以,让我来总结一下你做的这个例子,对吧?所以,只是,第一,你花了很多时间在初始指令上,以及所有这些,产品规格也包含了关于技术栈和你想要的一切的细节。>> 对。>> 而且,至关重要的是,你还包括了一些关于,你知道,包括测试的说明,而且,也许这对你来说很明显,但对我来说,这是一种新的学习方式,就是让 AI 沿途进行提交,就像沿途进行提交。>> 是的。是的。这是软件工程历史最佳实践之一,也许隐藏在某本书里,或者只是在工作中学会的,现在被更清晰地表达出来,因为代理实际上也是这样工作的。它们需要反馈。它们需要将输出管道回传,以便它们能够理解它们在哪里出了问题。这就是为什么你看到像 TypeScript 这样的类型化语言,Linter,编译器,你知道,运行测试到测试,所有这些东西。它们有助于代理更好地工作。而且,提前设置它们很好,这样你就不会陷入这样的境地:你让人工智能做某事,代理去写一些代码,然后它不起作用。所以,你用类似“嘿,这不起作用”的东西来提示它,对吧?>> 是的。是的。是的。但代理不知道如何去搜寻更多信息,更多信号来弄清楚什么可以放入上下文中,为什么它不起作用。类型语言,测试,Linter,它们为你提供了这些东西,这些东西对程序员手工编写代码很有帮助,而且当你并行化你正在做的工作时,它们也对代理很有帮助。>> 是的,它似乎因为你写了测试,它就有上下文来修复自己的问题。所以,你必须一直说它不起作用。>> 对。而且,现在我展示的例子没什么大不了的,但当你有运行时逻辑错误时,它真的会开始发挥作用。所以,当你构建应用程序时,当你编译应用程序时,你会得到一些反馈。更棘手的事情是,当你的应用程序实际上正在工作并运行,用户正在尝试使用它,并且他们遇到了某个错误,而且该错误希望有一个错误消息。希望有一个堆栈跟踪,这是一个特定的点或指向错误发生代码部分的指针。>> 如果你有那个信息,>> 而且你可以把它传回给代理,这肯定会让弄清楚出了什么问题变得容易得多。>> 太棒了,伙计。那么,让我们来谈谈真正的工程师如何使用 Cursor 和 AI 工具来处理一个已建立的代码库,对吧?因为代码行太多了,无法同时放入上下文。我认为对我来说,用“vibe coding”来构建应用程序的第一个版本,这大致是我在这里做的,但区别在于我积累了上下文和知识,知道我正在使用什么工具,并知道如何提出正确的问题。最大的区别是第一天之后会发生什么,因为我可能会构建这个应用程序,我只是为自己构建它。它只是一个一次性的东西。我不太关心代码,我只是为了尝试一些原型而做的。Vibe coding 非常适合这个。直接扔掉代码,对吧?没关系。如果这是一个我试图长期构建和维护的东西,它是一个,你知道,一个我想建立的业务,或者是我和我的团队一起工作的代码,或者是我为我的公司编写的生产软件。我不能用“vibe coding”来做。我必须知道我正在处理什么。我必须做正常的软件工程。但是,正常的软件工程,你可以用人工智能来增强自己。而且,我认为我们现在看到的是,存在一种健康的怀疑态度。而且,我认为很多写了很长时间代码的工程师都在试图弄清楚这个新的勇敢的世界对他们意味着什么。我的目标是帮助向许多人展示,他们是怀疑的,但可能对我们的未来感到乐观和谨慎乐观,人工智能可以非常有效地自动化那些无聊的事情,那些他们本来就不想做的工作。它不一定总是从头开始生成一个完整的应用程序。虽然你最终会这样做,对吧?你总是会构建新的东西。从第一天到第一百天或第一千天。对于一些小事情,比如重新格式化,或者解析大量数据并试图弄清楚某个特定部分,或者总结长信息,将一种格式转换为另一种格式,人工智能也有很多实际用途。像这样的小事情真的很有帮助。>> 是的,就像你知道,不仅仅是依赖项,人工智能也可以帮助。>> 是的。所以,我想你给有经验的工程师的建议是,不要忘记你已经拥有的所有知识,你知道,工程本身并没有消亡,事实上,它比以往任何时候都更受欢迎,但也许试着用人工智能来简化一些你必须做的无聊的事情,对吧?就是这样的建议。是的,有很多关于工程结束的噪音,而且,你知道,我只是觉得很多噪音都没有帮助,因为如果你构建了一个应用程序,而你不知道它实际上是如何工作的,它可能在第一天或第一周运行得很好,但你最终会陷入一个非常糟糕的境地。而且,你现在已经开始看到了,有些人已经开始使用一些较新的工具,他们构建了第一个版本并将其发布出去,然后他们不得不回去,像买一本教科书一样学习基础知识,然后才能进一步发展。我对这件事有两方面的感受。一方面,我很高兴它让更多人更容易获得软件。另一方面,我希望它能让那些对实际构建软件以及这段旅程的样子感到兴奋的人。对我来说,当我开始做 Web 开发时,我爱上了构建软件,因为我能真正看到它。而且,使用人工智能模型生成代码并获得可用的应用程序,我可以看到,我认为这将激励更多人进行编码,这很美妙。>> 所以,我的目标是帮助他们学习之后需要什么,学习到第 100 天需要什么,如何真正构建真实的软件并进行软件工程。而且,人工智能仍然可以成为其中的重要组成部分。>> 你有什么
一些给那些想要学习这些东西,比如学习原理的产品经理或者其他人的建议?嗯,是的,是像一次只做一些小项目,或者说,你如何开始接触这些东西?去读一本书,或者?是的,我认为这是边做边学,然后也要学习提问,因为我认为工程师被训练成对很多事情持怀疑态度,并且知道自己知识的不足之处,然后提出正确的问题。所以,当你尝试应用自己去构建东西并试验新技术,试验人工智能时,你肯定会遇到你不理解的事情。你可以一边构建和使用代码,一边学习,你只是在尝试,对吧?同时,我强烈建议任何真正想尝试的人去学习计算机科学,去学习工程学。嗯,有很多事情一开始可能并不明显,比如理解数据结构和算法,以及创建的各种代码片段,这些都会很有帮助。比如,如果你真的不知道循环是什么,当你看到人工智能生成一个 for 循环,而你又不确定你在看什么时,那可能会很困难。再说一次,如果你有提问的心态,人工智能可以帮助你理解 for 循环是什么。它可以给你一个学习如何使用循环和条件语句,以及理解不同类型变量的路线图。所有这些核心的编程知识,你都需要积累和学习。你只需要有好奇心,不是说我只想用这个工具,就像某种快速致富的计划,或者快速构建一个应用程序的计划。它并不是真的那样运作的。你需要的是我想使用这些工具,因为我想学习如何构建软件。是的。所以,所以这是关于做所有事情的。就像你知道的,构建应用程序,尝试询问人工智能这些东西是什么,同时也要去阅读技术教科书来建立你的基础知识,这有点像?正是如此。是的,因为否则你可能只是构建一些东西,你知道,就像我们已经看到人们在编码一些东西,然后他们的 API 密钥泄露了,或者其他什么,如果你不知道你在做什么,这可能会很糟糕。是的,我的意思是,如果你从来没有接触过这些东西。嗯,首先,你不知道什么是 API,所以你肯定不知道什么是 API 密钥,而且你可能也不知道客户端和服务器的区别。所以你不知道要问什么问题,为什么 API 密钥在客户端上是坏事。你甚至不会知道要问这个问题。我认为教导新开发者或新构建软件的人有一种责任,在我们将数据库支持的应用程序投入生产之前,退一步学习这些东西。而且我认为工具会越来越好地内置一些东西。我认为现在 Cursor 非常专注于帮助专业开发者更好地构建软件。但我对许多为产品经理、为其他第一次接触编码的人构建的工具也感到非常兴奋。我希望他们能为初学者增加更多的工具,为那些只是想弄清楚这些东西的设计师或产品经理增加更多的工具,也许可以引导你在产品中学习。我认为那会很棒。让我们通过谈论你的经历来结束。嗯,有几个关于你在 Verscell 和现在在 Cursor 的经历的问题,比如,你们在这些公司是如何构建产品的?比如,嗯,就像你知道的,是否有非常明确的职能?你只是写 Cursor 的 PRD,或者如何,你们如何构建新功能?是的。是的,我认为 Verscell 和 Cursor 在公司生命周期方面有所不同。Verscell 是一家比 Cursor 更成熟的公司,你知道,是一家更成熟的公司,无论是在它们存在的时间长短方面,还是在产品开发流程的成熟度以及实际发货软件的意义方面。所以,Cursor 的发展速度非常快。我的意思是,我们尝试了很多事情。我们看看什么有效,什么无效。我认为给予工程师很大的自主权来端到端地拥有这个过程,我们没有,我想也许只有一个产品经理,或者我们的第一个产品经理很快就会到来。所以我们还在建立这种能力,我们有工程师,他们是具有产品思维的工程师,我有点认为这是未来的一个方向,工程师能够扩展到其他领域。你已经看到了设计工程师。我过去写过关于产品工程的文章。我认为这些能够做一些产品工作、做一些设计工作、做一些工程工作的人有一个健康的融合或混合。话虽如此,当然,一个优秀的产品经理可以对产品产生巨大的影响,尤其是一个成熟的产品,他们知道他们正在优化的杠杆和旋钮,而不是在一个早期创业公司中更通用的角色。嗯,两家公司都发展得很快。两家公司都关心构建出色的软件。而且,我在 Verscell 工作了五年,学到了很多东西,而且在 Cursor 的几周内就已经学到了很多东西。是的。而且我觉得通才现在已经有了,以前是这样的,当一个初创公司规模扩大,有很多员工,首先,很多初创公司不再需要雇佣那么多人了,对吧?因为人工智能可以做很多工作。是的。是的,但也觉得那些能够承担所有职责的人,你知道,为了更好的说法,现在有更长的,你知道,保质期,对吧?他们可以自我扩展,即使在像 Anthropic 这样的公司,甚至像,你知道,OpenAI,仍然非常有价值,对吧?是的。我有一个很好的故事和轶事,来自我在 Cursor 的头几周,我们想给一个客户或一群客户退款并发送电子邮件。所以和 Stripe 谈谈,发送一封电子邮件。我几乎不得不删除我大脑中的 SaaS 软件部分,因为我和我们的一个工程师 Eric 坐下来。我看着他处理这个任务,我以为,你知道,他会登录某个工具,然后工具会帮助他提交退款,或者通过并提交电子邮件。他正在运行一个脚本,我想,嗯,这不可能奏效,对吧?他可能需要考虑,你知道,进行脚本的试运行,以便我们可以验证事情。如果出现网络问题并且出现故障怎么办?你需要记录状态,因为你正在处理记录中的一百条,你知道,不要重复那一百条,哦,我们必须确保电子邮件的可送达性没有问题,而且我们可能想测试电子邮件的外观。听起来有很多事情。我只是看着他系统地解决所有这些问题,并用工程师的思维思考这些问题,构建了一个非常健壮的软件。对我来说,这似乎是一个脚本,但实际上是为他所需的确切功能定制的软件,它集成了 Stripe。它集成了发送电子邮件的 API。而且它效果很好。他测试了一切,进行了试运行,自己测试了,你知道,测试了失败状态,然后把它提交到了一个脚本库中,就像他为这些任务构建的自定义软件一样。这就像给工程师提供了这些极其强大的工具,让他们能够做任何任务并连接到任何服务。我觉得这真的很有趣。所以他不需要点击任何用户界面,或者其他什么。他只是运行了脚本,就完成了。是的。是的。哇。是的。我的意思是,我的意思是,这就是世界正在走向的方向,对吧?就像一堆脚本或子代理,可以为你做专门的任务,然后你就可以,你知道,你可以去喝杯咖啡什么的,而他们正在做这件事。是的。而且整个例子只有在一位优秀的工程师才能实现。他知道如何使用他的工具,知道要问的正确问题,对如何将这些工具结合使用有极大的关心,并且他们可以做惊人的事情。就像代理只是在成倍地提高他们的生产力。太棒了,伙计。我希望我们都能成为像 Eric 一样的人。是的,我也是。我正在向他学习。是的。所以,所以,人们在哪里可以找到你的,你知道,新的 Cursor 教学内容,或者,你知道,它很快就会出来吗?是的。我的网站是 le.com。我在 xx.comrob 上发帖。那主要是我的内容所在。我也在 YouTube 上做一些事情。太棒了,Lee。很高兴再次和你交谈,伙计。我,我认为你确实是一位博学家。你知道如何构建东西,但你也了解开发者营销方面。所以 Cursor 的一次强有力的招聘。他们很幸运有你。谢谢。我感谢你。