- 人工智能
- AI Agent
- 代码智能体
- 自主智能体
- MCP Clients
- CLI
【免费下载链接】atomcode
Claude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get Started
本文以 atomcode 评审引擎内置的 package.json 评审规则 为主体,完整讲解这条规则覆盖的三类 npm 依赖清单问题(非确定性版本号、dependencies/devDependencies双重声明、scripts引用了未声明的工具依赖),并结合 规则匹配与渲染模块、atomcode review 命令行入口 的源码,说明该规则是如何被自动匹配、按批次作用域注入到评审 Agent 的系统提示词中的,以及如何通过--rules-dir在运行时热替换规则内容而无需重新编译。
一、规则本体:评审引擎对 package.json 的三条检查项
crates/atomcode-review/rules/package_json.md 的完整内容如下:
[package.json] This batch contains package.json; pay extra attention to: - Avoid introducing dependencies with versions set to `latest` or `*`; use deterministic version numbers. Note: when the version number is not on a newly added line, ignore this rule. - Dependency conflicts or duplicate declarations: the same dependency exists in both `dependencies` and `devDependencies` - Required tool dependencies not declared: tool names such as eslint, jest, prettier appear in `scripts` but are not listed in `devDependencies`这五条(含注释行)文本就是评审 Agent 在评审到package.json变更时"额外重点关注"的领域检查清单。逐条拆解其工程含义:
1. 禁止latest/*这类非确定性版本号
"dep": "latest"或"dep": "*"意味着每次安装都可能解析到不同的版本,破坏可复现构建。规则要求评审器在 diff 中新增的依赖行出现这类版本时上报。
特别值得注意的是括号中的限定:"when the version number is not on a newly added line, ignore this rule(当版本号不在新增行上时,忽略此规则)"。这是对评审范围纪律的精确约束——内置评审人格明确要求"只报告由本 diff 新增或修改行引入的问题"(评审人格定义 中的 Review Scope 一节)。也就是说,存量依赖早已是*版本、而本次 diff 只是动了旁边某个字段,不算本次变更引入的问题,不应上报。这条限定直接对应 atomcode 评审体系中"finding 必须锚定到 diff 的新增/修改行"的核心原则。
2.dependencies与devDependencies中的重复声明
同一个包同时出现在两个字段里属于典型的依赖清单错误:安装器行为取决于实现细节(通常是后者覆盖前者),会让"这个包到底是运行时依赖还是开发依赖"变得含糊。规则要求评审器检查这种冲突/重复声明。
3.scripts中引用了未声明的工具
package.json的scripts字段里出现eslint、jest、prettier等工具命令,但devDependencies中并没有声明对应包,是"幽灵依赖"(phantom dependency)的经典形态:开发者本机全局装过该工具时脚本能跑,CI 全新容器里则直接失败。规则要求把这类"脚本用到了、清单没声明"的不一致作为发现上报。
这三条规则恰好覆盖了package.json变更中最高频、也最容易被通用 JSON 规则漏掉的语义问题——通用的 JSON 规则只检查键名拼写,不会理解 npm 依赖语义。两者在仓库中的对照非常直观:
- json.md(泛型
*.json规则)只有一条:"Check for spelling errors in json keys; ignore json-value content."; - package_json.md 则针对 npm 清单的依赖语义给出上面三条专属检查项。
二、规则如何被匹配:match_rule的有序匹配表
规则文档本身是"单一事实来源",编译期通过include_str!嵌入二进制。rules.rs 顶部的模块注释说明:
Built-in rule docs are compiled in from
rules/*.md(the single source of truth);--rules-dir <dir>overrides any rule by name at runtime.
真正把package.json映射到package_json规则的,是MATCHERS有序匹配表(见 rules.rs 第 17-106 行)。其关键条目是:
("package.json", "package_json"), // 具体文件名,优先于泛型扩展名 ... ("*.json", "json"), // 兜底的泛型 JSON 扩展名规则匹配语义有三个要点,源码注释写得很明确:
- FIRST match wins(首个命中生效)。注释特别强调:具体文件名(
build.gradle、package.json、mapper xml)必须排在泛型扩展名(*.json、*.xml)之前,否则package.json会被*.json抢走,只会触发通用的 JSON 键名拼写检查而丢失依赖语义规则。 - 匹配对象是小写化的 basename(不含目录),模式只支持
*通配符,由手写的 wildcard_match 实现(前缀锚定 + 中缀查找 + 后缀锚定)。 - 入口函数 match_rule 返回规则名(如
"package_json"),无匹配则返回None。
单元测试 matcher_order_specific_before_generic 精确锁定了这个优先级行为:
assert_eq!( match_rule("web/package.json"), Some("package_json"), "specific beats *.json" ); assert_eq!(match_rule("conf/settings.json"), Some("json"));即web/package.json命中专属规则,而任意其他*.json(如conf/settings.json)只落入泛型 JSON 规则。另外还有一个守卫测试 every_matcher_rule_has_a_builtin_doc,强制 MATCHERS 中每个规则名都必须在RULE_DOCS中注册了对应文档,防止将来新增匹配项时忘记放入规则文件。
三、规则如何被注入:从 diff 到系统提示词的完整链路
1. 解析变更文件
评审入口先对 diff 做确定性处理。changed_files_from_diff 从 unified diff 的+++ b/<path>行提取变更文件列表(跳过/dev/null表示的删除),与 git 来源无关——PR diff、glab mr diff管道、CI 工件都可以解析。atomcode review的完整调用在 review.rs 第 215 行:
changed_files = atomcode_review::changed_files_from_diff(&diff); // Language rules matched against the changed files. if !args.no_rules { let section = atomcode_review::render_rules_section( &changed_files, args.rules_dir.as_deref(), );同一个changed_files集合还承担第二个职责:作为文件白名单过滤掉锚定在 diff 之外文件上的发现——源码注释称这是模型常见的幻觉(把未变更的代码判成坏的),过滤逻辑见 review.rs 第 188-189 行注释。
2. 分组渲染:一条规则只注入一次,且严格声明作用域
render_rules_section 把变更文件按命中的规则分组,每组生成形如:
## Targeted review focus for this batch (each rule applies ONLY to its listed files) ### Applies to: web/package.json, web/src/package.json [package.json] This batch contains package.json; pay extra attention to: ...这解释了两个设计细节:
- 规则原文开头的 "Thisbatchcontains package.json" 措辞,正对应这里的按批次(batch)注入模式;
### Applies to:一行明确列出该规则只适用于哪些文件,源码注释称之为 scoping——混合语言的变更批次不会互相污染(一条 Go 规则永远不会被应用到 SQL 文件上)。 - 同一规则文档无论匹配到几个文件都只渲染一次,由测试 render_groups_scope_files_and_renders_doc_once 锁定:
assert!(s.contains("Applies to: svc/a.go, svc/b.go"), "same-language files grouped"); assert_eq!(s.matches("[Go]").count(), 1, "go doc rendered once");3. 拼入 persona:规则区段位于内置人格之后
atomcode review把渲染出的规则段放入cfg.persona_append。最终的提示词组成在 assemble.rs 的 compose_persona:(全量覆盖 persona 或内置 reviewer 人格) + "\n\n" + 追加段;CLI 侧在 review.rs 第 356-360 行 保证语言规则段排在用户自定义 append 之前:
cfg.persona_append = match (rules_section, user_append) { (Some(r), Some(u)) => Some(format!("{r}\n\n{u}")), (Some(r), None) => Some(r), (None, u) => u, };同时,CLI 会向 stderr 打印一条可观测性日志,确认规则确实被注入(组合后的系统提示词对调用方不可见):
[rules] injected for 3 changed file(s) 321 chars会话内的code_review工具走完全相同的注入路径——review_tool.rs 第 610-619 行 同样调用render_rules_section(&files, self.cfg.rules_dir.as_deref()),把规则段拼进评审任务文本。
四、运行时热替换:--rules-dir与--no-rules
内置规则是编译期嵌入的,但仓库提供了不重新编译即可调参的通道。atomcode review的两个相关参数(定义见 review.rs 第 85-93 行):
| 参数 | 说明 |
|---|---|
--rules-dir DIR | 从DIR/<name>.md按规则名覆盖内置规则;目录里没有的名字回退到内置版本 |
--no-rules | 完全禁用语言规则注入(例如需要做"干净提示词"的 A/B 实验时) |
覆盖逻辑在 load_rule_doc:先尝试读rules_dir/package_json.md,文件存在且非空就用它;否则回退到编译内置的RULE_DOCS条目(注册位置见 rules.rs 第 136 行)。
要针对自己的团队定制 npm 清单检查(比如额外要求"新增依赖必须写入engines兼容范围"、或豁免某些内部脚手架包),实操方式是:
# 1. 准备覆盖目录,文件名必须与规则名一致 mkdir -p /tmp/my-rules cp <仓库路径>/crates/atomcode-review/rules/package_json.md /tmp/my-rules/package_json.md # 2. 在复制出的文件里增删检查项(其余语言规则仍用内置版) # 3. 运行评审时指向覆盖目录 atomcode review \ --base main \ --rules-dir /tmp/my-rules \ --json几个实用提示:
- 只放
package_json.md即可,不需要复制其他语言的规则文件——缺失的名字自动回退内置,测试 rules_dir_overrides_builtin 验证了这一点:覆盖了go.md后,x.sql仍然走内置 SQL 规则。 - 覆盖文件不能是空文件:
load_rule_doc对trim().is_empty()的内容同样回退内置,防止误清空规则。 - 覆盖只影响"规则文本";匹配逻辑(哪个文件触发哪条规则)始终由源码中的
MATCHERS表决定,要改变触发条件需要改 rules.rs 并重新构建。
五、评审如何消费这些规则:report_finding 与 P 级约束
规则段只是"注意力引导"——它告诉评审器在这个批次里额外关注什么;发现如何被结构化上报,由内置 reviewer 人格统一约束。每个确认的问题必须调用一次report_finding,字段包括title、body、priority(P0 最严重到 P3 最轻)、confidence(0.0–1.0)、file_path、line_start、line_end、suggestion,见 persona.rs 第 96-120 行。对应到本文的规则:
latest/*版本属于"静态可判定的依赖错误"(构建/安装阶段即出错),按人格的降噪规则满足"可锚定到新增行 + 有清晰触发条件 + 有可解释的失败模式"三要素,适合上报;- 人格同时禁止伪造问题("Do not fabricate problems to appear thorough")——这解释了为什么规则原文要为第一条加"仅新增行"的限定:防止模型为了凑发现数而把存量
*版本也报出来。
评审 agent 本身是严格只读的:挂载的工具集只有read_file/grep/glob/list_directory/ast_grep/web_search/report_finding及代码智能工具,写/编辑/bash 工具注册了但从不挂载,由测试 review_mounts_readonly_set_only 锁定(见 assemble.rs 的review_tool_names)。
六、局限与适用前提
- 规则匹配只看小写 basename,不含目录信息:位于任意路径的
package.json(如web/package.json)都会命中,而 pnpm workspace 中命名为package.json的目录级清单与 monorepo 根清单适用同一条规则;若需按目录区分,只能靠--rules-dir统一改写文本。 package-lock.json不在本规则管辖范围,而且它属于低信号文件——is_low_signal_file 会把package-lock.json、pnpm-lock.yaml、yarn.lock等锁文件直接排除出深度评审目标(测试 low_signal_file_covers_common_lockfiles 锁定了这个清单)。锁文件的评审策略是"优先看变更片段",见人格中 III 节的大文件处理原则。- 规则的生效前提是 diff 模式(
--base/--staged/--pr/--diff-file);--task自定义任务模式跳过 diff 计算,也就没有规则注入。
七、小结与可验证路径
本文的核心脉络:一条 5 行的 package_json.md 规则文档,通过 rules.rs 的有序匹配表被精确定位到package.json变更(优先于泛型*.json规则),由render_rules_section分组渲染成带Applies to:作用域的"目标评审焦点"段,经persona_append拼在内置 reviewer 人格之后注入 agent;--rules-dir提供按文件名的运行时覆盖,--no-rules提供整体禁用,覆盖回退与分组行为均有单元级测试锁定。
想自行验证,可以在仓库根目录运行(只跑atomcode-reviewcrate 的规则模块测试):
cargo test -p atomcode-review --lib rules相关入口文件:
- 规则文档:crates/atomcode-review/rules/package_json.md、crates/atomcode-review/rules/json.md
- 匹配与渲染:crates/atomcode-review/src/rules.rs
- 评审 agent 组装与工具挂载:crates/atomcode-review/src/assemble.rs
- 会话内
code_review工具的规则注入:crates/atomcode-review/src/review_tool.rs - CLI 参数与注入日志:crates/atomcode-cli/src/review.rs
- 评审器人格(评审范围/降噪/上报协议):crates/atomcode-review/src/persona.rs
- 人工智能
- AI Agent
- 代码智能体
- 自主智能体
- MCP Clients
- CLI
【免费下载链接】atomcode
Claude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get Started
相关推荐
解析 atomcode-review 的 Makefile 评审规则:构建脚本审查清单与规则注入机制
解析 atomcode review 的 Makefile 评审规则:构建脚本审查清单与规则注入机制 atomcode 的评审子系统 atomcode revi
人工智能AI Agent代码智能体自主智能体MCP ClientsCLIAtomCode Review 的 ArkTS 评审规则深度解析:HarmonyOS .ets 代码审查清单与其注入机制
AtomCode Review 的 ArkTS 评审规则深度解析:HarmonyOS .ets 代码审查清单与其注入机制 在 AtomCode 的内置代码评审能
人工智能AI Agent代码智能体自主智能体MCP ClientsCLIatomcode-review 的 Lua 评审规则:规则注入机制与 Lua 专项检查清单深度解析
atomcode review 的 Lua 评审规则:规则注入机制与 Lua 专项检查清单深度解析 本文以 atomcode review 内置的 lua.md
人工智能AI Agent代码智能体自主智能体MCP ClientsCLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考