首页
/ Zed Zeta 编辑预测评测样本详解:以 vscode--add-interface-method.md 为例

Zed Zeta 编辑预测评测样本详解:以 vscode--add-interface-method.md 为例

2026-09-06 11:12:32作者:郜逊炳

本文以 crates/edit_prediction_cli/evals/vscode--add-interface-method.md 这一评测样本为核心,完整讲解 Zed 编辑器编辑预测模型(Zeta)评测样本的 Markdown 格式规范——包括 front matter、Edit History、Cursor Position、Expected Patch 四个核心部分的语义与写法,并结合 example_spec.rsexample.rs 等源码解析该格式如何被解析、校验并用于模型预测与打分。读完后你可以独立读懂并手写一个合法的 Zeta 编辑预测评测样本。

一、文件定位:这是 Zeta 编辑预测模型的评测样本

Zed 内置的 Zeta 编辑预测(edit prediction)功能会在你编码时预测下一步编辑。围绕它,仓库维护了一套评测(evals)体系:模型针对"给定编辑历史 + 当前缓冲区 + 光标位置"预测一个补丁(patch),再与人工标注的期望补丁比对打分。

该体系包含两层:

vscode--add-interface-method.md 正是其中取自 VS Code 仓库的一次真实编辑场景,文件名遵循"仓库名--场景描述"的命名习惯(对应 ExampleSpec::filename 中的文件名净化逻辑)。

二、样本整体结构:front matter 与四个部分

该文件完整结构如下(按原文顺序):

  1. +++ 包裹的 TOML front matter,声明样本来自哪个仓库、哪个提交;
  2. ## Edit History:一段 unified diff,记录光标动作发生前的连续编辑历史;
  3. ## Cursor Position:一个以文件路径为 fence info 的代码块,内含 [CURSOR_POSITION] 光标标记;
  4. ## Expected Patch:模型应当预测出的 diff 补丁。

2.1 front matter:锚定评测复现点

文件开头是:

+++
repository_url = "https://github.com/microsoft/vscode"
revision = "b64eaf598008e2d600a81d846108f72cb37b48e2"
+++

它告诉评测工具:本样本基于 microsoft/vscode 仓库的特定提交快照。解析时这段 front matter 被提取为 FrontMatter(定义于 example_spec.rs),除 repository_urlrevision 外还支持可选的 tagsuncommitted_diff_requires_edit_history_rollback 字段。

配套地,Example::repo_name 会从 repository_url 中解析出 owner 与仓库名(同时支持 git@http 两种形式),RepoName::worktree_path 则据此把样本映射到本地 git worktree 目录,保证评测时能检出到完全一致的仓库状态。[CURSOR_POSITION]<|user_cursor|> 等常量定义在 crates/zeta_prompt/src/udiff.rs

2.2 Edit History:编辑历史 diff

