LobeHub deep-review Logic 维度详解:一套可执行的逻辑正确性审查规则(边界条件、并发、错误路径与需求偏差)
本文围绕 LobeHub 仓库中多智能体代码审查技能(deep-review)的 Logic Correctness 维度规则文件,完整讲解这套"逻辑正确性"审查清单:它检查哪些典型 bug 类别(边界条件、文本解析、null 传播、竞态、错误路径、状态机、需求偏差、回归测试缺口),每一步如何执行检查,以及"什么算违规、什么不算违规"的校准边界。读完你能理解该维度在 LobeHub 的"独立审查 → 独立验证 → 全局去重"流水线中的位置,并把这套清单迁移到自己项目的 code review 实践中。
这个维度在 deep-review 技能中的定位
LobeHub 把代码审查做成了一套可执行的规则体系:审查质量不依赖"更聪明的模型",而是来自细粒度、可执行的维度规则文件,每个维度单独一个 Markdown 文件,告诉审查子代理"怎么查、什么算违规、什么不算违规"。规则统一放在 references/dimensions/ 目录下,共 14 个维度,Logic Correctness 是其中之一,其规则文件是 logic.md。
该文件以 YAML frontmatter 声明了三条元信息,这直接决定了它如何被流水线调度:
id_prefix: logic # 该维度产出的 finding 统一使用 "logic-1"、"logic-2" 这样的 id
verify: true # 该维度的候选发现必须经过独立 verify 子代理证伪后才进报告
skip_when: docs/lockfile-only diff # 仅文档/lockfile 变更的 diff 跳过该维度
结合 SKILL.md 中的维度总表可以确认三件事:
- Logic 维度的 id 前缀是
logic,覆盖范围是"edge cases, null, races, error handling, state machines, requirement deviation, test coverage",且Verified?一列为yes——即它的每条候选发现都要被独立验证。 - 剪枝(pruning)表规定:ai-coding-bad-habits、code-style、logic、business-logic、reuse-architecture 五个维度"never skip(仅 docs/lockfile-only diff 例外)"。也就是说,任何包含代码变更的 diff,逻辑正确性维度都必然被审查,这是所有维度中覆盖面最广的一类。
- 两种模式都复用同一批维度文件:light 模式只读各文件的
Quick checklist小节,deep 模式则读完整文件加上适用的 rule sources 和被路由的参考文档。
在流水线中,Logic 维度处于"找 bug 的经典战场"(classic bug hunt)的角色:它回答"这次改动是否做了需求要求的事,并在真实输入下站得住脚"。而设计层面的判断(框架误用、自己制造复杂度)被明确划给 business-logic 维度,两者的分工边界在 business-logic.md 开头有一句对照说明——"whether the code is correct belongs to the logic dimension; this dimension asks whether it is well-conceived"。
Quick checklist:完整审查清单逐项解析
下面是规则文件 Quick checklist 的全部条目,逐条展开。light 模式的独立审查员只读这一节,deep 模式的审查员则连后面的 "How to check"、"Violations"、"Not violations" 一起读,所以这一节是整个维度的执行核心。
1. 边界条件(Edge cases)
空数组/空字符串、零、边界索引、第一页/最后一页、单元素集合。这是最基础的"枚举输入空间"动作:对每个被修改的函数问一句"什么输入会弄坏它"。
2. 文本解析器/提取器:系统性枚举,而非抽查
这是该维度里最有实战价值的一条,针对 envelope、marker、delimiter 这类基于标记/分隔符做提取的解析函数:
- 要求系统性枚举输入空间,而不是凭感觉抽查。枚举清单至少包括:空 payload、只有 marker 的 payload、body 内部出现 delimiter/marker 字面量、截断/部分输入;
- 有一条重要的"扩散规则":一旦在函数中发现某处 delimiter 查找是脆弱的,必须把同样的攻击应用到该函数里每一处
indexOf/lastIndexOf/ 正则查找——不能只修被点名的那一处。
这与 "How to check" 第 5 步呼应:对文本解析函数,先写出对抗性输入清单(empty、marker-only、body-contains-delimiter、truncated),再逐条对照代码——不允许"想到哪补到哪"。
3. null/undefined 流入假设非空的代码
典型 bug 类别:上游返回了可选值,下游按必达值处理。注意与 verify 阶段的"反证优先"配合——后面会讲到,验证者被要求先找反例(上游保证、早退、框架行为),所以上报此类问题必须确认调用方真的可能传入空值。
4. 竞态条件(Race conditions)
并发变更、过期闭包(stale closures)、顺序有依赖但未 await 的 Promise。
5. 错误处理(Error handling)
失败路径留下"半改状态"(half-mutated state)或 UI 卡死的场景。检查动作是"把每条错误路径追踪到终态":用户收到了什么反馈、状态是否回滚、日志是否落盘。
6. 状态机(State machines)
本次改动之后是否存在不可达/未处理的状态。
7. 需求偏差(Requirement deviation)——本维度最有特色的一条
规则原文的核心论断是:即使代码内部完全自洽,只要 diff 与需求/验收标准/PR、issue、对话中记录的关键决策相矛盾,也要上报。 理由是审查者无法区分"实现中途的合理调整"和"决策被遗忘(上下文丢失、压缩)"。因此修复永远是二选一的:让实现对齐已记录的决策,或者更新记录并说明决策为何改变。
这一条把"逻辑正确"从"代码自洽"扩展到了"与需求记录一致",是纯静态审查工具难以覆盖的角度。
8. 回归测试要求
- Bug fix 必须附带一个覆盖被修复场景的回归测试——注意第 4 步检查要求
ls同目录__tests__/确认"被修复的场景真的被覆盖",而不是"随便动了某个测试"; - 纯样式/CSS 修复是唯一豁免项,因为它的实际断言往往只能是"样式表源字符串匹配",不构成值得发布的回归测试(此豁免引用 testing SKILL.md 的核心原则第 5 条:"After fixing a bug, add a regression test that fails before the fix and passes after",以及同条的 style/CSS skip 说明);
- 新的 service / store action / utility 需要测试覆盖;
- 新的数据库 Model/Repository 必须在同一个 PR 里带上同目录的
__tests__/<name>.test.ts,且包含 user isolation 测试。这一条同样来自 testing SKILL.md("every new file underpackages/database/src/models/**orsrc/repositories/**ships with a sibling__tests__/<name>.test.tsin the same PR"),仓库中确实大量存在这类测试,例如packages/database/src/models/__tests__/agent.test.ts等。
Rule sources 与 "How to check" 五步法
deep 模式的审查员在审 diff 前必须先读两份规则源(rule sources):
- 审查 prompt 中 scope summary 里的需求背景——它是判断"需求偏差"的主要标尺(primary yardstick);
.agents/skills/testing/SKILL.md——回答"什么需要测试、这里的测试如何组织"。
随后的检查流程被固定为 5 步,可以照抄为自己的 review 操作手册:
- 逐行读 diff,带着副作用的视角;对每个被改函数问"什么输入会弄坏它?"
- 追踪每条错误路径到终态:用户反馈、状态回滚、日志三处都要落到。
- 行为对照 scope summary:即使代码内部自洽,偏差也是 finding。
- 对修复类改动:
ls同目录__tests__/,确认被修复的场景确实被覆盖,而不是任何测试被碰过即可。 - 对文本解析函数:先写对抗性输入清单(empty、marker-only、body-contains-delimiter、truncated),再逐项对照代码读——不要随想随评(ad hoc)。
Violations 与 Not violations:校准边界
这套清单同时定义了"什么必须报"和"什么禁止报",后者与 SKILL.md 的核心原则 4(Calibrate to codebase and lifespan)一脉相承。
Violations(必须报告):
- 存在具体的输入/状态序列,能产生错误结果、崩溃、UI 卡死或半提交状态;
- 改动相对需求静默收窄或放宽了行为;
- bug fix 没有附带"本可以抓到原 bug"的测试(纯样式/CSS 修复除外)。
Not violations(禁止报告):
- 系统根本无法产生的假想输入——上报前必须对照调用方核实;
- 无逻辑的平凡胶水代码缺测试;
- 简单需求的简单实现——不要要求防御性编程去覆盖"上游代码已保证不可能"的状态。原文给出的例子是:现有代码库刻意保持乐观更新(optimistic updates)的简单风格,审查要匹配这个基准,而不是要求穷举边界处理(calibration principle)。
"禁止报"这一侧的存在,是这套规则能降低误报率的关键:它把审查基准锚定在"代码库已达到的标准"而不是理想化标准上。
源码纵深:Logic 维度的输出如何在流水线中被消费与校验
以下实现证据说明该维度文件不是孤立文档,而是被 prompt 模板和输出校验器严格消费的规则契约。
Finding 的 JSON 契约:logic-1 示例恰好是本维度的空输入场景
review-prompt.md 是所有审查子代理的统一 prompt 模板,要求输出严格的单 JSON 对象,每条 issue 必含 id、dimension、issue_type、nature、severity、likelihood、location、summary、core_problem、fix_cost、fix_options、need_test 等字段。模板里给出的范例 finding 正是 Logic 维度的产物,且与前面 Quick checklist 第 1 条(空输入)直接对应:
{
"id": "logic-1",
"dimension": "logic",
"issue_type": "empty input",
"nature": "introduced",
"severity": "p1",
"likelihood": "high",
"location": "src/api/user.ts:87",
"summary": "Batch delete accepts an empty id list and builds invalid SQL.",
"core_problem": "Because empty input is not rejected, submitting an empty selection returns a server error.",
"scenario": "The bulk-action UI submits after the final selected row is deselected.",
"fix_cost": "low",
"fix_options": ["Require at least one id in the input schema"],
"need_test": true
}
这里的 core_problem 有固定文风要求:一句话 "Because 〈缺失什么〉, when 〈谁做 X〉, 〈后果〉"——把"根因 + 触发条件 + 后果"压缩成一句可复述的因果链。severity 只表达影响面(p0 生产事故 / p1 本次必须修 / p2 可延后),likelihood 独立表达真实生产路径上的触发频率(high/medium/low),且 likelihood: low 时 scenario 字段必须写出完整的前置条件链。
独立验证:三值判定取代置信度
frontmatter 的 verify: true 对应 verify-prompt.md 定义的独立验证环节:验证子代理与审查子代理永不共用同一个 agent,且返回 confirmed / false_positive / need_more_context 三值判定,而不用"置信度百分比"(SKILL.md 反幻觉原则 1 的解释是:听起来经过校准的分数作为硬过滤并不可靠)。
验证程序对每条 finding 要求 10 步固定动作,其中与 Logic 维度最相关的是:
- 第 3 步"先找反例":找上游保证、早退、框架行为等阻止该场景存在的证据——这正是对 Not violations 第 1 条(假想输入)的程序化落实;
- 第 9 步应用代码库/生命周期校准:广泛存在且本次未恶化 → 判
false_positive,reason 以over-scrutiny:开头; - confirmed 判定必须给出 file-and-line 证据,不确定性只能落为
need_more_context,禁止"猜测式确认"。
Zod 校验器:把清单规则变成机器可查的硬约束
scripts/validate-output.ts 用 Zod 定义了审查输出的 schema,并作为 CLI 入口(validate-output.ts <review|verify|consolidate> [input-file],从文件读取或 stdin 读取,自动提取 ```json 围栏内容)。其中 superRefine 写下的条件校验,正是把 Logic 维度的清单规则翻译成了硬错误:
likelihood === 'low'但缺少scenario→ "low-likelihood findings require scenario";nature === 'exposed_legacy'但缺少exposure/scenario→ 报错(要求给出"改动前触达不到、改动后能被触发"的前后对照);nature === 'introduced'却带了exposure字段 → 报错;- issue id 全局唯一性校验。
也就是说,"low 可能性必须写出完整前置条件链"这类审查纪律,不依赖模型自觉,而是由这段可执行 schema 在流水线中强制拦截。
回归测试豁免的判定路径
Light 模式下,审查员按 light-review-prompt.md 只读 Quick checklist 小节执行同样清单;而清单中"bug fix 必须带回归测试"的判定依据,全部锚定在 testing/SKILL.md 的可验证内容上:回归测试必须"修复前失败、修复后通过";style/CSS 修复(selector、hover、mask、spacing、color)若唯一可行断言是样式表源字符串匹配则豁免;数据库 Model/Repository 的测试走 getTestDB() 集成风格、BM25/全文搜索块用 describe.skipIf(!isServerDB) 保护、且必须测 user isolation。
如何把这套维度规则落到自己的项目
LobeHub 的做法给出一个可复用的结构:一个维度文件 = frontmatter 元信息(id 前缀、是否验证、剪枝条件)+ Quick checklist(两种模式共用的最小清单)+ Rule sources(规则依据的可读文件)+ How to check(固定步骤)+ Violations(必须报)+ Not violations(禁止报,锚定代码库现有基准)。其中对逻辑正确性审查最值钱的三点设计:
- 需求偏差与代码自洽分开判定——"代码没 bug 但和记录的需求矛盾"单独成立为 finding,修复方式二选一(对齐实现 / 更新决策记录);
- 文本解析检查先枚举后读码——对抗性输入清单前置,且一处 delimiter 查找脆弱就同构攻击全部
indexOf/lastIndexOf/正则查找; - 报告纪律机器化——把"low 可能性必须附场景链""遗留代码必须给前后触发的对照"等规则写进 Zod schema,让格式违规在流水线里被自动拒绝,而不是靠审查者自觉。
对于 LobeHub 仓库的使用者,这套文件是只读的规则资产:可以直接阅读各维度文件对照自己项目的 review 习惯做校准,或在 fork/包装仓库中按 SKILL.md "Extension packs" 一节描述的机制(deep-review-* 同名维度文件扩展、新名称维度叠加)为自己的部署补充 Logic 维度的项目级细则,而不需要改动本仓库。
atomcodeClaude 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 StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00