Ohhnews

分类导航

$ cd ..
Jetbrains Blog原文

为什么我们仍然需要IDE:AI智能体时代的开发驾驶舱

#ide#ai智能体#软件开发#开发工具#人机协作

这事我已经琢磨了大约一年。开发者圈子的风向已经变了,你刷新闻时几乎不可能不看到有人宣称“我再也不打开 IDE 了”或者“我一切都在终端里做”。这些工作流对一些人确实有效,但并非人人适用。我真心认为,IDE 体现了我们热爱这份工作的原因。那么问题就变成:世界在变,我们该如何向前走?

工作流已经变了,环境也需要跟上

编码智能体不再只是实验;对我们中的许多人来说,它们已经是日常软件开发的一部分。我们不再只是按 Tab 补全。我们把涉及多个文件、探查依赖关系、跨包重构的实质性任务交给智能体。工程的日常节奏正在演变:重点不再是一行行敲代码,而是引导意图。 [LOADING...] 如今,JetBrains Rider 看起来更像一个用于智能体开发的驾驶舱:智能体会话、它们的状态以及完整的项目上下文都在同一个视图中。

可以把这种转变想象成从手动驾驶飞机转向使用现代飞机的飞行计算机。计算机可以处理复杂的执行,但它之所以有能力,是因为它连接着飞机的仪表:导航、高度、速度和发动机数据。飞行员不必时时刻刻操作每一个控件,但仍然需要一个驾驶舱,能看见整个飞行过程、理解正在发生什么,并在航线改变时介入。

智能体驱动的软件开发也是如此。智能体可以规划并执行一项重大变更,但它周围需要丰富的环境,指挥它的工程师也是如此。代码分析、导航、依赖信息、类型检查、测试,以及对代码周边系统的访问,提供了终端或孤立会话可能无法清晰呈现的上下文。智能体可能会运行编译器或测试;IDE 则让结果成为项目整体图景的一部分,因此你不仅能知道某件事是否失败,还能理解它影响了什么以及为什么。

飞行员也掌控着这次飞行,即使计算机完成了大部分工作。工程师也要对最终发布的内容负责,即使大部分代码是智能体写的。这意味着要在上下文中审查变更、理解其后果,并且之后能够解释和捍卫结果。

还有判断力:决定提议的航线是否正确,而不只是飞机能否到达目的地。智能体可以产出可运行的实现;工程师仍要判断它是否契合架构、用户,以及真正值得解决的问题。

这正是 IDE 的角色变得格外有趣的地方。它是驾驶舱,智能体和开发者可以在其中看到同一个项目、使用同样的仪表,并共同做出决定最终交付什么的决策。一个提示词可以启动工作。而 IDE 是你引导、验证并对结果负责的地方。

从“敲语法”到“引导意图”

这就是上下文问题。智能体可以跨代码库推理,但如果你看不到它所看到的东西,你并没有真正引导它——你只是在指望它做对了。

智能体工具不是一时风潮。它们已经成为我们许多人构建软件的核心方式,而且不会消失。成为一名好开发者,从来都不是关于你打字有多快。打字只是机械性的部分。真正的工作是弄清什么需要变更,并决定如何处理它。打字占据了白天太多时间,以至于很容易把它和工作的核心混为一谈。

现在打字不再是瓶颈,一天的工作看起来就不一样了。你会在智能体的计划运行前阅读它。你会抓住它漏掉的那个边界情况。你会追问它提出的变更是否真的是正确的变更,而不只是能跑通的变更。花更少时间产出代码,花更多时间判断代码是否正确。

最近我用一个自己基本没有实际经验的技术栈做了点东西。我想构建一个浏览器扩展,但读完文档后,我并不清楚如何初始化并配置这个项目。

我没有先把每个细节都学会再开始,而是把问题指向了一个智能体。它处理了大量机械性工作,从创建项目到配置它、把最初的部分搭起来,而我则专注于我想构建的东西。我不必知道确切的语法或设置流程,也能表达意图。智能体并没有取代学习。它给了我一个可运行的项目,让我可以探索、质疑和改进,而不是一个空白文件或空工作区。一旦我打开 IDE,我就能看到各个部分如何组合在一起,追踪不熟悉的代码,并基于一个真实存在的东西来引导下一步。

几年前,这个项目不会发生,或者会慢得多,因为障碍始终是“我不够了解它,没法启动”。智能体降低了这个障碍。它处理了一部分机械性工作,让我能专注于问题、方向以及真正重要的决策。

即使在很小的任务上,它也会把你拉进更大的图景。如果智能体为了过去只需两行代码修复的事情改动了十几个文件,那么你才是那个必须知道这十几个文件是否选对了的人。这意味着你一天中更多时间处在架构层面,更多思考服务之间如何相互依赖、一项变更实际上会向下游影响什么,以及智能体的计划是否符合系统应有的工作方式。过去,一个工单/问题单意味着“我需要编辑这个函数来解决这个问题”。现在,它意味着“我需要定义整个变更的正确形态,然后让智能体去编辑正确的东西”。这很难在一个聊天窗口里完成。你看着智能体通过一个一次只显示一条消息的界面对你的代码库做出真实决策。如果这些工具能跨整个项目推理,你也需要能跨整个项目看到它,以及它们正在如何影响项目;否则,你就只是在点批准。