Edit History 部分是一个 ```diff 代码块,记录了模型预测前开发者刚刚做的一系列编辑。本样本的历史共 4 个文件:

文件 编辑内容
src/vs/platform/window/electron-main/window.ts ICodeWindow 接口中新增 onDidTriggerSystemContextMenu: Event<{ x: number; y: number }> 只读属性
src/vs/platform/windows/electron-main/window.ts CodeWindow 类中新增对应私有 Emitter 与只读事件成员
src/vs/platform/windows/electron-main/windows.ts IWindowsMainService 接口中新增 onDidTriggerSystemContextMenu: Event<{ window: ICodeWindow; x: number; y: number }>
src/vs/platform/windows/electron-main/windowsMainService.ts WindowsMainService 实现类中新增对应的 Emitter 与只读事件成员

这段历史的语义是:开发者正在给"系统右键菜单触发"事件打通从窗口到窗口服务层的转发链路。接口先改、实现跟上,这是编辑预测最需要"续写"的典型场景。

解析侧,Edit History 代码块会被累积拼接进 ExampleSpec.edit_history 字段(from_markdown 中 Section::EditHistory 分支)。值得注意的是,历史块之间还允许出现 // User accepted prediction: 这样的行级标记(常量 ACCEPTED_PREDICTION_MARKER,见 example_spec.rs),用于声明"这一段编辑来自用户接受的模型预测";解析器检测到标记后的下一个 diff 块会在其前面重新插入该标记行,测试 test_from_markdown_accepted_prediction_marker 验证了这一往返行为。

此外,ExampleSpec 还支持本样本未使用的可选部分(见 to_markdown):Reasoning(标注者推理说明)、Uncommitted Diff(未提交改动)、Recently Opened Files / Recently Viewed Files(最近打开/浏览文件列表,每行 路径\t光标偏移 格式)、Rejected Patch(用于 DPO 的拒绝样本)。

2.3 Cursor Position:光标位置的编码约定

Cursor Position 部分的写法:

## Cursor Position

```src/vs/platform/windows/test/electron-main/windowsFinder.test.ts
	function createTestCodeWindow(options: { lastFocusTime: number; openedFolderUri?: URI; openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
		return new class implements ICodeWindow {
			onWillLoad: Event<ILoadEvent> = Event.None;
			onDidSignalReady: Event<void> = Event.None;
			// <[CURSOR_POSITION]
			onDidClose: Event<void> = Event.None;
			onDidDestroy: Event<void> = Event.None;
			whenClosedOrLoaded: Promise<void> = Promise.resolve();
			id: number = -1;
```

格式要点有三:

  • 代码块的 fence info 字符串就是光标所在文件的路径。解析器据此填充 spec.cursor_pathfrom_markdown 中 Section::CursorPosition 分支);
  • [CURSOR_POSITION] 标记位于光标下一行,其上方注释中的符号指明光标列:
    • ^:光标列就是 ^ 字符所在列(向上指向光标);
    • <:光标位于该行第一个非空白字符处(当光标列比注释前缀还靠左时,set_cursor_excerpt 会自动退化为这种格式)。
  • 标记行本身不是文件内容cursor_excerpt 会从摘录中剔除整行标记行,再用"标记行上方一行的行首 + 标记列"计算光标在摘录内的字节偏移,返回 (摘录文本, 光标偏移) 供构建预测 prompt。

本样本中 // <[CURSOR_POSITION] 使用 < 形式,语义是"光标位于下一行 onDidClose: ... 行首缩进之前"——即开发者正准备在该处插入一行代码。这套 ^/< 标记与偏移计算的往返正确性由 test_cursor_excerpt_with_caret 覆盖(含行尾、文件末尾无换行等边界),而较新的内联标记 <|user_cursor|>(直接写在摘录文本中)则由 test_cursor_excerpt_with_inline_marker 验证,两种标记都优先于注释行形式被检测(cursor_excerpt 先查 INLINE_CURSOR_MARKER)。

如果 Cursor Position 部分缺失或为空,from_markdown 会直接报错 Missing cursor position codeblockexample_spec.rs)——这是格式上的硬性要求。

2.4 Expected Patch:期望的模型输出

## Expected Patch

```diff
--- a/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts
+++ b/src/vs/platform/windows/test/electron-main/windowsFinder.test.ts
@@ -7,60 +7,61 @@ import * as assert from 'assert';
 	function createTestCodeWindow(options: { lastFocusTime: number; openedFolderUri?: URI; openedWorkspace?: IWorkspaceIdentifier }): ICodeWindow {
 		return new class implements ICodeWindow {
 			onWillLoad: Event<ILoadEvent> = Event.None;
+			onDidTriggerSystemContextMenu: Event<{ x: number; y: number }> = Event.None;
 			onDidSignalReady: Event<void> = Event.None;
 			onDidClose: Event<void> = Event.None;
 			onDidDestroy: Event<void> = Event.None;
 			whenClosedOrLoaded: Promise<void> = Promise.resolve();
 			id: number = -1;
```

期望补丁只有一处新增:在测试用的匿名 ICodeWindow 实现中补上 onDidTriggerSystemContextMenu: Event<{ x: number; y: number }> = Event.None;,与 Edit History 中接口新增的成员一一对应(匿名类必须实现接口的全部成员,否则类型检查失败)。这构成了一个干净的单行插入任务:类型签名来自历史 diff,插入位置由光标锚定。

Expected Patch 部分允许出现多个 diff 代码块,解析时依次推入 spec.expected_patchesSection::ExpectedPatch 分支)。若补丁中还内嵌了 <|user_cursor|> 标记,expected_patches_with_cursor_positions 会把它拆成"干净补丁 + 新文本中的光标偏移",供打分时同时比较编辑内容与新光标落点;编码/解码的幂等性由 test_encode_cursor_in_patch_is_idempotent 保证。

三、从源码看这个 .md 是如何被消费的

评测 CLI 读取样本的入口是 read_example_files,它按扩展名分派:

  • .json / .jsonl:直接反序列化为 Example 结构(ExampleExampleSpec 基础上平铺了 promptpredictionsscoreqa 等运行时字段,因此 JSON 形式的样本还能承载模型的预测结果与打分结果,形成"输入 + 输出 + 分数"一体的评测记录);
  • .md:走 parse_markdown_exampleExampleSpec::from_markdown,得到一个尚未运行的"纯规格"样本(predictionsscore 等字段为空);
  • 其他扩展名直接 panic 报错。

ExampleSpec 的完整字段定义(example_spec.rs)还包括 human_feedbacktelemetry(来自生产遥测的被拒预测来源信息)、rating 等,说明这套 Markdown 格式不仅是本地手写样本的格式,也是从真实编辑会话中导出、再回流评测的通用载体——to_markdown / from_markdown 构成可往返的序列化对。

from_markdown 使用 pulldown_cmark 事件流解析:H2 标题切换当前 section,fenced code 块按当前 section 归属;标题层级受严格约束(H4 以下直接报错),缩进代码块同样报错,保证样本文件只能是受控格式。

四、这个样本考察的预测能力

把三部分合起来,样本对模型提出的任务是:

  1. 从多文件编辑历史中抽象意图:历史里 4 个文件都在做同一件事——为 onDidTriggerSystemContextMenu 事件逐层"接口声明 → 实现类 → 服务接口 → 服务实现"地补全成员;
  2. 识别遗漏点:测试文件中的匿名 ICodeWindow 实现类是这次接口扩展的唯一漏改点;
  3. 在光标锚定的精确位置生成类型签名完全一致的插入行(Event<{ x: number; y: number }> 泛型参数必须与接口声明一致,且默认值为 Event.None,与该测试文件中其他事件成员的写法保持一致)。

这类"接口新增成员后同步补全所有实现"的场景是编辑预测高价值用例之一,仓库中同目录的 vscode--add-async-and-await.mdvscode--add-class-decorator.mdvscode--log-object-property.md 等样本考察了类似的多步续写能力,可对照阅读。

五、复现与运行要点

  • 样本解析与预测的关联通过 repository_url + revision 完成:评测工具按 RepoName::worktree_path 在统一 worktree 目录下检出对应仓库版本,保证 Edit History 中 diff 的上下文路径与 Cursor Position 中的路径在快照内真实存在;
  • 书写新样本时,最小合法结构即"front matter + Edit History(可为空,写作 (No edit history) 语义)+ Cursor Position(必须有路径 fence 与 [CURSOR_POSITION] 标记)+ Expected Patch",其余部分按 ExampleSpec 字段 按需添加;
  • 解析失败点集中在三处:缺少 Cursor Position 代码块、标记行缺少 ^<cursor_excerptcursor position marker line must contain '^' or '<' before [CURSOR_POSITION])、以及不合法的标题层级或缩进代码块,编写样本时可据此自测格式。

这套样本格式的设计取向值得借鉴:用纯文本 Markdown 承载"上下文快照 + 光标 + 期望编辑"三元组,既可人工评审、可 diff 协作,又能被 from_markdown 严格解析回结构化规格,使编辑预测的评测数据与代码库一起版本化管理。

登录后查看全文
热门项目推荐
相关项目推荐