JetBrains构建AI Agent 工程平台的探索
发布时间:2026-01-05 08:00 浏览量:34
导读
本文整理自 JetBrains 的孙涛先生在技术大会上的分享。孙涛先生在 JetBrains 早期负责 IDE 的 Debugger 相关实现,后投身于 AI Coding 的浪潮,参与构建 JetBrAIns AI。在分享中,他详细回顾了 JetBrains 团队在 IDE 中构建 AI 功能的曲折历程与工程实践,从最初的 AI 插件形态,到构建平台化的 AI IDE,再到最终拥抱开放生态,集成不同类型的 Agent。
本文将重点介绍 JetBrains 在此过程中遇到的核心挑战,包括早期模型能力对提示词工程的依赖、AI功能与庞大 IDE 平台集成的技术债务问题。更重要的是,文章将深入探讨 JetBrains 为何以及如何将 AI 功能集从应用层下沉至平台层,并详细介绍一个旨在统一 Agent 接入标准的开放协议——ACP(Agent Client Protocol)。最后,分享将展示 JetBrains 在“代码生成”之外的 AI 功能规划,如基于 IDE 索引的巨量源码上下文引擎(EmbArk)、AI 版的本地历史(ReCap)以及用 AI 调整 IDE 配置(Ask Settings)等。
主要内容包括以下几个部分:
1. IDE 中的 AI 工作流:从编辑优先到智能体
2. 早期探索的困局:构建独立 AI 插件的曲折之路
3. 破局:构建适用于 AI 长期演进的 IDE 平台
4. 定位辨析:CLI Agent 与 AI IDE(既生瑜,何生亮?)
5. 架构演进:拆分 AI 功能集与 Junie 的重构
6. Agent Client Protocol (ACP):连接孤岛的桥梁
7. Demo:为 Gemini CLI 接入 ACP 实现
8. ACP 协议的生态价值
9. “生成”之外:JetBrains 团队的未来 AI 功能构建
10. 结语与探讨
分享嘉宾|孙涛 JetBrains 技术专家
编辑整理|陈锡杜
内容校对|郭慧敏
出品社区|DataFun
01
在探讨复杂的工程实践之前,我们首先需要梳理 IDE 中 AI 功能的演进层次。
最初的 AI 工作流是“编辑优先”(Editor-first)的,AI 作为辅助工具,服务于开发者的即时编辑任务。这包括最常见的多行代码补全,以及“下一跳预测”。“下一跳预测”是一个典型的场景:当开发者修改一个变量名时,光标会自动跳转到下一次引用该变量的位置,并给出相应的重命名建议。
JetBrains 在此基础上做了进一步的探索。以其自研的 Malam 14B 多行补全模型为例,它并非一次性生成所有代码,而是引入了“热点停顿”机制。当开发者按下Tab 键接受补全时,光标会跳转到代码中的关键调用点(例如一个 add 方法)并停顿,允许开发者在此时介入修改或确认,然后再继续进行后续的补全。这种交互方式更贴近开发者的心智模型,AI 始终为人服务。
随着模型能力增强,AI 的应用场景从“行内”扩展到“跨文件”。AI Chat 开始出现,开发者可以提出更复杂的需求,例如“帮我创建一个模块,包含功能实现和完整的单元测试”。这个阶段的 AI 开始具备小范围的多文件编辑能力和代码库语义搜索能力。
语义搜索是 AI 带来的一大价值。例如“帮我找出当前函数所有的异步用法”,这是传统的字符串匹配无法完成的。要实现这一点,AI 必须依赖强大的“Codebase”能力,即对整个代码库的理解。在 JetBrains IDE 中,这一能力基于其成熟的索引功能。尽管开发者时常诟病 IDE 启动时构建索引所消耗的大量内存,但这正是实现深度代码理解和上下文感知的基础。
工作流的最终形态,是具备自主计划、分析和复合工具使用能力的 Coding Agent。以 JetBrains 的 Junie 为例,它采用了经典的“Plan-Execute”范式。开发团队对其进行了优化,使其能够识别并优先执行计划中可以并行的步骤,以缩短交付结果的时间。
更关键的是,Junie Agent 在生成代码的过程中,会反复调用 IDE 内置的静态分析功能进行确认。这确保了生成的代码不仅在功能上贴近需求,还在质量上符合规范,有效避免了编译错误、空引用、潜在的代码漏洞等问题,显著提高了代码的准确性和可用性。
在2023年初期,面对市场上已有的 AI 编码工具,JetBrains 的第一反应是利用其成熟的插件生态,构建一个独立的 AI 插件。然而,这条看似顺理成章的道路却充满了挑战。
早期的模型(如 GPT 3.5)编码能力并不稳定,且“工具调用”(Function Calling)的能力时常失效,非常依赖提示词(Prompt)来弥补模型的短板。
为了让模型能生成“可用”的代码,团队陷入了繁重的提示词工程。他们为几乎所有的 AI 功能都编写了对应的 Prompt,甚至需要按编程语言进行区分,例如 generate-unit-tests|python、generate-unit-tests|go 等。在今天看来,这种“一个功能、一个语言、一个提示词”的做法是不可想象的,但在当时却是不得已而为之。
随着提示词工程日益复杂,如何管理和重用这些具备特定技能的 Prompt(或微型 Agent)成为了一个难题。
为此,JetBrains 团队设计了一套适用于 Kotlin 语言的智能体开发框架——Koog。这个框架在理念上类似于 LangChain,用于为 IDE 中的各种 AI 功能提炼和管理Agent 工作流。
最痛苦的问题来自平台自身。IntelliJ Platform 是一个有 20 多年历史的庞大工程,最初为跨平台(Java)而设计,其架构中并未预留 AI 功能所需的核心接口。
当团队需要实现高阶 AI 功能时,发现平台层缺乏必要的“扩展点”(Extension Points)。例如,当其他工具厂商希望在 IntelliJ IDE 中构建自己的 AI 插件,并询问如何实现“灰色的多行补全预测内容”时,团队发现平台根本没有提供这样的高层 API。
为了强行实现功能,JetBrains 自己的 AI 团队也不得不去“魔改”平台代码。这导致了严重的技术债务,并且在开源社区引发了负面反响——开发者抱怨 JetBrains 为了实现自己的 AI Assistant,随意修改了平台的核心接口。
团队认识到,“插件模式”走不通,AI 绝不能只是一个外挂的功能,而必须成为平台的核心能力。为此,JetBrains 启动了对 IDE 平台的 AI 化改造。
首先,团队着重开发了一套评估功能集,包括模型能力评估与 AI 功能效果评估。他们内部开发了 “LLM Eval” 工具套件,用于量化比对不同大模型在特定 IDE 任务上的表现。例如,在“为变量提供新命名”这个功能上,评估工具不仅会测试模型是否能给出 5 个更好的命名,还会考量模型是否遵循了当前项目的代码规范(如驼峰式命名法或帕斯卡命名法),并输出详细的指标。
其次,团队开始梳理和实现 IntelliJ Platform 中真正面向 AI 的功能集。
其中最核心的改造之一就是“Codebase 问答”能力的平台化。一些竞品(如 Cursor)采用了远端 RAG 技术,但这不符合 JetBrains 众多企业用户无法连接外网环境的安全要求。
因此,JetBrains 决定利用其最强大的资产——IDE 索引。他们基于已有的 PSI(Program Structure Interface,抽象语法树的一种实现)API,打造了一套完全在本地运行、基于 IDE 索引的 RAG 技术。这使得 AI 功能可以深度理解项目的上下文,而无需任何远程依赖。
此外,团队还开发了 “MCP Server” 插件,该插件默认集成在最新版 IDE 中。它通过 MCP 协议,将 IDE 的核心能力(如调试数据、运行时分析)暴露出去,使得外部的 Coding Agent 可以将功能完备的 IntelliJ IDE 作为一个“工具”来调用。
在 AI 平台化建设的同时,市场上以 Claude Code 为代表的 CLI(命令行)Agent 发展迅猛。这引出了一个问题:CLI Agent 和 AI IDE 之间是竞争还是互补?
JetBrains 的答案是:
两者定位不同,并不冲突。
CLI Agent
更服务于“生成”任务,适合“从 0 到 1”的工作,例如快速搭建项目脚手架或生成完整文件。
AI IDE
更服务于开发者的“完整工作流”,适合“从 1 到 1.1”的精细化编辑和交互。
AI IDE 拥有 CLI 难以企及的独特优势:
深度编辑交互
:如前所述的行内补全、下一跳预测、热点停顿等。
原子化安全重构
:IDE 的重构是基于 AST 的,是原子化、可感知的,而 CLI Agent 的“请求重构”上下文感知弱,且操作非原子化。
运行时状态感知
:IDE 能够实时分析运行时的变量、堆栈、内存用量和 CPU 耗时,并将其提供给 AI 进行根本原因分析(RCA)。CLI Agent 无法感知这些运行时状态。
全局上下文理解
:AI IDE 基于项目索引(而非文件系统 API)来理解代码库,能快速访问任意代码片段,实现“我的项目”的专属问答。
强工作流集成
:AI 功能无缝嵌入到编辑、调试、版本控制等所有环节。
明确了平台定位后,JetBrains 对其自有的 Junie Agent 进行了“拆分”和重构。
拆分的直接原因是 Junie 变得过于“臃肿”和“一体化”。Junie 的独立实现中堆叠了用户交互、Agent 调度、提示词、工具调用等所有功能。
这种“大而全”的架构带来了两个问题:
提示词设计保守
:Junie 的提示词设计相对保守,它很少对自己的工作“推倒重来”。这在维护既有大型项目时表现良好,但在新项目或需要创造性编码时,就显得多样性不足。
功能实现困难
:代码生成与工具调用等功能堆叠在一起,导致实现 Background Agent(后台异步运行)等复杂功能时变得异常困难。
功能下放
:将那些依赖平台、与 IDE 依赖深刻的功能(如指令钩子 / 和 @、索引重用机制、会话管理、计划功能等)从 Junie 中剥离,下放并回归到 IntelliJ Platform 平台层。
进程管理
:IDE负责 Agent 的进程管理,所有的 Coding Agent(包括 Junie)都以独立的子进程形式实现。
保留双重实现
:部分工具(如文件操作)保留双重实现,允许 Agent 自行选择是使用文件系统 API 还是调用 IDE 的全局搜索。
在拆分初期,团队在跨进程通讯(IPC)上遇到了麻烦。他们最初使用了自研的 rd-protocol 框架,但发现它与 MCP 协议的亲和力很差,且不支持 Json-Rpc,生态拓展性几乎为零。
正当 JetBrains 团队在推进 Agent 平台并苦恼于 IPC 问题时,一个实验性的 IDE 项目 Zed 公开了 ACP(Agent Client Protocol)协议的构想。
ACP 的出现完美契合了 JetBrains 当时的需求,JetBrains 迅速成为首个适配此协议的商业 IDE 厂商。
ACP 是一个非常精巧、小巧的协议,它严格遵守 MCP 的 Json-Rpc 规范,被誉为“面向 Coding Agent 的 LSP 协议”。
它的核心价值在于“解耦”与“开放”:
开发者自由选择
:ACP 协议允许开发者在 IDE 中自由选择自己喜欢的 Coding Agent。无论你习惯用 JetBrains Junie、Claude Code 还是 Gemini,都可以在同一个 IDE 平台中使用。
IDE 能力开放
:IDE 内的工具(如文件 diff、查找、重构、调试信息、代码库索引)将依赖 ACP 协议,以 MCP 的形式统一提供给 Agent 集成,Agent 侧免配置。
接入成本极低
:对于使用命令行做交互的 Coding Agent 来说,提供 ACP 兼容非常方便。
专注点分离
:JetBrains 这样的 IDE 厂商可以更专注于与编辑、调试、运行时相关的平台核心能力;而 Agent 构建团队则可以专注于代码生成的速度与质量。
为了展示 ACP 的简洁性,分享中演示了如何为一个命令行的 Gemini CLI 接入 ACP 实现。
首先,在 IDE 中实现的 Agent 支持侧,需要将 Agent 的能力枚举并返回。这包括:
基本能力
:必须能接受文本 Prompt。
拓展能力
:是否支持图片、音频或“嵌入式内容”。
“嵌入式内容”是一种为大模型节省 Token 的机制,它将一个完整的代码文件抽象为“文件名、MIME 类型、总行数、关键函数实现”等元数据信息,再提供给模型。此外,还需要为 Agent 添加必要的会话管理实现。
其次,在 ACP 的实现中,开发者仅关注消息实现本身,不关注具体的 IDE 客户端或 Agent 的能力调用。通过使用 Pipe 建立 Agent 和 Client 之间的双向通信管道,利用 StdioTransport(标准输入输出流)来传输数据。
最后,在客户端应用中,只需通过命令行(例如 createProcessStdioTransport)直接在进程外调用 Gemini CLI 即可。
目前,Gemini CLI 的官方 Repo 中已经提供了 ACP 协议的兼容实现,包括认证管理、会话管理、对话处理等,开发者可以参照这个实现,轻松为其他 Coding Agent 做适配。
演示中展示了一个 Kotlin JVM 程序,它通过 Kotlin ACP SDK 封装了 Gemini CLI。这个程序(Client)向 Gemini Agent(Server)发出一个需求:“把我当前的代码文件加一个别的参数”。Agent 开始思考,将推理流和工具调用请求反馈回来,并最终成功修改了 Client 端的代码文件。这证明了通过 ACP 封装和调用外部 CLI Agent 的工作流是完全可行的。
08ACP 协议的生态价值
ACP 协议的推广对整个 AI 编码生态具有重要价值,它为三方带来了共赢。
极大地降低了插件开发成本。
无论是 IntelliJ 还是 VSCode,Agent 团队都无需再花费巨大精力维护复杂的 IDE 插件(这些插件很多时候只是在重复造轮子,实现本该由平台提供的能力)。团队可以专注于自己的核心优势:代码生成的速度、质量,以及对小众编程语言或稀疏语料的训练。借助 IDE 提供的更佳上下文,实现更复杂的工具调用。
JetBrains 的目标并非停留在“代码生成”。在分享的最后,孙涛先生介绍了 JetBrains 正在构建的、超越“生成”范畴的 AI 功能(分享时为内部工具,部分预计在 2025.3 版本上线)。
这是 JetBrains 内部的巨量源码上下文引擎,即前文提到的基于 IDE 索引的 RAG 技术的最终形态。
它的一个关键实践是:
将 AI 索引的生成步骤放到了 CI/CD 流程中
。当开发者推送代码时,CI 流程会自动为每个代码文件生成一个“描述文件”(或称“说明书”),包含“这个文件是干什么的”、“有哪些关键函数实现”、“实现了哪些接口”等元数据。
通过这种方式,一个上千行的复杂代码文件,可以被压缩为一个几十行的描述文件,极大地提升了上下文搜索的效率和准确性。
IDE 中的 Local History(本地历史记录)功能(不依赖 Git)深受开发者喜爱。ReCap 将其 AI 化,旨在解决一个痛点:当开发者周末休息两天,或开了一天会后,晚上回来想不起自己之前的工作进度和思路。AI 版的 Local History 将帮助开发者快速回忆起上下文。
IntelliJ IDE 的配置项繁多且复杂,开发者(甚至 JetBrains 自己的员工)也常常记不住。Ask Settings 允许开发者用自然语言调整 IDE 配置,例如:“帮我把整个 IDE 的代码风格规范调整成 Google 的 Java 规范”。
这并非简单地将配置文件(.idea 文件夹下的 XML)交给大模型处理(这既消耗 Token,又有幻觉风险),而是构建了一个能理解自然语言、并
调用 IDE 自身 Setting API
的Agent,以确保配置的准确性和安全性。
10结语与探讨
JetBrains 在 AI Coding 领域的探索,经历了一条从“独立插件”到“平台魔改”,再到“功能下沉”和“开放生态”的演进之路。ACP 协议的出现和被采纳,标志着 AI IDE 的发展思路正从“功能堆叠”转向“平台赋能”。未来,IDE 的核心竞争力将不仅在于“生成”代码,更在于如何利用 AI 深度整合调试、运行时和海量上下文,为开发者提供覆盖完整工作流的智能体验。
以上就是本次分享的内容,谢谢大家。
- 上一篇:神回复:屎浪给的诱惑,我唱起了情歌~
- 下一篇:男子把袜子衣服同洗致感染 医生提醒