这也是 IDE 自有工具发挥作用的地方——不仅为你,也为智能体。

验证与理解,才是责任归属所在

这是归属问题。代码正确和代码属于你,是两回事,而其中只有一件能在事后复盘中留存下来。

产出更多代码现在很容易。智能体能在几秒钟内写出一个能工作的函数,而且很多情况下第一次就写得不错。那已不再是真正的难点;把它当成难点,最终就会交付一些团队里没人真正理解的东西。

瓶颈转移到了验证。我们现在担心的是这些问题:“这是正确的吗?”“它是否处理了用户真正会遇到的情况?”“它是否符合系统其余部分应有的行为,而不只是这个函数孤立运行时的行为?”智能体生成代码的速度比你阅读还快,这意味着阅读它——真正地读,而不是扫一眼 diff——成了工作中慢的那部分。这没关系,因为这本来就应该是慢的那部分。

这很重要,因为你无法拥有自己不理解的代码。如果智能体写的某个东西里出现了 bug,而你的合并提交写着“智能体写的”,那就在故障分诊电话或事故复盘上祝你好运吧。提交上有你的名字,所以你需要足够理解这项变更,才能辩护、调试并向别人解释它。这才让它真正属于你,而这不是靠读一份智能体做了什么的聊天摘要就能发生的。它发生在你和实际变更待在一起、放在上下文中、待得足够久以至于确定无疑的时候。凌晨两点被呼叫的人不是智能体,参加事故复盘的人不是智能体,绩效评估上写名字的人也不是智能体。是你。责任不会仅仅因为作者身份转移就跟着转移,也没有团队会接受用“智能体干的”来替代“我理解我交付了什么”。

这也正是 IDE 一直以来为之构建的东西。早在智能体出现之前,IDE 的主要功能就是让你验证某个问题的解决方案:跳到定义、查看函数在哪里被调用、在发布前捕获类型错误,并追溯变量来自哪里。这些功能都不需要为智能体工作而重新发明;只需要让它们指向智能体的输出,而不是你自己的代码。理解代码的工具一直存在。唯一的新变化是,你不只在使用自己的代码?

为你构建的东西感到自豪

这是判断力问题,而且从来都不是真正关于智能体。

这其实不是关于工具的讨论。这是关于软件工程这门学科究竟建立在什么之上,以及这一点在转向智能体工作的过程中是会延续下来,还是会被丢掉。

很容易觉得,“我几乎没自己敲代码”,并认为这是被排除在过程之外。其实不是,只要背后的思考在每一个重要方面仍然是你的。你可以一行都不敲,却仍然是设计架构的人,是在团队其他人不认同时知道为什么某个方案正确的人,或者是在发布前抓住智能体细微错误的人。这不是比逐行手写更小的工作。它一直是同一份工作,只是把打字拿掉了。

值得记住的是,工程师从来不是真正以生产代码为业。工程师解决问题。代码一直只是一种媒介,恰好需要大量手工劳动来生产,于是劳动被误认成了手艺。一个写得比你打字还快的智能体,并不是在取代手艺;它是在去掉工作中从来都不是重点的那部分。

所以,为你一直真正在做的工作感到自豪:判断力、架构、关于什么应该存在以及为什么的最终决定。如果智能体帮你更快到达那里,那不是工程工作的缩小版。它仍是同样的标准,同样认真地坚持,只是以工具终于允许的速度前进。

每位开着自动驾驶飞行的机长仍然需要一个驾驶舱来控制航向。仪表不会取代飞行员;正是它们让飞行员能够安全驾驶如此复杂的机器。把 IDE 看作你的编码驾驶舱。它不是智能体周围可有可无的“锦上添花”。它让“引导一个智能体”而不是“只是和它聊天”真正成为可能。

面向开发者和智能体的 IDE 工具

IDE 具备独特的能力来应对上述问题,就像飞行计算机一样。我们应当设法让智能体也能使用飞行员所拥有的同样仪表和控制装置,以及用于验证和审查的工具。功能丰富的 IDE 还为你提供行使判断力的机会,通过提供完成工作所需的一切,帮助你理解和真正拥有代码。

LLM 是概率性的。它们在猜——有充分依据的猜,但仍然是猜。软件工程不是。类型系统对代码能否编译没有意见;它要么能编译,要么不能。智能体的思考方式与系统实际行为之间的这道鸿沟,正是大多数真实 bug 所在。

现在,这道鸿沟大多是在事后被弥补的。有些智能体已经在任务中途运行编译器、linter 和测试,这确实有用,因为它能抓住原本会被发布的错误。但运行一项检查,和像开发者那样真正看见系统,并不是一回事。智能体得到的是编译器错误或运行时错误,可能还有堆栈跟踪。使用 IDE 的人得到的是类型检查器、linter 和测试套件与实际导航和上下文整合在一起,不只是通过/失败,还有原因。由此,你可以追溯其来源,并理解它如何连接到更大的图景。工具已经不再缺席智能体的循环。缺少的是它所连接的深度,以及在正确时机选择正确工具的能力。

