首页
/ Ruff ty 生态系统报告汇总实战:summarise-ecosystem-results Agent 技能完整解析

Ruff ty 生态系统报告汇总实战:summarise-ecosystem-results Agent 技能完整解析

2026-09-05 21:00:55作者:咎竹峻Karen

本篇技术指南围绕 Ruff 仓库中的 Agent 技能 summarise-ecosystem-results 展开,讲解它如何把一个 Ruff PR 上 ty(Rust 编写的 Python 类型检查器)的生态系统测试报告,转化为可复现、可溯源、经过最小化验证的 PR 级变更摘要。读完本文,你将掌握该技能的证据冻结流程、报告模板契约、七步工作流、子代理并行执行协议,以及它与 minimizing-ty-ecosystem-changes 技能、collect_ty_ecosystem_run_metadata.py 等仓库脚本之间的协作关系。

一、背景:什么是 ty 的生态系统测试结果

Ruff 仓库的持续集成会为每个 PR 运行一套「生态系统检查」:用 ty-ecosystem-report.yamlty-ecosystem-analyzer.yaml 两条工作流,把 PR 版本与 merge base 版本的 ty 分别编译后,对 mypy-primer 托管的大批量真实 Python 项目做差分类型分析,产出结构化的变更清单(diff.json)与可部署的详细 HTML 报告,并把结果以 ecosystem-results 评论的形式回贴到 PR 上。

当一个 PR 触发了大量项目诊断变化时,人工阅读原始报告成本极高。summarise-ecosystem-results 技能就是为此设计的标准操作规程(SOP):它定义了一个 Agent(或遵循该 SOP 的人)如何从 PR 编号、PR 链接、GitHub 评论或详细 HTML 报告出发,冻结证据、复现每一条保留下来的行为变化、将其最小化到可溯源的最小复现例,最终产出一份符合严格模板契约的 PR_<number>_ECOSYSTEM_SUMMARY.md

该技能的完整文件结构如下(位于仓库 .agents/skills/summarise-ecosystem-results/):

主文件通过 frontmatter 声明了触发场景:当用户说 "summarise ecosystem results"、"summarize this ty ecosystem report"、"what changed in this ecosystem run?" 等,或要求汇总某个 PR 的 ty 生态系统结果时,应使用本技能。输入形式可以是 PR 编号、PR URL、GitHub 上的 ecosystem-results 评论,或直接提供的详细 HTML 报告。

二、五项执行优先级

SKILL.md 将全部工作约束为五条优先级,它们决定了整篇摘要报告的取舍与组织方式:

  1. 用 Actions 运行的精确环境复现每一条被保留的、源码可归因的行为:不是用本地最新版 ty,而是用该次 Actions 运行所使用的精确 Ruff 修订版本编译出的二进制;
  2. 为每个不同的源码可归因行为变化,产出「保持溯源链的最小复现例」:这个最小化必须通过完整的 advanced-minimization 工作流完成,而不是随手写一个看起来类似的例子;
  3. 消除所有第三方导入,除非已确认 ty 的行为依赖于该库的身份或第三方搜索路径分类;同样消除所有不必要的标准库导入。只有验证过「删除导入」和「内联其定义」两种操作都不能保住底层行为后,才允许保留某个导入;
  4. 报告以新增或实质变化的项目失败开头(包括间歇性严重失败),随后覆盖稳定的诊断变化与完全最小化的示例;
  5. 执行、审计与可追溯性的簿记内容不得出现在报告中:报告面向的是读者需要的分析结论,而非工作过程流水账。

这五条优先级共同划定了报告的边界:先讲「发生了什么新变化、有多严重」,再给出「经过验证的最小证据」,过程性细节一律剥离。

三、GitHub CLI 遥测约定

技能中有一条容易忽略但贯穿始终的工程约定:每一次直接或间接调用 gh 的命令都必须以 GH_TELEMETRY=false 前缀开头,例如:

GH_TELEMETRY=false uv run --script scripts/collect_ty_ecosystem_run_metadata.py ...

子代理也必须遵守同样的约定。原因在文档中说明得很直白:Codex 工具调用可能各自开启新的 shell,因此某次调用中的 export GH_TELEMETRY=false 对后续调用不生效,逐条命令加前缀是唯一可靠的做法。这条约定同时出现在姊妹技能 minimizing-ty-ecosystem-changes 中,是整个生态系统调查链路的公共纪律。

