构建长距离“下一次编辑建议”
2026年2月26日 作者 Vikram Duvvur, Gaurav Mittal, Benjamin Simmonds
去年二月,我们在 GitHub Copilot 中发布了“下一次编辑建议”(NES)。NES 不仅仅是在光标处插入代码,而是通过预测你下一步的修改意图,在附近提供编辑建议,从而扩展了“幽灵文本”的功能。这虽然是一个重大的进步,但它仅在光标周围的小范围内有效。而在实际的编辑工作流中,你通常需要进行的下一次修改往往在几个屏幕之外。
这正是我们着手解决长距离“下一次编辑建议”问题的原因:将 NES 扩展到预测和建议文件中的任何位置,而不仅仅是当前光标位置附近。

从附近编辑到文件任意位置
试想一下典型的重构过程:你重命名了一个函数,文件中所有其他位置的函数调用也需要更新;或者你更改了一个参数类型,导致 200 行之后的验证逻辑出现错误。这些正是你期望 NES 提供帮助的时刻,但遗憾的是,真正有意义的下一次编辑往往超出了它的有效范围。
这带来了一个严峻的建模难题。搜索空间从附近的几行代码爆炸式增长到文件中的每一行。此外,出错的代价并不均衡:正确的跳转能为你节省大量工作,但不必要的跳转会打断你的思维流,让你更难信任接下来的建议。系统不仅必须学会在哪里跳转,还必须学会什么时候不跳转。
我们没有修改现有的编辑生成模型,而是决定采用多模型方法。我们训练了一个专门的位置模型,其唯一职责是预测下一次编辑应该发生在何处。一旦选定有效位置,原始的 NES 模型便会生成编辑建议。
这种分离有两个好处。首先,每个模型可以专注于一项任务:一个模型学习空间意图(跳到哪里),另一个模型在局部窗口内生成高质量的编辑内容。此外,它使我们能够独立迭代位置预测,而不会干扰对核心 NES 模型的持续改进。
通过评估框架衡量成功
在训练位置模型之前,我们需要一种方法来衡量它是否真正适用于现实世界的编辑场景。
我们设计了一个结构化的三步评估过程:
- 识别常见的多处编辑工作流
- 构建代表性的光标跳转示例
- 测量跳转和不跳转的准确率

我们首先分析了开发者在现实场景中如何将编辑串联起来——重命名、签名更改、文档更新等,而不是将每次编辑视为孤立事件。其共同点在于:编辑会在文件中的多个非相邻位置产生连锁反应。
基于这些工作流,我们建立了一个评估数据集,其中每个示例都包含真实的下一次跳转行、近期编辑历史和光标上下文。
至关重要的是,我们同时测量了跳转和不跳转的准确率。虽然许多示例需要预测新位置,但相当一部分示例需要保持在当前行。一个跳转过于频繁的模型可能会像错过重要转换的模型一样具有破坏性。试想一下,如果你每打完变量名的一半就收到一个跳转建议,那将是多么糟糕的体验。
通过将评估建立在真实工作流的基础上并衡量跳转与不跳转的情况,我们确保了离线指标能够反映开发者的实际编辑方式,而不是人工编造的场景。
构建训练数据集
有了评估体系,我们转向了训练数据。虽然评估数据集小到可以手动构建,但训练需要更大规模的数据。我们从用于训练核心 NES 模型的同一数据集开始,其中包含了开发者如何在文件中移动和编辑的轨迹。
通过重放这些轨迹,我们将每一次光标移动转换为一个训练样本。在应用过滤(例如确保跳转位置出现在提示词中)后,我们得到了最终的训练数据集。
通过监督微调进行训练
为了训练位置模型,我们使用了监督微调(SFT)并进行了有针对性的超参数搜索。我们最好的结果来自于围绕现有 NES 模型超参数的结构化网格搜索。通过将搜索空间限制在已知在相关设置中表现良好的值,我们能够高效地探索组合并确定高性能的配置。
在确定这种方法之前,我们还尝试了贝叶斯优化,这是一种旨在优化昂贵黑盒函数的技术。在我们的案例中,每次评估都需要从头开始训练模型,使得实验成本高昂。虽然理论上很有吸引力,但这种方法并没有比更具针对性的网格搜索带来明显的改进。
最终,结构化网格搜索产生了我们性能最好的监督模型,并为后续迭代提供了稳定的基础。
为远距离编辑设计用户体验(UX)
如果用户从未注意到或不信任模型生成的建议,那么再好的模型也不够用。使用标准 NES 时,建议会出现在光标附近且处于直接视野内,因此很自然地会被发现。而长距离 NES 的最相关编辑可能不在你的直接视野范围内。因此,UX 必须解决一个更难的问题:如何在不打断你思路的情况下呈现远距离编辑建议。

