一个 PR 花两天才合并,问题可能是没人点开,也可能是修改来回拉扯,或批准后一直搁置。只看总时长会把三种病混成一个数。GitHub 新增的分段指标,让团队能用中位数和 P90 判断该加审查人、缩小 PR,还是改自动合并规则。
这次API增加了什么
GitHub 9 月 25 日宣布,企业和组织的仓库级 Copilot 使用报告新增 pull_request_review_times 数组。每个条目把 PR 生命周期拆成三段:从 ready for review 到第一次审查、第一次到最后一次审查、最后一次审查到合并;每段都提供中位数和第 90 百分位(P90),单位为分钟。
口径非常关键。当前只统计由人创建、且至少被另一名人类审查后合并的 PR;Copilot、其他机器人和作者自己的审查不计入。数据按合并日归属,9 月 21 日之前进入 ready 状态的 PR 不纳入该分段,而且没有历史回填。安静的一天返回空数组 [],不是零。

为什么一定要同时看P50和P90
中位数 P50 代表典型 PR,P90 代表最慢的那一成。若 P50 很短、P90 很长,说明大多数流程没问题,但某些仓库、时区或高风险改动缺少兜底;若两者都长,才更像系统性产能不足。
我的核心判断是:这些指标是排队系统的症状,不是开发者绩效分。拿 P90 给个人排名,会鼓励快速点“批准”、拆成没有意义的小 PR,甚至绕过审查。正确用法是按仓库和变更类型找瓶颈,再验证干预是否降低尾部等待。
最小实践:下载并读取日报
官方接口先返回短时有效的 NDJSON 下载链接,再从报告行里读取数组。下面脚本使用当前文档要求的 2026-03-10 API 版本,密钥只从环境变量读取。
async function main() {
const token = process.env.GITHUB_TOKEN;
const org = process.env.GITHUB_ORG;
const day = process.argv[2] ?? "2026-09-26";
if (!token || !org) throw new Error("缺少GITHUB_TOKEN或GITHUB_ORG");
const headers = {
Accept: "application/vnd.github+json",
Authorization: `Bearer ${token}`,
"X-GitHub-Api-Version": "2026-03-10",
};
const metaUrl = `https://api.github.com/orgs/${org}/copilot/metrics/` +
`reports/organization-1-day?day=${day}`;
const meta = await fetch(metaUrl, { headers });
if (!meta.ok) throw new Error(`GitHub API ${meta.status}`);
const { download_links: links = [] } = await meta.json();
for (const link of links) {
const text = await (await fetch(link)).text();
for (const line of text.trim().split("\n").filter(Boolean)) {
const row = JSON.parse(line);
for (const item of row.pull_request_review_times ?? []) {
console.log(JSON.stringify({
repo: row.repository_name, merged: item.total_merged,
firstReviewP90: item.p90_minutes_ready_to_first_review,
reworkP90: item.p90_minutes_first_to_final_review,
mergeP90: item.p90_minutes_final_review_to_merge,
}));
}
}
}
}
main().catch((error) => { console.error(error); process.exitCode = 1; });
运行环境需 Node.js 18 以上:GITHUB_TOKEN=... GITHUB_ORG=... node pr-metrics.mjs 2026-09-26。令牌需要组织 Copilot metrics 只读权限,且组织必须启用相应策略。本次无目标组织权限和真实令牌,示例未在本次任务中实际运行;已使用 Node.js 26.7 做静态语法检查。
三种指标对应三种动作
首次审查慢:设置代码所有者和轮值审查人,给高风险目录明确响应时限,而不是群里反复催人。
首次到最终审查慢:查看 PR 尺寸、测试反馈速度和需求是否频繁变化。一个 3000 行 PR 的问题通常不是审查人不努力,而是交付单元太大。
最终审查到合并慢:检查分支保护、部署窗口、必需检查和自动合并。批准后等待很长,往往是机器或权限流程而非代码讨论。
汇总时别把百分位再平均
API 按仓库和作者、审查者类型给出聚合值。把多个仓库的 P90 简单取平均,得不到整个组织的 P90:小仓库的一条慢 PR 会获得与大仓库数百条 PR 相同的权重。若拿不到原始时长,至少按 total_merged 做加权展示,并明确它仍是近似值;更稳妥的是保留仓库维度,分别观察趋势。
还应把“速度”和“质量”并排。审查变快但回滚率、线上缺陷或二次修复上升,不是有效改进。可以为每个仓库同时记录变更失败率、紧急回滚、PR 大小和必需检查耗时。这样才能分辨是审查人响应慢,还是 CI 队列把人类等待伪装成协作问题。
一个可执行的四周实验是:第一周只采集基线;第二周为高 P90 目录设置主备审查人;第三周开启批准后的自动合并;第四周比较三段指标、样本数和失败率。不要同时改十项规则,否则即使数值下降,也无法知道哪项措施有效。
对跨时区团队,分钟数还要结合工作时间解释。周五晚提交、周一审查在日历上很慢,却未必违反团队约定。若产品不提供工作时段口径,可以在自建分析中为每个团队计算“营业分钟”,但要公开时区和节假日规则,避免用不透明修正制造漂亮数字。
风险与适用边界
数据刚开始积累且没有回填,早期样本很薄;单次审查的 PR,“首次到最终”会是 0;total_merged 通常低于仓库全部合并数。小团队每日只有一两个 PR 时,按天的 P90 会剧烈跳动,至少应看四周滚动窗口,并同时保留样本数。
这套指标适合诊断人类参与的审查流程,不适合衡量纯机器人 PR、未合并 PR 的积压,也不能直接证明 Copilot 提升了研发效率。建议先记录四周基线,再一次只改变一项流程,观察三段中哪一段真的下降。
仪表盘之外还要保留定性复盘。每月抽查几条极慢与极快的 PR,问清等待原因、是否有人绕过流程、合并后是否返工。数字负责指出异常,工程师负责解释因果;两者缺一,优化就容易变成追逐指标。
你们团队最慢的一段通常是等第一次审查、反复修改,还是批准后没人合并?
关注「蜗牛聊AI」,一起看懂技术变化背后的真正机会。
本文首发于 java4u.cn,转载请注明出处。

