news 2026/9/7 3:31:40

Zed 编辑预测评测样例解析:以 tree-sitter 的 if-let 改 match 重构为例理解 Zeta 评测格式

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Zed 编辑预测评测样例解析:以 tree-sitter 的 if-let 改 match 重构为例理解 Zeta 评测格式

Zed 编辑预测评测样例解析:以 tree-sitter 的 if-let 改 match 重构为例理解 Zeta 评测格式

【免费下载链接】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 仓库中的编辑预测(edit prediction / Zeta)评测样例 tree-sitter--if-let-to-match.md 展开。你将看到这条"把 Rust 的if let重写为match"的真实重构是如何被拆解为编辑历史、光标摘录与多个可接受补丁的,以及ep评测 CLI 如何解析、重放并给模型输出打分——读完后你可以独立读懂并书写 Zed 编辑预测的 Markdown 评测样例,并将其纳入评测流水线运行。

一、这个文件在 Zed 评测体系中是什么

crates/edit_prediction_cli/evals/目录存放的是编辑预测模型的手写评测样例(eval examples),当前目录中共有 19 个.md样例,覆盖 tree-sitter、zed、flask、vscode 等多个上游仓库的典型编辑场景。文件名约定为<仓库>--<任务>.md,本文件即"在 tree-sitter 仓库上完成 if-let to match 重构"这一评测项。

这些 Markdown 文件不是给人读的技术文档,而是可直接被 CLI 消费的评测输入。在 Cargo.toml 中,edit_prediction_clicrate 声明了二进制ep[[bin]] name = "ep"),其入口 main.rs 定义了全局参数与子命令;当输入是.md文件时,读取链路如下:

  • read_example_files()(example.rs)按扩展名分派:json/jsonl/md,其中mdparse_markdown_example()
  • parse_markdown_example()调用ExampleSpec::from_markdown()(example_spec.rs),用 pulldown_cmark 遍历 Markdown 事件流,按二级标题切分章节;
  • 识别的章节标题常量与本文档完全对应:Edit HistoryEDIT_HISTORY_HEADING)、Cursor PositionCURSOR_POSITION_HEADING)、Expected PatchEXPECTED_PATCH_HEADING),另支持Uncommitted DiffRecently Opened FilesRejected Patch等可选章节(见 example_spec.rs 的常量定义);
  • Expected Patch下的每个```diff代码块都会追加为expected_patches中的一项——这正是本样例能给出三种可接受补丁的机制来源。

二、Front Matter:用 repository_url + revision 钉死外部仓库状态

文件开头是一个 TOML 前置块:

+++ repository_url = "git@github.com:tree-sitter/tree-sitter" revision = "17e3c7a5c56527a179fa6e37ce7ee934493e5047" +++

ExampleSpec::from_markdown()会以+++为界剥离前置块,反序列化为FrontMatter结构(example_spec.rs):

字段本样例取值作用
repository_urlgit@github.com:tree-sitter/tree-sitter评测代码来自哪个外部仓库(SSH 或 HTTP 形式均可,Example::repo_name()两种都能解析)
revision17e3c7a5…精确到该仓库的某次提交,保证评测可复现
tags(可选)分类标签
uncommitted_diff_requires_edit_history_rollback(可选)控制 uncommitted diff 与编辑历史的回滚语义

评测运行时会依据这两个字段重建现场:load_project.rs 的setup_worktree()会把该仓库克隆到本地(或复用已有克隆并fetch指定 revision),再为样例创建一个独立的 git worktree 并checkout到钉死的 revision——这意味着本样例重放的是 tree-sitter 仓库在17e3c7a这个提交时的crates/loader/src/loader.rs,而非当前 Zed 仓库中的任何文件。

三、Edit History:重放"用户手动重构到一半"的现场

## Edit History章节是一个 unified diff,描述模型被调用之前用户在编辑器里已完成的编辑。本样例的编辑历史包含两个 hunk,内容是:

// 原始形态(删除行) if let Ok(entries) = fs::read_dir(parser_container_dir) { for entry in entries { ... } } // 目标形态(新增行,重构进行到一半) match fs::read_dir(parser_container_dir) { Ok(entries) => { for entry in entries { ... } // Ok 分支已展开 // ← 此处尚未补充 Err 分支 }

即:用户在loader.rs里把if let Ok(entries) = fs::read_dir(...)逐行改写为match fs::read_dir(...) { Ok(entries) => { ... }Ok分支的语句体已经整体展开(可以看到内部find_language_configurations_at_path(...)调用的缩进也随 match 臂加深了一级),但Err分支还缺失——这正是等待模型续写的位置

这个历史会被真实"重放"进缓冲区:run_load_project()apply_edit_history()直接调用edit_prediction::udiff::apply_diff()(load_project.rs),把 diff 逐 hunk 应用到一个临时打开的 buffer 上;应用完成后,EditPredictionStore还会收集出本次会话的编辑事件序列(edit_history_for_project()),最终组装进Zeta2PromptInput作为模型的上下文事件流——也就是说,模型看到的不是静态 diff 文件,而是"用户刚刚做过的这些编辑"。

四、Cursor Position:光标摘录与^[CURSOR_POSITION]标记行

## Cursor Position章节的代码块语言标注为文件路径crates/loader/src/loader.rs(解析器会把它存入spec.cursor_path),块内是一段带光标标记的代码摘录:

if let Some(parser_dir_name) = entry.file_name().to_str() { if parser_dir_name.starts_with("tree-sitter-") { self.find_language_configurations_at_path( &parser_container_dir.join(parser_dir_name), false, ) .ok(); } // ^[CURSOR_POSITION] } } } } }

标记约定由 example_spec.rs 的cursor_excerpt()精确定义:

  • 标记行是紧随光标行之后的一行,包含字符串[CURSOR_POSITION]CURSOR_POSITION_MARKER);
  • 行内第一个^字符所在的,就是光标在"标记行上一行"中的列偏移;若光标列早于注释前缀长度,则退化为<[CURSOR_POSITION]形式,取该行第一个非空白字符位置;
  • 另有一种内联标记<|user_cursor|>INLINE_CURSOR_MARKER,见 udiff.rs),把光标直接嵌在文本中间,解析时直接按内联偏移计算。

在本样例中,^指向.ok();所在行的行尾(即整个Ok(entries) => { ... }块结束、}闭合match之前),精确刻画了"用户敲完 Ok 臂、光标悬在等待补 Err 臂"的瞬间。

解析后load_project::cursor_position()(load_project.rs)还要做一件关键校验:用纯摘录文本在 buffer 全文中做match_indices要求恰好匹配一次"More than one cursor position match found"会直接报错),然后把摘录偏移加上摘录内偏移,得到最终的Anchor光标锚点。这一"摘录必须唯一"的设计,保证了人工编写的 Cursor Position 摘录不能太短而撞车。

五、Expected Patch:一个样例,三种可接受答案

## Expected Patch下本样例给出了三个独立 diff 块,对应三种都算对的模型输出:

  1. + Err(error) => {}—— 用命名绑定error但空作用体丢弃;
  2. + Err(_) => {}—— 用_显式忽略;
  3. 多行未闭合形态:
+ Err(e) => { + + }
光标落在空作用体内部——模拟"用户刚开括号、准备往里敲东西"的中间编辑态。

三个补丁块中都出现了形如# ^[CURSOR_POSITION]的标记行,它标注的是补丁应用完之后光标应停在的位置^的列对应新增文本中的列,例如第三个变体里光标落在空行上,即新Err臂作用体的开头)。ExampleSpec::expected_patches_with_cursor_positions()(example_spec.rs)会对每个补丁调用 udiff.rs 的extract_cursor_from_patch()恢复出(干净补丁, 期望光标偏移)二元组:逐行解析 diff,把内联光标标记从+行中剔除、并按上下文/新增行的累计字节数换算出光标在新文本中的绝对偏移。从源码结构看,#开头的标记行不属于标准 diff 内容行,评测工具链(如同文件的strip_diff_metadata())会将其与index/diff --git等元数据一并剥离,只保留可用于应用与比对的 hunk 内容行。

"多个 expected patch"的意义在于:真实编辑预测的正确答案天然不唯一。if letmatchErr臂的写法因人而异,若评测只认一种拼法,会把大量行为正确的预测误判为失败。打分时 score.rs 的run_scoring()会把每个 expected patch 都经edit_prediction_metrics::prepare_expected_patches()预演(在光标摘录原文上试应用)后,逐条调用score_prediction()与模型的actual_patch比对,多个期望答案共同构成该样例的"及格线"。

六、跑这条样例:ep CLI 的最小工作流

结合 main.rs 的Command枚举,针对单条 Markdown 样例的典型流程为:

# 1. 读取并校验样例(输出规范化 JSONL) ep read crates/edit_prediction_cli/evals/tree-sitter--if-let-to-match.md -o out.jsonl # 2. 为样例建 git worktree、重放编辑历史、解析光标、生成 prompt_inputs ep load-project out.jsonl -o out.jsonl # 3. 调模型生成预测(provider 字符串见 main.rs 的 PredictionProvider::from_str) ep predict out.jsonl --provider=zeta2 # 4. 或直接一步到位:预测 + 对 actual/expected 补丁打分 ep eval out.jsonl --provider=zeta2

几个可复用的筛选与调参开关(均为EpArgs全局参数):

  • --name tree-sitter--if-let-to-match:按样例名子串过滤,只处理这一条;
  • --repo tree-sitter:按repository_url子串过滤;
  • --max-parallelism N(默认 10)、--limit N--offset N:控制并发与取样窗口;
  • --markdown-m):输出改为每样例一个.md文件(命名取自样例名),方便回看评测结果;
  • --failed=keep|skip|skip-no-files:失败样例在输出中的处理方式(失败样例无论如何都会落到 run 的failed/目录)。

predict阶段的 provider 字符串支持zeta2(默认)、zeta1teacher:<backend>teacher-jumps:<backend>等形态(解析逻辑见 main.rs,含sonnet45/sonnet46/gpt52/gpt54/gpt55等 teacher 后端别名)。

load-project这一步产出的prompt_inputs是评分的前置条件:run_load_project()在解析出光标后,会基于 buffer 快照计算光标摘录与语法范围(compute_cursor_excerpt/compute_syntax_ranges),连同EditPredictionStore中还原出的编辑事件,填入Zeta2PromptInput;score.rs 中明确提示prompt_inputs is required for scoring - run prediction first,即跳步运行eval/score会直接报错。

七、这条样例的设计意图小结

  • 单一仓库 + 钉死 revision:Front Matter 把评测锚定在 tree-sitter 的17e3c7a提交,编辑历史与光标摘录都出自该版本的crates/loader/src/loader.rsep通过 git worktree 机制现场重建,保证任何人任何时间跑出的输入状态一致;
  • 重构进行到一半的"半态":Edit History 刻意停在matchErr臂的位置,考察模型能否依据上下文(fs::read_dir返回Result<ReadDir, _>、既有Ok臂结构)补全惯用的错误分支,而非补全任何"看起来像"的语句;
  • 多可接受答案 + 期望光标:三个 expected patch 覆盖了Err(_)、命名绑定与未闭合臂三种形态,且每处都标注了补丁后光标落点,使打分不仅看"改得对不对",还能看"改完后光标在不在合理位置"(对应ActualCursoreditable_region_offset的评分输入,见 example.rs)。

八、关键文件索引

文件角色
crates/edit_prediction_cli/evals/tree-sitter--if-let-to-match.md本文剖析的评测样例本体
crates/edit_prediction/src/example_spec.rsMarkdown 样例的序列化/解析规范(from_markdowncursor_excerpt、期望补丁光标提取)
crates/zeta_prompt/src/udiff.rs光标标记常量与补丁光标解码(extract_cursor_from_patchstrip_diff_metadata
crates/edit_prediction_cli/src/example.rs样例读取(.md/.json/.jsonl)与Example数据模型
crates/edit_prediction_cli/src/load_project.rsworktree 重建、编辑历史重放、光标解析与 prompt 输入组装
crates/edit_prediction_cli/src/score.rs期望补丁预演与打分入口
crates/edit_prediction_cli/src/main.rsepCLI 参数、子命令与 provider 解析

适用前提:以上命令与格式均基于当前仓库的edit_prediction_cli实现;ep是仓库内二进制,需在工作区中通过 Cargo 构建运行,且涉及外部仓库克隆(依赖可访问的 git 远端)与模型 provider 的相应凭证/配置。

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

FPGA网络通信实战:从MAC到PHY,打通以太网数据通路

呼&#xff0c;终于写到网络通信这章了。从点灯、按键、串口一路走过来&#xff0c;到这一章&#xff0c;前面学的时序概念、状态机、FIFO、异步处理&#xff0c;全都得拿出来用一遍。很多朋友到这一步会慌&#xff1a;网络通信听起来太系统级了&#xff0c;又是MAC又是PHY&…

作者头像 李华
网站建设 2026/9/7 3:30:48

AI应用开发工程实践:从Agent编排到模型部署的落地指南

做AI应用开发最怕的一件事&#xff0c;不是模型效果不够好&#xff0c;而是demo跑通之后不知道该往哪个方向用力。最近很多项目都顶着AI的名头&#xff0c;实际卡住的点都在Agent编排、模型部署、测试回归和批量任务这些工程环节。我打算把日常会反复用到的AI工程实践整理成一套…

作者头像 李华
网站建设 2026/9/7 3:30:17

GitHub热榜实战:从数据导出到开源项目高效筛选

8 月 31 日这天&#xff0c;GitHub 热榜上的涨星趋势和平时不太一样。排在前面的&#xff0c;不是又一个全新的深度学习框架&#xff0c;而是一批看起来普通、实际上能解决具体问题的项目。最受关注的&#xff0c;是把 QQ 空间内容导出到本地的 gaoshu705/qzonearchive。在它周…

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

别让GitHub热榜变成收藏夹:五步筛选法识别优质开源项目

每天都有大量开发者打开 GitHub Trending&#xff0c;但真正能从热榜里挖到宝的人并不多。原因很简单&#xff1a;热榜只告诉你哪些项目正在被关注&#xff0c;却没告诉你它为什么值得被关注。如果你只是机械地给热门仓库点 Star&#xff0c;那 GitHub 对你就只是一个“收藏夹”…

作者头像 李华
网站建设 2026/9/7 3:29:47

Toad for Oracle替代方案:破解版风险与免费工具选型指南

简介&#xff1a;面向Oracle开发人员与数据库管理员的Toad简体中文破解版资源包&#xff0c;专为解决英文原版工具上手门槛高、商业授权费用昂贵等问题而整理。内置完整中文语言包、常用PL/SQL开发组件及辅助分析模块&#xff0c;可满足日常SQL编辑、数据库对象浏览、性能调优等…

作者头像 李华