news 2026/9/7 23:47:52

剖析 Zed 的编辑预测评测用例:`project::Event` 匹配臂改名场景与多目标期望补丁

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
剖析 Zed 的编辑预测评测用例:`project::Event` 匹配臂改名场景与多目标期望补丁

剖析 Zed 的编辑预测评测用例:project::Event匹配臂改名场景与多目标期望补丁

【免费下载链接】zedCode at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.项目地址: https://gitcode.com/GitHub_Trending/ze/zed

本文以 Zed 仓库中的真实评测文件 zed--change-match-arm.md 为主体,完整解读 Zed 内置编辑预测(Zeta)模型评测用例的文档结构:TOML frontmatter 如何钉住代码库版本、Edit History/Cursor Position/Expected Patch三个小节如何映射到ExampleSpec数据模型、[CURSOR_POSITION]游标标记的编码方式,以及“多目标期望补丁”的设计意图。读完本文,你能看懂并独立构造一个可被edit_prediction_cli流水线加载、运行与评分的评测用例。

1. 这个文件是什么:一条 Zeta 编辑预测评测用例

crates/edit_prediction_cli/evals/目录存放着编辑预测模型的手写评测用例,同一目录下还有flask--add-test-function.mdtree-sitter--if-let-to-match.mdvscode--add-async-and-await.md等同名约定文件(仓库名 + 双横线 + 场景短名)。zed--change-match-arm.md 是其中之一,它针对的是 Zed 自身代码库中一次“给match的某个匹配臂改名”的编辑场景。

文件以 TOML frontmatter 开头:

repository_url = "git@github.com:zed-industries/zed" revision = "be5763632dccb33470ca233c36ccd9e5e790e3b2"

这两个字段直接对应评测用例的数据模型ExampleSpec(定义于 example_spec.rs):

  • repository_url:评测所基于的仓库,流水线据此克隆代码;
  • revision:钉住的具体提交。评测必须在“用户编辑之前”的那个代码状态上运行,模型看到的才是编辑前快照。从源码结构看,自动生成的用例同样遵循“指向编辑前基线提交”的约定,例如 split_commit.rs 中会自动生成revision = format!("{}~1", commit_hash)这类父提交引用。

ExampleSpec中与本用例正文三个小节一一对应的字段是edit_historycursor_path+cursor_positionexpected_patches,对应的 Markdown 标题常量也定义在同文件内(EDIT_HISTORY_HEADING/CURSOR_POSITION_HEADING/EXPECTED_PATCH_HEADING,见 example_spec.rs)。此外该结构体还支持uncommitted_diffrejected_patch(用于 DPO 的负样本)、telemetryhuman_feedback等可选字段,手写评测用例可以按需省略。

用例正文第一行还有一句人写的备注:

This prediction requires the model to see theproject::Eventenum.

这句话是整个用例的灵魂,后面第 3 节会专门展开。

2. 用例主体三段式结构完整解读

2.1## Edit History:给模型提供“编辑前情”

用例正文第一个小节是一段 unified diff,模拟用户在做目标编辑之前刚刚完成的改动:

--- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -1035,7 +1035,7 @@ project_state.recent_paths.push_front(path); } } - project::Event::DiagnosticsUpdated { .. } => { + project::Event::Disk { .. } => { if cx.has_flag::<EditPredictionJumpsFeatureFlag>() { self.refresh_prediction_from_diagnostics( project,

它的语义是:用户在edit_prediction.rs中刚把一个匹配臂project::Event::DiagnosticsUpdated { .. }改名为project::Event::Disk { .. }。对编辑预测模型而言,这段“编辑历史”是关键上下文——它暗示用户正在进行一次“枚举变体改名”的批量重构,下一步的合理编辑就是把其他匹配臂也同步改到新的变体名上。字段edit_historyExampleSpec中是纯字符串,允许包含一个或多个 hunk;uncommitted_diff_contains_edit_history布尔字段则用于区分编辑历史是独立给出还是混在未提交 diff 里。

2.2## Cursor Position:预测的锚点

第二小节给出目标文件在预测时刻的局部内容,并用一行注释标记出光标确切位置:

crates/edit_prediction/src/edit_prediction.rs { project_state.recent_paths.remove(ix); } project_state.recent_paths.push_front(path); } } project::Event::Disk { .. } => { // ^[CURSOR_POSITION] if cx.has_flag::<EditPredictionJupsFeatureFlag>() { self.refresh_prediction_from_diagnostics( project,

(以上为原文摘录;原文标记行为if cx.has_flag::<EditPredictionJumpsFeatureFlag>() {。)

注意^[CURSOR_POSITION]标记的写法:一个^指向上行中光标所在的字符列,标记本身嵌在代码行内。这个标记格式由zeta_prompt::udiff模块统一管理,example_spec.rs 直接重导出CURSOR_POSITION_MARKERINLINE_CURSOR_MARKERencode_cursor_in_patchextract_cursor_from_patch;在自动拉取用例的路径中,标记按format!("{}[CURSOR_POSITION]{}", before, after)拼进文本(见 pull_examples.rs)。模型侧的提示词最终会基于这个标记确定“可编辑区域”的起点与光标列,评分时再反过来从模型输出中提取光标位置。

另有一个与游标截取相关的约束值得注意:MAX_CURSOR_FILE_SIZE被设为 64KB(example_spec.rs),超过该大小的文件不会直接截取全文作为游标内容,而是回退到基于 git 的加载方式。

2.3## Expected Patch:多目标期望补丁

第三小节是本用例最有意思的部分——它给出了两个并排的期望补丁:

--- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -1032,10 +1032,10 @@ project_state.recent_paths.push_front(path); } } - project::Event::Disk { .. } => { + project::Event::DiskBasedDiagnosticsFinished { .. } => { if cx.has_flag::<EditPredictionJumpsFeatureFlag>() { self.refresh_prediction_from_diagnostics( project,
--- a/crates/edit_prediction/src/edit_prediction.rs +++ b/crates/edit_prediction/src/edit_prediction.rs @@ -1032,10 +1032,10 @@ project_state.recent_paths.push_front(path); } } - project::Event::Disk { .. } => { + project::Event::DiskBasedDiagnosticsStarted { .. } => { if cx.has_flag::<EditPredictionJumpsFeatureFlag>() { self.refresh_prediction_from_diagnostics( project,

两个补丁把project::Event::Disk { .. }分别改名为DiskBasedDiagnosticsFinishedDiskBasedDiagnosticsStarted。这不是冗余,而是“多目标”设计:ExampleSpec.expected_patches的类型是Vec<String>(example_spec.rs),即一个用例可以声明多个可接受的正确答案,评分逻辑(score.rs)会判断模型输出是否命中其中任意一个。从源码结构看,这种设计承认了“改名重构”场景下存在多个语义上都说得通的目标变体,避免因唯一标准答案造成误判,使评测更贴近真实重构的不确定性。

3. 为什么“模型必须看到project::Event枚举”

用例开头的备注要求模型看到project::Event枚举定义,原因在于:要判断匹配臂该改成哪个变体,模型必须知道这个枚举当前到底有哪些变体。这一点在当前仓库源码中可以直接印证。

project::Event定义于 project.rs,其中与诊断相关的三个变体是:

pub enum Event { // ... DiskBasedDiagnosticsStarted { language_server_id: LanguageServerId, }, DiskBasedDiagnosticsFinished { language_server_id: LanguageServerId, }, DiagnosticsUpdated { paths: Vec<ProjectPath>, language_server_id: LanguageServerId, }, // ... }

也就是说,评测钉住的那个历史版本中刚出现的Disk变体,在现行代码里已经演进为DiskBasedDiagnosticsStarted/DiskBasedDiagnosticsFinished两个明确语义的变体(分别对应基于磁盘的诊断开始与结束)。这些事件自下而上的传播链路是:LSP 存储层先发出LspStoreEvent(变体定义与发出点见 lsp_store.rs 及 lsp_store.rs),再由Project统一转发为project::Event(见 project.rs)。

而“看到枚举定义”正是编辑预测提示词构造中“语义上下文检索”要解决的问题:retrieve_context.rs 负责在构造提示词时为模型补齐被引用项(如枚举定义、调用处)的源码,并且该流程依赖example.spec.repository_url非空(retrieve_context.rs);它还会监听LspStoreEvent::DiskBasedDiagnosticsFinished(retrieve_context.rs)来判断语言服务器已完成磁盘扫描、符号信息可以安全使用。换句话说,本用例同时考察了模型对“跨文件引用上下文”的理解能力——这正是备注那句话的测试意图。

事件改名的“牵一发动全身”也可以从事件消费方得到佐证:DiskBasedDiagnosticsFinished至少被 diagnostics.rs、项目面板、工作区 pane 以及协作集成测试(integration_tests.rs)等多处匹配处理,这也解释了为什么一次变体改名会体现在多个match臂上。

4. 评测用例如何被 CLI 加载与运行

edit_prediction_cli是承载整条评测流水线的 crate(Cargo.toml),围绕本用例的核心环节如下:

  1. 钉版本加载项目:load_project.rs 会按repository_url定位(或克隆)本地仓库,校验/补建origin远程,git fetchcheckoutrevision(必要时创建 worktree 与临时分支),从而精确还原用例声明的代码快照;用例的uncommitted_diff(若有)在此基础上应用,再把光标文件按cursor_path/cursor_position打开。
  2. 构造提示词并预测:光标文件内容以[CURSOR_POSITION]标记方式进入提示词(zeta_prompt模块),预测结果记入Example结构的predictions字段(见 example.rs)。
  3. 评分score子命令对比模型实际补丁与expected_patches列表,命中即视为通过;Example结构同时保留了scoreqa等字段用于记录多轮评测结果。
  4. 修复与数据集工具repair模块可对失败用例做修复尝试,split_dataset支持按repository_url等字段分层切分数据集(split_dataset.rs),pull_examples则从 git 历史自动挖掘新用例(pull_examples.rs)。

对应这些能力的模块源码都位于 crates/edit_prediction_cli/src/(load_project.rspredict.rsscore.rsrepair.rsretrieve_context.rs等),可以直接阅读以了解每一步的实现细节。

5. 构造同类评测用例的要点小结

以本文件为模板,一个合格的编辑预测评测用例需要满足:

  • 钉住基线版本repository_url+revision指向“目标编辑发生前”的提交,保证评测可复现(frontmatter 见 zed--change-match-arm.md);
  • Edit History 提供因果:diff 要能解释“用户正在做什么风格的重构”,让期望补丁成为编辑历史的逻辑延续;
  • Cursor Position 给出精确锚点:局部代码摘录中用^...[CURSOR_POSITION]标记光标列,标记格式需与zeta_prompt::udiffCURSOR_POSITION_MARKER约定一致;
  • Expected Patch 支持多目标:当存在多个语义合理的正确答案时,并列写出多个 diff 块,对应expected_patches: Vec<String>
  • 必要时声明上下文依赖:像本用例一样用一句话注明模型必须看到的定义(如project::Event),提示评测执行方该场景依赖语义上下文检索,而非仅靠单文件局部信息。

参考路径

  • 评测用例本体:crates/edit_prediction_cli/evals/zed--change-match-arm.md
  • 用例数据模型:crates/edit_prediction/src/example_spec.rs
  • 项目加载逻辑:crates/edit_prediction_cli/src/load_project.rs
  • project::Event枚举与事件转发:crates/project/src/project.rs
  • LSP 事件源:crates/project/src/lsp_store.rs
  • 上下文检索:crates/edit_prediction_cli/src/retrieve_context.rs
  • 评分与修复:crates/edit_prediction_cli/src/score.rs、crates/edit_prediction_cli/src/repair.rs

【免费下载链接】zedCode at the speed of thought – Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter.项目地址: https://gitcode.com/GitHub_Trending/ze/zed

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/7 23:46:59

JSP+Servlet+MySQL汉服电商网站设计与实现:从数据库到部署全攻略

作为一名老Java Web开发者&#xff0c;看到“jsp福建汉服天下电子商务网站设计与实现”这个标题&#xff0c;第一反应确实是有点怀念。这几乎是每个计算机专业学生都绕不开的课设标配——用JSPServletMySQL撑起一个完整的电商项目。但说真的&#xff0c;把它做好、做稳、做得出…

作者头像 李华
网站建设 2026/9/7 23:45:12

显式 GC 的使用:留与去,如何选择?

目录 一、什么是显式 GC? (一) 垃圾回收的基本原理 (二)显式 GC 方法和行为 1. System.gc() 方法 2. 显式 GC 的行为 (三)显式 GC 的使用场景与风险 1. JVM 如何处理显式 GC 2. 显式 GC 的风险 二、显式 GC 对性能的影响 (一) 全 GC 与 STW 1. Full GC 是如…

作者头像 李华
网站建设 2026/9/7 23:44:19

MISRA C:2023新规解读:10大高危漏洞与代码修复实战

简介&#xff1a;一份聚焦C语言安全编码的PDF技术文档&#xff0c;面向嵌入式开发、系统软件研发及需要满足功能安全认证的C语言工程师&#xff0c;系统讲解MISRA C 2023新标准的规则变化与工程落地方法。文档共63页&#xff0c;围绕10大高危漏洞展开&#xff1a;内存泄漏、双重…

作者头像 李华
网站建设 2026/9/7 23:41:51

mayavi+PyQt5集成实战:从环境搭建到三维可视化

如果你打算在 Python 里同时做三维科学可视化和桌面端交互界面&#xff0c;那“mayavi PyQt5”这个组合你一定绕不开。mayavi 负责把等值面、体渲染、流线这些复杂三维内容快速画出来&#xff0c;PyQt5 负责外面的窗口、控件和交互逻辑&#xff0c;两者拼在一起&#xff0c;就…

作者头像 李华