拒绝花架子:在复杂代码库中解决硬核问题 – Dex Horthy, HumanLayer

AAI Engineer
컴퓨터/소프트웨어경영/리더십AI/미래기술

Transcript

00:00:00(欢快的音乐)
00:00:02大家好,你们好吗?
00:00:23很高兴来到这里,我是 Dex。
00:00:25正如刚才精彩的介绍所言,
00:00:27我已经研究智能体(Agents)好一段时间了。
00:00:29我们在六月 AI Engineer 大会上关于“12 因子智能体”的演讲,
00:00:32成为了有史以来最受欢迎的演讲之一。
00:00:34我想大概排在前八名左右,
00:00:35是六月那场大会中表现最好的演讲之一。
00:00:38在那次演讲中,我也许提到了“上下文工程”。
00:00:41那么今天我为什么在这里?我要聊些什么?
00:00:44我想聊聊我在六月 AI Engineer 大会上
00:00:46最喜欢的演讲之一,
00:00:47虽然我知道大家昨天都听到了 Igor 的更新,
00:00:49但由于主办方没让我改幻灯片,
00:00:50所以今天的内容将围绕 Igor 在六月提到的那些观点。
00:00:54基本上,他们对不同规模公司的
00:00:5610 万名开发者进行了调查,
00:00:58结果发现,大多数时候
00:01:00当你将 AI 用于软件工程时,
00:01:01会产生大量的返工和代码库频繁变动。
00:01:04它在处理复杂任务时效果并不理想,
00:01:07尤其是针对那些旧有的(Brownfield)代码库。
00:01:08从图表中可以清楚地看到,
00:01:10虽然你的交付量增加了,
00:01:11但其中很大一部分只是在修补
00:01:14上周产出的低质代码。
00:01:15另一方面,
00:01:18如果你在做全新的项目,比如简单的 Vercel 仪表盘,
00:01:21那效果会非常棒。
00:01:25但如果你要处理的是一个有 10 年历史的 Java 代码库,
00:01:28可能就没那么好用了。
00:01:29这与我的个人经验非常吻合。
00:01:30在与许多创始人及优秀工程师交流后发现,
00:01:32代码质量太差、技术债务堆积如山,
00:01:35导致 AI 在现有代码库中无法发挥作用。
00:01:37也许未来模型变得更强时可以解决,
00:01:40但这正是“上下文工程”要解决的核心问题。
00:01:42我们该如何充分利用现有的模型?
00:01:44我们该如何管理上下文窗口?
00:01:46我们在八月份讨论过这个话题。
00:01:48我要坦白一件事。
00:01:49第一次使用 Claude Code 时,我并没觉得多惊艳。
00:01:53当时觉得,还行吧,稍微好用一点,
00:01:54我理解它的逻辑,也喜欢它的交互体验。
00:01:56但从那以后,我们团队摸索出了一些门道,
00:01:59我们实际上能够获得
00:02:01两到三倍的吞吐量提升。
00:02:02我们的交付速度变得极快,以至于别无选择,
00:02:06只能改变原本的协作方式。
00:02:07我们重新梳理了软件开发的所有流程。
00:02:11当时只有三个人,花了八周时间,过程非常艰辛。
00:02:12真的非常不容易。
00:02:14但既然解决了,我们就再也回不去了。
00:02:16这就是所谓的“拒绝低质产出”。
00:02:18我想我们在这方面取得了一些进展。
00:02:20这篇文章九月份在 Hacker News 上爆火。
00:02:23成千上万的人在 GitHub 上
00:02:25获取了我们的“调研-计划-执行”提示词系统。
00:02:28我们的目标是(虽然是误打误撞总结出来的):
00:02:31我们需要能处理旧有代码库的 AI。
00:02:35能解决复杂问题的 AI。
00:02:38而且要高质量,拒绝垃圾代码。
00:02:40此外,我们必须保持“心理对齐”。
00:02:42稍后我会详细解释
00:02:43那具体是什么意思。
00:02:44当然,和所有事情一样,
00:02:46我们希望尽可能多地消耗 Token。
00:02:47将能外包的任务有意义地交给 AI
00:02:50是非常关键的。
00:02:52这具有极高的杠杆效应。
00:02:53所以,今天的主题是“面向编程智能体的高级上下文工程”。
00:02:56我先来为此做一个定义。
00:02:58使用编程智能体最幼稚的方式
00:03:01是向它提要求,然后指出它错在哪里,
00:03:03不断修正、不断追问,
00:03:05直到上下文用尽,或者你放弃,甚至气得想哭。
00:03:09我们可以做得更聪明一点。
00:03:11大多数人在 AI 探索的早期阶段
00:03:13就会发现:如果一段对话
00:03:17已经跑偏了,
00:03:21最好直接开启一个新的上下文窗口。
00:03:24你会说:好吧,刚才那条路走不通。
00:03:25让我们重新开始。
00:03:26同样的提示词,同样的任务。
00:03:27但这一次,我们要换一条路径。
00:03:29别再试刚才那个方向了,因为没用。
00:03:31那该如何判断什么时候该重头开始呢?
00:03:34如果你看到这个,
00:03:37(观众大笑)
00:03:39大概就是该重开的时候了,对吧?
00:03:41这是当你指责 Claude 搞砸了时,它通常会说的话。
00:03:45我们可以更上一层楼。
00:03:47我们可以采取我所谓的“主动压缩(Intentional Compaction)”。
00:03:50基本上,无论当前是否在正轨上,
00:03:53你都可以利用现有的上下文窗口,
00:03:56要求智能体将其压缩成一个 Markdown 文件。
00:03:59你可以审查这个文件,并给它打上标签。
00:04:00这样当新的智能体启动时,
00:04:02它就能直接进入工作状态,而无需重新经历
00:04:04所有的搜索、代码库理解
00:04:05以及同步进度的过程。
00:04:07压缩的内容包括什么?
00:04:09问题是,在你的上下文窗口中
00:04:11究竟是什么在占用空间?
00:04:13包括文件搜索、代码流理解、
00:04:17文件编辑以及测试和构建的输出。
00:04:20如果你用的某些 MCP 协议会在上下文窗口中
00:04:22倾倒大量的 JSON 和一堆 UUID,
00:04:25那真的谁也救不了你。
00:04:26那么我们应该压缩什么?
00:04:28稍后我会详细讲解细节,
00:04:30但这是一个非常好的压缩示例。
00:04:31这正是我们正在处理的内容,
00:04:33包含了对于解决当前问题
00:04:34至关确切的文件和行号。
00:04:37为什么我们对上下文如此着迷?
00:04:39因为 LLM 曾因此在 YouTube 上被群嘲过。
00:04:42它们不是纯函数,因为它们具有随机性,
00:04:45但它们是无状态的。
00:04:46要让 LLM 表现得更好,唯一的办法
00:04:49就是输入更高质量的 Token,
00:04:51从而获得更高质量的输出。
00:04:52在每一轮循环中,
00:04:53无论 Claude 还是任何编程智能体在选择下一个工具时,
00:04:55可能存在数百个正确和错误的下一步。
00:05:00但唯一能影响后续输出的,
00:05:03只有对话中已经存在的内容。
00:05:05因此,我们要优化这个上下文窗口,
00:05:07追求其正确性、完整性、大小,
00:05:10以及一定的“轨迹”。
00:05:11“轨迹”这一点非常有趣,
00:05:12因为很多人会说:
00:05:13“我让智能体去做某事,
00:05:16结果它做错了。”
00:05:17“于是我纠正它,斥责它,
00:05:18结果它又做错了。”
00:05:20“然后我又斥责它。”
00:05:21此时 LLM 回看这段对话,
00:05:23它会想:好吧,我做错事,
00:05:24人类骂我;
00:05:25我又做错事,人类又骂我。
00:05:26那么在这段对话中,概率最高的下一个 Token
00:05:29就是我应该再做错点什么,
00:05:31好让人类能再骂我一次。
00:05:33所以,要警惕你的对话轨迹。
00:05:35反过来看,
00:05:36最糟糕的是错误信息,
00:05:39其次是信息缺失,最后是过多的噪音。
00:05:42如果你喜欢公式,这里有一个简单的公式
00:05:44供你参考。
00:05:47Jeff Huntley 对编程智能体做了大量研究。
00:05:51他总结得很好:
00:05:51你对上下文窗口的使用越多,
00:05:53得到的结果就越差。
00:05:55这引出了一个概念。
00:05:56一个非常、非常学术化的概念,叫作“降智区(The Dumb Zone)”。
00:05:59这是你的上下文窗口。
00:06:01大约有 16.8 万个 Token。
00:06:03其中一些预留给了输出和压缩。
00:06:05这因模型而异,
00:06:07但我们这里以 Claude Code 为例。
00:06:09在 40% 左右的界限,你就会开始看到
00:06:10回报递减的现象,具体取决于你的任务。
00:06:14如果你的编程智能体中集成了太多的 MCP,
00:06:17你几乎一直在“降智区”内工作,
00:06:18永远得不到好的结果。
00:06:21人们讨论过这个。
00:06:21我就不多说了。
00:06:22具体效果因人而异。
00:06:2340% 只是一个基于任务复杂度的
00:06:26大致参考标准。
00:06:28回到压缩,或者我从现在起称之为
00:06:31“巧妙避开降智区”。
00:06:33我们可以使用子智能体(Subagents)。
00:06:37如果你有一个前端子智能体、一个后端子智能体、
00:06:39一个 QA 子智能体和一个数据科学子智能体,请打住。
00:06:44子智能体不是为了拟人化角色,
00:06:47而是为了控制上下文。
00:06:49你可以这样做:如果你想在大型代码库中
00:06:51查找某项功能的运作方式,
00:06:53如果编程智能体支持子智能体,你可以引导它去做,
00:06:56或者你可以构建自己的子智能体系统,
00:06:58基本上你会说:嘿,去查查这个是怎么运行的。
00:07:00它就可以派生出一个新的上下文窗口,
00:07:03去完成所有的阅读、搜索、
00:07:05查找、阅读整个文件
00:07:07以及理解代码库的工作,
00:07:09然后只向父智能体返回
00:07:13一条非常简洁的信息,
00:07:14比如:嘿,你要找的文件在这里。
00:07:17父智能体只需阅读那一个文件,就能直接开始工作。
00:07:20这非常强大。
00:07:22如果你运用得当,
00:07:23就能得到这样高质量的回复,
00:07:25并能极好地管理上下文。
00:07:29比子智能体效果更好,或者说建立在其之上的,
00:07:30或者在子代理层之上
00:07:32是一个我称之为“频繁有意压缩”的工作流。
00:07:35稍后我们会讨论“研究、计划、执行”模式,
00:07:37但核心在于你不断地
00:07:39保持极小的上下文窗口。
00:07:41你围绕上下文管理来构建整个工作流,
00:07:45它分为三个阶段:研究、计划、执行,
00:07:48我们将努力全程保持在“智能区”。
00:07:51研究阶段的核心是理解
00:07:53系统如何运行,找到正确的文件,
00:07:55并保持客观。
00:07:56这是一个你可以用来做研究的提示词。
00:07:58这是研究提示词的输出结果。
00:08:00这些都是开源的。
00:08:01你可以自己去获取并尝试。
00:08:04在计划阶段,你需要列出确切的步骤。
00:08:06你要包含文件名和代码行片段。
00:08:08你要非常明确地说明在每次修改后
00:08:10我们将如何进行测试。
00:08:11这是一个很好的计划提示词。
00:08:12这是我们的一个计划示例。
00:08:13里面包含了实际的代码片段。
00:08:16然后我们开始执行。
00:08:17如果你读过这些计划,
00:08:17你会很容易发现,即便是世界上最笨的模型
00:08:20大概率也不会把这事搞砸。
00:08:23所以我们只需按照计划执行,
00:08:24并保持低上下文运行。
00:08:26至于计划提示词,就像我说的,
00:08:27它是整个过程中最枯燥的部分。
00:08:30我想把这些付诸实践。
00:08:31在工作中,我和我的哥们 Vaibhav 合作了一个播客,
00:08:34他是 Boundary ML 公司的 CEO。
00:08:37我说:“嘿,我要试着一站式修复
00:08:39你那 30 万行 Rust 代码的
00:08:41编程语言库。”
00:08:42整集节目都在讲这个。
00:08:45大约有一个半小时。
00:08:46我现在不打算细说,
00:08:47但我们做了大量的研究工作,
00:08:48后来因为效果不好都扔掉了。
00:08:49接着我们对比了有研究支持和没研究支持的计划,
00:08:51并对比了所有的结果。
00:08:53那段时光非常有趣。
00:08:54那是周一晚上。
00:08:55到了周二早上,我们正在录节目时,
00:08:57他们的 CTO 已经看到了那个 PR(拉取请求),
00:08:59但他并不知道这只是我为播客做的一个节目效果。
00:09:03他基本上就在说:“行,这看起来不错。
00:09:04我们会把它加进下一个版本。”
00:09:05他当时有点懵。
00:09:08这就是那个计划。
00:09:09但不管怎样,是的,事实证明了。
00:09:12它在遗留代码库中非常有效,且没有废话。
00:09:14但我还想看看我们是否能解决更复杂的问题。
00:09:17Vaibhav 还是有点怀疑。
00:09:19于是我们在一个周六坐下来搞了大约 7 个小时,
00:09:21最后给 BAML 提交了 35,000 行代码。
00:09:24其中一个 PR 在一周后就被合并了。
00:09:26不得不说,其中一部分是代码生成。
00:09:28比如你更新了行为,
00:09:29所有的基准文件也随之更新,
00:09:31但那天我们确实交付了大量代码。
00:09:33他估计这 7 个小时抵得上平时一到两周的工作量。
00:09:36所以很酷,我们确实能解决复杂问题。
00:09:40不过这种方法也有局限性。
00:09:41我曾和哥们 Blake 坐下来,
00:09:42尝试从 Parquet Java 中移除 Hadoop 依赖。
00:09:46如果你知道 Parquet Java 是什么,
00:09:47那我真的很同情你,
00:09:50不知道你的职业生涯经历了什么才沦落至此。
00:09:53结果进行得并不顺利。
00:09:55这是当时的计划和研究。
00:09:57到最后,我们抛弃了所有东西,
00:09:58重新回到了白板前。
00:10:00我们不得不,一旦我们弄清了
00:10:01所有的陷阱在哪里,
00:10:03我们就得回到:“好吧,
00:10:05这一切实际上该如何拼凑在一起?”
00:10:06这引出了一个非常有趣的观点,
00:10:09Jake 稍后也会谈到。
00:10:11不要把思考外包出去。
00:10:13AI 无法取代思考。
00:10:14它只能放大你已经完成的思考,
00:10:17或是放大你思考的缺失。
00:10:19所以人们会问:Dex,
00:10:21这就是“规格说明驱动开发(SDD)”,对吧?
00:10:23不,SDD 这个概念已经坏掉了。
00:10:27不是理念坏了,是这个说法坏了。
00:10:30它没有明确的定义。
00:10:33这是来自 ThoughtWorks 的 Brigetta。
00:10:35很多人说“规格说明(Spec)”,
00:10:37其实指的只是更详细的提示词。
00:10:39有人记得这张图片吗?
00:10:41有人知道这是哪儿来的吗?
00:10:43好吧,这太冷门了。
00:10:44永远不会有所谓的“智能体元年”,
00:10:46因为存在“语义扩散”。
00:10:47Martin Fowler 在 2006 年就说过。
00:10:49我们提出了一个定义良好的好词,
00:10:52然后每个人都变得很兴奋,
00:10:53每个人都开始赋予它一百种不同的含义,
00:10:56最后它就变得毫无用处了。
00:10:59有人把智能体当成人,有人当成微服务,
00:11:02有人当成聊天机器人,有人当成工作流。
00:11:05谢谢你,Simon。
00:11:06我们又回到了原点。
00:11:07智能体不过是循环中的工具。
00:11:09规格说明驱动开发也正面临这种局面。
00:11:11我原本在演讲开始时放了 Sean 的幻灯片,
00:11:15但那导致很多人
00:11:15把注意力放错了地方。
00:11:17他的观点是“忘掉代码,代码现在就像汇编语言”,
00:11:19你只需要专注于 Markdown 文档。
00:11:21非常酷的想法,但现在人们说 SDD
00:11:24指的是写更好的提示词,或者产品需求文档。
00:11:26有时它指的是使用可验证的反馈循环
00:11:28和反压机制。
00:11:30或许是像 Sean 教我们的那样,
00:11:32把代码当作汇编来看待。
00:11:34但对很多人来说,它只是在写代码时
00:11:36参考一堆 Markdown 文件。
00:11:37或者我最喜欢的,上周刚看到的:
00:11:39“规格说明”就是开源库的文档。
00:11:43所以这个词完了。
00:11:44SDD 被过度炒作,现在已经没用了。
00:11:48它的语义已经扩散了。
00:11:49所以我想谈谈四样
00:11:52目前真正有效的东西,即我们在内部
00:11:55以及和用户沟通中发现的战术和实践步骤。
00:11:59我们做研究,弄清楚系统是如何运作的。
00:12:02你们记得电影《记忆碎片》吗?
00:12:03用 Peter 的话来说,这是关于上下文工程
00:12:05拍得最好的一部电影。
00:12:07男主醒来后没有记忆,
00:12:09他必须读自己身上的纹身来搞清楚自己是谁,
00:12:11以及他在做什么。
00:12:12如果你不对智能体进行入职引导,它们就会胡编乱造。
00:12:17这是你的团队,这对你们大多数人来说
00:12:19是非常简化后的模型。
00:12:19你们大多数人的组织结构比这大得多。
00:12:21但假设你想在这一块做点工作。
00:12:23你可以做的一件事是
00:12:26在每个代码仓库里都放入“入职文档”。
00:12:27你放入大量的上下文。
00:12:28说明仓库是什么,它是如何运作的。
00:12:29这是对代码库中所有上下文的压缩,
00:12:32让智能体在真正开始工作之前
00:12:34能够预先看到这些信息。
00:12:36但这很有挑战性,因为有时文档会变得太长。
00:12:39随着你的代码库变得非常庞大,
00:12:41你要么得把文档写得更长,
00:12:43要么就得漏掉一些信息。
00:12:45所以当你阅读这些内容时,
00:12:48你在阅读这个庞大的
00:12:49拥有 500 万行代码的单体仓库上下文,
00:12:52你会用掉所有的“智能区”
00:12:53仅仅为了学习它是如何运作的,导致你无法
00:12:55在“笨蛋区”进行任何有效的工具调用。
00:12:57所以,你可以按层级对这些内容进行分片。
00:13:02你可以做所谓的“渐进式披露”。
00:13:04你可以把它拆开,对吧?
00:13:05你可以只在每个仓库的根目录下放一个文件,
00:13:08然后在每个子层级添加额外的上下文,
00:13:11取决于你是否在这里工作,
00:13:13这里才是你需要知道的内容。
00:13:15我们不为文件本身写文档,
00:13:17因为文件本身就是事实来源。
00:13:18但当你的智能体在工作时,
00:13:19你调入根上下文,
00:13:21然后再调入子上下文。
00:13:22我们不讨论具体的工具,
00:13:23你可以用 CloudMD,
00:13:24也可以用 Hoax,管它是什么。
00:13:26但这样你在“智能区”依然有充足的空间,
00:13:28因为你只调入了你真正需要的信息。
00:13:31这种方法的问题在于内容会过时。
00:13:33所以每当你发布一个新功能,
00:13:35你都需要进行类似缓存失效的操作,
00:13:38并重新构建大部分的内部文档。
00:13:42你可以利用大量的 AI
00:13:43把更新这些文档作为流程的一部分。
00:13:46我来问个问题。
00:13:48在实际代码、函数名、
00:13:50注释和文档之间,
00:13:51有没有人想猜猜这张图的 Y 轴代表什么?
00:13:57- 废话。 - 废话。
00:13:58实际上是你在代码库任何一个部分
00:14:01能发现的谎言数量。
00:14:03所以你可以把更新文档作为流程的一部分,
00:14:06但你可能不该这么做,因为你大概率做不到坚持。
00:14:08我们更倾向于“按需压缩上下文”。
00:14:11如果我正在开发一个涉及 SCM 供应商、
00:14:14JIRA 和 Linear 的功能,
00:14:15我只需要给它一点引导。
00:14:17我会说,嘿,我们现在要处理
00:14:18代码库中这一块的部分,
00:14:21一个好的研究提示词或斜杠命令
00:14:24甚至可能会运用你的技能,
00:14:27启动一堆子代理来对代码库进行纵向切片
00:14:30穿过代码库,然后构建一份研究文档,
00:14:33这只是一个基于代码本身真实情况的
00:14:35代码库重要部分的快照。
00:14:39我们正在压缩真相。
00:14:41计划就是杠杆。
00:14:43计划是关于意图的压缩。
00:14:45在计划中,我们将概述确切的步骤。
00:14:48让我们拿走研究成果、PRD、Bug 票
00:14:50或者其他任何东西。
00:14:52我们创建一个计划,并创建一个计划文件。
00:14:54所以我们再次进行了精简。
00:14:55我想停下来谈谈心理对齐。
00:14:58有人知道代码审查是用来做什么的吗?
00:15:00心理对齐,心理对齐。
00:15:05它是为了确保事情是正确的等等。
00:15:08但最重要的一点是,我们如何让团队中的每个人
00:15:10在以下问题上保持同步:
00:15:11代码库是如何变化的,以及为什么要变化?
00:15:14我每周可以读一千行 Golang 代码。
00:15:17抱歉,我读不了一千行。
00:15:18这很难,但我能做到。
00:15:19但我不想这么做。
00:15:20随着我们团队的成长,所有的代码都会被审查。
00:15:23我们不会不读代码。
00:15:24但作为团队的技术负责人,
00:15:27我可以阅读计划并保持更新。
00:15:29对我来说,那就足够了。
00:15:30我可以尽早发现一些问题,
00:15:32并保持对系统演进方式的理解。
00:15:35Mitchell 发过一篇非常好的帖子,
00:15:36关于他一直把 AMP 线程
00:15:38放在拉取请求(PR)中,这样你看到的就不只是
00:15:41GitHub 上的一大堆绿色文本,
00:15:43而是确切的步骤、提示词,
00:15:44以及“嘿,我最后运行了构建且通过了”。
00:15:46这会让审查者身临其境,
00:15:49这是普通 GitHub PR 无法做到的。
00:15:51当你交付的代码量
00:15:52达到原来的两到三倍时,
00:15:54你有责任找到方法让团队
00:15:57保持同步,并向他们展示“这是我执行的步骤”
00:16:00以及“这是我们手动测试的方式”。
00:16:01你的目标是杠杆,所以你需要高度确信
00:16:04模型确实会做正确的事情。
00:16:06如果我不读这个计划,我就无法知道实际上
00:16:08会发生什么,以及会发生哪些代码更改。
00:16:11所以随着时间的推移,我们不断迭代,让我们的计划包含
00:16:14关于即将发生变化的实际代码片段。
00:16:17所以你的目标是杠杆。
00:16:18你需要意图的压缩
00:16:19以及可靠的执行。
00:16:22而且,我有物理背景。
00:16:23我们喜欢在峰值和曲线的中心画线。
00:16:28随着计划变长,可靠性会提高,
00:16:30但可读性会下降。
00:16:31对于你、你的团队和你的代码库来说,有一个甜点位,
00:16:33你应该试着找到它。
00:16:35因为当我们审查研究和计划时,
00:16:37如果它们写得好,我们就能实现心理对齐。
00:16:40不要把思考外包出去。
00:16:42我以前说过,这不是魔法。
00:16:44没有完美的提示词。
00:16:46如果你不看计划,它就无法奏效。
00:16:50所以我们围绕着你——开发者——构建了整个流程,
00:16:53让你与智能体反复互动,
00:16:55在计划创建时就进行阅读。
00:16:56如果你需要同行评审,
00:16:58你可以把它发给别人说:
00:16:58“嘿,这个计划看起来对吗?”
00:17:00“这个方法正确吗?”
00:17:00“审视这些事物的顺序正确吗?”
00:17:03Jake 同样写了一篇非常好的博客文章,关于
00:17:05让“研究-计划-执行”流程产生价值的核心
00:17:07在于你,即环节中的人类,去确保它的正确性。
00:17:11所以如果这次演讲你只能带走一个观点,
00:17:14那就是:一行烂代码只是一行烂代码。
00:17:17但计划中的一个错误部分可能导致 100 行烂代码。
00:17:22而研究中的一个错误,比如对系统运作方式
00:17:25和位置的误解,
00:17:27会让你的整个任务都泡汤。
00:17:29你会把模型引向错误的方向。
00:17:31因此,当我们与内部及用户合作时,
00:17:34我们不断尝试将人类的精力和重点
00:17:36转移到这个流水线中杠杆率最高的部分。
00:17:39不要把思考外包出去。
00:17:41警惕那些只会喷出
00:17:43一大堆 Markdown 文件只为了让你感觉良好的工具。
00:17:45我在这里就不点名了。
00:17:47有时候这会做得过头。
00:17:49我喜欢这样考虑:
00:17:51是的,你并不总是需要完整的“研究-计划-执行”。
00:17:54有时候你需要多一点,有时候需要少一点。
00:17:56如果你只是要修改按钮的颜色,
00:17:57直接告诉智能体怎么做就行了。
00:18:00如果你在做一个简单的计划,而且是个小功能,
00:18:04或者你在做跨多个代码库的中型功能,
00:18:07那么先做一次研究,再制定计划。
00:18:09基本上,你愿意做的这种上下文工程
00:18:10和精简工作越多,
00:18:13你能解决的问题难度上限就越高。
00:18:15所以如果你处于最困难的情况,
00:18:18你可能不得不做更多工作。
00:18:19很多人问我,我该如何知道
00:18:21要用到多少上下文工程?
00:18:23这需要练习。
00:18:24你会出错,你必须一遍又一遍地
00:18:26经历失败。
00:18:27有时候你会做得太大,有时候会太小。
00:18:29选一个工具,然后开始练习。
00:18:32我不建议在 Claude、Codex
00:18:35和所有这些不同的工具之间反复横跳搞最优解。
00:18:36我不是一个迷恋缩写词的人。
00:18:40我们说过“规格驱动开发”已经过时了。
00:18:42我不认为“研究-计划-执行”就是最终的步骤。
00:18:44核心在于精简和上下文工程,
00:18:47以及保持在“聪明区”。
00:18:48但人们非要管这叫 RPI,
00:18:50我也无能为力。
00:18:52所以要保持警惕,没有完美的提示词,
00:18:55也没有银弹。
00:18:56如果你真的想要一个时髦的词,
00:18:58你可以叫它“支架工程”(Harness Engineering),
00:19:00它是上下文工程的一部分,
00:19:01关乎你如何与 Codex、Claude、Cursor 等的
00:19:03集成点进行对接,
00:19:05以及如何定制你的代码库。
00:19:07那么接下来呢?
00:19:11我认为编程智能体这类东西实际上
00:19:12会变得平庸化。
00:19:13人们会学会怎么做,并做得越来越好。
00:19:15难点将在于:你如何调整你的团队
00:19:17和 SDLC 中的工作流,以适应一个
00:19:2199% 的代码由 AI 交付的世界。
00:19:24如果你弄不清楚这一点,你就麻烦了。
00:19:26因为目前正出现一种裂痕:
00:19:27资深工程师不采用 AI,
00:19:29因为它没能让他们快多少;
00:19:31而初级和中级工程师大量使用它,
00:19:33因为它填补了技能差距,
00:19:35但它也产生了一些垃圾代码,
00:19:36这让高级工程师每周都感到更加厌恶,
00:19:38因为他们一直在清理
00:19:40上周由 Cursor 交付的垃圾。
00:19:42这不是 AI 的错,
00:19:44也不是中级工程师的错。
00:19:46文化变革非常困难,
00:19:48如果要奏效,它必须由上而下地推动。
00:19:50所以如果你是公司的技术领导者,
00:19:52选一个工具并开始练习。
00:19:54如果你想帮忙,我们正在招聘,
00:19:56我们正在构建一个 Agent 型 IDE,帮助各种规模的团队
00:19:59加速迈向 99% AI 生成代码的征程。
00:20:03如果你想和我们一起工作,我们很乐意聊聊。
00:20:06请访问我们的网站,给我们发邮件,
00:20:08或者在会场找我。
00:20:09非常感谢大家的关注。
00:20:11(观众鼓掌)
00:20:13(欢快的电子乐)

