00:00:00大家都知道使用编程智能体需要一套框架,但没多少人
00:00:04拥有一套既简单、又真正属于自己,还能随着时间不断进化的框架。现在,
00:00:09GitHub 上有很多过度设计的框架。人们创建的这些多智能体系统,
00:00:15我尊重开发者的工作,但很多时候你只需要一些
00:00:19非常简单、能帮你搞定工作的东西。因为我知道你有想要实现的奇思妙想,
00:00:24你不想在构建智能体编程工作流上花费的时间,比
00:00:29实际写代码的时间还要多,所以这就是我今天要分享的内容。这是我的一套极简框架,
00:00:35每当我开始一个新项目并使用编程智能体时,我都会用到它。现在,
00:00:40“棕地开发”(在现有代码库上工作)略有不同,那是另一个视频的主题。今天,
00:00:45我们专注于“绿地开发”。我们需要一个简单的框架来快速起步,
00:00:50尽可能快地构建新事物,而且我在这里涵盖的所有内容都是通用的。
00:00:56无论你使用哪种编程智能体,这些原则都适用。这个视频主要分为两个
00:01:00部分,我将一边讲解一边进行现场构建,
00:01:05让一切变得非常具体。目前我的代码库里除了
00:01:11AI 层之外几乎什么都没有。我带来了一些命令和技能,这是我
00:01:16每个项目的起点。我们要从头开始创建一些东西,
00:01:21所以我们需要从初步规划开始,创建一个叫做 PRD(产品需求文档)的东西。这是
00:01:27初始工作范围,用来创建我们应用程序的最小可行产品。这里面有很多
00:01:32内容,在进入实际编码之前,先设置好初始的 AI 层。
00:01:37然后我们把 PRD 拆分成不同的工作阶段,并利用 PIV 循环来逐一击破。
00:01:43我会解释那是什么意思,我们会看一个例子,然后在
00:01:47我进行整个实施过程中,我会介绍我们需要时刻遵循的四大黄金法则。
00:01:52这些黄金法则会在创建 PRD、AI 层以及进行 PIV 循环的过程中自然地融入。
00:01:57例如,上下文管理。在与 AI 编程助手协作时,
00:02:03上下文是你最宝贵的资源。这将是贯穿始终的一个大主题。
00:02:08还有为所有事物创建命令和技能,以及系统进化心态,
00:02:14因为我们系统的目标是创造出
00:02:18可靠且可重复的东西。我在讲解过程中会提到这一点。所以,我只是想触及
00:02:23贯穿始终的核心主题。这将是一个干货满满的视频。那么,
00:02:28我们从初步规划开始,创建我喜欢称之为“AI 层”的东西。我会解释
00:02:34那是什么,现在我们一起来构建它。所谓的 AI 层,就是代码库中
00:02:39所有为了给编程智能体提供上下文而创建的资源。比如 PRD:我们要建什么?
00:02:45全局规则:我们要怎么建?命令:这样我们就有了可复用的
00:02:50编程智能体工作流。我们先专注于核心部分。还有子智能体,这样我们可以
00:02:55委派调研任务。通常我处理 AI 层的方式(我也把这作为资源分享给你们),
00:03:01是我有一套通用的命令集,我会把它们带入任何新项目。
00:03:07其核心在于,随着代码库的增长和功能的完善,我也会
00:03:13不断进化我的命令,让它们针对特定用例变得更强大,让它们与代码更契合。
00:03:18这通常也是我给你们的建议。如果你愿意,可以把这作为起点。
00:03:23我会在说明栏放上 GitHub 仓库链接。保持简单的初衷是你可以
00:03:27轻松地将其据为己有,并根据你的用例和工作习惯进行演进。这就是
00:03:33为什么我推荐这种方式,而不是像 Beemad 或 GitHub spec kit 那样复杂的框架。
00:03:38它们确实非常强大,但很难真正变成你自己的。我希望你能
00:03:42把这变成自己的东西。现在我给你们展示创建一个完整 PRD 的过程,定义
00:03:48代码库的初始规则。我们甚至会稍微自定义我们的第一个命令。然后
00:03:52我会全程讲解子智能体。我知道在通过 PIV 循环编写实际代码前
00:03:57要做这么多规划,但这很重要。前期的规划
00:04:03看起来进度变慢了,但如果我们制定了非常好的计划,比如有了完善的
00:04:07规则和 PRD,意味着后续的所有开发都会变得
00:04:13更快、更可靠。所以我们先从 PRD 开始。很多人称之为“规范(spec)”。这
00:04:18本质上就是构建应用程序初始版本的所有工作范围。而在那之后,
00:04:24当我们有了好的基础,就会转向棕地开发。那是我下一期
00:04:28视频的内容,敬请期待。在我使用 Claude Code 时,
00:04:34目前除了 AI 层外基本是个空项目,我会先进行一段随意的对话。
00:04:40只是告诉它我的想法,也许还有关于技术栈和
00:04:45架构的一些想法。你从非结构化的方式开始,这能让你更轻松地启动。
00:04:50然后最终你会走到这一步:利用对话作为上下文,来
00:04:55创建一个结构化的 PRD。我有一个命令可以帮我们完成。等讲到那里我再细说,
00:05:01但首先,让我们从想法开始。为了作为本视频的
00:05:06有趣示例,我想构建一个类似于 Linktree 的东西,更像是一个自托管版本,
00:05:12你可以设置自己的着陆页,上面有一堆可以整理的链接。
00:05:16还要有分析功能,比如各个链接的点击率。我想建一个这样的东西。
00:05:20现在拿它做例子很好,因为它不是那种一眼看穿的琐碎项目,
00:05:24你不能随手瞎写(vibe code)就搞定其中的酷炫功能;但它
00:05:29也不会过于复杂,导致视频结束时我们还没做出什么东西。
00:05:33我要用一个语音转文字工具来完成这一步。我强烈推荐使用
00:05:39像 Aqua voice 这样的工具。这是我用的。当然也有很多优秀的免费开源选项,
00:05:43比如 Whisper Flow、Epicenter Whispering,都是很棒的工具,但我喜欢用语音
00:05:48转文字,因为我保证,我打字速度永远达不到每分钟 226 个单词。所以我会
00:05:54先用这种工具把我想构建的内容来一次大脑“信息大卸货(brain dump)”。这会是
00:05:59非常原始的信息,但我现在会当着你们的面进行一次现场头脑风暴,请留意
00:06:03我要求 Claude Code 做什么,因为这和我分享的想法同样重要。
00:06:09稍后我会解释其中的原因。顺便说一下,你可以用
00:06:13任何 AI 编程助手完成这整件事。那么开始吧:我想构建一个 Link in Bio 页面生成器。
00:06:20类似于 Linktree,用户可以创建账户。他们可以创建
00:06:24自己的着陆页,并在上面指定链接。他们可以更改排序。我希望他们
00:06:29能有分析功能,可以看到链接的点击率。他们还可以自定义
00:06:33主题。至于技术栈,我在考虑使用 Next.js,数据库和
00:06:37身份验证我想用 Neon。所以一定要启动一个子智能体去调研一下。
00:06:43至于架构,我没那么挑剔。非常希望能听到你
00:06:48给出的建议。关于我们如何处理主题和链接构建等所有事情。
00:06:55我还希望你派出一个智能体去进行大量的网络研究,看看创建
00:07:00这种 Linktree 类应用程序的最佳实践。然后在那之后,我希望你
00:07:04带着一堆问题回来找我,这样我们就能在构建细节上达成一致。
00:07:10很好。我要把这些发送出去了,几秒钟内它就会转录完成。
00:07:14好了。瞧,我们开始全速前进了。我刚才做的
00:07:20最重要的事情其实是在最后,当我告诉它在调研完之后
00:07:25问我一堆问题时。这一点非常关键,请务必记住:对于
00:07:32任何使用编程智能体的规划,你的头号目标就是减少编程智能体
00:07:37所做的假设数量。因为归根结底,当编程智能体在代码库中犯错时,
00:07:42一半的时间不是因为代码写得烂,而是因为你们在具体要构建什么上没有达成一致。
00:07:48常说的一句话是:一行坏代码只是一行坏代码。但一个
00:07:54坏计划里的一行,可能会导致一百行坏代码。而在 PRD 里的一行错误,可能会导致一千行
00:08:02坏代码,因为你们的方向偏了。所以,我一直在进行大量的实验,
00:08:08寻找随着时间推移减少假设的方法。而让编程智能体
00:08:13直接向我抛出一连串问题,这种方法对我来说效果非常好。因为尤其是
00:08:17Claude Code 带有“询问用户问题”的工具,它可以提供多选题或让你自己写答案。
00:08:23我们稍后会看到。这太强大了。它们在考虑所有边缘情况和
00:08:28我们可能都没想到的细节方面做得非常好。我们很难仅靠自己
00:08:33就推断出编程智能体可能会做出哪些假设。所以它非常强大。然后
00:08:38我做的另一件事,正如你在这里看到的,是运行了不同的子智能体
00:08:42来进行调研。我喜欢在任何规划、创建 PRD 甚至是
00:08:48我们稍后会谈到的 PIV 循环规划过程中使用子智能体。在使用
00:08:53Claude Code 时,我实际上不需要创建自己的子智能体,因为探索和
00:08:59调研子智能体已经内置在工具中了。对于其他编程智能体,你可能需要
00:09:04自己构建,这就是为什么我想在这里特别提到它。但现在几乎所有
00:09:08优秀的编程智能体都支持子智能体的概念。我非常喜欢用它们做调研。其
00:09:14原因是“上下文隔离”。再次强调,这里的核心主题之一是我们要保护好
00:09:20主编程智能体的上下文。之所以说调研是子智能体的绝佳
00:09:26用例,是因为当它们探索时,它们在查看所有内容。它们在进行大量的
00:09:32代码库探索或网络搜索。它们会为自己的工作加载数万、甚至数十万个
00:09:36Token。但实际上我们关心的只是它们的发现,即它们最后返回给
00:09:41主上下文的总结。这样我们可以保持主上下文的整洁。我不建议
00:09:46在代码实施过程中使用子智能体,因为在实施时,我们通常关心
00:09:51我们正在编辑和创建的文件中的所有上下文。否则根据我的经验,这会导致很多幻觉。
00:09:57这也是为什么 Claude Code 没有内置用于实施的智能体。
00:10:01它只用于调研。这正是我们现在看到的。所以我要让
00:10:06一切运行完,等它准备好问题我就回来。好了,所有的
00:10:12子智能体调研都完成了,我们现在有一组初始问题要回答。当我
00:10:17看这些问题时,我想你也会和我一样欣赏这种做法,因为我们正在澄清
00:10:22大量的事情。我们在这里回答的每一个问题都是在消除编程智能体的一个
00:10:26假设。因为它是多选题,而且它提供的选项通常都很棒,我们可以
00:10:31快速处理完。这样在进入实施阶段时,我们就能非常确信
00:10:36所有细节都已经敲定了。例如,公开页面的 URL 结构
00:10:41应该如何运作?其实我喜欢第一个选项,然后砰,进入下一个。每个用户
00:10:46应该能创建多少个页面?我们就每个用户建一个页面吧。我是说,有些问题
00:10:50直接用默认选项就行,但很多情况下它会
00:10:54产生根本性的误解,这时候我就可以输入自己的答案来彻底澄清。我
00:10:59不知道现在会不会遇到这类例子,但我现在要做的是去
00:11:03回答它所有的问题,完成后再回来。你不需要看我回答每一个
00:11:07问题,因为它可能会问多达 20 到 25 个问题。它会挖掘得非常深。
00:11:14再次重申,你得对此有点耐心,但你回答的每一个问题都可能
00:11:19让你免于写出数百行坏代码。这里刚好有个很好的例子,我想澄清一些
00:11:24和它建议的完全不同的东西。顺便说一下,这是 Claude 问我的
00:11:30第二批问题。链接编辑器是否应该有一个实时手机框架
00:11:35预览?就像 Lovable 或 Bolt.new 那样,你能看到你正在创建的内容,
00:11:39左边是构建器,或者预览应该是内联的?我其实两个都想要。
00:11:44所以我可以去聊天框说这个事。它会在之后再问我其他问题,
00:11:49但现在我们可以针对这个特定的点进行一点对话。于是
00:11:53我在这里说:我想要一个内联编辑器,但我也想能看到
00:11:58预览。基本上我想要三个按钮:一个只能看到编辑器,一个
00:12:03能同时看到两者,一个只能看到预览。我发过去,然后它会回来
00:12:08问我更多问题,我会继续这个过程。好了,Claude 问完了
00:12:13一堆问题,可能比我需要的还多,但你完全可以根据自己的需要进行调整。现在
00:12:18是时候创建我们的 PRD 了,因为你可以从最终的规范总结中看到,
00:12:23它现在对我们要构建的东西有了非常清晰的理解,
00:12:28甚至知道我建完后要部署到 Vercel。太棒了。我觉得它
00:12:31现在真的不再做无根据的假设了。所以现在我要做的是
00:12:36直接运行我的 `create PRD` 命令。我会把它放在 `.claud/prd.md`。你完全可以
00:12:43把它放在任何地方,随便起什么名字。我正在使用刚才
00:12:47提到的命令,因为回到我们的四大黄金法则,其中一个重要的法则
00:12:53就是“万物皆可命令化(commandify everything)”。如果你做某件事超过两次,而我显然已经
00:12:59开启过不止几个项目了,你就应该把它做成一个命令。或者也可以叫技能(skill),
00:13:03因为 Claude Code 最近合并了命令和技能,但我还是喜欢把它们区分开:
00:13:10命令是你自己调用的东西,比如 `/commit`;而技能是智能体
00:13:15决定读取上下文时的行为,比如学习如何做一些新事情。所以我在这里创建了一个
00:13:20命令,因为在这个对话节点,我想运行这个命令
00:13:27来输出一份结构化的 PRD。在这个命令里,我给了它精确的结构,
00:13:32以及我希望 PRD 包含的所有不同章节。这样我就能让整个过程变得可重复,
00:13:38对吧?我向你们展示的这个系统的一个核心部分,就是你可以创造一套适合你的流程,
00:13:42然后在新功能和新代码库中一遍又一遍地复用它。
00:13:48所以我要执行 `/create PRD`,让它跑起来,等我们拿到最终 PRD 后我再回来。好了,
00:13:53我们的 PRD 创建好了,内容非常详尽,但这很好,
00:14:00因为我们并不是要把这一大坨直接丢给编程智能体去实现。相反,
00:14:04我们将按照 PRD 中描述的阶段来分步构建。我不会
00:14:09在镜头前做大量的验证工作,不值得浪费你们的时间,但我确实想说,
00:14:14仔细通读一遍并确保你们在所有事情上都达成了一致是非常重要的。否则
00:14:18未来会导致很多坏代码。我想先快速指出的
00:14:22第一件事是我们的 MVP 范围,在这里我们可以看到所有的提问都在
00:14:29我们的 PRD 中得到了体现。这很重要,因为我们刚刚进行的对话其实只是
00:14:34喂给 PRD 的非结构化上下文。只有 PRD 会留存下来。所以我们需要
00:14:40确保我们与智能体进行的整个对话都被记录在这里。我们还有
00:14:44“超出范围(out of scope)”部分,这同样重要——明确什么是我们现在不想构建的。我们还有完整的
00:14:49目录结构。所以它已经大致理解了代码库里会放些什么,
00:14:53这很好,因为我们已经确定了技术栈和架构。最
00:14:58重要的一点是我们划分了工作阶段。这样一来,当我们使用稍后会讲到的
00:15:04核心命令时,我们就能明确:在我们的代码库里,哪些已经建好了?
00:15:09根据 PRD,接下来要建什么?在构建 MVP 的每一个对话开始时,
00:15:13这都将是重要的上下文片段。顺便说一下,
00:15:19这就是我列出阶段的部分。其中每一个都将是一次细粒度的
00:15:24实施,也就是我们的一次 PIV 循环。所以我们先打基础,然后做链接管理。
00:15:29接着做主题功能,我们会逐个进行规划。这样我们永远不会
00:15:33让编程智能体一次做太多的事。好了。我们刚创建了 PRD,这
00:15:38真的是重头戏。我们马上就要进入第一次实施了。接下来
00:15:43我们需要设置的是规则。起初这会比较基础,因为随着我们实际代码库的
00:15:48演进,我们的规则肯定也是演进得最剧烈的。因为我用的是
00:15:53Claude Code,我只是引用了 `.agents` 和 `agents.md`,因为这更像是
00:15:58全局规则命名的通用标准。所以这里最重要的一点是,
00:16:04我们希望编程智能体始终遵循的约束和约定都要放在这个全局规则文件里。
00:16:10比如运行应用程序的命令、我们的测试策略、我们的日志
00:16:16策略。无论我们在构建什么,我们都希望编程智能体能看到这些。所以我们
00:16:20现在要创建它,至少是一个能让我们起步的初始版本。然后
00:16:25我这里的另一个组成部分是参考文件夹(reference folder)。顺便说一下,你也可以用 Claude Code 的技能来实现,
00:16:30但这更通用,因为很多时候我们希望智能体记住其他上下文,
00:16:35但仅限于我们处理应用程序特定部分的时候,比如当我们
00:16:40在开发前端时,才需要一份构建前端组件的指南。之所以不想把
00:16:44这些全部塞进 `agents.md`,是因为这个文件在每一次
00:16:49对话中都会被加载到编程智能体的上下文中。记住,上下文是宝贵的。所以我们要保持它的简洁,
00:16:55然后只需指向这些文件即可。我们可以告诉编程智能体:如果你在
00:17:00开发前端,那么你可以阅读这个文件。或者如果你在构建新的 API 接口,那么你可以
00:17:04这本质上是渐进式披露。我们拥有不同层级的上下文,
00:17:09智能体可以随着时间的推移逐步发现,确保它只根据当前任务
00:17:14加载实际需要的上下文。针对这一点,我准备了另一个指令。同样,“指令化”一切,
00:17:20就像我有喜欢的 PRD 模板一样,我也有一个创建全局规则的模板。
00:17:25首先,我们要探索代码库中已有的内容。
00:17:30因为我设计的这套流程既适用于现有代码库,也适用于新项目。所以对于这一点,
00:17:35它主要会探索 PRD。它会弄清楚我们的技术栈、架构,
00:17:38针对测试和日志策略进行一些网络研究,然后将所有这些内容
00:17:43与我的指导结合起来,生成全局规则。我这里有具体的结构。
00:17:50所以它将基于我拥有的这个模板生成。我也给你们快速展示一下,
00:17:55因为这是我非常喜欢的全局规则模板。你可以看到,
00:17:59这里的一切都是我们无论如何都希望智能体关注的。比如:技术栈、
00:18:04运行和测试的命令、项目结构。所以它本质上是我们代码库的索引、
00:18:08架构、代码模式,例如命名规范、测试和验证策略。
00:18:13总体上很基础,但我们要先创建它,然后我会给你们看几个
00:18:17参考文档的例子,也就是我们的次级按需上下文。
00:18:22现在我进入 Claude,就在刚才创建 PRD 的同一个对话中,
00:18:27我直接输入 “create rules”,因为我可以利用之前的全部对话内容作为辅助上下文。
00:18:33它立刻就明白了:好,这是我们的 PRD,这是我们的技术栈等等。
00:18:38好了,”create rules” 指令执行完毕,我们现在拿到了全局规则。我已经把它打开了。
00:18:43内容很标准:有技术栈和命令,比如我们数据库使用的是 Drizzle ORM,
00:18:47还有项目结构、架构、代码模式。
00:18:52为了简洁起见,我并没有在这里进行太多的自定义或加入过多的个人想法,
00:18:57但根据你的技术水平,这是你确保约束条件、规范和代码模式
00:19:03完全符合你构建代码库方式的最佳时机。如果你愿意,可以在这里投入大量时间。
00:19:07我没这么做是因为我现在主要想和你们探讨高层级的思路。
00:19:12此外,我还让它针对构建前端组件和 API 接口的
00:19:16最佳实践进行了一些网络研究。基于这些研究,
00:19:21我还让它创建了一些按需上下文。同样,如果你愿意,
00:19:24这些也可以是 Claude 的代码技能 (code skills)。回到全局规则文件,
00:19:29向下滚动到“按需上下文”部分,就在这里:当开发前端组件时,阅读此文件;
00:19:34当开发 API 路由时,阅读此文件。所以最初只加载了 clod.md,
00:19:40之后它会根据需要自行决定是否引入这些文件。根据我的经验,
00:19:45它非常擅长引用这些内容,前提是我们的全局规则足够简洁。比如我们这个规则
00:19:50甚至不到 240 行,只有 233 行。然后我们有 api.md 和 components.md,
00:19:58这些文件要大得多,因为当我们处理非常具体的任务时,
00:20:03引入更多信息来确保编码智能体获得良好的指导是没问题的。
00:20:08再次回到我们的图表:规则(Rules)定义了我们想要“如何”构建,
00:20:14而 PRD 定义了我们具体要构建“什么”。有了这两样东西,
00:20:19我想讨论的最后一项内容是指令,特别是“prime”指令。
00:20:23接着我们将进入第一阶段的计划制定和代码编写。目前,
00:20:29我们已经有了初始的 AI 层:PRD、规则,以及我引入的那些通用指令,
00:20:34你可以随意使用。现在我们要进入执行阶段了。但问题是,
00:20:39在与 AI 编码助手开始每一次新对话时,我们需要让它快速熟悉代码库。
00:20:44我们在构建什么?下一步要做什么?这就是 prime 指令的用武之地。
00:20:50这是一条指令,我们会在每个新会话开始时运行 /prime。
00:20:56这是一个引导过程,让它探索我们的代码库,直到它建立起心智模型,
00:21:02为下一个功能的实现做好准备。我们会让它阅读文档、探索结构,
00:21:06它也可以调用子智能体来完成这些工作。另外它还会检查 Git 日志,
00:21:11稍后我会详细讲解,就是将 Git 日志作为我们的长期记忆。
00:21:15这样它就能看到代码库随时间演进的过程,从而帮助它
00:21:21针对下一步的构建做出决策。运行完这个指令后,
00:21:26它会向我们输出它对代码库的理解。这样我们就能确认它是否掌握了
00:21:31代码库的情况,然后继续构建下一项内容。我不想在这里太详细地展开
00:21:36prime 指令的内容,但我们确实利用 Git 操作来发挥历史记录的优势。
00:21:40然后我们会读取核心文件,并识别出任何需要特别注意的内容,
00:21:45比如应用程序的主要入口。最后这份输出报告是用来验证
00:21:49它的理解是否正确。我们可以随着时间的推移不断优化它,使其更贴合项目。
00:21:55举个很小的例子,在阅读核心文档时,我可以要求它
00:22:01“阅读 Drizzle 迁移文件,以便了解数据库架构”。
00:22:08它甚至能自动补全,完全知道我想干什么。所以当你逐渐建立起自己的认知,
00:22:12知道你想要编码智能体在这个代码库中重点关注哪些核心内容时,
00:22:16比如 reference 文件夹里的其他文档,就可以加到这里。现在我要进入 Claude,
00:22:20但我会开启一个全新的对话,因为我们要开始第一个 PIV 循环了。
00:22:25稍后我会解释整个 PIV 循环,但看好了,我直接运行 Prime。
00:22:30这将是我进行任何探索之前的对话起点。在这种情况下,它会意识到:
00:22:34“这是一个全新的项目。让我看看 PRD”。然后它会建议:
00:22:39“我们先进行第一阶段吧,为项目打下基础”。Prime 执行完毕。
00:22:44这里是项目概览:个人主页链接生成器。当前状态是一个
00:22:49只有文档的空仓库。我之前做过一次测试构建,所以它才这么显示,
00:22:54但我现在已经清空了。然后它从我们的 PRD 中提取了第一阶段:基础搭建。
00:22:59这就是它建议我们构建的内容,也正是我想要的。
00:23:04我希望它逐个从 PRD 中挑选阶段,以便我们进行粒度细致的
00:23:10PIV 循环。说到 PIV 循环,我们现在就开始讲解。
00:23:14PIV 是计划 (Plan)、执行 (Implement)、验证 (Validate) 的缩写。
00:23:20我们会提取一项专注的工作(通常是 PRD 中的一个阶段),并让它跑完这整个流程。
00:23:29所以我们要针对将要处理的内容制定一个结构化的计划。就是这一部分,
00:23:34这个过程其实和创建 PRD 非常相似。接着进入执行阶段,
00:23:38我们的目标是将所有的编码工作委托给编码智能体。最后进行验证。
00:23:44我将快速过一下这个流程,然后我们再实操演示。首先,在计划阶段,
00:23:50我们有两个层级的计划:一个是顶层的项目规划,即我们已经完成的
00:23:55PRD 和规则创建;现在我们要进行的是针对具体任务的规划。
00:24:00正如我刚才提到的,这两者很像。创建结构化计划与创建
00:24:07结构化 PRD 非常相似。主要区别在于,结构化计划只专注于
00:24:13单个功能及其随之而来的所有任务。所以现在我们要深入到代码层面,
00:24:19虽然不再是高层级的抽象,但我们仍然会从一段非常“非结构化”的对话开始。
00:24:24我喜欢称之为“氛围规划” (vibe planning),即我们只是探讨大概的想法。
00:24:30具体要构建的内容是什么架构?派生出子智能体进行代码库分析和文档研究,
00:24:35然后弄清楚完成这个功能需要解决哪些具体任务。
00:24:40我们会进行这样的对话,稍后我给你们看例子。然后我们将对话内容
00:24:44转化成一份结构化文档,就像对待 PRD 一样。这里的目标是根据我们的对话,
00:24:50为 AI 编码助手创建一个详细的“作战计划”。对话是上下文的一部分,
00:24:56但我希望在结构化计划中包含非常具体的几个板块:该功能的目标和成功标准、
00:25:02需要参考的任何文档(可能是子智能体发现的)、任务列表,
00:25:09任务甚至可以细化到需要创建或更新的单个文件。而整个计划中
00:25:13最重要的部分可能就是验证策略了。这有点像测试驱动开发 (TDD),
00:25:18在写任何代码之前,我们就得明确如何验证这个功能。
00:25:23这迫使我们和编码智能体都必须对成功标准有极其清晰的认知。
00:25:27我们制定了结构化计划,并且深度参与其中,但之后我们就把
00:25:33所有的编码工作委托给智能体。但这并不是随性编码 (vibe coding)。
00:25:38我之所以选择“信任并核实”智能体,是因为我在执行阶段的前后
00:25:45加入了计划和验证这两个我深度参与的环节。我们会让编码智能体
00:25:51通过单元测试、集成测试和端到端测试来检查自己的工作。我们稍后会看到。
00:25:56但我也会亲自进行代码审查并手动测试应用程序。我会亲自运行它,
00:26:01像真实用户一样操作一遍,确保万无一失后再提交代码并发送到
00:26:06生产环境或测试环境。这里最关键的一点是,在计划和执行之间,
00:26:11我会重置上下文。这是黄金法则之一:上下文是非常宝贵的。
00:26:16虽然我们为了弄清功能实现进行了冗长而详细的对话,但我希望
00:26:20我创建的结构化计划就包含了编码智能体完成工作所需的全部上下文。
00:26:26这样我就能开启一个全新的对话,只发送这份计划,因为它已经包含了
00:26:32所有需要参考的文档和完整的任务列表。我们知道要做什么,也知道如何验证。
00:26:38这样我们就能直接切入主题开始执行,保持专注,对吧?
00:26:44我们不希望在编写实际代码时,有大量的无关背景信息导致对话臃肿。
00:26:50好,现在让我们开始第一个 PIV 循环。这会比你想象的简单得多,
00:26:55因为我们将从前期所做的大量规划中获得回报。我们和编码智能体步调一致,
00:27:00确信它理解了我们要构建的内容。因此,对于最初的这些阶段,
00:27:06甚至不需要做太多的规划。回到这里,我们已经完成了 Prime 指令,
00:27:12和编码智能体达成了一致。我只给了它一个很简单的提示:
00:27:16“没错,第一阶段看起来不错。请向我确认我们要构建的所有内容”。
00:27:22通常在第一个循环之后的 PIV 循环中,内容会更详细。比如“让我们查看代码库,
00:27:27以确定我们要如何构建它”。但在这里,它非常简单。看起来不错。
00:27:31现在记住,一切皆指令。我想把这段对话和第一阶段的想法转化为
00:27:36一份带有任务列表和验证方案的结构化计划。我有另一个指令来实现它,
00:27:40叫做 /plan-feature。我把它发过去,现在这个指令就像创建 PRD 一样,
00:27:44它内置了结构化计划的概念。我也给你们看看这个指令。
00:27:49打开 plan-feature。它接受一个可选参数,让我可以指定想构建的内容。
00:27:53在这个例子中,我直接使用了对话历史记录。它已经知道了,但我们会经历一个分阶段的过程:
00:27:59功能理解,深入研究代码库(这在后续的 PIV 循环中更适用),它会做大量的研究,
00:28:04拉取相关的文档,确保在进入执行阶段前拥有丰富的背景信息。
00:28:10你现在看到的就是模板。我们要描述问题陈述、任何背景或参考资料。
00:28:17这里有我们的执行计划和任务列表。当然,还有我们的测试策略。
00:28:23我们要预先定义验证方案。创建好计划后,我们当然要验证它。
00:28:28我们要非常具体,明确每一步:这就是我们希望你验证应用程序的方式。
00:28:33我实际上正在使用 Vercel 的 agent-browser-cli 技能,我专门做过视频介绍,
00:28:38链接我会放在这里。我们将构建全自动的浏览器自动化流程。智能体会启动
00:28:44后端和前端,运行数据库迁移,去构建它自己的链接树,
00:28:49基本上就是确保一切操作都和真实用户使用时一模一样。非常令人兴奋,
00:28:55而且验证过程会非常详尽。这样当控制权交回给我们时,
00:29:00我们可以对实现方案非常有信心。虽然我们还是会亲自验证,但工作量会少得多。
00:29:05好了,计划已经生成了。让我们来看看。我在镜头外做了一些验证,
00:29:11等会儿给你们看。通常你需要进行多次迭代,因为你要确保它对第一阶段的理解
00:29:17与你的 PRD 以及你真正想构建的内容是一致的。去仔细检查所有的板块,我鼓励你们这么做。
00:29:21这是带有任务列表的执行计划。非常详细,这很好。既然我们现在
00:29:26专注于单个功能,就需要变得具体。我们还有包含完整验证金字塔的验证方案,
00:29:31正如我所称呼的那样:类型检查、Lint 检查和单元测试。对于端到端测试,
00:29:36我们非常具体地规定了希望智能体走通的所有用户路径。这样当它把成果交还时,
00:29:42我们就能对实现充满信心。这是它起初做得不太好的地方。
00:29:47所以我做了一个后续提示,作为一个快速示例,展示在发送去执行之前,
00:29:52我们可以如何迭代和完善计划。还有一个小干货,我保证马上开始执行,
00:29:56但这真的很重要:通常编码智能体并不擅长处理环境变量。它们会在这里翻车。
00:30:01如果你在执行前没设好环境变量,它就会做一堆模拟测试并声称验证通过,
00:30:05但实际上并没有,这真的很让人抓狂。所以通常在规划的同时,
00:30:10我会创建一个 .env.example 文件并让它查看。这样它就知道了我设置的
00:30:15所有环境变量,然后我也会设置好真实的环境变量。显而易见,
00:30:20我不会展示这个文件,因为里面有我的数据库 URL 之类的秘密。但因为我已经设置好了,
00:30:24现在我们可以一鼓作气完成整个执行过程,不仅是写代码,它还可以运行数据库迁移,
00:30:29启动后端和前端,使用 Vercel agent-browser-cli 测试一切。在这个过程中,
00:30:34它不需要因为等待我设置环境变量而中断。现在我已经完美地搭好了台子,
00:30:38准备进入执行阶段,我对这个计划非常满意。现在,记住要重置上下文,
00:30:43因为上下文是宝贵的。我现在处于一个全新的对话窗口,我将运行 execute 指令,
00:30:48唯一的参数就是我指向的那份计划。这就是它现在需要的全部上下文。
00:30:53我会暂停一下,等它跑完整个流程再回来。实际上,我们现在正将
00:30:57所有编码工作委托给智能体,收获前期在规划上投入的成果。到了这一步,
00:31:03每一个 PIV 循环都会变得飞快,这全靠我们之前做的那些铺垫。
00:31:09好了,执行完成了。从截图可以看到它完成了完整的端到端测试。
00:31:13所以你可以对实现方案相当放心,因为智能体已经处理好了一切,
00:31:19但人为验证仍然很重要。我们要确保“信任并核实”。
00:31:23至于代码审查,那涉及非常细节的内容,我现在就不做了,
00:31:29但如果你技术背景比较强,这绝对是很重要的一步。我要做的是和你们一起现场测试应用。
00:31:34我在镜头外唯一做的就是预先创建了一个账号,以确保基础的身份验证功能正常,
00:31:40除此之外还没动过。看这个,太酷了。它看起来已经非常非常漂亮了。
00:31:45我可以设置我的显示名称,写个简介,比如“一个很酷的 AI 开发者”。
00:31:51我可以设置头像 URL。我刚把一张图片上传到了 Imgur,效果看起来也很棒。
00:31:56我可以添加一些链接,比如 YouTube。地址是 [youtube.com/atcolemedine](https://www.google.com/search?q=https://youtube.com/atcolemedine)。
00:32:01看起来不错。再加一个链接,LinkedIn。我现在手头没有我的 LinkedIn 链接,
00:32:06那就随便填个 linkedin.com 吧,无所谓。太酷了。
00:32:11让我再加一个,X (Twitter)。好,就填 x.com。非常棒。我可以拖动它们进行排序,
00:32:16右边的预览会实时反映出来。我可以只看编辑器,然后调整预览效果。
00:32:21目前的主题看起来不是最好的,只是白花花的一片,但我记得那是后面阶段的事,
00:32:26因为目前我们只是在构建基础。所以现在很多地方还不完美,
00:32:30但作为一个起点,它已经看起来极其出色了。然后我可以点击保存。
00:32:35好的,加载 API 接口。这是在本地运行的。成功了,“更改已成功保存”。
00:32:39我刷新一下页面,所有内容都还在。太不可思议了。这看起来真的非常棒。
00:32:43既然我们已经建立好了稳固的基础,现在我想快速聊聊提交信息 (commit message)。
00:32:49我有另一个指令叫 /commit,它非常基础。如果你愿意,可以让它更详细些,
00:32:55但本质上,你只是想为智能体提供如何创建 Git 信息的说明,
00:32:59因为我们将把它作为我们的长期记忆。回到图表,这是黄金法则之一:
00:33:08你的提交历史就是你的长期记忆。如果我们标准化提交信息(这就是为什么使用
00:33:11/commit 指令使其可复用),那么智能体在运行 Prime 过程时,
00:33:18就可以查看 Git 日志来了解我们最近构建了什么,从而引导接下来的开发
00:33:24以及可能需要遵循的模式。这就是这条提交信息的威力所在。
00:33:28我会运行 /commit,虽然我自己运行 git commit 也很容易,
00:33:32但这能保证提交信息的格式始终如一。在这个例子中,没有什么可提交的,
00:33:37因为我在镜头外已经运行过了,但在每次执行完成后,这一点非常重要。
00:33:42在搭建好项目基础后,另一件极其重要的事情是,
00:33:46你需要建立一套回归测试框架。我们要确保...
00:33:51策略。无论我们在构建什么,我们始终希望我们的编码代理能够看到这一点。所以我们想要
00:33:57现在就创建它,至少创建一个初始版本让我们开始。然后另一个
00:34:01组件是参考文件夹。顺便说一下,你也可以为此使用 clod 代码技能,
00:34:06但这更通用,因为很多时候我们希望代理拥有其他上下文,
00:34:11回到这张图表,这是金科玉律之一:你的提交历史就是你的长期记忆。
00:34:17因此我们要规范化消息内容,这就是为什么我们使用 "/commit" 命令来确保可重用性,
00:34:22这样当智能体在处理提示词时,它可以查看 Git 日志来了解最近构建的历史,
00:34:28这将引导接下来的操作,并提供它可能需要遵循的模式。
00:34:32这就是这个提交消息的威力所在。所以我输入 "/commit",
00:34:38虽然我自己运行 "git commit" 也很简单,但这样做能确保
00:34:43消息格式始终保持一致。在这种情况下,因为我已经在镜头外运行过了,
00:34:48所以没有可提交的内容,但在每次功能实现后,完成这一步都至关重要。
00:34:53在项目基础搭建完成后,另一件非常重要的事情
00:34:58是建立回归测试框架。我们要确保
00:35:04随着未来不断进行 PIV 循环(即针对所有想要构建的功能反复执行此过程),
00:35:09我们需要确保旧的功能不会损坏。关于这部分,我会在
00:35:14另一段视频中详细讲解,包括如何亲自实现这类测试工具链的所有策略,
00:35:19因为本质上你会告诉智能体:"现在的情况很好,
00:35:25但我也可以在 Aqua Voice 中要求你列出所有
00:35:31你完成的端到端测试,并把它们整理成一个命令给我。这样我以后
00:35:36构建其他功能时可以运行它,以确保之前构建的所有内容依然正常工作。"
00:35:41大概就是这样。同样,我现在不会深入探讨细节,
00:35:46因为建立并创建测试工具链需要一些时间,但这正是
00:35:50在持续开发过程中保持应用稳定的方法。而且,
00:35:55创建和维护这些工作确实需要大量精力,因为你必须不断更新它。
00:36:00不过市场上也有一些可以自动处理这些问题的强大解决方案。
00:36:05其中之一就是 QA tech。他们拥有能随代码库共同进化和适应的 AI 测试智能体。
00:36:11所以当你添加越来越多功能时,它们会自动增加更多测试用例,
00:36:16以确保在持续构建过程中,应用始终运行良好。我很快给你们演示一个例子。
00:36:22上手非常简单。进入 QA tech,他们有免费层级供你开始和尝试。
00:36:26我在这里创建一个项目,然后你只需要粘贴想要测试的 URL 即可。
00:36:30由于我已经提交并推送到了 GitHub,所以我把这个应用
00:36:35在一分钟内就部署到了 Vercel。这是免费托管网站最简便的地方,尤其是用 Next.js 构建的项目。
00:36:40现在回到我的项目,粘贴这个 URL。
00:36:45创建项目并分析代码库需要一点时间。
00:36:50我们可以说:"我想为我的网站设置一套完善的测试。帮我创建
00:36:55最初的 3 到 5 个测试用例。" 这有点像 Bolt.new 或 Lovable,
00:36:59你可以直接给出提示词,让它为你的项目设置测试套件。
00:37:04这是他们的推荐入门方式。我直接发送请求。
00:37:08最酷的是,它会深入挖掘并实际爬取你的网站,而你
00:37:12完全不需要管理任何基础设施。它会分析网站并生成测试用例。
00:37:16等它完成后我再回来。现在执行到一半,我想快速向你们展示,
00:37:21它在几分钟内就爬取了我的网站。其中非常重要的一点是,
00:37:25我们需要一种登录网站的方法,让自动化工具能够执行操作。
00:37:29所以他们提供了一个输入用户名和密码的入口,并会以安全的方式存储。
00:37:34我在这里创建了一个测试账号。保存一下。然后
00:37:38它会使用该账号进入网站,深入理解我们想要测试的所有用户路径。
00:37:43好了,它已经为我们生成了一系列测试用例,我们
00:37:48甚至可以点击进入每一个案例,查看它执行的确切流程。现在,
00:37:53我们的这些测试就全部就绪了。QA tech 中的 AI 测试智能体
00:37:59会随着时间的推移不断进化这些用例,确保它们能持续覆盖代码库中的所有内容。
00:38:04随着功能不断增加,这真的非常酷。当然,我们也可以构建自己的命令系统
00:38:09来完成类似操作,但我非常感激有这样一个平台能为我处理好这一切。
00:38:14后台还有智能体,我可以与之交流来处理测试,
00:38:19确保我真正对所有内容进行了回归测试。这样,每当
00:38:24有任何功能损坏时,我可以进来这里说:"应用现在有个 Bug,
00:38:28创建一个应该会失败的测试。让我解决问题,
00:38:33然后测试就应该能通过了。" 这就引出了我的最后一条金科玉律:系统进化心态。
00:38:40当我们代码库中遇到 Bug 时,重要的不仅是修复 Bug 本身,
00:38:46还要思考如何改进我们的 AI 层,以便这种情况不再发生。比如,我们可能
00:38:51需要对风格指南和规则描述得更具体,或者为此创建一个新的按需上下文。
00:38:57也许我们需要在命令或工作流中加入更多端到端测试,
00:39:02不惜一切代价确保不再遇到此问题。然后我们还可以
00:39:06像我在 QA tech 或自定义命令系统中展示的那样,添加测试来确保
00:39:12该问题不会在代码库中再次出现。这种做法的威力在于,虽然
00:39:16前期投入了时间,但能让编程智能体随着时间的推移变得更可靠、更具可重复性,
00:39:21随代码库同步进化。所以我们实际上在并行做三件事:
00:39:26在构建代码库的同时,我们也在进化测试库、代码库以及 AI 层。
00:39:32天哪,这种复利效应会非常惊人。回到 Cloud Code,我给你们举个简单的例子。
00:39:37我在镜头外进行的一次迭代是调整网站样式。
00:39:43因为如果你回看视频开头,你会发现我忘了明确说明样式,
00:39:47即我希望网站长成什么样。所以 Cloud Code 就自己做了一些假设,
00:39:51结果看起来并不是很理想。所以我必须对此进行迭代。
00:39:56我可以这样做:"起初我不喜欢你为前端实现的样式。
00:40:01我们的 AI 层在样式指南方面的规则和按需上下文显然不够完善。
00:40:06所以我希望你进行一些元推理。先不要更改任何内容,但帮我思考一下,
00:40:10现在我们可以对规则或按需上下文做哪些更改、添加或更新,
00:40:15以便在后续构建分析页面或其他页面时,
00:40:20能拥有更一致的样式。"
00:40:25这里重要的一点是我告诉它先不要更改任何内容,
00:40:29因为通常我希望能对 AI 层的变更拥有更多控制权,而对于代码库,
00:40:34我只想尽可能多地委托给智能体。我会让它和我一起推理,
00:40:39但我通常喜欢亲自进行这些细微且专注的调整。你可以看到,
00:40:44它建议在参考文件夹中创建一个 "style.md",也就是为我们添加第三个按需上下文。
00:40:50我想这应该会和 "components.md" 配合使用。那个文件更倾向于:"这里是我们应该如何布局内容",
00:40:54而 "styles.md" 则是:"它是如何运作的。这里是我们应该如何使用 Tailwind CSS 和 ShadCN 的。"
00:40:58我不打算演示完整的实现和纠错过程了,
00:41:03只是想给你们展示一个好例子,说明每当我们遇到 Bug 或不符合预期的情况时(
00:41:06就像现在这样),这都是进化 AI 层的绝佳机会。
00:41:11这样,随着项目不断推进,我们就能与针对该项目的编程智能体配合得越来越默契。
00:41:16朋友们,这正是整个过程中杠杆率最高的部分,我真的把最好的留到了最后。
00:41:20以上就是全部内容。这确实是一个在启动新项目时,
00:41:26利用编程智能体获得可靠且可重复结果的极简流程。
00:41:32在完成系统进化后,我们只需回到起点,进行更多的 PIV 循环,
00:41:35按照同样的流程来完成 PRD 中的所有阶段,添加其他功能,
00:41:40不惜一切代价达成最小可行性产品(MVP)。然后,
00:41:45我们将在下一段视频中进入布朗地(Brownfield)开发阶段。
00:41:49如果你觉得这些内容不错,并想通过我完整的命令和规则资源库进行更深入的研究,
00:41:54或者想看看系统进化真正的样子并深度参与其中,
00:41:59请务必查看我在 Dynamics 社区中开设的智能体编码课程。
00:42:04我会在视频描述和置顶评论中附上链接。这就是我目前要分享的所有内容。
00:42:08如果你喜欢这段视频,并期待看到更多关于智能体编码和布朗地开发的内容,
00:42:13请点赞并订阅。就这样,
00:42:17我们下个视频再见。
00:42:22再见。