Netflix如何借助JetBrains IDE智能提升AI编码代理效率
Netflix 将 JetBrains 的无头代码智能引擎——也就是 IntelliJ IDEA 背后的同一引擎——接入 Claude Code 和 Codex,然后针对多种场景进行基准测试。细节和数字见下文。
概览
目标:提升智能体的 ROI
JetBrains 与 Netflix 着手为编程智能体提供准确、达到 IntelliJ IDEA 级别的代码理解能力,且无需运行 IntelliJ IDEA 实例。
“像 Claude Code 这样的编程智能体在浏览 Java/Kotlin 代码时又慢又不可靠,尤其是在跨库(JAR)边界时。我们集成了无头 JetBrains IDE 的代码引擎,让智能体在无头环境中、无需运行 IDE 也能获得 IntelliJ IDE 级别的代码智能。我们创建了一套包含真实编程任务的基准测试,结果表明,借助 JetBrains IDE 的代码引擎,智能体始终更高效——使用更少的 token 和更短的时间,具体提升幅度取决于模型。” —— Paul Bakker,Netflix 资深软件工程师
Netflix 正试图解决、Paul 在上文描述的 JAR 问题:JVM 项目通常只以 JAR 文件形式发布库,而从不附带源码。智能体必须解压 JAR(还要猜哪些重要),可能还要反编译 class 文件,然后在这种不完整的视图中进行 grep。
解决方案:JetBrains IDE 智能
JetBrains 多年来一直在构建 IntelliJ IDEA 背后的代码智能引擎。它基于对项目源文件(包括所有库)的确定性索引。如今,这种智能通过 LSP 暴露,并可在兼容 VS Code 的编辑器中使用。Netflix 使用的正是该引擎的无头构建版本。
仅靠 LSP 还不足以让编程智能体直接使用:它只是一个使用某种协议的服务器,智能体没有便捷方式调用它,也没有内置的进程管理来在多次调用之间复用正在运行的实例。Netflix 自己通过下一节介绍的守护进程和 CLI 填补了这一空白。
架构详解:保持索引热态
为项目构建索引需要实实在在的时间,就像第一次在 IntelliJ IDEA 中打开大型项目一样。编程智能体会以许多细小、细粒度的步骤调用 LSP,而一个真实任务需要多次这样的调用。如果每次调用都启动一个新的 LSP 服务器,那么每一次调用都会产生数秒的冷启动开销——即使该项目的索引在一分钟前已经构建完成也是如此。
要避免重复调用时冷启动 LSP 服务器进程的开销,就需要一个守护进程。JetBrains 正在开发并交付守护进程,但在评估时还没有可用的守护进程,因此 Netflix 为自己的需求构建了一个:
- 每次工具调用都是短生命周期且无状态的——它只是通过 shell 调用 CLI。
- 守护进程是持续运行的部分:其会话管理器按项目根目录将每次调用路由到匹配的服务器进程,该进程在内存中持有该项目的索引。
- 对同一项目的第二次调用会完全跳过索引,直接通过 stdio 连接到热服务器。
- 守护进程和 CLI 均使用 Java 开发,并以 GraalVM 可执行文件形式分发,因此没有来自 JVM 的启动或运行时开销。
Netflix 如何衡量 JetBrains IDE 智能的 ROI
为了解 JetBrains IDE 智能是否(以及在多大程度上)提升编程智能体的性能,团队开发了一套基准测试。相同模型、相同任务、相同代码库——唯一变量是智能体能否调用 JetBrains IDE 智能。结果以启用 JetBrains IDE 智能的运行与未启用它的运行之间的性能差异来报告。
评估环境与方法:
这些基准测试运行了多次,以验证结果并观察新 LSP 版本带来的变化影响。
结果
在所有测试的模型、智能体和任务类型中,JetBrains IDE 智能总体上让编程智能体更高效——通常效率提高 20%–30%,最佳情况下最高约 65%,具体取决于模型、智能体和任务。更强、推理强度更高的模型获得的提升最大。这些模型更昂贵,因此效率提升更为重要,但它们也更擅长有效利用索引。
各配置的效率提升,结合了 token 和时间节省。每次比较都会对相同任务、模型和代码库运行两次——一次启用 JetBrains IDE 智能,一次不启用。
效率是各配置 token 节省和时间节省的平均值。正确性在每次运行中都保持稳定或有所提升。*仅 token:该配置的批量搜索调用使代码导航时间比较不具代表性——参见文章正文。数据为快照,会随新模型发布而变化。
这些数字是快照,而非固定的基准测试结果。每一次新模型发布都会改变智能体搜索、推理和使用工具的方式,因此具体百分比会不断变化——这也是本文报告区间而非逐模型结果的原因。在 Netflix 的多次运行中保持不变的是总体形态:所有测试的模型和智能体都变得更高效;最大提升来自高推理强度设置下的最强模型;不同模型之间的提升幅度差异明显。
代码导航任务:全面提升效率,正确性保持稳定或有所提升
测试的每个模型和推理强度级别在启用 JetBrains IDE 智能时都使用了更少的 token——无一例外——节省幅度大致在 15% 到 60% 之间。提升幅度主要取决于模型:最强模型获得的改进远超其他,而较轻量配置则落在两个区间的低端。正确性在大多数运行中保持稳定,并在两次运行中有所提升——从未下降。
具体到代码导航任务,有一个工具/模型组合已经将多个搜索调用批量合并为单个命令,因此无论是否启用 JetBrains IDE 智能,它在代码导航中都只发起一次工具调用。对于那一次调用,调用 JetBrains IDE 智能比批量搜索命令稍慢——这正是该组合明显没有时间收益的原因,但这并不能公平反映真实使用情况。因此,更广泛的端到端任务套件才是更可靠的时间衡量依据;在这些任务中,JetBrains IDE 智能在测试的每个模型和智能体上都更快。
端到端任务:持续更高效,正确性不受影响
在扩展的端到端运行中,所有测试的模型和智能体的正确性都保持稳定,因此收益完全体现在效率上,而不是任务是否完成。从完成时间和 token 消耗来看,每个模型和智能体组合在启用 JetBrains IDE 智能后效率大约提高 10%–30%。这在很大程度上可以用得出相同结论所需的工具调用更少来解释。
其他评估过的替代方案
在确定采用所述方案之前,Netflix 排除了另外两种方案。第一个被否决的是自研内部 CLI,它连接到正在运行的 IntelliJ IDEA 实例以访问项目索引。该流程与本文所述类似,但要求 IDE 处于运行状态。这种方法不适合 Otto、Bitbot、分布式重构工具、CI 等环境中的无头智能体。
第二个考虑的是现有的 Eclipse LSP,它在 VS Code 中用于 Java。但对于 Netflix 的构建系统(基于 Gradle),它根本行不通。
下一步
Netflix 接下来做什么
测试之后,Netflix 得出结论:“基准测试表明,在智能体旁边拥有一层确定性智能层是有益的。”当然,它并不会让每个编程智能体任务都按固定百分比缩短。但对于这个特定问题——解析跨 JAR 边界的真实结构——收益很大,在不同模型上都能保持,而且不会在正确性上付出任何代价。
Netflix 计划用同样的基准测试方法评估 Python、TypeScript/JavaScript 和 Go。面向这些语言的编程智能体也有类似问题。当然,项目中下载库的方式因语言而异,因此问题的机制和可能的解决方案也会不同。JetBrains 计划继续合作,并进一步支持这项评估。
JetBrains 的观点:LSP 只是其中一步,而非终点
面向 Java 的 JetBrains IDE 智能已经过 Netflix 测试,现在作为 Java & Kotlin by IntelliJ IDEA 扩展的一部分发布。JetBrains 还在继续尝试 LSP+CLI 方案,并将在准备就绪后报告结果。
LSP 的基本原语是文本文档中的一个位置。规范将位置定义为“两个字符之间,就像编辑器中的插入光标”。对于在键盘前工作的人类来说,这是自然的原语。但智能体并不真正以光标位置来思考。它们会提出关于程序的问题,例如“为什么 createUser() 内部的这个调用未解析?”以及“哪些测试覆盖了这个方法?”等等。关键在于理解代码各部分之间的关系,而不是查看光标位置。而且文本位置是一种脆弱的身份标识——在任意给定位置之前插入一个字符,都会导致该位置移动。
智能体需要的不是更精确的光标,而是一层能够以与任务本身相同的方式来提供答案的能力——也就是说,以符号、诊断、测试关系、运行时行为等来表达——并返回足够上下文来对答案进行推理,而不仅仅是文本文档中的位置。
“这就是我所说的代码引擎:它不是另一种让智能体模仿编辑器交互的协议,而是一组针对程序结构和执行的精确操作——它返回足够上下文,以便真正对结果进行推理。LSP 很有用,但它不应该定义最终面向智能体的抽象。如果你把智能体工具当作智能体是编辑器前的一个小人来构建,你就会迫使它用光标坐标说话。智能体需要的是代码引擎,而不是虚拟编辑器。” —— Aleksey Stukalov,JetBrains IDE 部门负责人
Netflix 的数据证明,代码智能值得为之投入。决定这种智能以何种形态呈现,才是前方的挑战。