Key Takeaway

通过高级上下文工程和“研究-计划-执行”工作流主动压缩信息,开发者可以在不外包思考的前提下,大幅提升 AI 在复杂旧有代码库中的交付质量与效率。

Highlights

AI 在复杂或旧有(Brownfield)代码库中常导致大量返工,交付物中很大一部分只是在修补低质量代码。

提出了“降智区(The Dumb Zone)”概念,即当上下文窗口占用超过约 40% 时,模型处理复杂任务的可靠性会显著下降。

核心方法论是“主动压缩(Intentional Compaction)”,利用子智能体或提示词将复杂背景浓缩为简洁的 Markdown 计划。

推崇“研究-计划-执行(Research-Plan-Execute)”工作流,强调人类开发者在计划阶段进行“心理对齐”的重要性。

警惕“规格说明驱动开发(SDD)”等术语的语义扩散,主张将精力集中在更高杠杆的意图管理而非单纯的提示词工程。

未来挑战在于团队文化变革,技术领导者需重新设计开发生命周期(SDLC)以适应 99% 代码由 AI 生成的世界。

Timeline

AI 编程的现状与旧有代码库的挑战

Dex Horthy 开场回顾了他在 AI 工程师大会上的影响力,并引用调查数据指出 AI 在软件工程中的瓶颈。他强调虽然 AI 增加了产出量,但在处理具有十年历史的 Java 等旧有代码库时,往往会产生大量需要返工的垃圾代码。这种现象导致技术债务堆积,使得资深工程师对 AI 产生抵触情绪。作者分享了自己团队通过改变协作方式,在八周内实现吞吐量翻倍的转型经历。这一节奠定了全篇的主基调,即必须拒绝低质量产出并解决复杂环境下的 AI 应用问题。