四、交付物:PR 摘要报告的模板契约

4.1 交付物形态

最终交付物是在仓库根目录创建的 PR_<number>_ECOSYSTEM_SUMMARY.md,其内容基于 assets/report-template.md 改编。文档对成品有三个硬性要求:

  • 必须是适合直接粘贴为 GitHub 评论的 GFM(GitHub-Flavored Markdown),每个段落与列表项只占一个源文件行
  • 使用模板的「结构与省略规则」作为报告契约:模板中写了「某情况下删除整个小节」的 HTML 注释,就是契约的一部分;
  • 删除所有占位符与 HTML 注释;引用外部源码位置时一律用永链(permalink),例如 project file.py:123绝不输出裸 URL

此外还有一个与 Codex App 集成的小约定:如果在一个 Codex App 线程中被要求做的唯一事情就是汇总生态系统报告,应把该线程重命名为 "PR ecosystem summary",便于事后检索。

4.2 模板的四个正文小节

report-template.md 定义了报告的骨架,各小节都有「无内容则整体省略」的省略规则,编号在每节内从 1 连续递增:

  1. ## Project failures —— 新增、修复或变化的稳定项目级失败。每个失败一个编号小节,列出受影响项目及其 merge base 与 PR 两侧的结果(merge base: <base outcome>; PR: <PR outcome>),并解释崩溃、panic、溢出、超时或异常退出,附相关 stderr;
  2. ## Intermittent severe failures —— 涉及间歇性结果的严重失败。与上一节不同,这里必须同时给出两侧的出现频次(count/runsnot present),且不得包含未变化的失败或仅频次波动
  3. ## Affected projects —— 稳定的诊断行为变化。每个不同的行为变化列出一组「Report entries」(<project> file.py:line 列表),解释 merge base 与 PR 两侧的精确行为,只有当同一解释和同一最小化复现例能覆盖全部条目时才能归组;
  4. ## Reproduction —— 溯源元数据清单,固定字段包括:详细报告链接、Actions 运行(run ID 与 attempt 号)、Ruff 两侧提交(merge base 到 PR revision)、ecosystem-analyzer 修订版本、mypy-primer 修订版本、依赖截止点(EXCLUDE_NEWER)、各项目的 Python 版本、各项目的 strict / non-strict 分析模式,以及「Comparison method」——即运行两个 ty 二进制的精确命令。对于 strict 项目,命令中必须包含 --config analysis.strict-equality-semantics=true--config analysis.strict-generic-narrowing=true 两个标志。

4.3 最小复现例的注释规范

模板对最小复现例(一个 Python 代码块)有一项关键的呈现规范,模板注释给出的示例格式是:

from typing import Final

# Merge base: `[error-code-1] "Some error message"`
# PR: no diagnostic
x: Final = 42

if x:
    # Merge base: `[error-code-2] "Some error message"`
    # PR: `[error-code-2] "Some other error message"`
    Y = 56

即:每一行出现新增、变化或被移除诊断的代码行,其上方必须紧邻注释,同时标注 merge base 与 PR 两侧的完整错误消息与错误码,重复诊断也要保留。这让读者不用运行任何环境就能看懂「改了什么」。

模板头部注释还明确禁止的内容:变更计数表、机器人更新时间戳、复现完整性簿记、导入审计细节、穷尽式可追溯性附录、裸 URL、工件哈希——这些都属于第五条优先级所说的「不得出现在报告中」的过程性信息。

4.4 报告策略(Reporting Policy)

SKILL.md 的 Reporting Policy 一节给出三条取舍规则,决定了哪些变化值得写进报告:

  • 聚焦相对 merge base 的新增或实质变化行为:评估对象是单条诊断与失败结果,而不是某个项目整体「flaky 或持久失败」的状态;
  • 省略:flaky 的诊断变化、未变化的失败、以及不改变观测结果的频次波动;
  • 必报:新增、修复或实质变化的 panic、崩溃、溢出与超时,涉及间歇性行为时附上 merge base 与 PR 两侧的频次。

五、七步工作流详解

技能的核心是一份七步工作流。下面逐步展开,并结合其引用的参考文档补充关键操作细节。

