news 2026/9/7 8:23:45

Zed 编辑预测评测样例(evals)格式深度解析:从 hello-world 改名样例看 `ep` CLI 的数据规范

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zed 编辑预测评测样例(evals)格式深度解析:从 hello-world 改名样例看 `ep` CLI 的数据规范

Zed 编辑预测评测样例(evals)格式深度解析:从 hello-world 改名样例看epCLI 的数据规范

【免费下载链接】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

本文以 hello-world--rename-accepted-group-by.md 这一评测样例文件为主线,完整拆解 Zed 编辑预测(Edit Prediction / Zeta)评测数据的 Markdown 格式:TOML front matter、Edit History 中的"用户接受预测"标记、[CURSOR_POSITION]光标注释的列定位语义,以及 Expected Patch 的游标编码方式;并结合 example_spec.rs 与 example.rs 的解析实现,说明如何用 edit_prediction_cli 的ep命令驱动这条评测链路。读完后你可以独立编写、阅读和运行 Zed 的编辑预测评测样例。

1. 这个样例文件在仓库中的位置与作用

该文件位于 crates/edit_prediction_cli/evals/ 目录下,是 Zed 编辑预测模型的评测样例之一。同一目录中还有来自 flask、tree-sitter、vscode、zed 等仓库的样例(如 flask--rename-accepted-prediction.md、tree-sitter--tuple-to-struct-definition.md),命名遵循仓库名--场景描述.md的约定。

文件名本身就是样例名:解析入口read_example_files(example.rs)在读入.md文件后,若spec.name为空,就直接取文件主名(去掉扩展名的部分)作为样例名:

"md" => { let mut example = parse_markdown_example(&content).unwrap(); if example.spec.name.is_empty() { example.spec.name = filename; } examples.push(example); }

也就是说,hello-world--rename-accepted-group-by这个文件名精确表达了该样例测试的语义:在 hello-world 仓库中,用户先接受了一次自动补全,随后对补全出的函数做改名,模型应当能预测出"连带修改函数体内引用"的完整重命名。

2. 样例全文结构:front matter、编辑历史、光标与期望补丁

下面逐段解析该样例文件的真实内容(与仓库文件完全一致)。

2.1 TOML front matter:锚定到确定性的仓库状态

+++ repository_url = "https://github.com/octocat/hello-world" revision = "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" +++

front matter 用+++定界,内部是 TOML。解析器ExampleSpec::from_markdown(example_spec.rs)会先strip_prefix("+++\n")取出 front matter 并用toml::from_str::<FrontMatter>反序列化,可识别的字段包括:

字段含义
repository_url样例所锚定的仓库地址。从源码结构看,repo_name()(example.rs)会同时解析git@github.com:owner/repo.githttps://github.com/owner/repo.git两种形式,并据此推导 worktree 缓存路径(owner/repo
revision固定到某个提交哈希,保证评测可复现
tags可选标签数组(可选字段,省略时为空)
uncommitted_diff_requires_edit_history_rollback可选布尔值,控制加载Uncommitted Diff章节时是否需要回滚编辑历史(可选字段,省略时为 false)

该样例只使用了repository_urlrevision两个必填字段。

2.2 Edit History:三段 diff 讲述"手写 → 接受预测 → 改名"的完整故事

样例的## Edit History章节包含三段```diff代码块,其中第二段前有一行特殊注释:

--- a/README +++ b/README @@ -1,1 +1,6 @@ -Hello World! +function filterByStatus(items, status) { + return items.filter(item => item.status === status); +} + +function groupBy +

// User accepted prediction:

