Reviewer Personas
约 2622 字大约 9 分钟
2026-05-30
Reviewer personas 不是把同一份代码交给多个 Agent 重复看一遍。它们应该按风险维度分工,每个角色只负责自己能看清的那部分风险。
如果一个 reviewer 什么都看,最后往往只会看最显眼的问题。persona 的意义,是让 correctness、testing、security、maintainability、performance、reliability、project standards 等风险都有明确负责人。
核心结论
一个 reviewer persona 是否有价值,主要看边界是否清楚:
- 它看什么风险。
- 它不负责什么判断。
- 它的典型发现应当有什么证据。
- 它发现问题后应交给谁处理。
边界不清时,review 很快会变成噪声:所有 reviewer 都泛泛说“需要更多测试”,或者某个 reviewer 越权替产品、设计、安全、发布负责人做最终取舍。
Persona 矩阵
| Persona | 关注点 | 典型发现 | 不负责什么 |
|---|---|---|---|
| Correctness | 逻辑、状态、边界、错误传播。 | 某个空状态会导致错误渲染;并发状态下会覆盖用户输入。 | 不评价代码风格是否优雅。 |
| Testing | 覆盖缺口、弱断言、脆弱测试。 | 新行为没有失败路径测试;测试只断言组件存在。 | 不用测试数量替代需求正确性。 |
| Security | 鉴权、输入、权限、敏感数据。 | 新接口没有权限校验;用户输入进入危险路径。 | 不把所有质量问题都升级为安全问题。 |
| API Contract | 路由、序列化、类型签名、版本兼容。 | 返回字段改名但调用方未同步;公开类型变窄。 | 不重新设计产品 API。 |
| Data Integrity | migration、backfill、幂等、回滚和数据一致性。 | 迁移无法回滚;重复执行会写入重复数据。 | 不替代发布窗口和运维决策。 |
| Performance | 查询、缓存、批处理、计算成本。 | 列表页引入 N+1;渲染中重复做昂贵计算。 | 不为了微优化牺牲可读性。 |
| Reliability | 错误处理、重试、超时、后台任务稳定性。 | 外部调用失败没有降级;任务重试会重复写入。 | 不替代 incident 或发布决策。 |
| Maintainability | 复杂度、重复、耦合、抽象边界。 | 新 helper 复制已有工具;状态在多个位置重复维护。 | 不为了“整洁”改变已确认行为。 |
| Scope / Simplicity | 范围漂移、过度设计、一次性抽象。 | 小需求顺手引入通用框架;改动覆盖无关模块。 | 不压制必要的设计决策。 |
| Project Standards | 项目规则、命名、路径、文档和 portability。 | 文档写入个人机器绝对路径;提交信息不符合项目约定。 | 不重新定义项目规则。 |
| Adversarial | 大 diff、敏感路径、数据变更里的反常失败。 | 看似正常的 happy path 会被异常输入绕过。 | 不把低概率猜测当高置信 finding。 |
矩阵不是插件内部 agent 清单。它提供的是阅读方式:每个 persona 都要把注意力收窄到一个风险面。
行为正确与测试缺口
Correctness 和 Testing 经常一起出现,但它们不是同一个角色。
Correctness 关心行为是否真的成立。它会问:
- 新状态是否覆盖了空值、错误、权限不足、重复提交和并发情况?
- 数据从输入到输出的路径里有没有被错误转换?
- 错误是否被吞掉、误报或传播到错误层级?
- 这个变更是否破坏了已有调用方的约定?
Testing 关心证据是否足够。它会问:
- 关键行为是否有测试,而不仅是实现细节被覆盖?
- 失败路径、边界路径和回归路径是否能被捕捉?
- 断言是否足够强,还是只证明“代码跑过”?
- 测试是否过度依赖内部结构,导致重构时脆弱?
| 分工 | Correctness | Testing |
|---|---|---|
| 主要问题 | 行为是否正确。 | 如何证明行为正确。 |
| 证据来源 | 代码路径、状态转换、错误链路。 | 测试用例、断言、覆盖范围。 |
| 典型输出 | 这里会在某条件下算错。 | 这里缺少能防回归的测试。 |
如果 correctness 发现了行为 bug,testing 应该补上能证明这个 bug 不再复发的测试。反过来,如果 testing 只说“缺测试”,但说不清测试要证明什么,这个 finding 还不够可执行。
安全、接口、数据与可靠性
Security、API Contract、Data Integrity 和 Reliability 的共同点是:它们关心失败代价,而不是代码表面能不能跑。
Security reviewer 需要关注:
- 未授权访问、越权操作和权限边界。
- 用户输入、公开接口和外部回调。
- 敏感数据暴露、日志泄露和错误信息泄露。
- 默认配置是否过宽,是否引入隐式信任。
API Contract reviewer 需要关注:
- 路由、序列化字段、类型签名和版本兼容。
- 公开接口是否出现破坏性变化。
- 调用方是否仍按旧契约使用返回值。
- 错误格式、状态码或事件 payload 是否改变。
Data Integrity reviewer 需要关注:
- migration、backfill、回滚和重复执行。
- schema 变化是否和代码读取路径一致。
- 批处理失败后是否能安全重跑。
- 数据修复是否留下审计和验证方式。
Reliability 视角需要关注:
- 外部依赖失败、超时、重试和降级。
- 后台任务、队列、缓存和最终一致性。
- 部分失败时系统是否留下不可恢复状态。
这些 persona 的发现通常不能自动修。权限、数据和发布稳定性往往牵涉产品、架构或运维取舍。评审报告应清楚标出风险和证据,再交给对应负责人决定。
性能与可维护性
Performance 和 Maintainability 都容易被误用。
Performance 不应该变成“任何循环都要优化”。它适合关注明确的热路径、数据规模、查询成本和缓存行为:
| 性能问题 | 更好的 finding 形态 |
|---|---|
| “这里可能慢” | “列表页每个 item 触发一次查询,数据量增加时会变成 N+1。” |
| “建议缓存” | “相同计算在单次渲染中重复执行,可以用已有缓存层避免重复成本。” |
| “可以并发” | “这三个请求无依赖关系,串行会把延迟相加。” |
Maintainability 也不应该变成主观审美。它关注的是未来修改成本:
- 是否复制了已有工具或模式。
- 是否把临时逻辑扩成长期抽象。
- 是否让一个模块承担了不该承担的职责。
- 是否出现死代码、无用导出、复杂条件和隐式耦合。
- 是否为了短期方便破坏类型边界或组件边界。
可维护性 finding 要避免“我不喜欢这个写法”。更好的表达是:这个结构会在哪类后续修改中增加成本,是否已有项目模式可以替代。
Scope / Simplicity:防止顺手扩大
Scope / Simplicity reviewer 关注的是变更是否超过了原本问题需要的范围。
它会问:
- 这次 diff 是否修改了和目标无关的模块?
- 是否为了一个具体需求引入了通用框架、配置层或插件机制?
- 是否把本该留给后续 change 的内容提前塞进本次实现?
- 是否出现“顺手优化”“顺手重构”,但没有测试或 spec 支撑?
这个 persona 很容易被误解成“只允许最小改动”。不是。必要的设计调整当然可以做,但它需要回到计划、spec 或明确的技术判断里,而不是混在实现细节中悄悄发生。
Project Standards:项目规则不是可选项
Project Standards reviewer 的职责是把项目规则带进 review。它不是代码风格偏好,而是检查变更是否违反项目已有约定。
在 OpenSpec 驱动项目里,这类检查会看:
- 是否遵守 OpenSpec artifacts 的事实源边界。
- 是否把公开文档写入个人机器绝对路径、私密会话或临时环境事实。
- 是否手写主题已经提供的导航。
- 侧边栏、permalink、frontmatter 是否一致。
- 提交信息、文件命名和文档格式是否符合项目规则。
这类 persona 的价值,是把“项目约定”变成每次变更都能检查的 review 维度,而不是只靠某个人记得。
Adversarial:主动找反常路径
Adversarial reviewer 不负责覆盖所有代码质量问题。它的价值在于从反常输入、恶意路径、极端状态和大 diff 盲区里找失败模式。
它适合在这些情况出现:
- diff 很大,普通 review 容易只看主路径。
- 触及 auth、payments、data mutation、external APIs 等敏感边界。
- 新增复杂状态机、批处理、迁移或跨系统同步。
- 需求里有“默认允许”“自动推断”“回退处理”等容易被绕过的逻辑。
Adversarial finding 必须有证据或可复现推理。它不能只是“也许会有问题”。如果只是低置信猜测,应降级为待确认问题,而不是阻塞项。
Finding 应该长什么样
不管 persona 是什么,一个可执行 finding 至少应该包含:
| 字段 | 作用 |
|---|---|
| 风险 | 说明问题会造成什么后果。 |
| 证据 | 指向代码、测试、文档、行为或可复现路径。 |
| 条件 | 说明在哪个场景下触发。 |
| 严重度 | 帮助决定是否必须先修。 |
| 建议动作 | 说明是自动修、开发者修、补 spec、补测试,还是人工判断。 |
没有证据的 finding 只能算提醒。没有建议动作的 finding 很难进入执行。没有边界的 finding 容易把一次 review 变成无限扩展的重构建议。
如何避免 persona 噪声
persona 越多,越需要约束输出质量。
| 噪声类型 | 处理方式 |
|---|---|
| 多个 reviewer 重复同一问题 | 合并为一个 finding,保留最清楚的证据。 |
| 低置信猜测 | 标为待确认,不能和高置信问题同级。 |
| 超出范围的建议 | 记录为后续事项,不能阻塞当前变更。 |
| 审美偏好 | 要求转成项目规则、用户影响或维护成本,否则丢弃。 |
| 自动修风险过高 | 交给人工或后续任务,不在 review 中静默修改。 |
Reviewer personas 的目标不是让报告变长,而是让风险更具体、更可分派、更容易处理。