尧图精选

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

🕒 发布时间:2026/9/13 5:03:06 📁 来源:尧图网络
open-code-review 审查规则体系完全指南优先级链、rule.json 配置与文件过滤原理【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibabas 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-reviewOCR的官方规则文档 pages/src/content/docs/ko/review-rules.md 展开结合仓库源码与测试系统讲解 OCR 的审查规则Review Rules机制规则如何通过四层优先级链决定每个文件该被 LLM 用什么标准审查rule.json的三个独立字段include/exclude/rules如何编写以及五道关卡的文件过滤算法如何把 diff 中的文件送到模型面前。读完本篇你将能够为任意项目编写项目级、全局级甚至单 PR 级别的自定义规则并能用ocr rules check与ocr review --preview调试规则生效路径。规则是什么告诉 LLM 审什么规则Rules是 OCR 审查时的注意力控制器。它回答一个问题当审查src/api/user.go或UserMapper.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/IsUserIncludedsystem_rules.go#L226-L263Include为空时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结尾会被当作规则文件引用并读取其内容替换resolveRuleEntriessystem_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]——字符类。模式匹配大小写不敏感路径会先转小写再匹配。源码中resolveDetail与matchProjectRuleEntry都执行strings.ToLowersystem_rules.go#L166-L177、system_rules.go#L535-L553花括号展开由expandBraces完成。拿不准时用ocr rules check path验证。文件如何被过滤五道关卡过滤器是位于 internal/agent/preview.go 的五道关卡算法whyExcludedpreview.go#L34-L60。对 diff 中的每个文件OCR 依次询问binary——是二进制文件吗是则排除。user_exclude——路径命中用户exclude模式吗命中则排除。user_include——用户定义了include时路径命中吗命中则直接放行跳过下面的unsupported_ext与default_path关卡。unsupported_ext——文件扩展名在允许列表中吗不在则排除。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.Previewreview_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 开始决定用什么规则审。对每个文件按声明顺序查--rulecustom层按声明顺序查repo/.opencodereview/rule.json按声明顺序查~/.opencodereview/rule.json落到内建系统规则层。系统层内建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 —— BicepAzure模板**/*.elmelm.md —— Elm 源码**/*.{jsonnet,libsonnet}jsonnet.md —— Jsonnet 配置模板与库**/*.thriftthrift.md —— Apache Thrift IDL 通信兼容性**/*.capnpcapnp.md —— Capn 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 中还有文档表格未列出的模式如**/*.pug→pug.md、**/*.nix→nix.md、**/*.{hs,lhs}→haskell.md、**/*.{nim,nims,nimble}→nim.md、**/*.swift→swift.md、**/*.zig→zig.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 的内容showAtRefsniffer.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: truesystem_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、--preview、ocr rules check等命令完整说明配置指南 —— 配置文件位置与层级解析链架构文档 —— 解析后的规则如何进入 Agent 提示词【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibabas 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),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →