首页
/ LobeHub deep-review Logic 维度详解:一套可执行的逻辑正确性审查规则(边界条件、并发、错误路径与需求偏差)

LobeHub deep-review Logic 维度详解:一套可执行的逻辑正确性审查规则(边界条件、并发、错误路径与需求偏差)

2026-09-04 16:20:34作者:牧宁李

本文围绕 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 中的维度总表可以确认三件事:

  1. Logic 维度的 id 前缀是 logic,覆盖范围是"edge cases, null, races, error handling, state machines, requirement deviation, test coverage",且 Verified? 一列为 yes——即它的每条候选发现都要被独立验证。
  2. 剪枝(pruning)表规定:ai-coding-bad-habits、code-style、logic、business-logic、reuse-architecture 五个维度"never skip(仅 docs/lockfile-only diff 例外)"。也就是说,任何包含代码变更的 diff,逻辑正确性维度都必然被审查,这是所有维度中覆盖面最广的一类。
  3. 两种模式都复用同一批维度文件: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 under packages/database/src/models/** or src/repositories/** ships with a sibling __tests__/<name>.test.ts in the same PR"),仓库中确实大量存在这类测试,例如 packages/database/src/models/__tests__/agent.test.ts 等。

Rule sources 与 "How to check" 五步法

deep 模式的审查员在审 diff 前必须先读两份规则源(rule sources):

  1. 审查 prompt 中 scope summary 里的需求背景——它是判断"需求偏差"的主要标尺(primary yardstick);
  2. .agents/skills/testing/SKILL.md——回答"什么需要测试、这里的测试如何组织"。

随后的检查流程被固定为 5 步,可以照抄为自己的 review 操作手册:

  1. 逐行读 diff,带着副作用的视角;对每个被改函数问"什么输入会弄坏它?"
  2. 追踪每条错误路径到终态:用户反馈、状态回滚、日志三处都要落到。
  3. 行为对照 scope summary:即使代码内部自洽,偏差也是 finding。
  4. 对修复类改动ls 同目录 __tests__/,确认被修复的场景确实被覆盖,而不是任何测试被碰过即可。
  5. 对文本解析函数:先写对抗性输入清单(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 必含 iddimensionissue_typenatureseveritylikelihoodlocationsummarycore_problemfix_costfix_optionsneed_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: lowscenario 字段必须写出完整的前置条件链。

独立验证:三值判定取代置信度

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(禁止报,锚定代码库现有基准)。其中对逻辑正确性审查最值钱的三点设计:

  1. 需求偏差与代码自洽分开判定——"代码没 bug 但和记录的需求矛盾"单独成立为 finding,修复方式二选一(对齐实现 / 更新决策记录);
  2. 文本解析检查先枚举后读码——对抗性输入清单前置,且一处 delimiter 查找脆弱就同构攻击全部 indexOf/lastIndexOf/正则查找;
  3. 报告纪律机器化——把"low 可能性必须附场景链""遗留代码必须给前后触发的对照"等规则写进 Zod schema,让格式违规在流水线里被自动拒绝,而不是靠审查者自觉。

对于 LobeHub 仓库的使用者,这套文件是只读的规则资产:可以直接阅读各维度文件对照自己项目的 review 习惯做校准,或在 fork/包装仓库中按 SKILL.md "Extension packs" 一节描述的机制(deep-review-* 同名维度文件扩展、新名称维度叠加)为自己的部署补充 Logic 维度的项目级细则,而不需要改动本仓库。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.12 K
2.72 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
528
590
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
904
1.82 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
854
1.34 K
docsdocs
暂无描述
Markdown
889
5.78 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.52 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.33 K
1.45 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
982
503
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
540
384