- 人工智能
- 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 内置的 lua.md 评审规则文档为主体,完整解读其中面向 Lua 代码的六个专项检查维度,并结合 rules.rs 的源码,讲清这份规则是如何被匹配、编译进二进制、按需注入评审 agent 系统提示词的,以及如何用--rules-dir在不重新编译的前提下热调整规则。读完你可以直接复制这套清单人工评审 Lua 变更,也可以为自己的项目定制 Lua 评审规则。
规则文档在仓库中的位置与角色
crates/atomcode-review/rules/目录是 atomcode-review 所有内置语言评审规则的单一事实来源(single source of truth)。每个.md文件是一份针对特定语言/文件类型的“评审重点清单”,开头一行[Lua] This batch contains Lua code; pay extra attention to:这样的标注用于让模型明确该段规则的作用对象。这些文档通过include_str!在编译期打进二进制:
- 规则文档注册在 rules.rs 的
RULE_DOCS表中(("lua", include_str!("../rules/lua.md"))); - 文件模式匹配表
MATCHERS中("*.lua", "lua")一行声明了“凡 diff 中变更的文件名以.lua结尾,就套用lua规则”; - 完整支持列表与匹配顺序见 LANGUAGES.md。
规则不是全量塞进提示词,而是按本次 diff 实际变更的文件按需注入——这是后文机制部分的重点。
Lua 专项检查清单:原文六大维度逐条解读
以下完整继承 lua.md 的原始内容,并在每个维度下补充该检查点背后的 Lua 语言原理,帮助理解“为什么值得查”。
1. 拼写错误与死代码(Typos / Dead Code)
原文要求关注:
- 声明处的
local/函数/字段名拼写错误(不要在调用处报告)、日志/错误消息中的拼写错误; - 不可达代码、未使用的
local、大段被注释掉的代码块。
要点在于“在声明处报告,而不是调用处”。这利用了 Lua 的一个特性:拼错一个local变量名(例如把connetion声明后写成connection去用),编译器不会报错——未声明的标识符在 Lua 里静默地变成全局变量读写,错误要到运行时才以诡异方式暴露。因此评审锚点必须放在“写错的那个声明行”,而不是每一个用错的地方,避免同一缺陷被重复上报多次。
2. 错误处理(Error Handling)
pcall/xpcall的返回值被忽略(没有检查ok, err二元组);在必须恢复的路径上抛出error()却从未被捕获;- 函数以
nil, err约定返回错误,调用方只取了第一个返回值,把错误直接丢掉。
Lua 没有原生异常(LuaJIT 环境尤其如此),社区通用错误协议是ok, err = pcall(fn)或result, err = fn()。这条规则针对的是最常见的两种破坏:pcall(fn)单值调用(ok被丢弃,异常被静默吞掉)和local data = load_cfg()单值取用(err被丢弃,失败路径无感知)。评审时应确认每一处可能失败的调用都检查了第二个返回值。
3. 易错语义(Error-Prone Semantics)
这一节是清单中信息密度最高的部分,对应 Lua 语言里最反直觉的几处设计:
- 意外全局变量:忘记写
local的赋值会泄漏或覆盖共享状态——尤其是for循环外的循环变量、模块文件里的临时变量;对nil值做索引(t.field而t为nil)会直接运行时错误; - nil 与 false 的真值性:Lua 中只有
nil和false是假值,0和""都是真值。这导致if x then无法像 JavaScript 那样靠“0/空串为假”做防御,if count then之类的判断是错的; - 1 基索引的 off-by-one:循环边界、切片逻辑容易差一;
#t长度运算符对含nil空洞的表结果未定义(table.insert(t, 5, nil)之后的#t行为依实现而异);ipairs在第一个nil处停止——这意味着用ipairs遍历带空洞的表会静默截断;- 整数/浮点与类型转换陷阱:Lua 5.3+ 引入整数(integer)与浮点(float)双数值类型,
//整除、%取模、大整数精度、以及字符串与数字之间的隐式转换("10" + 1合法但"10" .. 1不合法)都是易错点。
这几条本质上是把“Lua 语言规范中最容易写出 bug 的语义”固化成了评审检查点,是典型的“按语言特性定制规则”的范例。
4. 安全(Security)
- 代码注入:对不可信输入执行
loadstring/load/dofile/loadfile等价于任意代码执行; - 命令注入:
os.execute/io.popen拼接外部输入; - SQL 注入:用
string.format/字符串拼接构造查询(在 OpenResty/lua-resty-mysql 场景下尤其常见),应改用参数绑定或转义 API; - OpenResty 特有:不校验就信任
ngx.req/ngx.var的输入;用户可控路径导致的 path traversal;硬编码密钥。
这条规则明显面向 Lua 的真实生产主战场——Nginx/OpenResty 网关脚本。与 shell.md 等通用规则不同,它在同一类别下按生态(OpenResty、lua-resty-mysql)细分了风险面,说明每份规则文档都是按“该语言最常见部署形态”定制的。
5. 并发与资源(Concurrency and Resources)
清单特别注明“仅在以下情况报告”,并给出了明确的反例排除:
- 文件/socket 句柄(
io.open、socket)在错误路径上没有被关闭; - 协程挂起后一直持有资源不释放;在 OpenResty 中用同步 I/O 阻塞事件循环;
- 不要报告:局部、短生命周期且已经关闭的句柄。
“report only in the following cases” + “Do not report” 的写法值得注意:规则不仅告诉评审模型“查什么”,还明确“不要报什么”,这是控制误报率(false positive)的关键手段——与 persona.rs 中“纯格式/命名偏好属于噪声,一律不上报”的全局纪律形成配合。
6. 性能(Performance)
- 循环内用
..拼接字符串——Lua 字符串不可变,每次..都产生新串,O(n²) 分配;正确做法是攒进表再table.concat; - 热循环中反复做全局查找——应局部化(
local绑定或 upvalue),因为全局表查找比 upvalue 读取慢得多; - 循环中反复重建/重哈希大表;可以提升到循环外的模式编译(
string.match的 pattern 会预编译,重复编译是浪费)。
规则是如何被注入的:从 diff 到系统提示词
理解完清单内容,再看它的生命周期。整条链路在源码中都可验证:
第 1 步:从 diff 解析变更文件集
changed_files_from_diff 逐行扫描统一 diff 中的+++ b/<path>行(/dev/null表示删除,跳过),与 git/PR/stdin 来源无关。CLI 入口 review.rs 在拿到 diff 后立即调用它得到changed_files——这个集合既驱动规则匹配,也用于后续“丢弃锚定在 diff 之外文件上的 finding”的确定性过滤。
第 2 步:按文件名匹配规则(first match wins)
match_rule 取路径的小写 basename,与MATCHERS表逐项做*通配匹配,第一个命中者胜出。表序有意安排为“具体文件名优先于泛化扩展名”(如package.json排在*.json之前),对 Lua 来说就是简单的*.lua→lua。同一次 diff 可以同时命中多条规则——例如改了src/handler.lua和conf/app.yaml,会同时注入lua与yaml规则。
第 3 步:分组渲染,一份文档只渲染一次
render_rules_section 把变更文件按规则名分组,输出形如:
## Targeted review focus for this batch (each rule applies ONLY to its listed files) ### Applies to: src/handler.lua, test/handler_spec.lua [Lua] This batch contains Lua code; pay extra attention to: ...(lua.md 全文)两个设计要点:
- 作用域隔离:每个规则段落显式列出它适用的文件名(
### Applies to: ...),混合语言批次不会互相污染——“Go 规则永远不会被应用到 SQL 文件上”(见 rules.rs 头部注释); - 同规则多文件去重:同一语言的 N 个文件共享一份文档渲染(测试 rules.rs 中的 render_groups_scope_files_and_renders_doc_once 断言文档只出现一次),控制提示词体积。
第 4 步:追加到 persona 之后
在 review.rs 的组装逻辑里,渲染出的规则段被放进cfg.persona_append,与用户通过--append-system-prompt提供的内容按“引擎注入的语言规则在前、用户追加在后”的顺序拼接,最终成为内置 reviewer persona(persona.rs)之后的附加系统提示词。命令还在 stderr 打印可观测性日志[rules] injected for N changed file(s) (M chars),让调用方确认规则确实被注入。
除了atomcode review命令,挂在宿主 agent 上的code_review子代理工具走完全相同的渲染路径(review_tool.rs 中同样调用render_rules_section(&files, self.cfg.rules_dir.as_deref())),所以无论独立评审还是宿主内评审,Lua 规则都会随*.lua变更文件出现。
相关配套:Lua 文件能用哪些只读工具调查
评审 agent 只挂载只读工具集(read_file/grep/glob/list_directory/ast_grep/report_finding,以及可选的 web 与代码图工具,见 assemble.rs)。这里有一个值得注意的实现事实:codeintel 代码图的语言枚举 lang.rs 目前不包含 Lua,因此对 Lua 文件的跨文件引用分析(find_references/trace_callers等)不可用,评审 agent 对 Lua 的上下文调查主要依赖read_file/grep/ast_grep——这也解释了为什么 Lua 规则清单中大量依赖“阅读声明处”的静态检查点而非引用图查询。
运行时定制:--rules-dir与--no-rules
内置规则是编译期打进二进制的,但 load_rule_doc 提供了按名覆盖的运行时机制:只要<rules-dir>/<name>.md存在且非空,就用它替代内置版本;目录里没有的规则仍回退到内置。对应 CLI 参数:
--rules-dir <dir>:从目录热调整规则,缺失的名字自动回退内置;--no-rules:完全禁用语言规则注入(提示词 A/B 实验用的干净基线)。
典型工作流(引自 LANGUAGES.md 并替换为 Lua):
mkdir -p ./my-rules cp crates/atomcode-review/rules/lua.md ./my-rules/lua.md # 编辑 ./my-rules/lua.md —— 例如增加团队特有的 Nginx 配置约定、 # 收紧“死代码”标准,或删除不适用的 OpenResty 条目 atomcode review --rules-dir ./my-rules这个覆盖行为由测试 rules_dir_overrides_builtin 验证:目录中的go.md覆盖内置 Go 规则,而目录里没有的 SQL 规则继续用内置版。另有一个守护测试 every_matcher_rule_has_a_builtin_doc 保证MATCHERS里每一条规则都在RULE_DOCS中注册了文档,防止新增匹配项时忘记附上规则文档。
小结
lua.md 看似只是一份几十行的 checklist,实则是 atomcode-review “按文件类型精准注入语言专家视角”机制的一块拼图:
- 内容层:六个维度(拼写/死代码、错误处理、易错语义、安全、并发资源、性能)全部锚定 Lua 语言的真实陷阱——
pcall返回值丢弃、nil/false真值性、ipairs截断、5.3+ 双数值类型、loadstring注入、OpenResty 输入校验、循环内..拼接——并用 “Do not report” 显式压误报; - 机制层:
*.lua变更文件触发匹配 → 规则文档按组渲染一次并标明作用文件 → 追加在 reviewer persona 之后,实现“同语言不重复、跨语言不串扰”; - 定制层:
--rules-dir支持按名热覆盖、--no-rules支持完全关闭,规则调优不需要重编译。
这套“规则即文档、注入即提示词”的模式也适用于其余 40 余种语言规则(完整清单见 LANGUAGES.md),理解了 Lua 这一份,就理解了整个规则体系的工作方式。
- 人工智能
- 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 的 ArkTS 评审规则深度解析:HarmonyOS .ets 代码审查清单与其注入机制
AtomCode Review 的 ArkTS 评审规则深度解析:HarmonyOS .ets 代码审查清单与其注入机制 在 AtomCode 的内置代码评审能
人工智能AI Agent代码智能体自主智能体MCP ClientsCLIAtomCode Review 的按语言规则注入机制:以 C 语言审查清单 (rules/c.md) 为例
AtomCode Review 的按语言规则注入机制:以 C 语言审查清单 rules/c.md 为例 AtomCode 的 atomcode review 是
人工智能AI Agent代码智能体自主智能体MCP ClientsCLIatomcode-review 的 Kotlin 评审规则:一份被注入到只读评审 Agent 系统提示词中的语言专项检查清单
atomcode review 的 Kotlin 评审规则:一份被注入到只读评审 Agent 系统提示词中的语言专项检查清单 本文以 Kotlin 评审规则 h
人工智能AI Agent代码智能体自主智能体MCP ClientsCLI
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考