open-code-review 审查规则体系完全指南:优先级链、rule.json 配置与文件过滤原理
2026/9/13 5:02:56 网站建设 项目流程

open-code-review 审查规则体系完全指南:优先级链、rule.json 配置与文件过滤原理

【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibaba's scale. Hybrid architecture code review tool: deterministic pipelines + LLM Agent, precise line-level comments, built-in multi-language ruleset (NPE, thread-safety, XSS, SQL injection), OpenAI & Anthropic compatible.项目地址: https://gitcode.com/GitHub_Trending/op/open-code-review

导读

本篇指南基于 open-code-review(OCR)的官方规则文档 pages/src/content/docs/ko/review-rules.md 展开,结合仓库源码与测试,系统讲解 OCR 的审查规则(Review Rules)机制:规则如何通过四层优先级链决定"每个文件该被 LLM 用什么标准审查",rule.json的三个独立字段(include/exclude/rules)如何编写,以及五道关卡的文件过滤算法如何把 diff 中的文件送到模型面前。读完本篇,你将能够为任意项目编写项目级、全局级甚至单 PR 级别的自定义规则,并能用ocr rules checkocr review --preview调试规则生效路径。

规则是什么:告诉 LLM "审什么"

规则(Rules)是 OCR 审查时的注意力控制器。它回答一个问题:当审查src/api/user.goUserMapper.xml这类文件时,Agent 应该重点关注哪些风险——是 NPE、线程安全、XSS,还是 SQL 注入?规则并不直接执行静态检查,而是以 JSON 形式组织、经路径匹配后把规则正文注入到模型提示词中,让 Agent 带着明确的检查清单去读代码。