上下文工程定义与“降智区”陷阱

演讲者深入探讨了“高级上下文工程”的概念,对比了不断纠错的幼稚用法与聪明的管理策略。他提出了一个学术性的概念——“降智区(The Dumb Zone)”,指出当上下文窗口填充超过一定比例(如 40%)时,模型的逻辑能力会因噪音和随机性而退化。为了避免模型在对话轨迹中“习惯性犯错”,他建议开发者在对话跑偏时果断重开窗口。此外,他还展示了如何利用工具将冗长的搜索和编辑记录压缩成确切的 Markdown 文件。通过优化上下文的正确性和完整性,可以确保模型在每一轮循环中都能基于最高质量的 Token 进行决策。

子智能体与“研究-计划-执行”模式

本段详细介绍了通过子智能体(Subagents)控制上下文的实战战术。子智能体并非为了拟人化,而是为了派生新的窗口去处理繁琐的代码阅读和搜索任务,仅向主智能体返回简洁的结论。Dex 重点讲解了“研究-计划-执行”这一开源提示词系统,其中研究阶段负责保持客观,计划阶段则要求列出确切的代码行和测试步骤。他分享了与 Boundary ML 合作的案例,在 7 小时内交付了 35,000 行 Rust 代码,效率抵得上平时一两周的工作。这证明了只要不将“思考”外包给 AI,复杂的系统重构依然可以通过智能体高效完成。

