跳到主要内容

IDE 插件即产品:当你的编程智能体超出了编辑器的插件 API 限制

· 阅读需 13 分钟
Tian Pan
Software Engineer

AI 编程工具的默认思维模型是 VS Code 内部的一个面板。一个对话框,几个行内建议,或许还有一个“应用差异(apply diff)”按钮。这种构想已经过时两年了。该领域的领先产品并不是 VS Code 扩展;它们是完整的编辑器,只是启动时碰巧看起来像 VS Code。Cursor 是一个分叉版本(fork)。Windsurf 是一个分叉版本。Zed 是一个从零开始构建的原生编辑器。这种模式并非巧合 —— 当智能体(agent)的覆盖面最终超过了宿主编辑器的插件 API 所能支持的范围时,必然会出现这种情况。

如果你正在构建一个编程智能体,并且仍然将“发布一个插件”视为理所当然的分发选择,那么你即将撞上那些领跑者在 2024 年左右遇到并选择翻越的那面墙。这面墙有个名字:插件 API 是为了给人类控制的编辑器添加功能而构建的,而不是为了托管一个想要控制编辑器的自主智能体。

插件 API 的初衷

VS Code 的扩展 API 是业界最优秀的 API 之一。它提供了语言服务器、调试适配器、自定义视图、命令面板、悬停提示、代码操作、树状视图、状态栏项目、webview、任务和终端。你可以用它构建高质量的语言扩展或周密的生产力工具。该 API 在设计成熟时,其假设是人类才是主体:用户打字、用户运行命令、用户点击“应用”。扩展只是进行响应。

智能体颠倒了这一点。智能体是执行者;编辑器则成为了一个界面,在这里,智能体的动作被呈现给正在监督而非驾驶的人类。这种反转给插件 API 的某些部分带来了压力,而这些部分是“人类在环(human-in-the-loop)”的扩展从未触及过的。

以下是几个暴露出缝隙的例子:

  • 自定义差异(diff)和审批 UI。 智能体想要提出涉及多个文件的更改,并支持逐块审批、行内原理解释、并排预览以及“批准此文件中的所有更改”功能。插件 API 只给你一个内置的差异编辑器和一个 webview。Webview 是一个沙箱化的 iframe,无法直接修改编辑器 —— 你必须通过扩展宿主(extension host)来调度一切。你想要的每一个 UX 细节都需要付出一次事件总线往返的代价。
  • 多面板编排。 智能体循环希望在保持对话面板可见的同时,更新计划面板,同时文件面板显示当前的编辑内容,而终端面板则流式输出测试结果。宿主编辑器决定了布局语法,而这种语法是为“编辑器 + 侧边栏 + 底部面板”设计的,而不是为智能体的“作战室(situation room)”设计的。
  • 亚秒级的全项目上下文。 智能体需要了解三个文件之外的函数,而不仅仅是光标下的那一行。这需要一个紧贴编辑器自身缓冲区状态的索引,而不是通过 JSON-RPC 管道进行通信的独立进程,那样每次查询都会产生 50 毫秒的额外开销。
  • 编辑器内的智能体遥测。 智能体读取了什么?它调用了哪些工具?哪些被拒绝了,原因是什么?智能体希望在它正在修改的代码行内渲染自己的追踪(trace)UI。插件 API 很少能深入暴露编辑器自身的界面到这种程度,除非使用一个重新实现了一半编辑器功能的 webview。

这一切都不是 VS Code 的缺陷。这是一种类别不匹配。该 API 的范畴是为了保证扩展的安全、可移植以及在版本迭代中的表现稳定。智能体需要的界面则是非安全的、不可移植的且与版本耦合的 —— 而这些恰恰是一个健康的插件契约拒绝暴露的东西。

扩展、分叉还是从零构建

一旦你接受了插件模型存在局限性,你就会面临三扇门。它们并不等同,每一扇门都代表着不同的风险。

