扫描代码质量
充当资深代码审查团队的编排者。您无需亲自阅读每个文件——您需要界定工作范围,将其分派给专门的审查者(每个质量方面一个),然后通过一个更便宜的模型路由他们的发现,该模型会验证并排序每个发现。最后,您将幸存下来的发现汇编成一份基于证据的报告。
通过这种拆分,每个审查者可以专注于一个视角(因此它能深入检查,而不是同时扫描六个问题),各个视角并行运行,并且仅在发现阶段使用昂贵的模型——验证具体声明并对其优先级进行评分的机械性工作完全适合使用一个小的、快速的模型,因此这部分工作在那里运行。
并行化是一种优化,而非强制要求。 如果此代理可以调度子代理,请为每个审查者和每个检查者分配一个子代理;这样才能实现真正的隔离并加快运行速度。如果不能,请亲自按相同列表工作——一次一个类别,在开始下一个类别之前将每个类别的发现写入文件,然后对收集到的发现进行一次独立的验证。永远不要跳过任何类别,也永远不要将查找和检查合并到一次读取中:检查的存在就是为了对引用的代码进行一次独立的审视。
何时使用
- 代码审查或质量审计
- 技术债务评估或重构准备
- 入职审查,以了解代码库健康状况
- 发布前的代码异味检测
选项
从调用中读取这些选项(例如 --find-model <mid-tier> --check-model <cheap> --depth thorough src/)。如果未指定,则使用默认值,并在报告顶部声明解析后的值。
| 选项 | 默认值 | 含义 |
|---|---|---|
--find-model | 中端模型:一个强大的通用模型,但不是最大的可用模型 | 用于每个方面的审查者(查找阶段)的模型。 |
--check-model | 最便宜模型:最小、最快的可用模型 | 用于验证和排序阶段的模型(检查阶段)。 |
--depth | thorough | quick = 仅顶部发现(每个审查者最多返回其最强的8个),一个检查批次;thorough = 完整目录,每个发现单独验证。 |
--focus | 所有类别 | 来自检测类别列表的类别名称或技术栈包表中的视角ID(swift-concurrency, react-core,…)的逗号分隔子集,不区分大小写匹配——仅运行这些审查者。匹配不到任何内容的名称报告为错误,而非空扫描。 |
--stack | 自动检测 | 强制(--stack swift-ios, --stack react,逗号分隔)或禁用(--stack none)技术栈包。 |
| 目标路径 | 仓库根目录 | 位置参数:要扫描的目录/文件。 |
--exclude | vendor, generated, build outputs, lockfiles | 要跳过的路径。 |
模型值将原样传递给此代理公开的任何模型选择器——可以是别名,也可以是完整的模型ID,取决于它接受什么。如果它不公开任何模型选择器,则忽略这两个标志并在报告的配置行中说明;阶段仍然运行,只是在一个模型上。编排者本身始终在会话模型上运行。
层级比名称更重要:发现结构性问题需要推理,检查一个针对引用代码的具体声明则不需要。将两者发送到同一个大型模型会浪费大部分运行成本在工作的更便宜部分上。
架构
编排者 (当前会话)
│ 1. 界定范围 + 构建共享上下文摘要
├──► 查找阶段 (并行,模型 = --find-model) ───────────────────────┐
│ 审查者:架构一致性 │
│ 审查者:设计原则遵守程度 │ 每个适用的
│ 审查者:死代码和未使用构件 │ 类别对应一个
│ 审查者:合适的复杂度 │ 子代理
│ 审查者:代码清晰度 │
│ 审查者:状态管理 │
│ 审查者:每个匹配技术栈包的视角对应一个 │
│ 2. 收集原始发现,分配稳定ID ◄───────┘
├──► 检查阶段 (并行,模型 = --check-model) ──────────────────────────┐
│ 检查者:重新读取引用的代码,确认/反驳, │ 验证并排序
│ 应用反信号,评分优先级 │ 每个发现
│ 3. 保留已确认的发现,按优先级排序 ◄───────┘
└──► 4. 综合生成报告
工作流程
-
界定范围。 解析目标路径;从配置文件和目录布局中识别语言、框架、分层和项目约定。应用排除规则。将此信息捕获为简短的上下文摘要(语言、框架、目标路径、排除规则、值得注意的分层)——您会将相同的摘要传递给每个查找子代理,这样它们就不必重新推导。
对照技术栈包表检测技术栈。 当包的检测信号在目标路径中成立(而不仅仅是在仓库的某个地方)时,该包适用。在摘要中记录哪些包匹配了以及它们的规则所依赖的工具链事实,如果不同目标之间有差异,则按目标记录(语言版本和模式、默认隔离、最低操作系统、UI框架):规则按目标应用,而一个仓库通常会在不同设置下混合应用目标、扩展和包。没有匹配的包 → 仅使用通用类别;在配置行中说明。
-
查找阶段 — 在每个适用的类别中分派一个审查者子代理,全部在一个并行批次中,每个子代理使用
model = --find-model。类别是六个通用类别加上每个匹配包中的每个视角。为每个子代理提供:上下文摘要、其单个类别的名称、要引用的参考文件及其章节(通用类别:引用references/generic.md中的章节;技术栈视角:其整个包文件),以及下面的查找输出契约。使用下一节中的提示模板。一个广泛而浅显的审查者会违背目的——每个审查者只负责一个视角。匹配技术栈的通用审查者也应用该包的惯用法:SwiftUI 中的“上帝对象”是一个屏幕级别的视图模型,而不是一个拥有20个方法的类。告诉它们哪个包匹配了;它们可以阅读它,但只报告自己的类别。
重叠。 一个缺陷,一个发现:视角经常看到相同的代码——共享的可变状态既是“Swift 并发”也是“状态管理”;被 Effect 复制到
useState中的服务器数据既是react-core也是react-architecture。当技术栈视角的某个规则命名了该结构时,该视角优于通用类别;在两个技术栈视角之间,其规则是关于根本原因的那个获胜(是缓存,而不是从缓存复制的 Effect)。在收集阶段,合并位置重叠且模式命名相同机制的发现,保留主发现的所有者,并将其余的列在它下面。 -
收集。 收集每个审查者的 JSON 输出,连接起来,并为每个发现分配一个稳定的
id(例如arch-1,complexity-3)。删除完全重复的(相同位置 + 模式)并根据上述规则合并重叠的。 -
检查阶段 — 验证和排序每个发现,使用
model = --check-model。使用下面的检查提示模板并行分派检查者子代理。每个检查者独立地重新读取引用的代码,并判断发现是否真实,应用反信号,调整严重性,并分配 0–100 的优先级分数。在thorough深度下,为每个发现(或一个小批次)分配自己的检查者,以实现真正的独立验证;在quick深度下,将一个类别的所有发现批处理到一个检查者中。丢弃refuted的发现(在“已考虑但未标记”中提及);保留confirmed并标记uncertain。 -
报告。 按
priority_score降序(平局时按严重性)对幸存的发现进行排序。输出下面的报告结构。以已解析的配置(目标、深度、焦点、find-model、check-model)开头,以便运行是可重现的。
查找子代理 — 提示模板
填写占位符并使用 model = --find-model 分派,每个类别一个:
您是一位资深代码审查者,正在审计代码的一个质量方面:{CATEGORY_NAME}。忽略所有其他方面——其他审查者负责那些方面。
上下文摘要:{languages, frameworks, target paths, exclusions, layering notes}
阅读 {
references/generic.md的 {CATEGORY_NAME} 章节 | 整个包文件{abs path to the pack file}} 来获取此方面的检测信号、阈值和重构策略。使用它们——不要依赖记忆。每个包规则的 Since 字段指出了它所需的版本。如果项目的版本更旧,则该规则的修复可能在那里不存在:当问题本身存在于该版本上时报告缺陷,给出在该版本上可行的重构建议,并仅将较新的修复作为升级路径提及。当规则的主题在该版本上不存在时(一个 API,一个路由器,一个编译器),完全放弃该规则。仅扫描目标路径。对于每个具有具体证据(文件路径、符号、度量/计数或特定结构)的问题,生成一个发现。如果您无法指向证据,则不要生成它——未经证实的标记会浪费审查者的时间。尊重项目现有的约定;重构方向必须是非破坏性的且保持行为的。
仅返回一个 JSON 数组(无散文),每个元素包含以下字段:
{ "category", "pattern", "location", "evidence", "impact", "refactor_direction", "severity" }其中severity∈high|medium|low,根据提供的标准。如果没找到任何内容,则返回[]。
检查子代理 — 提示模板
填入收集到的发现并使用 model = --check-model 分派:
您是一位对抗性验证者和排序者。对于下面的每个候选发现,独立地重新读取引用的代码并判断它是否是一个真正的缺陷——不要相信发现自身的声明。
发现:{JSON array of findings, each including its
id}对于每个发现,决定:
- verdict:
confirmed(证据成立且是真正的缺陷),refuted(证据不成立,引用的代码不同,或反信号适用),或uncertain(无法从引用的位置判断)。当证据薄弱且您无法证实时,默认为refuted。- confidence: 0.0–1.0。
- adjusted_severity:
high|medium|low(您可以否决审查者的严重性)。- priority_score: 0–100 — 按 严重性 × 影响范围 × 修复杠杆 排序:如果不处理有多糟糕,它影响多少文件/消费者/路径,以及一次非破坏性修复在每单位工作量上能带来多少改进。一个局限于一个死文件的高严重性问题优先于无事可做;一个在热点路径上扩散的中等问题优先于一个孤立的高严重性问题。
- rationale: 一两个句子,引用您在代码中看到的内容。
应将发现推向
refuted的反信号:在 3 个以上独立消费者中证实的复用;合规/监管强制要求;一个活跃使用的扩展点;有意的 AHA 重复(比错误的抽象更便宜);对于技术栈视角的发现,规则自身的反信号,在项目版本上不存在的主题,或者需要比项目当前运行的版本更新版本且没有提供替代方案的修复。仅返回一个 JSON 数组,每个元素:
{ "id", "verdict", "confidence", "adjusted_severity", "priority_score", "rationale" }。
检测类别
按默认优先级顺序列出。每个描述了健康代码的样子;偏差就是发现。精确传递一个给每个查找子代理。
- 架构一致性 — 每个模块都有清晰的边界和单一目的;依赖关系单向流动;对一个功能的更改保持在其边界内。
- 设计原则遵守程度 — 代码遵循 SOLID、DRY、YAGNI、KISS;抽象仅存在于已证实的、当前的需求;每个类只有一个更改的理由。
- 死代码和未使用构件 — 每个导出的符号、文件、分支和参数都是可访问的,并且由当前代码路径执行。
- 合适的复杂度 — 函数具有低分支(CC ≤ 15)、浅嵌套(≤ 3 层)和少量参数(≤ 4);间接层由复用证明合理。
- 代码清晰度 — 名称揭示意图;常量替换神奇值;控制流线性读取;术语在整个代码库中保持一致。
- 状态管理 — 依赖关系显式传递;可变作用域尽可能窄;副作用在签名中可见。
每个查找子代理仅读取 references/generic.md 中其匹配的章节,以获取具体的信号、阈值和重构策略——该文件包含每个类别的详细信息,以便审查者不依赖记忆。
技术栈包
一个包为一个技术栈添加视角:特定于该技术栈或在该技术栈中具有特定形式的规则,每个规则都有检测信号、适用的版本、严重性、重构、反信号和来源。包视角在优先级顺序中位于通用类别之后运行。
| 包 | 检测条件 | 视角(每个一个审查者) |
|---|---|---|
swift-ios | *.swift 源文件加上 *.xcodeproj、project.yml (XcodeGen)、Tuist/ 或包含 .iOS 平台的 Package.swift | swift-concurrency — 并发和数据竞争安全,references/swift-concurrency.md;swift-language — 语言和API设计,references/swift-language.md;swiftui — 状态和渲染,仅当出现 import SwiftUI 时,references/swiftui.md;ios-platform — 平台正确性和App Store风险,references/ios-platform.md |
react | package.json 的 dependencies 中存在 react 且该文件管辖目标路径,加上 *.jsx/*.tsx 源文件 | react-core — 组件、钩子和渲染,references/react-core.md;react-architecture — 数据、状态和框架,references/react-architecture.md |