这归结为平衡三个关注点:保持建议简洁、确保可读性,并尽量减少对代码遮挡的影响。
这不仅仅是一个发现力问题,更是一个信任问题。当系统建议将光标移到别处时,你需要快速评估该跳转是否相关且值得关注。UI 必须传达足够的上下文来评估建议,而无需强制进行完整的上下文切换。
我们没有选择在行内渲染巨大的 diff 或强制转移用户的注意力,而是设计了一个紧凑的小部件,它会出现在光标附近,并优先选择可用空间。该小部件适应周围的编辑器布局,通过缩小或扩展来自然地嵌入空白处,例如行尾或代码块之间。
由于完整的编辑可能非常遥远且篇幅很大,小部件不会尝试渲染全部内容。相反,它提供了一个轻量级的预览,即受影响行之一的片段,并带有 diff 风格的高亮显示。这为你提供了足够的上下文来判断相关性并决定是否采取行动。
如果预览看起来有用,你可以选择跳转到建议位置并检查或应用完整的编辑内容。如果没有用,你可以继续编辑,不受干扰。
验证:从内部试用到 A/B 测试
我们在发布新功能前总是会进行内部试用(dogfooding),长距离 NES 也不例外。早期的反馈揭示了一个明显的模式:模型太急于跳转。即使预测方向正确,频繁的建议也会变得令人分心。根本原因是数据集不平衡:“不跳转”的样本远少于“跳转”的样本。模型学会了自信地跳转,却没学会何时该保持原位。
我们通过扩充“应保持在当前行”的样本(例如跳转完全没有意义的部分输入的标识符)来重新平衡数据集。重新训练后,跳转和不跳转的准确率都有所提高,建议感也明显更加深思熟虑。
为了大规模验证,我们进行了长距离 NES 与标准 NES 的 A/B 测试。结果令人振奋:通过 NES 编写的代码量增加了 23%,其他参与度指标也有所提升。但实验也带来了权衡:远距离建议被拒绝的频率高于标准 NES。考虑到这是一种新的交互模式,部分结果在预料之中,但这同时也表明模型在何时建议跳转方面仍需更加谨慎。
这不仅是建模问题,也不是单纯的 UX 问题,而是两者兼而有之。改进长距离 NES 需要在收紧模型跳转预测的同时,确保界面能够轻松评估和采纳相关建议。
强化学习:学习何时不跳转
验证结果得出了一个明确的结论:监督模型需要更多的克制。
为了解决这个问题,我们引入了使用带有验证奖励的强化学习(RLVR)的阶段。我们没有仅仅依赖监督标签,而是增加了一个评分信号,基于模型的预测跳转位置与最终光标移动的匹配程度。与实际编辑行为高度一致的预测会受到更大的奖励,而不必要或时机不当的跳转则会受到惩罚。
这使模型能够在不需要新的手动标注或 UX 插桩的情况下,直接针对实际编辑条件进行优化。
结果是在主动性和克制之间取得了更好的平衡。更新后的模型不仅改善了离线指标,还将这些收益转化为在线性能,在增加通过 NES 编写的代码量的同时降低了拒绝率。随着这些信号到位,我们在下个月开始发布改进版本。
下一步是什么?
展望未来,我们计划通过跨文件建议来扩展这项工作,使模型能够进行当前文件之外的推理。我们也在探索一个统一的模型,它可以同时预测下一次编辑的位置和内容,这可能会提高整体建议的相关性。
试一试
长距离“下一次编辑建议”现已在 VS Code 中提供,供拥有 GitHub Copilot 订阅的用户使用。只需确保你在 VS Code 中启用了“下一次编辑建议”和扩展的 NES 范围 github.copilot.nextEditSuggestions.extendedRange 。下次进行重构工作(重命名变量、更新函数签名或进行连锁修改)时,欢迎试用并向我们反馈!
编码愉快! 💙
致谢
衷心感谢我们的开发者社区,是你们源源不断的反馈促使我们为 VS Code 和 GitHub Copilot 提供尽可能最佳的体验。同时,非常感谢 GitHub 和微软的研究人员、工程师、产品经理和设计师,是你们策划了训练数据,构建了训练流水线、评估套件和部署架构;也要感谢 VS Code 和 GitHub Copilot 团队,确保了模型的顺利发布。