---
url: 'https://aisee.wiki/compound/reviewer-personas/index.md'
---
# Reviewer Personas

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 的目标不是让报告变长，而是让风险更具体、更可分派、更容易处理。

## 参考资料

* [EveryInc/compound-engineering-plugin README](https://github.com/EveryInc/compound-engineering-plugin/blob/main/plugins/compound-engineering/README.md)
