从 0 学习 Alibaba Open Code Review(四):自定义规则 rule.json 解析

📅 2026/7/6 14:06:39
从 0 学习 Alibaba Open Code Review(四):自定义规则 rule.json 解析
前言上一篇文章中我学习了 OpenCodeReview 的 Git Diff 解析流程。通过对比下面几类命令git status--short gitdiff--name-status gitdiff--numstat gitdiff--stat gitdiffocr review--preview理解了Git diff 决定本次审查哪些文件 [M] 表示文件被修改 7 -1 表示新增 7 行、删除 1 行 ocr review --preview 可以在不调用 LLM 的情况下预览审查范围。第三篇解决的是ocr review 看哪些代码这一篇继续学习另一个重要问题ocr review 按什么规则审查代码在第一篇中已经配置过.opencodereview/rule.json并且在规则中写了重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。当时只是知道加了规则后OpenCodeReview 的审查结果更关注 SQL 注入、异步错误处理和权限校验问题。但还没有系统理解rule.json 应该放在哪里 rule.json 的结构是什么 path: **/*.js 是什么意思 merge_system_rule: true 是什么作用 include / exclude 如何影响审查范围 ocr rules check 输出怎么看 rule.json 在源码里是如何加载和匹配的本文就围绕.opencodereview/rule.json学习 OpenCodeReview 的自定义规则机制。一、本篇学习目标本文主要解决下面几个问题1. .opencodereview/rule.json 应该放在哪里 2. rule.json 的整体结构是什么 3. path: **/*.js 为什么能匹配 JavaScript 文件 4. rule 字段如何影响审查重点 5. merge_system_rule: true 是什么意思 6. include / exclude 字段有什么作用 7. ocr rules check 如何验证规则是否命中 8. rule.json 和 Git diff 的关系是什么 9. 从源码角度看rule.json 是如何进入 Agent 审查流程的二、规则文件的位置当前练习项目的 Git 根目录是D:\agent\open-code-review-main\ocr-practice-demo本次练习代码放在D:\agent\open-code-review-main\ocr-practice-demo\s01当前规则文件实际放在D:\agent\open-code-review-main\ocr-practice-demo\s01\.opencodereview\rule.json也就是ocr-practice-demo └─s01 ├─.opencodereview │ └─rule.json └─src └─user.js这里有一个容易踩坑的点根据源码Open Code Review 加载项目级规则时并不是在所有子目录中递归查找 .opencodereview/rule.json而是加载 repoDir 下的 .opencodereview/rule.json。源码中的项目规则路径可以理解为repoDir/.opencodereview/rule.json也就是说如果当前执行命令时的repoDir是ocr-practice-demo那么默认项目规则路径是ocr-practice-demo/.opencodereview/rule.json而不是ocr-practice-demo/s01/.opencodereview/rule.json所以当前这个练习有两种正确用法。第一种把规则文件放到当前repoDir下也就是放到ocr-practice-demo/.opencodereview/rule.json这样执行ocr review或ocr rules check时就会自动作为 Project 规则加载。例如cd D:\agent\open-code-review-main\ocr-practice-demo ocr rules checks01/src/user.jsocr review这种情况下如果规则成功加载ocr rules check输出中的 Source 通常会显示为Project (.opencodereview/rule.json)这种方式比较适合真实项目因为项目级规则一般就应该放在项目根目录下由整个仓库统一使用。第二种保留当前文件位置但执行命令时显式指定规则文件如果继续把规则文件放在ocr-practice-demo/s01/.opencodereview/rule.json那么执行规则检查时需要显式指定规则文件ocr rules check--rules01/.opencodereview/rule.jsons01/src/user.js如果真正执行代码审查时也想使用这份规则文件也需要同样显式指定ocr review--rules01/.opencodereview/rule.json这种方式会把规则作为自定义规则文件加载输出中的 Source 通常会显示为Custom (--rule)三、查看rule.json内容当前规则文件内容如下{rules:[{path:**/*.js,rule:重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。,merge_system_rule:true}],exclude:[**/node_modules/**,**/dist/**,**/build/**]}这个 JSON 文件主要包含两类配置rules exclude其中rules表示针对不同文件路径配置不同审查规则。exclude表示排除不需要审查的文件或目录。OpenCodeReview 还支持include用来显式标记一些路径为用户关注范围。本文示例里暂时没有使用include。四、rule.json的整体结构可以把这个文件拆成下面几部分理解{rules:[{path:**/*.js,rule:用户自定义审查规则,merge_system_rule:true}],exclude:[**/node_modules/**,**/dist/**,**/build/**]}对应含义是rules: 定义哪些文件使用哪些审查规则。 rules[].path: 文件匹配模式。 rules[].rule: 匹配到文件后使用的自定义审查规则。 rules[].merge_system_rule: 是否把系统默认规则和用户自定义规则合并。 exclude: 从审查范围中排除的路径模式。其中rules是一个数组说明可以配置多条规则。例如rules:[{path:**/*.js,rule:JavaScript 文件重点检查 SQL 注入、XSS、异步错误处理。,merge_system_rule:true},{path:**/*.go,rule:Go 文件重点检查错误处理、并发安全、资源释放。,merge_system_rule:true}]这样就可以给不同类型的文件配置不同的审查重点。需要注意同一个rule.json里如果多条规则都能匹配同一个文件源码实现是first match wins也就是先匹配到的规则优先生效。五、理解path: **/*.js当前规则中有一行path:**/*.js这表示匹配任意目录层级下的 .js 文件。其中**表示任意层级目录。*.js表示所有以.js结尾的文件。所以**/*.js可以匹配src/user.js s01/src/user.js src/order/order.js test/user.test.js pages/index.js当前练习文件是s01/src/user.js它符合**/*.js所以这条规则可以命中它。从源码角度看OpenCodeReview 使用 glob 匹配规则并且支持**这种递归路径匹配。六、理解rule字段当前规则中最核心的是rule:重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。这段内容会告诉 OpenCodeReview当审查匹配到的 JavaScript 文件时要重点关注这些问题。也就是SQL 注入 硬编码密钥 空值异常 异步错误处理 权限校验缺失 删除类危险操作比如代码中有这样的函数functionupdateUserEmail(db,userId,email){db.query(UPDATE users SET email email WHERE id userId);returntrue;}这段代码就很容易触发规则中的SQL 注入 异步错误处理因为它直接拼接了 SQLUPDATE users SET email email WHERE id userId如果email或userId来自用户输入就可能产生 SQL 注入风险。所以rule字段的作用可以理解为告诉 AI Code Review Agent 本项目希望重点检查什么。源码里还有一个细节rule不一定只能写内联文本也可以写一个规则文件路径。例如{path:**/*.js,rule:rules/javascript.md,merge_system_rule:true}如果rule看起来像.md、.txt、.markdown文件路径OpenCodeReview 会尝试读取这个文件内容作为规则文本。这适合规则比较长的项目。七、理解merge_system_rule: true当前规则中还有一个字段merge_system_rule:true这个字段非常重要。它表示把系统默认规则和用户自定义规则合并使用。也就是说OpenCodeReview 不会只使用我写的这条规则而是会同时使用系统默认规则 用户自定义规则如果merge_system_rule没有配置默认可以理解为false。这时用户规则会替换系统规则只使用用户自定义规则所以两种情况可以对比为merge_system_rule: true 系统规则 用户规则 merge_system_rule: false 或不写 用户规则替换系统规则这也解释了为什么命中当前规则时ocr rules check输出里会同时出现System-Specific Rules User-Specific Rules因为当前配置明确写了merge_system_rule:true八、理解exclude字段当前规则中还有exclude:[**/node_modules/**,**/dist/**,**/build/**]这表示排除下面这些目录node_modules dist build也就是说如果 Git diff 中出现这些目录里的文件OpenCodeReview 可以根据规则把它们排除掉。这些目录通常不适合进行 AI Code Reviewnode_modules 是依赖目录 dist 是构建产物 build 是编译输出。它们大多数不是人工手写代码。如果把这些文件也交给 LLM 审查会造成审查范围变大 token 消耗增加 结果噪声变多 有效评论变少。所以exclude的作用是排除不应该进入审查范围的文件。这一点和第三篇中的 Git diff 有关系。Git diff 负责告诉 OpenCodeReview哪些文件变了而exclude可以进一步告诉 OpenCodeReview哪些变更文件不需要审查需要注意ocr rules check主要用于检查“某个文件会命中哪条规则”它不会完整模拟ocr review --preview的文件过滤结果。如果想确认某个文件是否会被排除应该看ocr review--previewPreview 里会区分Will review Excluded from review九、补充理解include字段虽然当前示例没有写include但 OpenCodeReview 的rule.json支持{include:[src/**/*.js],exclude:[**/node_modules/**]}可以简单理解为include 用来声明用户特别关注的路径 exclude 用来声明用户明确排除的路径。源码里的过滤顺序可以简化理解为1. 二进制文件优先排除 2. 如果命中用户 exclude则排除 3. 如果配置了 include 且文件命中 include则保留 4. 再检查扩展名是否支持 5. 再检查默认排除路径。其中exclude的优先级很高。如果一个文件同时命中include和exclude会被排除。十、使用ocr rules check验证规则是否命中为了确认s01/src/user.js是否命中了规则可以执行ocr rules checks01/src/user.js输出File: s01/src/user.js Source: Custom (--rule) Pattern: **/*.js Rule: ──────────────────────────────────────── ## System-Specific Rules (Mandatory) ... --- ## User-Specific Rules (Mandatory) 重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。 ────────────────────────────────────────如果规则文件在 Git 根目录作为项目规则加载Source 会是Source: Project (.opencodereview/rule.json)如果通过--rule显式指定规则文件Source 会是Source: Custom (--rule)这个区别可以帮助判断当前规则到底是从哪里加载的。十一、理解File输出中第一行是File: s01/src/user.js这表示当前检查的是s01/src/user.js也就是我要验证规则是否命中的目标文件。十二、理解Source输出中会出现Source: Custom (--rule)或者Source: Project (.opencodereview/rule.json)它表示当前命中的规则来源。OpenCodeReview 的规则来源有优先级1. Custom (--rule) 2. Project (.opencodereview/rule.json) 3. Global (~/.opencodereview/rule.json) 4. System built-in也就是说--rule 显式指定的规则优先级最高 项目规则次之 用户全局规则再次 最后才是系统内置规则。如果 Source 显示的是System built-in通常说明当前文件没有命中自定义规则或者自定义规则文件没有被正确加载。十三、理解Pattern输出中还有Pattern: **/*.js这说明当前文件命中了规则里的path:**/*.js也就是说s01/src/user.js 是 .js 文件 ↓ 匹配 **/*.js ↓ 应用这条规则所以Pattern这一行证明了path 匹配成功。如果没有命中自定义规则可能会显示系统规则的 pattern或者显示default十四、理解System-Specific Rules输出中出现了## System-Specific Rules (Mandatory)下面包含系统默认规则例如代码质量 死代码 空值检查 异步处理 安全检查 敏感信息泄露 特定语言最佳实践这些规则不是在当前rule.json里写的而是 OpenCodeReview 内置的系统规则。之所以会显示它们是因为配置了merge_system_rule:true也就是说选择了保留系统默认规则同时追加我的自定义规则。十五、理解User-Specific Rules输出的后面会出现## User-Specific Rules (Mandatory) 重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。这正是我在rule.json中写的内容rule:重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。这说明我的自定义规则已经成功加载 并且已经应用到当前 s01/src/user.js 文件上。到这里就可以确认rule.json 配置成功 path 匹配成功 系统规则和用户规则合并成功。十六、从源码角度理解规则加载流程第二篇中已经知道ocr review会进入runReview在runReview中会调用公共上下文加载逻辑。简化后的规则加载流程是runReview ↓ loadCommonContext ↓ rules.NewResolver(repoDir, rulePath) ↓ 加载系统内置规则 ↓ 加载 --rule 指定的 custom 规则 ↓ 加载项目级 .opencodereview/rule.json ↓ 加载全局 ~/.opencodereview/rule.json ↓ 生成 composedResolver ↓ 返回 Resolver 和 FileFilter其中Resolver负责根据文件路径找到应该使用哪段审查规则。FileFilter负责根据 include / exclude 判断文件是否应该进入审查范围。所以rule.json在源码里其实影响两个地方1. rules[].path rules[].rule 决定某个文件使用什么审查规则 2. include / exclude 决定某些文件是否应该进入审查范围。十七、规则如何进入 Agent Prompt真正执行审查时Agent 会针对每个变更文件解析系统规则。源码里的逻辑可以简化理解为executeSubtask ↓ resolveSystemRule(newPath) ↓ SystemRule.Resolve(path) ↓ 得到当前文件对应的规则文本 ↓ 替换 Prompt 模板中的 {{system_rule}} ↓ 发送给 LLM / Agent 执行审查所以rule.json不是单独运行的它最终会变成 Agent prompt 的一部分。可以理解为Git diff 决定 Agent 看哪些代码 rule.json 决定 Agent 审查这些代码时要重点关注什么。十八、rule.json 和 Git diff 的关系第三篇中已经学习过Git diff 决定本次有哪些文件发生变更。比如[M] s01/src/user.js表示s01/src/user.js被修改了。但是 Git diff 只解决一个问题看哪些文件它并不负责告诉 AI应该重点检查什么问题这个时候就需要rule.json。所以两者的关系可以理解为Git diff ↓ 决定本次变更了哪些文件 rule.json ↓ 决定这些文件应该按照什么规则审查也可以画成Git diff ↓ 找到变更文件 s01/src/user.js ↓ rule.json 匹配 path: **/*.js ↓ 加载系统规则和用户规则 ↓ Agent 按规则审查代码 ↓ 生成 Review 评论这是第四篇最重要的一点。十九、为什么加规则后审查结果会变化在没有自定义规则时OpenCodeReview 也会根据系统规则审查代码。但是加上下面这条规则后重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。Agent 的注意力会更集中到这些方向。比如我的代码里有functionupdateUserEmail(db,userId,email){db.query(UPDATE users SET email email WHERE id userId);returntrue;}这段代码本身就和规则中的关键词高度相关SQL 注入 异步错误处理如果是删除用户函数还可能和权限校验缺失 删除类危险操作相关。所以自定义规则的价值是把通用 AI Code Review 变成更贴近当前项目的 Code Review。不同项目关注的问题可能不一样。例如后端项目更关注 SQL 注入、权限校验、事务处理 前端项目更关注 XSS、状态管理、React Hooks 支付项目更关注金额精度、幂等性、重复回调 管理后台更关注越权操作和敏感数据泄露。因此rule.json可以让 OpenCodeReview 更贴近具体业务场景。二十、rule.json 在整个审查流程中的位置结合前几篇内容现在可以把ocr review的流程理解成这样用户执行 ocr review ↓ 读取 Git diff ↓ 确定本次变更文件 ↓ 根据 include / exclude 和默认规则过滤文件 ↓ 根据 rule.json 的 path 匹配当前文件规则 ↓ 根据 merge_system_rule 判断是否合并系统规则 ↓ 创建 Agent 审查任务 ↓ Agent 读取代码上下文 ↓ Agent 根据规则生成 Review 评论 ↓ 输出终端结果或 JSON其中Git diff解决的是审查哪些文件而rule.json解决的是按照什么规则审查这两个部分共同决定了一次 Review 的输入和审查方向。二十一、本文使用的 PowerShell 命令记录为了方便复盘本文使用了下面这些命令。1. 查看项目结构tree/F2. 查看当前规则文件如果规则文件仍然在s01目录下Get-Content.\s01\.opencodereview\rule.json如果已经移动到 Git 根目录Get-Content.\.opencodereview\rule.json3. 验证指定规则文件是否命中当前文件在s01/.opencodereview/rule.json时使用ocr rules check--rules01/.opencodereview/rule.jsons01/src/user.js如果规则文件已经移动到 Git 根目录.opencodereview/rule.json使用ocr rules checks01/src/user.js4. 验证文件是否会被审查ocr review--previewocr rules check负责看规则是否命中ocr review --preview负责看文件是否进入审查范围。二十二、本篇总结当前规则文件是{rules:[{path:**/*.js,rule:重点检查 SQL 注入、硬编码密钥、空值异常、异步错误处理、权限校验缺失和删除类危险操作。,merge_system_rule:true}],exclude:[**/node_modules/**,**/dist/**,**/build/**]}其中path: **/*.js表示匹配任意目录下的 JavaScript 文件。rule表示用户自定义审查重点。merge_system_rule: true表示合并系统默认规则和用户自定义规则。exclude表示排除不需要审查的目录。需要特别注意rule.json 如果要作为项目规则自动加载应该放在 Git 仓库根目录的 .opencodereview/rule.json 如果放在子目录需要通过 --rule 显式指定。通过执行ocr rules check--rules01/.opencodereview/rule.jsons01/src/user.js可以验证规则文件被成功读取 s01/src/user.js 命中了 **/*.js 系统规则和用户规则被合并 自定义规则已经生效。到这里可以把前几篇的学习串起来第一篇ocr review 能做什么 第二篇ocr review 是从哪里启动的 第三篇ocr review 看哪些代码 第四篇ocr review 按什么规则审查这一篇的核心结论是Git diff 决定审查哪些文件 rule.json 决定按照什么规则审查这些文件 ocr rules check 用来验证规则命中 ocr review --preview 用来验证审查范围。二十三、下一篇计划Agent 工具调用分析下一篇准备继续学习从 0 学 OpenCodeReview 源码Agent 工具调用分析前面几篇已经知道Git diff 决定输入 rule.json 决定规则 ocr review 会生成审查评论。但还没有深入理解OpenCodeReview 为什么不是简单把 diff 丢给 LLM file_read 是做什么的 file_find 是做什么的 code_search 为什么会出现 code_comment 如何生成评论下一篇就围绕这些工具调用日志展开继续分析 OpenCodeReview 的 Agent 审查流程。