这些规则分布在三个层次的 JSON 文件中,再加上内嵌在二进制里的系统默认规则,构成完整规则体系。系统默认规则位于 internal/config/rules/system_rules.json,通过go:embed编译进二进制(见 internal/config/rules/system_rules.go#L89-L91),因此任何环境下都必然存在一层兜底规则。

四层优先级链:谁先匹配谁赢

OCR 用四层优先级链解释规则。对每一个文件路径,它按顺序逐层扫描,第一次匹配到的模式即获胜

优先级来源路径说明
1(最高)--rule标志用户指定CLI 层覆盖。一旦指定,总是获胜
2项目配置<repoDir>/.opencodereview/rule.json项目级规则,可随仓库提交
3全局配置~/.opencodereview/rule.json用户机器级别的个人偏好
4(最低)系统默认内嵌system_rules.json覆盖主流语言的内置规则

优先级更高的层如果文件不存在,会静默跳过、不报错。所以一个没有.opencodereview/rule.json的项目,会自然回落到全局层和系统层。

从源码看,这一链条由 internal/config/rules/system_rules.go#L265-L347 中的composedResolver实现:NewResolver依次加载customRulePath--rule)、项目级、全局级规则,并解析内嵌系统规则;Resolve则按custom → project → global → system顺序调用matchProjectRuleEntry,命中即返回(system_rules.go#L447-L457)。注释中特别说明:monorepo 场景下RepoDir锚定在 git 顶层目录,ocr review从子目录运行时加载的是仓库根部的规则文件,路径匹配也以仓库根为基准。

值得注意的细节:buildFileFilter在合并include/exclude时,只取优先级最高且配置了 include/exclude 的那一层(system_rules.go#L349-L369),并将所有模式统一转为小写——这与下文要讲的"大小写不敏感匹配"一脉相承。

rule.json 文件格式(1~3 层通用)

--rule指定文件、项目级、全局级三个层次的 JSON 结构完全一致,一个典型示例:

{ "include": ["src/**/*.{ts,tsx}", "src/**/*.go"], "exclude": ["**/*.test.ts", "**/generated/**"], "rules": [ { "path": "src/api/**/*.go", "rule": "All exported handlers must validate request bodies before use." }, { "path": "**/*mapper*.xml", "rule": "Check SQL for injection risks, parameter errors, and missing closing tags." } ] }

三个字段彼此独立,语义如下:

  • include(可选)——glob 模式列表,作用是跳过(skip)内建默认排除模式(如测试文件排除)。它不是白名单:未命中任何include模式的文件仍会继续经受unsupported_ext(扩展名)与default_path(默认路径)两道关卡,仍可能被审查。代码中对应FileFilter.HasInclude/IsUserIncluded(system_rules.go#L226-L263),Include为空时IsUserIncluded一律返回false
  • exclude(可选)——OCR不应审查的文件的 glob 模式。在过滤算法内部它拥有最高优先级:只要命中exclude就立刻排除(对应FileFilter.IsUserExcluded,同样大小写不敏感)。
  • rules——{path, rule}条目数组,按声明顺序评估。对某文件,第一个命中的path决定该文件审查时模型收到的提示词。数据结构见 system_rules.go#L205-L217 的ProjectRule/ProjectRuleEntry,其Rule字段还支持merge_system_rule布尔标记(见下文进阶章节)。

此外,rule值若形如单行文件路径(无空格、以.md/.txt/.markdown结尾),会被当作规则文件引用并读取其内容替换(resolveRuleEntries,system_rules.go#L572-L630);文件需满足扩展名白名单、512KB 大小上限,且不得逃逸仓库目录(readRuleFileSafe)。

glob 语法

OCR 使用bmatcuk/doublestar/v4与 system_rules.go#L15):

  • *——匹配除/外的任意字符;
  • **——跨越目录边界匹配(src/**/*.go可命中任意深度的 Go 文件);
  • {a,b,c}——花括号展开,*.{ts,tsx,js,jsx}会展开为四个模式依次对比;
  • ?——匹配单个字符;
  • [abc]——字符类。

模式匹配大小写不敏感(路径会先转小写再匹配)。源码中resolveDetailmatchProjectRuleEntry都执行strings.ToLower(system_rules.go#L166-L177、system_rules.go#L535-L553),花括号展开由expandBraces完成。拿不准时用ocr rules check <path>验证。

文件如何被过滤:五道关卡

过滤器是位于 internal/agent/preview.go 的五道关卡算法whyExcluded,preview.go#L34-L60)。对 diff 中的每个文件,OCR 依次询问:

  1. binary——是二进制文件吗?是则排除。
  2. user_exclude——路径命中用户exclude模式吗?命中则排除。
  3. user_include——用户定义了include时,路径命中吗?命中则直接放行(跳过下面的unsupported_extdefault_path关卡)。
  4. unsupported_ext——文件扩展名在允许列表中吗?不在则排除。
  5. default_path——路径命中内建测试文件排除模式吗(如**/*_test.go**/*.test.{js,jsx,ts,tsx}**/*_spec.rb等)?命中则排除。

通过全部五道关卡的文件才进入 LLM。deleted(删除)不算关卡:它是Preview()单独计算的——当新路径为/dev/nulleffectivePath逻辑,preview.go#L114-L119),表示该文件没有值得审查的新内容。不想消耗 token、只想看过滤结果,用ocr review --preview(该命令在 cmd/opencodereview/review_cmd.go 中实现,调用agent.Preview,review_cmd.go#L494-L506)。

内建默认路径排除列表

文档列出的内建排除模式(完整清单见 internal/config/allowlist/default_exclude_patterns.json):

  • **/*_test.go
  • **/src/test/java/**/*.java
  • **/src/test/**/*.kt
  • **/*.test.{js,jsx,ts,tsx}
  • **/*.spec.{js,jsx,ts,tsx}
  • **/__tests__/**
  • **/test/**/*_test.py
  • **/tests/**/*_test.py
  • **/*_test.py
  • **/*_spec.rb
  • **/spec/**/*_spec.rb
  • **/*Test.java
  • **/*Tests.java
  • **/*_test.rs
  • **/oh_modules/**
  • **/*.test.ets

实际 JSON 文件中的清单比文档表格更长,还包含**/src/test/**/*.{kt,kts}**/__snapshots__/****/*.snap**/testdata/****/fixtures/****/*.generated.***/*.pb.go**/*.pb.cc**/kitex_gen/**/*.go、各类*_tbRTL 测试文件、.sol/.vy测试目录等 50 余条,覆盖测试文件、快照、生成代码、协议桩等多类噪音。

另外,过滤vendor/node_modules/target/这类高噪音目录发生在更早的 diff 阶段(文件级过滤器之前),由 internal/diff/git.go 处理。

想让命中这些测试文件模式的文件也参与审查?把它加进用户include列表即可——include会覆盖默认路径关卡。

每文件的规则解析:最终提示词从哪来

过滤器决定"审不审"之后,OCR 开始决定"用什么规则审"。对每个文件:

  1. 按声明顺序查--rule(custom)层;
  2. 按声明顺序查<repo>/.opencodereview/rule.json
  3. 按声明顺序查~/.opencodereview/rule.json
  4. 落到内建系统规则层。

系统层内建system_rules.json的模式与规则文档对应关系如下(按相对对比顺序整理):

模式规则文档
**/*.propertiesproperties.md —— i18n / 配置文件
**/*{mapper,dao}*.xmlmapper_dao_xml.md —— MyBatis 风格 Mapper SQL
**/pom.xmlpom_xml.md —— Maven 依赖
**/build.gradlebuild_gradle.md —— Gradle 依赖
**/package.jsonpackage_json.md —— NPM 依赖 / 脚本
**/Cargo.tomlcargo_toml.md —— Rust 清单
**/composer.jsoncomposer_json.md —— Composer 依赖、自动加载、脚本、插件
**/*.{json,json5}json.md —— 通用 JSON(含.json5
.github/workflows/**/*.{yaml,yml}github_workflows.md —— GitHub Actions 工作流 YAML
.github/**/*.{yaml,yml}github_config.md —— 其他.github配置 YAML
**/*.{yaml,yml}yaml.md
**/*.javajava.md
**/*.gogo.md —— Go 源码
**/*.{ftl,ftlh,ftlx}freemarker.md —— FreeMarker 模板(SSTI / XSS / null 处理)
**/*.{hbs,mustache}handlebars_mustache.md —— Handlebars / Mustache 模板
**/*.etsarkts.md —— ArkTS / HarmonyOS
**/*.astroastro.md —— Astro 组件与岛屿
**/*.{ts,js,tsx,jsx,mjs,cjs}ts_js_tsx_jsx.md
**/*.{kt,kts}kotlin.md
**/*.rsrust.md
**/*.Rr.md
**/*.{cpp,cc,cxx,hpp,hxx}cpp.md
**/*.cc.md
**/*.{py,ipynb}python.md —— Python 源码
**/*.{php,phtml}php.md —— PHP 源码与模板
**/*.protoprotobuf.md —— Protocol Buffers 通信兼容性
**/*.popo.md —— gettext 翻译源目录
**/*.potpot.md —— gettext 模板
**/*.{graphql,gql}graphql.md —— GraphQL schema 与操作
**/*.prismaprisma.md —— Prisma schema
**/*.jljulia.md —— Julia 源码
**/*.{tf,hcl,tfvars}terraform.md —— Terraform / HCL
**/*.bicepbicep.md —— Bicep(Azure)模板
**/*.elmelm.md —— Elm 源码
**/*.{jsonnet,libsonnet}jsonnet.md —— Jsonnet 配置模板与库
**/*.thriftthrift.md —— Apache Thrift IDL 通信兼容性
**/*.capnpcapnp.md —— Cap'n Proto schema 通信兼容性
**/*.{v,sv,vh}verilog.md —— Verilog / SystemVerilog RTL
**/*.{vhd,vhdl}vhdl.md —— VHDL RTL
**/*.mmatlab.md(或经内容嗅探转 objc.md)
**/*.mmobjc.md —— Objective-C++ 源码
**/*.solsolidity.md —— Solidity 智能合约
**/*.vyvyper.md —— Vyper 智能合约
(兜底)default.md

实际 system_rules.json 中还有文档表格未列出的模式,如**/*.pugpug.md**/*.nixnix.md**/*.{hs,lhs}haskell.md**/*.{nim,nims,nimble}nim.md**/*.swiftswift.md**/*.zigzig.md**/*.{ml,mli}ocaml.md**/*.{re,rei}ocaml.md等。

以 mapper_dao_xml.md 为例,这类规则文档是高质量的审查指令:它会要求 Agent 检查 SQL 关键词拼写、<if test="">动态 SQL 逻辑、JOIN 条件错误、缺 WHERE 的全表扫描风险、无分页的大查询、${}直接拼接导致的 SQL 注入等,同时强调"上下文不清时宁可漏报也不误报、只报告有明确证据的问题"——这正是规则文本注入模型后要执行的检查清单。

解析出的规则正文会被注入到 plan 与 main 任务提示词的{{system_rule}}占位符处(模板见 internal/config/template/prompts/plan_task_system.md 与 main_task_system.md)。

.m文件的内容嗅探

.m扩展名被 MATLAB 与 Objective-C 共用。OCR 通过查看文件第一个非空行来区分二者:若看起来像 Objective-C(如#import@implementation、C 风格注释等),则改用objc.md而非matlab.md;无法读取内容时回落到matlab.md

源码层面,这一逻辑在 internal/config/rules/sniffer.go 的sniffer装饰器中实现:sniffsAsObjC只对.m路径触发(sniffer.go#L87-L92),通过peekFirstLine读取首个非空行,再与objcSniffPrefixes前缀表(#import#include#pragma#if#define@import@interface@implementation@class@protocol///*)比对(sniffer.go#L153-L172)。注释中解释了设计取舍:故意不把裸#视为 ObjC 信号,因为 Octave 也用.m且把#当注释符,会误分类。review 场景下还会通过git show <ref>:<path>读取指定 ref 的内容(showAtRef,sniffer.go#L120-L142),超时上限 5 秒。

稳定性提示:此嗅探行为可能随 OCR 版本变化。若想对.m路径强制固定规则,请在项目级规则中显式声明——项目规则永远优先于系统层(嗅探只包裹 system 层,见 system_rules.go#L335-L346 的注释,这正是为了不干扰用户自定义.m规则)。

检查哪条规则生效:ocr rules check

规则行为与预期不符时,用ocr rules check查看哪个层级、哪个模式最终胜出:

$ ocr rules check src/main/java/com/example/UserService.java File: src/main/java/com/example/UserService.java Source: System built-in Pattern: **/*.java Rule: ──────────────────────────────────────── …contents of java.md… ────────────────────────────────────────
$ ocr rules check --rule custom.json src/main/resources/mapper/UserMapper.xml File: src/main/resources/mapper/UserMapper.xml Source: Custom (--rule) Pattern: **/*mapper*.xml Rule: ──────────────────────────────────────── …contents of your custom rule… ────────────────────────────────────────

实现上,runRulesCheck通过rules.NewResolver构建解析器,调用ResolveDetail拿到RuleDetail(含 Rule 文本、Source 层级、Pattern 模式,嗅探时额外输出Note:标注),再格式化打印(cmd/opencodereview/rules_cmd.go#L45-L82)。命令还支持--repo指定仓库目录。相关测试见 cmd/opencodereview/rules_check_test.go,覆盖了真实 git 仓库下的规则解析与非法仓库目录报错两条路径。

实战配方

项目级:强制编码标准

保存为<repo>/.opencodereview/rule.json并随仓库提交:

{ "rules": [ { "path": "src/api/**/*.go", "rule": "Every public handler must `defer tx.Rollback()` immediately after starting a transaction." }, { "path": "**/*mapper*.xml", "rule": "Check SQL for injection risks, missing parameter binding, and unclosed XML tags." } ] }

从源码看,项目层还支持merge_system_rule: true(system_rules.go#L489-L504)——默认用户规则替换系统规则,而开启此标记后会把命中的系统规则与用户规则合并输出,形成 "System-Specific Rules (Mandatory)" 与 "User-Specific Rules (Mandatory)" 两段,适合"既要系统默认检查、又要团队补充要求"的场景。

项目级:跳过生成代码,聚焦 src

{ "include": ["src/**/*.{ts,tsx,js,jsx}"], "exclude": ["**/*.gen.ts", "**/generated/**"] }

指定include后,src/内的文件即使命中内建默认排除模式(如测试文件)也会保留;src/外的文件照常经过扩展名与默认检查。再次强调:include是"跳过默认排除"的机制,不是白名单。

PR 级覆盖

ocr review --rule ./.review-rules-only-for-this-pr.json

该命令跳过项目层与全局层,为单个 PR提供一套完全不同的审查清单(例如只看安全问题的审查)。用法细节可参考 CLI 参考文档 中ocr review --rule的说明。

个人全局偏好

放在~/.opencodereview/rule.json,该机器上的所有仓库都会继承:

{ "rules": [ { "path": "**/*.{ts,tsx,js,jsx}", "rule": "Always check for unhandled promise rejections; warn on `// eslint-disable` without a reason comment." } ] }

相关文档

  • CLI 参考 ——ocr review --rule--previewocr rules check等命令完整说明
  • 配置指南 —— 配置文件位置与层级解析链
  • 架构文档 —— 解析后的规则如何进入 Agent 提示词

【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibaba's scale. Hybrid architecture code review tool: deterministic pipelines + LLM Agent, precise line-level comments, built-in multi-language ruleset (NPE, thread-safety, XSS, SQL injection), OpenAI & Anthropic compatible.项目地址: https://gitcode.com/GitHub_Trending/op/open-code-review

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询