解构规格驱动开发与语义扩散

Dex 对当前流行的“规格说明驱动开发(SDD)”提出了尖锐的批评,认为该词已因语义扩散而变得毫无意义。他引用 Martin Fowler 的观点,指出人们对 SDD 的定义各异,有的认为是写更好的提示词,有的则认为是将代码视为汇编语言。他警告开发者不要迷信时髦的缩写词,而应关注实质性的反馈循环和反压机制。在这一部分中,他通过分析 Parquet Java 的失败案例,提醒听众 AI 无法取代核心的逻辑构思。一旦研究阶段对系统运行方式产生误解,后续所有的自动化执行都会引向错误的方向。

心理对齐、渐进式披露与团队未来

最后一部分聚焦于团队管理和长期的文化变革。Dex 提出了“渐进式披露”的方法,建议在代码仓库的不同层级放置入职文档,以平衡上下文深度与模型智能。他特别强调“心理对齐”是代码审查的核心,技术负责人应通过阅读 AI 生成的“计划”而非仅仅扫描代码行来保持对系统的掌控。他观察到资深工程师与大量使用 AI 的初级工程师之间正出现技术裂痕,解决之道在于由上而下地推动工作流改造。演讲以 HumanLayer 公司正在构建的智能体型 IDE 作为结尾,呼吁开发者开始练习“支架工程”,迎接 99% 代码由 AI 交付的未来。

Community Posts

View all posts