5.1 第一步:冻结证据(Freeze the evidence)

这一步的细节全部沉淀在 references/evidence-acquisition.md,其要点是:

  1. 先保存用户显式提供的报告 URL 或 ecosystem-results 评论,再去定位 PR。若用户只给了 PR,则查找其 ecosystem-results 评论与关联的详细报告。关键纪律是:永远不能用 PR 的「当前报告」替换用户提供的报告,也忽略后续对评论的编辑、PR 的更新与新的 workflow run;
  2. 创建一个唯一的快照目录(mktemp -d 生成 ty-ecosystem-report.XXXXXX),保存匹配的评论 JSON、Actions 运行的 run view(含 attempt、headSha、jobs 等字段,写入 run.json),并用 gh api --paginate 拉取该 run 的全部 artifact 清单:
set -euo pipefail

snapshot_dir="$(mktemp -d "${TMPDIR:-/tmp}/ty-ecosystem-report.XXXXXX")"
ecosystem_comment_id="<matching-comment-id-or-empty>"
if [[ -n "$ecosystem_comment_id" ]]; then
  GH_TELEMETRY=false gh api "repos/astral-sh/ruff/issues/comments/$ecosystem_comment_id" > "$snapshot_dir/comment.json"
fi
GH_TELEMETRY=false gh run view <actions-run> --repo astral-sh/ruff --attempt <actions-attempt> \
  --json attempt,headSha,jobs,startedAt,updatedAt,url > "$snapshot_dir/run.json"
GH_TELEMETRY=false gh api --paginate --slurp \
  "repos/astral-sh/ruff/actions/runs/<actions-run>/artifacts?per_page=100" |
  jq '{artifacts: [.[].artifacts[]]}' > "$snapshot_dir/artifacts.json"
  1. 验证工件归属gh run download 无法选择 attempt,且较新的 rerun 可能在 Ruff 修订不变的情况下替换旧 attempt 的工件,因此下载前必须验证 full-report 工件创建于所选 attempt 的报告生成 job 期间、每个 diagnostics 分片创建于其对应的成功 shard job 期间。判断依据是「有效 job graph」而非 attempt 起始时间——部分 rerun 合法地继承先前 attempt 的成功 job 与工件。下载时只按不可变 artifact ID 直接下载repos/astral-sh/ruff/actions/artifacts/$artifact_id/zip),永不按可变名称重新解析;
  2. 当所选部署的 HTML 报告可访问时,逐字节比对它与已下载工件中的 diff.html,一致后才信任相邻的 JSON;随后把所选 attempt 传给元数据脚本(见 5.3),并验证冻结 HTML 报告中的 Ruff base/PR 修订与生成的不可变 manifest 一致;
  3. 优先使用所选 attempt 中经过验证的 full-report/diff.json 作为权威的结构化变更清单,保留与其匹配的冻结 HTML 报告,评论仅在有可用时用于导航;JSON 不可用时回退到冻结 HTML 报告。

reference 还特别澄清了 diff.json 的溯源逻辑:该 JSON 内部不含 Ruff 修订、Actions run ID 或 attempt 号,它的可信性来自「经过验证的工件 + 逐字节一致的 HTML 报告」,而不是内容本身的巧合匹配。部署站点上详细 HTML 报告旁边也有一个同级 diff.json,但只有当它与所选 HTML 报告冻结自同一不可变部署、且该部署能唯一对应到所选 Actions run 与 attempt 时才可采信。

5.2 第二步:识别变化的结果(Identify changed outcomes)

检查结构化 diff,覆盖:新增、移除、修改的项目;稳定的诊断新增/移除/改写;项目失败;间歇性的退出状态变化。必须保留的信息维度包括诊断级别、重复出现次数、源码 permalink、项目的 strict 属性、panic 证据与观测到的运行频次。过滤规则与 4.4 的报告策略一致:剔除 flaky 诊断与纯频次噪声,但绝不能借此剔除 flaky 项目中的稳定诊断或变化的严重失败。HTML 报告用作可视化上下文,或在结构化 JSON 无法安全获取时作为主要证据。

reference 强调一点容易被忽视的方法论细节:应在 ecosystem-analyzer 的精确修订版本上查看 JSON schema 或 diff 生成代码,不要假设字段名与分类在不同修订间保持稳定;同时记录每个受影响项目的 strict / non-strict 分析模式,strict 项目的对比命令必须带上两个 strict 分析标志。

5.3 第三步:从零复现(Reproduce from scratch)

这一步要求:忽略保留的记忆与本地旧产物;加载姊妹技能 minimizing-ty-ecosystem-changes;只收集一次精确运行元数据;在解释或最小化之前,先复现每一条保留下来的、源码可归因的诊断或 panic。复现命令模板由姊妹技能给出(此处摘录其核心):

GH_TELEMETRY=false uv run --script scripts/collect_ty_ecosystem_run_metadata.py \
  <actions-run> <project-name>... \
  --attempt <actions-attempt> \
  --output target/ty-ecosystem-run.json

该脚本 scripts/collect_ty_ecosystem_run_metadata.py 产出的 manifest 包含:被分析的两侧 Ruff 修订、Actions 的 EXCLUDE_NEWER、ecosystem-analyzer 与 mypy-primer 修订、以及每个项目的 CI Python 版本;无法唯一确定某个值时必须停下,不得用评论时间戳或本地默认值替代。项目本身则用 scripts/setup_primer_project.py 按报告 permalink 中的项目修订与依赖截止点检出到独立临时目录,并绕过脚本旁锁文件的干扰。两侧二进制(merge base 与 PR 的 profiling 版 ty)分别运行后,须精确核对报告中的差异,包括重复诊断与两侧退出状态;间歇性严重失败要按报告中的运行次数重复执行两侧,panic 的稳定指纹以 Rust panic 位置/决定性因果帧与 payload 为准,忽略受检 Python 路径与偶发 backtrace 差异。对无法恢复源码的结果,则依据已捕获的状态、stderr、panic 证据与运行频次来验证。

5.4 第四步:带溯源地完成最小化(Minimize to completion with provenance)

这一步是整个技能要求最严苛的部分,规则可以归纳为四句:

  • 每个不同的源码可归因行为变化,都要按完整的 advanced-minimization 工作流执行到「穷尽式检查不再产生任何进一步缩减」为止(参考 advanced-minimization.md);
  • 复现例必须从被引用的生态系统条目出发,经过一条「已验证的缩减链」推导而来;绝不允许用一个独立构思的、行为表面相似的例子替换原条目;
  • 接受复现例之前,必须尝试删除每一个导入、内联每一个第三方定义、内联相关的标准库定义;第三方导入只有在「ty 的行为依赖于该库身份或第三方搜索路径分类,且删除导入与内联定义都无法保住底层行为」时才能保留;
  • 若真正的外部阻碍导致无法完成,必须向用户报告该阻碍并明确标记任务为未完成——不得悄悄用未最小化的摘录替代,也不得把部分最小化的报告当作成品提交。

5.5 第五步:按成因归组(Group by cause)

只有当「相同的 base-to-PR 行为、相同的底层触发、相同的解释、相同的复现例」能覆盖全部条目时,条目才可归为一组。文档特意警告:诊断文本相同或展示的 @Todo 类型相同,都不构成等价性证明。这与 subagent-handoff.md 末尾的规则呼应:后续条目若与已最小化的条目行为变化与成因完全一致,子代理可以将其归类为重复而免于重复最小化,但必须解释匹配依据。

5.6 第六步:查找已有的 ty issue

