CodeRabbit:PR 标着“待审核”,下一步却在等作者
AI 编程工具和智能体让生成代码、创建拉取请求(PR)的速度变得更快。随着这些请求不断累积,团队必须决定哪些变更需要优先处理。这首先要理解每个 PR 下一步需要什么,以及谁能推动它前进。
这就是我们着手解决 CodeRabbit Triage 时所面对的问题。我们从整理队列开始,但很快意识到,只有当我们能清楚地看到每个 PR 处于什么状态时,整理才有意义。
一个排序列表无法告诉你的
收件箱式的概念是整理 PR 队列的自然起点。有些工具会把开放的 PR 分成若干区块,让审核人员在一个地方看到需要自己关注的工作。
我们也从类似的方法开始,但我们的筛选器有时会把已经批准某 PR 的人标记为“需要审核”。我们还会把已批准但存在合并冲突的 PR 显示为“需要再次审核”,尽管下一步其实是作者去 rebase。
这些 PR 确实匹配我们写的筛选条件。问题在于标签告诉审核人员要做什么:有人打开一个 PR 以为要审核,结果发现下一步动作属于作者。
这类反复出现的错误会让审核人员有理由怀疑整个队列。在决定是否行动之前,先打开每个 PR 检查状态,这种额外工作削弱了收件箱式界面的价值。
我们需要先确定每个 PR 下一步需要什么、谁对此负责,然后再决定它在队列中的位置。
决定一个 PR 下一步需要什么
要做到这一点,我们首先必须理清系统中每个部分负责判断什么。早期设计把分类、生命周期阶段、优先级、健康状态、准备度、下一步动作和所有权当作不同概念,但它们的职责有时会发生重叠。
这些重叠在实现过程中变得更加清晰。一个 PR 可以拥有很高的优先级,但暂时没有人能对它采取行动。界面必须同时解释它的优先级和它被什么卡住。
我们把工作流分类与对比排序分开,因为它们服务于不同的目的。
工作流分类决定 PR 下一步需要什么。显式规则评估现有证据,确定工作流状态、下一步步骤、负责角色,以及某个动作或审核是否已逾期。这些判断不借助 AI 模型完成。
对比排序决定关注顺序。一旦工作流状态确定,排序帮助决定先看哪些 PR,以及审核的深度。它不能改变 PR 的工作流状态。
分类器按顺序检查以下规则,并选择第一个匹配项:
关于 PR 是否应该继续推进的人工判断,优先于机械式修复,这就是为什么 needs_decision 排在 blocked 前面。如果一个 PR 与已经合并的某个工作重复,团队应该先决定是否保留它,再花时间解决冲突。请求修改(requested changes)也排在检测到的冲突之前,因为审核反馈提供了更具体的下一步。
即使分类器根据第一条匹配规则选择工作流状态,它也会记录所有适用的原因。然后它会确定一个下一步动作和一个负责角色。这些确定之后,排序决定 PR 在队列中的位置。
为什么“Other”仍然存在
即使有了这些规则,一些 PR 仍然需要一个兜底分类。在我们的场景中,Other 经常被误认为是低优先级分数。它是系统在当前证据不足以支持更具体的交接时使用的一个审核工作流标签。
当 Triage 无法从最新可审核提交的审核记录中推导出动作标签时,它会回退到 PR 的工作流状态:
- needs_review 在未记录该提交的已完成 CodeRabbit 审核时变为 Not reviewed by CodeRabbit;否则变为 Awaiting your review
- needs_update、blocked 和 needs_decision 变为 Waiting on author
- 所有其余状态,包括 monitor 和 close_candidate,都变为 Other
Other 还覆盖了没有任何动作标签能准确描述下一步的情况。等待检查(pending checks)就是一个例子。一个 PR 可能在等待检查完成后再合并,在检查运行期间不需要作者采取任何行动。
保留 Other 能让这些限制变得可见。更具体的标签需要支持证据;否则,我们有可能让审核人员或作者回去处理那些其实不需要他们行动的工作——这正是人们在 PR 收件箱式概念中会遇到的问题。
优先级如何计算
Triage 中的每个 PR 都会获得一个从 P0 到 P3 的优先级。我们使用确定性规则,根据关于 PR 的可验证证据计算它,因此同样的输入总是产生同样的结果。
计算使用三个信号。
- Severity —— 当前已通过验证的审核发现有多严重
- Urgency —— 关联的 Linear 或 Jira 工单有多紧急
- Impact —— 有多少其他开放的 PR 被阻塞,正在等待这个 PR
每个信号都被归一化为 0 到 1 之间的值,缺失的信号贡献为 0。我们组合它们的方式是:一个强信号可以单独产生高优先级,多个中等信号相互增强,而增加正面证据永远不会降低分数。
我们调节计算背后的曲线和权重。得到的分数映射到下面显示的四个优先级级别。
优先级帮助审核人员决定先看哪个 PR。工作流状态告诉他们接下来需要发生什么。例如,一个 P1 的 PR 可能修复了一个紧急问题,但仍然需要作者解决合并冲突或修复失败的检查。这些阻塞因素会出现在它的工作流状态中,并与优先级分数分开处理。
缺失证据需要特别小心,因为一个未经审核的 PR 可能会得到 P3。
那些没人看过的 PR
每个优先级模型都必须决定,如何处理一个没有审核发现、没有关联工单、也没有其他 PR 依赖它的 PR。我们把每个缺失信号都当作 0,于是得到这样的结果。
计算很简单,但结果很容易被误读。审核人员看到 P3,可能会认为这个 PR 优先级低,并据此认为已经有人检查过它,觉得没什么好担心的。
这会造成一个问题。一个有中等影响证据的 PR,排名可能高于一个完全没人评估过的 PR。未审核的 PR 因为证据缺失而得到更低的分数。
一个诱人的解决方案是凭空造一个数字。我们选择让分数继续与可用证据绑定。
- P3 反映的是可用的优先级证据——它意味着评分信号尚未建立起一个提升的近期优先级。一个 P3 的 PR 仍然可能有价值,并且需要仔细审核。
- 证据会过期——审核发现与它们被评估所针对的 PR 版本绑定。当新的提交到达时,过期的严重性贡献会被移除,直到有当前证据可用。
- 审核状态会与优先级同时显示——是否有人审核过该 PR、谁批准了它、它是否在等作者、检查是否通过或是否存在合并冲突,都记录在单独字段中。审核人员可以同时看到它的优先级和下一步需要发生什么。
对分数的每一份贡献,都可以追溯到审核人员可以检查的证据。
模型
CodeRabbit Triage 使用一个仓库级模型来比较 PR。它考虑相对于剩余工作的价值、时间敏感性、信息价值、返工风险、依赖顺序,以及每个变更需要的人工判断量。
两个 PR 可能有相似的检查和活动量,但其中一个能解锁发布,或验证了多个其他变更所依赖的某个假设。模型在排序时会考虑这些差异。
模型返回一个仓库本地排名、一个建议性的紧急程度评估、推荐的审核深度、一段简短解释,以及 PR 之间的关系。该评估不会取代由确定性规则计算出的 P0–P3 优先级。相反,模型可能贡献一个有界的注意力调整,该调整在 24 小时后过期,并输入下一轮确定性评分。
确定性代码产生显示的优先级,并控制工作流状态、下一步动作、准备度、资格、权限,以及任何会修改 PR 或发送通知的动作。
这种分离让模型可以调整 PR 的顺序,同时保留识别“谁下一步行动”的路由。它的调整作为单独的注意力信号存储,24 小时后过期,并可以输入下一轮确定性评分。
每个人都会看到个性化的队列,以及针对其角色定制的下一步动作。一个单独的注意力分数决定 PR 在该用户队列中的位置,使用以下信号:
- 谁拥有下一步动作
- 一次交接已经等待了多久
- 近期活动
- 等待压力
- 参与度
- 影响
- 审核工作量
仓库排名和模型输出不参与这个计算。一个 PR 在个人队列中的位置上升,取决于该用户对它的责任和行动压力。
这种责任延伸到采取行动。Triage 可以推荐审核人员,并解释为什么选择他们。请求审核、在 Slack 中提醒某人,或改变关联平台中 PR 的状态,都需要明确的人工操作。
界面
状态模型确定后,我们围绕分组、子分组、筛选、显示属性和已保存视图来设计界面。这些控件让用户可以根据需要回答的问题来组织队列。
第一个轴:分组
Triage 给审核人员一种聚焦的方式来排列优先级并处理队列。
- Workflow —— 查看哪些 PR 正在等待审核、需要作者跟进,或可以合并
- Author —— 查看谁的 PR 在等待,是什么拖住了它们
- Repository —— 查看跨仓库的哪些工作需要关注
第二个轴:子分组
子分组在每个组内增加了一层额外细节。先按 Priority 分组,再按 Review workflow 子分组,P1 组就会被拆分为等待人工审核、等待 CodeRabbit 审核、需要作者操作,或可以合并。
这为你提供了一个实用的早晨起点。你可以拿起分配给你的高优先级审核,看看哪些 PR 需要作者关注,并检查哪些可以合并。
想换一种视角,可以按 Review workflow 分组,再按 Review guidance 子分组。筛选出 Awaiting human review,你就可以把建议快速审核的 PR 与可能需要更多不被打断时间的 PR 分开。
这些视图依赖于每个 PR 的一致信息。一个标记为 P1 且等待人工审核的 PR,无论出现在哪里,都应该显示相同的优先级和状态。改变分组会改变你查看信息的方式;PR 的底层状态保持不变。
分组负责整理,筛选负责缩小范围
我们在这个项目开始时让筛选同时承担两项工作,但很快发现这很难管理。筛选决定哪些 PR 留在视图中。分组整理这些 PR,让审核人员看到哪些需要他们关注。
例如,你可以先筛选到一个仓库,然后按工作流对其 PR 分组,查看哪些正在等待审核,哪些需要作者操作。
用视图记住你的配置
配置好 Triage 看板或列表后,把它保存为视图。视图会保留筛选、分组、布局和排序,这样你每次都可以回到同一套配置,而不必重新构建。
Triage 在 Agentic Change Management 中的位置
CodeRabbit Triage 解决的是更大问题中的一部分。随着智能体让实现变得更便宜,团队收到的变更提议超出了他们验证和理解的时间。他们仍然需要对自己接受的代码负责。
Agentic Change Management 把这些责任带进一个共享工作流,处理由人和智能体创建的变更。它从独立审核和验证开始,帮助团队排定人工关注的优先级,解释变更如何影响代码库,并把安全分析扩展到已提交的代码。
Triage 负责优先级排序,并为每个 PR 确定下一步动作。它回答三个问题:
现在需要关注什么,为什么?
谁应该处理它?
然后审核人员就可以看到,一个 PR 为什么来到他们面前、它需要什么,以及推荐背后的证据,再决定如何进行。
队列现在是你的
CodeRabbit Triage 显示每个 PR 的当前状态、谁拥有下一步动作、该动作已经等待了多久,以及其优先级背后的证据。你可以看到为什么一个 PR 会接近你队列的顶部,以及你被要求做什么。
它现在已经可用。打开你的队列,看看哪些 PR 在等待你审核,哪些需要作者跟进,哪些已经可以合并。