
前言
在编程的世界里,Tab模型就是那种可以预测你下一步代码编辑的AI IDE工具。不过,不同的IDE叫法各有不同,比如Qoder称之为Next,Cursor叫Tab Tab,而Trae更名为Cue(现已升级为Cue-Pro)。如今,大多数IDE的预测功能还只是局限在单个文件内进行编辑预测,只有Augment Code和Trae支持跨文件的预测功能,而Cursor则似乎是个伪跨文件的选择(它只能在已经打开的文件中进行预测)。接下来,我们就来聊聊当前主流IDE在编辑预测技术方面的表现。
Qoder
Qoder是阿里推出的一款编程IDE,特色在于它可以建立Repo Wiki(DeepWiki的本地版本)。它的编辑预测技术被称为Next,整体体验还算可以。接下来,我们来看看博客中提到的一些技术细节。
后训练数据构建
模拟编辑数据构建
其实呢,训练的数据是从仓库的提交记录中构建出来的用户模拟编辑数据,而不是直接通过用户实际编辑时的数据来获得的。借助AST解析器(像Tree-sitter那样),在数百万行高质量代码中找出重要的编辑场景,然后自动模拟用户的操作过程。
博客中提到了一个标识符重命名的实例:
- 动作触发(Trigger Action):想象一下,我们找到一个变量、函数或类的声明位置,并模拟用户对它进行重命名。
- 联动推荐(Ripple Effect):通过AST的作用域分析和引用链,自动识别出该标识符在项目中所有的调用位置。
- 轨迹构建:把后续的一系列改动整理成有序的动作序列:[Edit Action 1] -> [Edit Action 2]
利用这种AST解析的方式,模拟用户在实际编辑时的动作。
这些数据应该用作SFT的训练数据,通过光标的停留位置加上历史编辑,预测出一系列动作,形成最终的编辑预测模型。
偏好数据构建
模型上线后,我们就可以开始收集用户的采纳和拒绝记录,以进行偏好学习。
Qoder会收集用户的行为日志,主要包括以下三类:
- 显式采纳(Explicit Accept):用户通过Tab键接受一整串编辑建议。
- 局部修正(Partial Edit):用户接受了前两个建议,但对第三个进行了手动调整。
- 显式拒绝(Explicit Reject):用户选择忽略建议继续输入,或者直接按下Esc键。
通过这种方式将原型模型的数据标注为多元组(Context, Response_Accepted 1, Response_Accepted 2, …, Response_Rejected 1, Response_Rejected 2, …)。
以往的模型优化只关注“采纳”的正例,但在Qoder NEXT的演进中,“拒绝”的信号其实包含更多的信息。如果模型推荐了obj.getName(),而用户手动改成了obj.getDisplayName(),那么这说明模型在某些语义场景下缺乏对业务逻辑的理解。这种正负例的构造用于RLHF,看起来有点像DPO这种离线训练方式。
ActionRL算法优化
在传统的对齐算法中,代码编辑预测场景面临一个大问题:正例和负例之间的相似性太高。博客中举了个例子:
在代码编辑中,一组对齐序列里,正例序列ywyw和负例序列ylyl通常有很长的公共子串。举个具体的例子:
- Context: user = User.find(id)
- 用户真实意图 y_w : user.update(name: “New”); user.save(); print(“Done”);
- 模型错误预测 y_l: user.update(name: “New”); user.delete(); print(“Done”);
模型把y_l视为一个整体进行惩罚。由于y_l中包含了正确的user.update和print,模型在优化过程中会降低对这些正确动作的概率分配,导致模型变得谨慎,甚至不敢给出任何建议。
为了解决这个问题,Qoder进行了优化,提出了ActionRL,这是一种聚焦于关键分歧动作的偏好优化算法。它的核心思想是:将学习目标从“整体序列的好坏”细化为“在第一个错误决策点做出更优的选择”。
A. 定位关键分歧动作
给定一组偏好样本,包括标注为“采纳”的轨迹和“拒绝”的轨迹,ActionRL首先对每条轨迹进行逐步对齐,识别出首次出现差异的位置,这个位置就是行为分歧点(Behavioral Divergence Point, BDP),表示模型在此时做出了不同的选择。接下来将结果拆分为若干个Action。
B. 截断似然估计
与传统的对齐算法不同,ActionRL将优化目标集中在分歧点处的条件分布上。模型会被引导在相同上下文条件下,更高概率地选择采纳或修正的动作,同时压制拒绝动作的可能性。这样的设计确保梯度更新直接作用于导致结果不同的决策点,而不受后续动作的干扰。
C. 损失函数重构
在许多实际场景中,拒绝轨迹在分歧点之后往往包含部分正确的子序列,ActionRL通过限制损失计算范围,有效屏蔽了此类后置信息的干扰,使得对齐训练信号更加聚焦且有韧性。通过这种处理,ActionRL确保:
分歧点惩罚:模型能够清楚地感知到y。
后缀忽略:对于t>t∗的部分,由于负例序列已经偏离了意图,其后续内容(即使可能包含正确动作)也不会对模型产生错误的干扰。
举个例子:
假设开发者正在重构一个用户处理函数:
| 动作阶段 | 采纳轨迹 ($y_w$) | 拒绝轨迹 ($y_l$) | ActionRL 处理逻辑 |
|---|---|---|---|
| Action 1 | if user.is_active: | if user.is_active: | 前缀保护:认定该决策正确 |
| Action 2 (BDP) | user.update_ts() | user.delete() | 分歧对齐:惩罚 delete,激励 update |
| Action 3 | user.save() | user.save() | 后缀截断:忽略后续重复或无关内容 |
通过这种方法,Qoder持续构建数据飞轮,每24小时优化一次。说实话,相比Qoder刚推出时的编辑预测功能,现在的确改善了不少,之前用的时候简直没法忍受。
Trae
Trae是字节跳动开发的一款IDE,可以说是目前国内最强的AI IDE之一。它的编辑预测和Agent功能在国内都是数一数二的。Trae最初的编辑预测叫Cue,最近更新后变成了Cue-Pro,支持跨文件的Repo-level级别编辑预测。接下来我们分别来了解Cue和Cue-Pro的相关内容。
Cue
Cue的博客内容介绍得不算特别详细,主要核心就是Cue的编辑预测是通过检索器和大模型的结合来实现的,而不是单纯依靠大模型直接输出,这一点和Augment Code的实现有些相似。
训练数据构建
Cue的训练同样是模拟用户的编辑数据(因为隐私政策问题,无法直接获取用户真实的编辑数据)。
- 模拟常见编辑场景:通过分析提交信息(commit messages)、初始提交状态和最终提交状态,开发相关算法来模拟真实的编辑场景。
- 优化Diff粒度:训练模型以读取细粒度的编辑事件,同时精细调整Prompt中呈现的diff粒度,以防止模型因过细的粒度被噪声干扰,或因过粗的粒度无法辨别新旧变化。
- 避免撤销用户近期修改:发现模型有时会倾向于撤销用户最近的更改,所以通过精细筛选训练数据来防止这种行为。这应该是通过分析大量的坏案例来获取数据,以优化模型的表现。
新型Diff格式
博客中提到正在研发一种新型的Diff格式,既紧凑又清晰,能够有效应用到源代码中。这个格式能够简洁地表示复杂的编辑,尽可能减少生成的Token数量,从而将延迟从秒级降低到几百毫秒。
以上内容仅供参考,因为这篇博客和Augment Code发布的博客有些相似,可能存在误导。
Cue-Pro
Cue-Pro是Trae最新的功能,达到了仓库级的编辑预测,感觉与Augment Code的补全功能对齐,前端展示也有些类似。Cue-Pro的博客没有详细提到模型的训练,而是以“心流”为故事,介绍了它的架构。
Cue-Pro架构
A. 意图回溯与预测
模型的输入变得更加多维:
- 多维输入:整合编辑历史、浏览轨迹和语言服务器协议的状态。
- 候选找回:利用大模型的推理能力推测当前意图(比如“重构依赖”),通过数据流分析和语义搜索,找回全库范围内所有相关的潜在修改点。
B. 拟人化的修改序列
智能编辑助手的优化之路
当模型识别到多个需要调整的地方时,它并不会一下子把所有的建议都抛出来,也不会把它们搞得乱七八糟。
- 逻辑优先:根据之前提到的专家标记数据,模型会分析出开发者接下来最有可能进行的“下一步”操作。
- 编译器习惯模拟:它会模仿开发者在面对编译错误时的修改方式,优先给出那些与逻辑关系最紧密的建议。
双重验证机制
- 分歧过滤:如果模型建议的某个改动虽然“技术上正确”(比如顺便重命名了一个变量),但与开发者当前的“主要任务”(例如:修复一个Bug)不相关,这个建议会被直接排除。
- 置信度排序:只有那些符合“心流连续性”的建议,才会被优先推送到用户界面。
看上去这些优化主要是为了过滤掉多余的编辑建议,难道是通过一个小模型完成的?还是模型在输出时同时给出了置信度呢?
关于Repo-Level的实现没有详细说明,我觉得可能是在检索器方面做了优化。一个可能的思路是利用大模型来标注一个提交中哪些跨文件的变化是相关的,从而形成检索器训练的正样本。希望未来会有相关的研究论文探讨这个问题。
增强代码编辑
AC的Next Edit模型听起来是目前最棒的,真可惜在国内受到的封号限制太严了。
架构方案
AC的Next Edit采用了三模型架构[4],其核心是通过检索器和大模型的两阶段合作来完成跨文件的编辑预测。
- 定位模型 (Location Model): 根据你的编辑历史,预测你可能会在何处进行下一次编辑(无论是在当前文件还是整个代码库中)。
- 生成模型 (Generation Model): 一旦确定了位置并理解了意图,便会提供具体的代码修改建议。
- 描述模型 (Description Model): 为建议的代码更改提供简短的描述,帮助用户快速了解变更内容。
算法层面
在早期的博客(2024.11)[5]中,提到AC通过自家研发的一种强化学习算法来优化Next Edit模型,称为RLDB(Reinforcement Learning from Developer Behaviors)。它通过公司内部人员的开发内容进行打点,捕捉IDE状态、用户的编辑历史,以及用户每个时间点的操作,然后设计多维度的奖励机制进行优化。
总结
目前的代码补全方案主要还是模拟用户的编辑序列,无论是通过大模型生成,还是使用AST等静态分析工具,受限于隐私政策,如何利用Pull Request数据来获取最真实的编辑序列非常重要。此外,如何将更多的信息输入给大模型,不仅仅局限于编辑历史,还可能通过RAG或图构建一些代码索引,也是优化的关键。
参考文章
[1]博客 | Qoder – 智能体编程平台
[2]https://www.trae.ai/blog/engineering_thought_0822
[3]Cue-Pro Technical Deep Dive | TRAE – Collaborate with Intelligence
[4]https://www.augmentcode.com/blog/the-ai-research-behind-next-edit
[5]Reinforcement learning from developer behaviors: A breakthrough in code generation quality | Augment Code












文章提到的跨文件预测功能让我觉得很实用,特别是在大型项目中,能节省很多时间。希望其他IDE也能跟上。
这篇文章让我了解了很多模型训练的细节,特别是偏好数据收集的部分,有没有更多的实例分享呢?
看到模型优化只关注采纳的正例,有点担心会影响后续的建议准确性。
偏好学习的过程很有趣,能否在未来的版本中看到更个性化的建议?希望能更懂我!
这篇文章让我对AI编程工具有了新的认识,特别是偏好学习的部分,真是个亮点。
对于跨文件的预测功能,确实能大大提升开发效率,尤其在多人协作时,大家有什么实际的使用体验吗?
文章中提到的局部修正让我想起了自己编辑代码时的小烦恼,有没有其他解决方案?
看到不同IDE的命名差异,Qoder的Next叫法挺有趣,是否会影响用户的接受度?
对比其他IDE,Qoder的预测功能确实还需提升,尤其是用户体验方面。