扩展(Extend)。 维持插件身份。依靠 API 提供的东西。生活在“聊天面板和行内建议”的盒子里。优势是巨大的:每个现有用户都可以在 30 秒内完成安装,你的扩展可以与开发者已经依赖的所有其他扩展并存,并且你可以免费继承安全更新和平台改进。代价是智能体覆盖面存在天花板。你无法发布一个体验绝佳的自定义差异审批流程。你无法拥有布局所有权。你必须通过宿主编辑器的 UI 原语来路由智能体的每一次观察。对于某些产品来说,这个天花板永远没问题。但对于想要成为主要循环的智能体来说,这个天花板就成了产品本身。

分叉(Fork)。 拿走开源编辑器并修改其核心。Cursor、Windsurf 和 Trae 都选择了这扇门。你继承了熟悉感(快捷键、命令面板、肌肉记忆)以及现代编辑器 90% 的工程投入(Tree-sitter、语言服务器、终端、调试器)。你需要支付三项“税费”。第一,你必须维护一个分叉版本 —— 每一个上游版本的发布都是一次合并成本,而安全补丁现在需要由你负责及时落地。第二,你割裂了市场。Cursor 不得不转向 Open VSX,甚至发布自己维护的热门扩展版本,因为微软的条款规定官方市场仅限微软产品使用;当用户发现熟悉的 C/C++ 扩展在版本更新后失效时,他们会察觉到这种隔阂。第三,你承担了品牌承诺:当 Live Share 或其他某些微软特有的功能停止工作时,用户会归咎于你,而不是插件契约。

从零构建(Build from scratch)。 Zed 所走的道路。原生 Rust、GPU 加速渲染、无 Electron,以及从第一天起就为支持实时协作和流式 AI 而设计的基于 CRDT 的索引缓冲区模型。这扇门的天花板是三者中最高的:你拥有渲染流水线、输入循环、缓冲区数据结构、文件监视器。你可以让智能体操作感觉像是一等公民的编辑器操作,因为它们确实就是。代价是一切都无法坐享其成 —— 你必须集成的语言服务器、必须实现的调试协议、用户必须重新建立的肌肉记忆,以及达到扩展生态均势的漫长道路。这扇门对几乎所有人都是关闭的,因为其工程成本是以一个精通编辑器开发的团队数年的时间来衡量的。

这个决定很少能做得一清二楚。许多团队从“扩展”开始,撞到天花板,原型化一个分叉版本,向高级用户发布分叉版,然后才发现维护负担到底是什么样子的。那些早期选对门的团队之所以成功,是因为他们对智能体的 UI 界面有着清晰的论点 —— 而不是因为他们更喜欢庞大的项目。

智能体究竟需要编辑器提供什么

为了做出正确的选择,请列出智能体必须执行的操作,并针对每一项询问:插件 API 是否能在不演变成一个独立 Web 视图(webview)项目的情况下承载它。

对于 2026 年的一个自主编程智能体来说,一份合理的清单应该是这样的:

  • 以智能体的速度读取打开的项目。 智能体运行在一个核心循环中,每一轮可能会发出十几个文件读取、正则搜索和符号查找请求。往返延迟即是用户感知的延迟。如果你的上下文获取工具因为跨进程边界和 JSON 序列化而导致每次调用耗时 80 毫秒,那么你每一轮循环的时间预算就会被这些基础设施开销耗掉数秒。
  • 在自定义的审批界面中渲染建议的更改。 逐个代码块(hunk)的接受、每个文件的理由说明、可选的内联测试运行,以及拒绝并重新发出提示(re-prompt)的能力。内置的差异编辑器是一个很好的基础组件,但很少能作为最终的用户体验(UX)。
  • 流式传输智能体自身的状态。 计划、当前步骤、工具调用、成本。用户希望看到智能体的思考过程。这种显示应该存在于编辑器界面内部,而不是在一个独立的窗口中。
  • 为组织策略暴露钩子点(hook points)。 智能体什么时候需要审批?哪些文件是禁区?哪些工具需要人工确认?钩子需要可靠地在进程内触发,且用户不能通过卸载扩展程序来禁用它们。
  • 与终端、调试器和语言服务器协作。 智能体的“验证”步骤是“运行测试、读取输出、解析失败原因、提出假设”。插件 API 允许你启动终端,但很少能让你以智能体所需的保真度通过编程方式读取终端输出。
  • 持久化与项目绑定的智能体记忆。 惯例、最近的决策、代码库里的“陈年旧账”。这些信息应该存放在项目旁边,采用智能体可以索引和引用的格式,而不是存放在你不断需要往返访问的供应商云端。