--- a/README +++ b/README @@ -4,3 +4,9 @@ -function groupBy +function groupByStatus(items) { + return items.reduce((groups, item) => { + const key = item.status; + (groups[key] = groups[key] || []).push(item); + return groups; + }, {}); +}
--- a/README +++ b/README @@ -4,4 +4,4 @@ -function groupByStatus(items) { +function groupByCat(items) { return items.reduce((groups, item) => {

三段 diff 的语义分别是:

  1. 手写编辑:用户把 README 的Hello World!替换为 JavaScript 代码,并手敲了function groupBy(未写完);
  2. 被接受的自动补全// User accepted prediction:注释标记的 diff,表示模型补全了groupByStatus的完整实现,且用户接受了这次预测——这正是样例名中rename-accepted的来源;
  3. 后续改名:用户把接受的补全改名为groupByCat(一个被截断的名字),触发本次评测:模型此时应预测出把名字补全为groupByCategory、并同步修改函数体内item.statusitem.category的编辑。

// User accepted prediction:这一行不是给人看的普通注释,而是解析协议的一部分。from_markdown中定义了常量:

const ACCEPTED_PREDICTION_MARKER: &str = "// User accepted prediction:";

(example_spec.rs)。解析时,如果某个 diff 代码块之前紧跟该行文本,解析器会把该行标记重新拼回edit_history字符串中(example_spec.rs),保证序列化/反序列化往返一致。同文件内的测试test_from_markdown_accepted_prediction_marker(example_spec.rs)验证了:三段 diff 均被保留、标记恰好出现一次、且只出现在第二段之前。

2.3 Cursor Position:#...^[CURSOR_POSITION]注释标记光标

```README function filterByStatus(items, status) { return items.filter(item => item.status === status); } function groupByCat(items) { # ^[CURSOR_POSITION] return items.reduce((groups, item) => { const key = item.status; (groups[key] = groups[key] || []).push(item); return groups; }, {}); }
`Cursor Position` 章节的代码块**信息串(info string)就是光标所在文件路径**(这里是 `README`),块内容是光标所在文件的节选。解析逻辑见 [example_spec.rs](https://link.gitcode.com/i/fc6b88b3a6aef362cd369f3179c433fd#L393-L396):`cursor_path` 取代码块 info string,`cursor_position` 取块内全文。 光标位置用一条注释行表达,其解析规则([example_spec.rs](https://link.gitcode.com/i/fc6b88b3a6aef362cd369f3179c433fd#L417-L473) 的 `cursor_excerpt` 文档注释与实现)为: - 注释行必须包含 `[CURSOR_POSITION]`(常量 `CURSOR_POSITION_MARKER`,定义于 [udiff.rs](https://link.gitcode.com/i/e59b52bed422861287f61c0e75c650c6)),位于光标所在行的**下一行**; - `^`:光标列 = `^` 字符在该行的列位置(指向上方的光标); - `<`:光标列 = 该行第一个非空白字符所在列(用于注释前缀较长、`^` 会越界到注释符内部的情况); - 此外还支持内联标记 `<|user_cursor|>`(常量 `INLINE_CURSOR_MARKER`,同样定义于 [udiff.rs](https://link.gitcode.com/i/e59b52bed422861287f61c0e75c650c6)),直接写在光标字节偏移处,例如 `let x = <|user_cursor|>42;`,解析时直接剥掉标记并返回其偏移量。 在本样例中,`#` 后的 `^` 指向 `function groupByCat(items) {` 中 `Cat` 之后的位置——即用户刚敲完 `Cat`、等待模型把名字补全为 `Category` 的时刻。测试 `test_cursor_excerpt_with_caret`([example_spec.rs](https://link.gitcode.com/i/fc6b88b3a6aef362cd369f3179c433fd#L521-L657))覆盖了 `^` 与 `<` 两种形式在行首、行中、行尾及文件末尾(无换行)的往返一致性。 注意解析器强制要求该章节存在,缺失会直接报错: ```rust if spec.cursor_path.as_ref() == Path::new("") || spec.cursor_position.is_empty() { anyhow::bail!("Missing cursor position codeblock"); }

(example_spec.rs)

2.4 Expected Patch:期望补丁里也编码了光标

--- a/README +++ b/README @@ -5,7 +5,7 @@ -function groupByCat(items) { +function groupByCategory(items) { # ^[CURSOR_POSITION] return items.reduce((groups, item) => { - const key = item.status; + const key = item.category; (groups[key] = groups[key] || []).push(item); return groups; }, {});

这是评测的"标准答案":模型应当输出的 unified diff。两个要点:

  • 期望补丁包含连带修改item.statusitem.category),这正是"改名的正确预测"与"只改名不改引用"的分界线,也是该样例的评测价值所在;
  • 补丁中同样有一行#...^[CURSOR_POSITION]标记,说明编辑完成后光标应落在哪里groupByCategoryCategory末尾)。ExampleSpec提供expected_patches_with_cursor_positions/set_expected_patches_with_cursor_positions(example_spec.rs)成对地提取/写回光标偏移,底层由extract_cursor_from_patch/encode_cursor_in_patch实现。源码注释说明:在样例的序列化表示中,编辑后的光标位置用"新增 diff 行内的内联标记"表达,偏移量是相对 hunk 起点、在新文本中的字节偏移

此外ExampleSpec还支持一个可选的## Rejected Patch章节(example_spec.rs),用于保存"用户拒绝的预测",对应训练中的 DPO 负样本(rejected_patch字段)。本样例未使用该章节——它考察的是正向预测,而非拒绝场景。

3. 解析链路:从.md文件到内存中的Example

把样例格式与解析实现对照起来,整条链路如下:

  1. CLI 读入read_example_files(example.rs)按扩展名分派——.mdparse_markdown_example.json走 serde 直接反序列化Example.jsonl逐行反序列化;输入为-时从 stdin 读取。
  2. Markdown 解析ExampleSpec::from_markdown(example_spec.rs)基于pulldown_cmark事件流,识别 H1(样例名)与七种 H2 章节标题(大小写不敏感):Uncommitted DiffRecently Opened FilesRecently Viewed FilesEdit HistoryCursor PositionExpected PatchRejected Patch,并处理 accepted-prediction 标记的回写。本样例使用了其中Edit HistoryCursor PositionExpected Patch三个章节。
  3. 内存结构Example(example.rs)=ExampleSpec(打平内嵌)+prompt_inputs(Zeta2 提示输入)+prompt(模型输入/期望输出,含 DPO 用的rejected_output)+predictions(实际预测列表,含actual_patchactual_cursor、logprob 等)+score+qa结果。前四个运行时字段在磁盘样例文件中不存在,由预测/评分流程填充。

ExampleSpec的完整字段列表(example_spec.rs)还包括tagsreasoninguncommitted_diffrecently_opened_filesrecently_viewed_filestelemetry(来自生产遥测的拒绝预测元数据:request_idrejection_reason等)、human_feedbackrating,覆盖了遥测捕获、用户评分等多种样例来源。

4. 如何运行这个样例

评测样例由 edit_prediction_cli 提供的ep命令驱动(二进制名在 Cargo.toml 中定义为ep)。

4.1 命令与全局参数

ep使用 clap 定义,全局参数(main.rs)包括:

  • --max-parallelism(默认 10)、--group-by-repo(同一仓库的样例集中处理)、--limit/--offset
  • --name:按样例名过滤,正好可以单独选中hello-world--rename-accepted-group-by
  • --repo:按仓库 URL 过滤;
  • 输入inputs:支持普通文件路径(.md/.json/.jsonl)以及captured-after:/rejected-after:/settled-after:/rated-after:等从 Snowflake 拉取遥测样例的特殊说明符(见 main.rs 的INPUTS_HELP);
  • -o/--output--in-place--failfast--failed(keep/skip/skip-no-files);
  • --markdown/-m:输出为 Markdown 而非 JSONL,每个样例写入一个.md文件——即evals/目录中这类文件的读写是同构的。

子命令包含predictscoreqadistillpull-examplessynthesizesplit-commit等;--provider可选 Mercury、Zeta1、Zeta2、Baseten、Teacher 系列及 Repair(main.rs)。

4.2 针对本样例的最小用法

对应当前仓库结构,运行编辑预测评测的典型形式是把样例文件作为输入传给ep的子命令,例如:

# 对该样例跑一次编辑预测 cargo run -p edit_prediction_cli -- predict \ crates/edit_prediction_cli/evals/hello-world--rename-accepted-group-by.md # 用 --name 在整批样例中按名过滤 cargo run -p edit_prediction_cli -- score --name hello-world--rename-accepted-group-by \ crates/edit_prediction_cli/evals/ # 结果以 Markdown 形式写回(-o 指定目录) cargo run -p edit_prediction_cli -- predict --markdown \ -o /tmp/ep-out \ crates/edit_prediction_cli/evals/hello-world--rename-accepted-group-by.md

其中score子命令复用PredictArgs(main.rs),用于把模型输出与Expected Patch对照打分;synthesize子命令的默认输出目录即crates/edit_prediction_cli/evals-generated(main.rs),用于从真实仓库提交中批量合成同类样例。另外,仓库还提供了一个独立的单元测试评测脚本 script/run-unit-evals,通过cargo nextest run --workspace --features unit-eval -E 'test(::eval_)'运行带unit-evalfeature 的eval_前缀单元测试(run-unit-evals),它面向的是各 crate 内嵌的单元级评测,与evals/目录这批 Markdown 样例分属两条评测通道。

5. 小结:这个样例教给模型的到底是什么

把各要素串起来,hello-world--rename-accepted-group-by构造了一条最小但完整的"上下文 → 行为"评测链:

  • 上下文由 Edit History 给出:先有手写编辑,再有一次已被接受的预测// User accepted prediction:标记),说明模型此前给出的groupByStatus实现已成为当前文件状态的一部分;
  • 触发点由 Cursor Position 精确定位到groupByCat这个名字的中间——用户改名的意图刚刚暴露;
  • 标准答案由 Expected Patch 给出:不仅把名字补全为groupByCategory,还连带把函数体内item.status改为item.category,并在补丁中标注编辑完成后的光标位置。

从源码结构看,epCLI 的评分与 QA 流程(scoreqa子命令及 score.rs、qa.rs)正是围绕"实际补丁 vsexpected_patches"这类字段展开的,而rejected_patch字段则为负样本(DPO)预留了同一格式通道。掌握本文介绍的 front matter、四个 H2 章节、光标注释(^/</<|user_cursor|>三种形式)与 accepted-prediction 标记,即可在该目录下编写新的评测样例,并用 example_spec.rs 中的往返测试方法验证其可解析性。

关键文件索引

文件作用
crates/edit_prediction_cli/evals/hello-world--rename-accepted-group-by.md本文剖析的评测样例
crates/edit_prediction/src/example_spec.rsExampleSpec定义、Markdown 解析、光标标记语义与往返测试
crates/edit_prediction_cli/src/example.rsExample结构、多格式文件读入、仓库名解析
crates/edit_prediction_cli/src/main.rsepCLI 参数、子命令与 provider 定义
crates/zeta_prompt/src/udiff.rs[CURSOR_POSITION]<\|user_cursor\|>常量及补丁光标编解码
script/run-unit-evals单元级评测的 nextest 运行脚本

【免费下载链接】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 8:21:28

C# Winform调用user32.dll实现自动点击工具实战

简介&#xff1a;这份C# Winform自动点击工具&#xff0c;专为需要定时或重复点击屏幕固定位置的办公自动化场景而设计&#xff1b;当用户不在工位时&#xff0c;工具可代替手工完成鼠标操作。项目基于DllImport特性引入Windows API user32.dll非托管动态库&#xff0c;通过托管…

作者头像 李华
网站建设 2026/9/7 8:18:05

Cap录屏:免费的开源录屏工具,3步录完直接拿链接

Cap录屏&#xff1a;免费的开源录屏工具&#xff0c;3步录完直接拿链接 【免费下载链接】Cap Open source Loom alternative. Beautiful, shareable screen recordings. 项目地址: https://gitcode.com/GitHub_Trending/cap1/Cap 录课程视频的时候&#xff0c;系统弹了个…

作者头像 李华
网站建设 2026/9/7 8:16:01

微信开源生产级大模型:部署实战与微调避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/7 8:14:53

JAVA第十课

跟日记本一起学JAVA&#xff01;相信你可以的&#xff0c;加油~本课闯关内容&#xff1a;1.照猫画虎&#xff08;0/7&#xff09; 2.基础知识(0/3&#xff09;这里的基础知识的…

作者头像 李华
网站建设 2026/9/7 8:13:20

Win32 API读取U盘VID/PID与物理序列号,识别扩容盘

简介&#xff1a;一套基于VC6的完整源码工程&#xff0c;主要功能是获取U盘等移动设备的厂商识别码、产品识别码、盘符及物理序列号。运行后输出形如“盘符&#xff3c;厂商识别码&#xff06;产品识别码&#xff3c;物理序列号”的设备路径&#xff0c;例如“G盘&#xff3c;V…

作者头像 李华