解决办法不是让智能体更擅长猜测,而是帮助它做出更有依据的决策。IDE 提供给你的那些确定性智能——比如类型解析、lint 检查和实时错误检查——需要在智能体工作时就可供它使用,而不只是供事后审查的人使用。一个能在任务中途检查自己的类型、在写下那一行时就看见 lint 错误、在继续之前运行刚刚被自己弄坏的测试的智能体,就不再是基于概率运作了。它是在用你的工具一直拥有的、有根基的事实来运作。

这就是正在发生的转变。不是更聪明的智能体,而是我们为开发者构建的同样确定性工具,终于指向了写代码的东西,而不只是指向事后检查代码的人。

一旦智能体能够使用开发者所依赖的同样工具,下一个问题就是:谁来选择这些智能体和工具?开发者应当能够为任务使用最好的工具,而不必重建工作流或在配置迷宫中摸索。IDE 应当是稳定的层,将智能体连接到丰富的开发工具,但只有当开发者不被锁死在某个提供商版本的工作流中时,它才真正有用。

我们不能有 AI 围墙花园

把整个工作流押在一个模型提供商身上是真实风险,不是假设风险。提供商可能改变定价、被收购、弃用模型、发生服务中断,并最终在几个月里落后于领域。如果切换提供商需要改变你的工具、工作流和配置,那么切换成本就成了留下来的理由,即使有更好的选择。目标不是让开发者管理一堆复杂的集成。恰恰相反:给他们一个可靠的环境,让他们使用自己想要的智能体和模型,同时拥有所需的项目上下文和开发工具,不必承受不必要的摩擦。

这正是 Agent Client Protocol(ACP)可以发挥作用的地方。ACP 为 IDE 和编码智能体提供了一种共享的通信方式,减少了每添加一个新智能体就需要单独定制集成的需要。这可以让智能体感觉像是 IDE 原生的一部分,而不让 IDE 依赖单一提供商。ACP 去掉了重复的集成工作;它不必去掉开发者的选择权。 [LOADING...] 借助 Air,你可以轻松地把已经在用的智能体无缝添加到 IDE 中,几乎不需要额外工作,从而使用你喜爱的工具,而不增加额外负担。

这还没考虑一个事实:每出一个新模型,整体宣传都会说它应当成为今后的首选模型。如果你的整个开发流水线都接在单一提供商的 API 上,那么每一个这样的事件也都会变成你的问题。这不是工具选择;这是你在没有真正决定的情况下承担的一项依赖。我们都知道承担依赖会发生什么:当变化出现时,它最终会让人头疼。

解决办法不是挑选正确的提供商。并不存在一个永远正确的提供商;今天最好的,一个月后未必最好,而在这个领域的发展速度下,过早锁定最终会让你卡在那里,为你当初的选择辩护,而那些理由早已不再成立。而当新模型最终出现时,它还得经过你软件开发需求的严苛考验,你才会觉得可以放心地“信任”它。

这意味着 IDE 本身不能对哪个模型在做工作有偏向。切换提供商、为不同任务运行不同模型、在新模型发布当周试用它——这些都不应需要重新配置整套环境。如果更换模型成了一个项目,你就不会去做,最终就会被困在你最初默认选中的那个模型上,而不是出于选择。

自带密钥(Bring Your Own Keys,BYOK)在实践中归根结底就是这个意思。你带上自己选择的模型和提供商的凭据——通常是 API 密钥,有时是账户或订阅——并将它们连接到 IDE。IDE 仍然是项目上下文、代码智能、工具和审查所在的地方。提供商提供模型,而你保留对使用量、限额和成本的控制。切换意味着选择另一个已配置的提供商或模型,而不是重建工作流。

ACP 和 BYOK 解决的是同一个问题的不同部分。ACP 帮助 IDE 通过通用接口连接不同的智能体。BYOK 让开发者选择这一体验背后的提供商凭据。一个提供互操作性;另一个保留控制权。原生的智能体体验应当让选择更容易,而不是取消选择。

对于喜欢折腾设置的人来说,这不是锦上添花。这是一种让筹码留在你这边、而不是留在提供商那边的方式。你使用当下真正好的东西,放弃不好的东西,并且永远不会处在一种“切换成本高于维持现状”的谈判位置上。

使用能解决问题的工具

真正摆在我们面前的问题,不是要不要把智能体和 IDE 一起用,而是怎样一起用。软件工程这门学科的目标,最终是用软件解决业务问题。这些年来,“软件”已经变了很多:从过去要冒着雪、来回走上坡路去编译打孔卡,到现在只要输入你想要的东西,就能让它凭空出现。我今天就在 IDE 里使用智能体,IDE 提供的智能与智能体的推理和速度相结合,是一种令人愉快的体验。但这确实只是转变的第一步——转变我们如何使用这些新工具来做我们一直做的事:解决问题。

这就是我们对 IDE 和智能体未来方向的看法。我们很想听听你的看法。