如果上述大部分功能只是“锦上添花”,那么发布一个插件即可。如果大部分功能构成了产品的核心,那么插件玩起来就像是在浏览器扩展里强行建个网站——技术上可行,但结构上是错的。

用户实际支付的迁移成本

关于“Fork 还是插件”的讨论往往纠结于工程成本。而决定产品成功与否的成本,是当你的智能体不再是一个插件而开始变成另一个编辑器时,用户的切换成本。

开发者拥有的不是一个干净的编辑器,而是一个累积了多年选择的堆栈:键位绑定、主题、字体、配色方案、代码片段、调试配置、每个仓库中签入的 .vscode/settings.json 文件、语言扩展、格式化工具集成、结对编程设置、远程开发会话、devcontainers。一个 Fork 版本或许能继承其中的 80%;但用户会花一个周末来重建缺失的 20%,并发现两件事:哪些日常工具在 Open VSX 上不存在,以及他们默默依赖了哪些微软专有的功能(如 Pylance、Remote-SSH、Live Share、C/C++ 扩展、.NET 工具链)。

处理这一问题最出色的团队做了三件事。他们在智能体的价值差距大到足以克服摩擦时才选择 Fork 时机,而不是在插件开始显得局促的那一天。他们从第一天起就大力投入扩展兼容性,包括在许可允许的情况下发布最常用扩展的维护镜像。他们让导入体验感觉像是升级而非迁移:首次运行时同步设置、导入键位映射、以及与用户刚离开的编辑器相匹配的合理默认设置。

失败的 Fork 并不是因为工程做得更差。而是因为它在智能体还没有证明自己的价值之前,就要求用户抛弃肌肉记忆。

AI 编程工具栈的新形态

退一步看,一个分层堆栈正在形成。底层是模型及其供应商。之上是智能体框架(agent harness)——核心循环、工具目录、上下文管理策略、策略钩子。再往上是编辑器界面——智能体的读取、写入和审批行为在这里被监督它的人类看到。围绕这一切的是组织接入的策略和可观测层。

有趣的转变在于,编辑器界面不再是一个薄薄的展示层。它是模型之后产品分化最明显的部分。两支使用相同前沿模型的团队,会因为编辑器界面给智能体提供的是聊天面板还是“作战中心”,而交付出感受完全不同的产品。

这就是为什么“IDE X 内部的一个 AI 功能”这种讨论框架在 2024 年是正确的,但在 2026 年是错误的。智能体不是一个功能,它是用户正在监督的循环。编辑器是监督者的控制台。如果把控制台仅仅当成是从宿主应用租用的一块屏幕空间,会给产品设定一个硬性的上限。

诚实地做出你的选择

如果你今天开始构建一个 AI 编程工具,诚实的决策过程应该是这样的:

如果你的智能体价值主要体现在聊天面板和一些内联编辑中,且你的护城河是模型、提示词或集成,而不是编辑器体验,那么请开发插件。你会移动得很快,并通过开发者已经信任的市场触达每一个人。

如果你的智能体 UX 需要插件 API 无法承载的界面,且团队有预算无限期地维护一个下游分支,并且价值差距将超过要求用户安装新编辑器的摩擦,那么请选择 Fork。要对持续的成本保持诚实;保持 Fork 版本同步的工作不是一次性的移植项目,而是一项永久的薪酬支出。

只有当你对编辑器本身应该是什么样有着根本性的理论,并且有团队能够执行它时,才从头开始构建。这里的门槛高得离谱。回报是,智能体的操作不再感觉像是嫁接上去的,而是原生的,因为它们本身就是。

错误的提问方式是“插件还是 Fork?”正确的提问方式是“我的智能体需要编辑器提供什么,而这个编辑器在设计之初并没有打算提供这些?”回答了这个问题,门自然就选好了。

References:Let's stay in touch and Follow me for more thoughts and updates