当某个诊断变化暴露了 ty 的既有不足时,应在 astral-sh/ty 的 issue tracker 中搜索覆盖该精确底层行为的 issue,并在报告相应小节中直接链接(模板中对应 **Existing ty issues:** ty#<issue-number> 段落,仅当确实找到匹配 issue 时才包含)。一个明确的辨析要求:不要把错误或不完整的第三方类型标注误判为 ty 的不足

5.7 第七步:撰写与验证(Write and verify)

填充模板后,须逐项自检:

  • 每个源码可归因的行为变化是否都配有完全最小化、保持溯源的复现例;
  • 核对每个变更编号、链接、诊断、保留的导入、复现例的源码出处、以及(需要时)因果指纹;
  • 每个保留的第三方导入是否都确实依赖「库身份或第三方搜索路径分类」;是否还有可避免的标准库导入;
  • 任何源码可归因小节中是否不含未最小化的摘录;

最后运行仓库的 Markdown 质量检查(prek 钩子,仅 dev 依赖组且锁定依赖):

GH_TELEMETRY=false uv run --only-group dev --locked prek run --files PR_<number>_ECOSYSTEM_SUMMARY.md

只有这些检查全部通过后,才把 Markdown 文件作为成品呈现。

六、并行执行与子代理交接协议

SKILL.md 的 Parallel execution 一节明确:当报告涉及多个受影响项目或可独立调查的条目时,本技能显式要求使用子代理。执行约束如下:

  • 精确运行元数据、两个 profiling 二进制与共享配置就绪后,在可用并发预算内、且保留一个主代理槽位的前提下,尽量多地派生子代理;子代理完成后用新任务立即补满空出的槽位;
  • 分配给每个子代理的项目集合或报告条目必须互不相交;表面相似性只能用于调度参考,不能推定因果等价;
  • 主代理独占四样东西:冻结的证据、共享的 profiling 二进制、共享配置、协调权与最终报告;
  • 若存在多个独立分配却未派生任何子代理,必须记录具体原因

详细的交接协议在 references/subagent-handoff.md 中,其核心机制可以概括为「不可变共享输入 + 主代理独家构建权 + 明确的分发清单」:

主代理职责。 冻结精确报告、run 与 attempt;为所有保留条目只运行一次 scripts/collect_ty_ecosystem_run_metadata.py;在派活前构建并复制两个精确修订的 profiling 二进制。随后发布四个不可变绝对路径:TY_ECOSYSTEM_RUN_METADATA(manifest)、TY_ECOSYSTEM_BASE_BINARYTY_ECOSYSTEM_PR_BINARY,以及把 PR 的生态系统配置(仓库中的 .github/ty-ecosystem.toml)一次性安装到 $TY_ECOSYSTEM_CONFIG_HOME/ty/ty.toml 后发布的 TY_ECOSYSTEM_CONFIG_HOME。快照、可选的结构化 JSON、二进制、manifest、配置副本与已安装配置一律视为只读共享输入

调试二进制的独家构建权。 若某个子代理需要精确修订的 debug 二进制来澄清模糊的内部类型,只有主代理可以构建:暂停所有 worker 并等待确认、验证共享 checkout 干净、记住原 ref、构建并复制后必须恢复原 ref(构建失败也要恢复),只有成功构建并恢复后才发布二进制路径。profiling 二进制始终是「行为神谕」(behavioral oracle)。

分发清单。 每个子代理的任务书必须包含:PR 与详细报告链接(及 ecosystem 评论链接);冻结 HTML 报告、可选结构化 JSON、可用分片的路径与所选 run/attempt(要求用已捕获输入而不再次抓取实时证据);精确分配的条目(区分「源码可归因」与「无可恢复源码」两类,间歇性严重失败附两侧运行次数);四个不可变路径;GH_TELEMETRY=false 前缀纪律;源码可归因任务须按 advanced-minimization 全流程产出完全最小化、保持溯源的复现例;查看 vendored 定义与 Rust 实现必须用 git -C <ruff-checkout> show <exact-revision>:<repository-relative-path>(依据 manifest 中的精确修订,而非恢复后的工作树);独立构思的类似物不满足任务、部分最小化的示例不算完成、遇外部阻碍须返回并标记未完成;无源码证据的结果只需验证已捕获的状态/stderr/panic 证据/频次;需要 debug 二进制时向主代理申请而不是自行构建或切换共享 ref;主代理请求暂停时停止所有 checkout 相关工作与子进程、确认后方可继续。

子代理禁行事项。 不得重新生成共享 manifest、不得重建共享 profiling 二进制、不得切换共享 Ruff ref、不得改写共享配置、不得覆盖其他代理的工作文件、不得信任此前的本地复现、不得用当前依赖元数据替代冻结版本。

要求返回的内容。 源码可归因任务返回:报告就绪的 GFM(精确描述 base 对 PR 行为与最小化代码),外加独立的工作笔记(原源码 permalink、复现步骤、被接受的缩减步骤、两侧二进制结果、间歇性失败的两侧运行次数、必要的因果指纹、导入审计)。无源码证据任务返回:报告就绪的 GFM(验证过的项目结果、相关 stderr、panic 证据、运行频次)。

七、与仓库脚本和姊妹技能的协作关系

从源码结构看,该技能并不是孤立存在的文档,而是围绕一组真实脚本与技能构成的调查流水线:

  1. 上游数据生产.github/workflows/ty-ecosystem-report.yaml 负责在每个 PR 上运行生态系统对比并部署详细报告、回贴 ecosystem-results 评论;.github/workflows/ty-ecosystem-analyzer.yaml 则维护 ecosystem-analyzer 自身的更新。本技能消费的全部证据都来自这条上游;
  2. 元数据采集scripts/collect_ty_ecosystem_run_metadata.py 读取 Actions run 的 job 元数据,生成包含两侧 Ruff 修订、EXCLUDE_NEWER、ecosystem-analyzer 与 mypy-primer 修订、各项目 CI Python 版本的不可变 manifest。姊妹技能说明中还指出,当前工作流把编译拆分为 Build ty (base)Build ty (pr) 两个 job,脚本从记录两侧修订的 base job 读取数据,同时兼容历史单次 Build ty job 的运行;
  3. 项目检出scripts/setup_primer_project.py 按指定修订与 --exclude-newer 把 mypy-primer 项目检出到临时目录,并打印项目专属的分析命令;
  4. 共享分析配置.github/ty-ecosystem.toml 是 CI 使用的用户级 ty 配置,技能要求把它以用户级配置形式安装($XDG_CONFIG_HOME/ty/ty.toml),使本地复现与 CI 行为一致,且不替代项目自身的配置发现;
  5. 最小化引擎minimizing-ty-ecosystem-changes/SKILL.md 提供本技能第三、四步依赖的全部操作细节——构建精确修订的 profiling 二进制(注意 PR revision 需显式 fetch,因为 pull-request 运行通常使用普通 clone 得不到的合成 GitHub merge commit)、复现命令模板(含 strict 项目追加 --config analysis.strict-equality-semantics=true --config analysis.strict-generic-narrowing=true 的完整 shell 片段)、以及五不变量:使用精确修订与环境、先复现后解释、复制的二进制与配置只读且每次缩减都对照两侧二进制验证、每个候选必须从上一候选推导、保留底层触发而非仅仅诊断规则或展示类型。

此外,仓库中还存在一个更朴素的生态检查脚本 scripts/ecosystem_all_check.py(自述为「less elaborate, more hacky ecosystem checker」,用于批量检查约 2.1k 个包的 checkout 中的 panic 与修复错误),它展示了生态检查的轻量形态;而本技能所描述的完整流程,则是生产级 CI 中差分分析、证据冻结与最小化的标准闭环。

八、要点总结

summarise-ecosystem-results 技能的价值不在任何单条命令,而在于它把「PR 上数百个项目诊断变化 → 一份可信摘要」这一过程压缩成了可审计的契约:

  • 证据先行:用户提供的报告优先于 PR 当前状态,工件按不可变 ID 验证归属后下载,diff.json 以「验证过的工件 + 逐字节一致的 HTML」作为溯源,任何无法唯一确定 run/attempt 的情况都要求如实报告不确定性而非猜测;
  • 复现先于解释:所有保留的源码可归因变化必须先复现,再最小化,且最小化以「穷尽式检查不再缩减」为完成标准,外部阻碍必须显式上报;
  • 溯源是硬约束:复现例必须由缩减链推导自被引用的报告条目,导入保留必须逐条通过「删除/内联都失效」的审计;
  • 报告契约严格:模板的四小节结构、注释规范、元数据字段与「过程簿记不入报告」的禁令共同保证产出的 PR_<number>_ECOSYSTEM_SUMMARY.md 可直接作为 PR 评论使用;
  • 可并行、可交接:通过四个不可变路径、主代理独家构建权与详细任务书清单,使多子代理并行调查共享同一冻结证据而互不干扰。

对 Ruff 维护者而言,这套规程把 ty 类型检查器演进中最敏感的「行为回归」问题,转化为一份编号清晰、逐条可验证、链接直达源码永链的变更摘要;对研究 Agent 工作流设计的读者而言,它同样是一份值得参考的「多代理证据冻结与交接」范本。

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