LobeHub deep-review Codex 手册:Deep 模式多子代理代码评审的工作队列与槽位编排
本文为 LobeHub 仓库 deep-review 技能的 Codex 环境手册(.agents/skills/deep-review/references/codex/main.md)的完整技术解读:它规定了 Deep 模式如何把多维代码评审拆成可并行的子代理任务,如何在有限的子代理槽位上运行"评审 → 验证 → 合并去重 → 报告 → 交互修复"的端到端工作队列,以及如何用 schema 校验脚本守住每个子代理的返回契约。读完后你可以理解该编排算法中 release(agent)、槽位复用、重试前插、severity 不变式检查等关键机制,并能参照 .agents/skills/deep-review/SKILL.md 在同一套规则上落地到其他编码代理环境。
手册定位:Deep 模式的环境分支
deep-review 是一个多维度代码评审技能,其核心设计来自 SKILL.md:评审广度来自并行的维度覆盖,精确度来自对抗式验证(独立 verify 子代理逐条证伪候选问题)与全局重复根因合并。技能提供两种入口模式——Light 模式(单个独立评审者走各维度 Quick checklist)和 Deep 模式(完整编排:维度评审代理 → 流水线验证 → 全局合并 → 结构化报告 → 交互式修复流),且明确"不自动从 Light 升级为 Deep"。Deep 模式只能在显式调用(/deep-review、"run deep review" 等)时运行,并且在一个逻辑需求(同一需求/PR/分支)内默认最多运行一次;修复后的复看、CI 修复、rebase、清理等后续场景一律使用 Light 模式,这些事件不重置 Deep 预算。
Deep 模式按当前环境选择执行手册,目前只支持两个环境:
- Claude Code → references/claude-code/main.md
- Codex → references/codex/main.md
环境不在列表内时,应告知用户 Deep 模式尚不支持该环境并提供 Light 模式,而不是即兴模拟其他环境的机制。Codex 手册与 Claude Code 手册最本质的差异在于:Claude Code 可以"在一个响应里每个维度并发一个 Task",而 Codex 的可用子代理槽位只有 3 个,因此 Codex 手册的核心贡献是把 14 个维度打包进 4 个复合分组,并围绕"有限的并发槽位 + 可回收的工作槽"设计了完整的工作队列算法。
运行时契约:能力探测与槽位模型
Codex 手册开篇定义的是"运行时契约"(Runtime contract),它要求主代理在 spawn 任何子代理之前先完成能力探测与绑定:
- 先检查会话中已经暴露的协作工具,只在会话明确说明协作工具是延迟加载(deferred)时才使用延迟工具发现;
- 从真实 schema 绑定以下能力:spawn(派生子代理)、wait for any completion(等待任意一个完成)、可选的显式 close/release(关闭/释放)、context inheritance control(上下文继承控制)、active concurrency limit(活跃并发上限);
- 显式把上下文继承设为 none。Codex 手册第一行即强调"每一个派生出的代理都收到自包含的 prompt"。继承无法关闭时,必须在报告中披露"独立性被削弱";spawn 能力不可用时,直接停止并提供 Light 模式;
- 从文档化生命周期中定义唯一的
release(agent)操作,其语义按实际行为三选一:- 完成即自动释放活跃槽位 →
release是空操作(no-op); - 已完成的代理会持有槽位直到显式关闭 →
release就是 close 它; - 槽位复用无法判定或无法实现 → 停止并提供 Light 模式。
- 完成即自动释放活跃槽位 →
手册特别警告:不要仅凭"是否存在 close 动词"来选择算法,槽位复用(slot reuse)才是真正关键的能力。从源码结构看,这条约束呼应了 SKILL.md 的核心原则 2(反自我批准):评审代理必须是独立第三方,主代理绝不能在内部"假装"跑 Deep 模式或退化为"主代理自己评审 diff"。release(agent) 的三态抽象正是为了让上层队列算法与具体环境的子代理生命周期解耦——队列算法只关心"一个槽位何时变空",不关心底层是自动回收还是需要手动 close。
分组表:把维度装进三个槽位
Codex 的分组表(Group table)是把相关维度打包以适配"常规三个可用子代理槽位"的映射方案:
| Group | 包含的维度 |
|---|---|
quality |
ai-coding-bad-habits, code-style, reuse-architecture, business-logic, ux |
correctness |
logic, performance, security, compatibility |
release |
release-risk |
process |
workflow, skill-freshness, observability |
这里的"维度"指 SKILL.md 中定义的 14 个内置维度(规则文件位于 .agents/skills/deep-review/references/dimensions/,每个维度一个文件),例如 logic 覆盖边界条件/空值/竞态/错误处理/状态机/测试覆盖,release-risk 是 ship/no-ship 门禁(不可逆持久化状态、迁移残留、部署时在途任务、prompt 行为漂移、共享面爆炸半径等)。
分组的执行策略在手册中给出三条规则:
- 剪枝(pruning)删除的是维度,空分组随之消失。剪枝标准来自 SKILL.md 的 Pruning table:例如
performance在 diff 未触碰 server/db/循环/渲染路径时跳过,ux在无用户可见面变更时跳过;而 ai-coding-bad-habits、code-style、logic、business-logic、reuse-architecture 五个维度"永不跳过"(仅 docs/lockfile-only diff 例外)。被剪枝的维度及其一行理由要写进报告头部。 - 启动顺序:
release、correctness、quality三组先行,让最大的证据产出流立刻开始;process组排队后置。模型档位上,process组用 fast tier,其余用 balanced tier(规则承载质量,不依赖更大的模型)。 - 扩展包维度:由 sibling 扩展包(如
.agents/skills/deep-review-cloud/)带来的扩展独有维度组成extras组,加入同一个队列,永远不能丢弃。扩展包机制见 SKILL.md 的 Extension packs 一节:同名文件扩展内置维度(两个都加载),新名字新增维度,缺失时技能自足运行。
Step 0 — 确定评审范围与背景
Step 0 要求遵循共享的范围规则 .agents/skills/deep-review/references/scoping.md,产出三样东西:{changes}(diff 文本或取数命令)、不超过 200 词的范围摘要(scope summary),以及 PR 模式下的 PR 元数据。
范围规则中有若干对编排正确性至关重要的细节,值得随手册一并掌握:
git diff恒用三点(<base>...HEAD),绝不用两点,否则会把他人在 base 上合入的新提交反向注入 diff;且 base ref 不能落后于分支真实分叉点,选择顺序为:PR 模式优先gh pr diff <num>→git fetch后origin/<default>...HEAD→ 本地<default>...HEAD(需先确认本地未落后)。用git log --oneline <base>..HEAD(两点)做健全性检查:列表中出现他人提交即说明 base 选错。- 先 stat 后全量、先剔除大文件再判大小:从 stat 与全量 diff 中排除 lockfile、
*.snap、生成文件与构建产物,然后按过滤后的数字分级——超大 diff(> 1500 行) 按目录拆成多个评审范围分批跑;小 diff(≤ 200 行且 ≤ 5 文件) 立即取全量文本作为{changes}内联进 prompt;其余为大型 diff,不取数,把带排除参数的命令本身作为{changes}传给子代理自行执行。未跟踪文件计入规模判断:小 diff 路径下整份内容追加进{changes},大型 diff 路径下列出路径供子代理读取。 - 子模块默认一起评审:给 §2 选定的命令追加
--submodule=log,由 gitlink 新旧对生成子模块 diff 命令(git -C <path> diff <old>..<new>),合并进{changes},发现位置加子模块路径前缀。 - 背景来源按优先级截断:会话上下文 → 用户引用的 issue → 当前分支的 PR(
gh pr list --head $(git branch --show-current)后gh pr view)→ 兜底git log提交信息。
范围摘要之所以有 200 词上限,是因为它会随每个子代理 prompt 一起分发(review-prompt.md 的 {scope_summary} 占位符),它是"这个改动是否违背需求"的首要标尺。
Step 1 — 选择维度与规则文件
按 SKILL.md 的剪枝表剪掉不适用的维度,探测 sibling 扩展包(deep-review-* 目录),并收集每个幸存维度的"内置 + 扩展"规则文件路径。维度文件内部可以路由到按面(surface)划分的参考文档(例如 release-risk 维度路由到 release-risk/ 下的 persisted-state / prompt-surface / rollout-surface 参考),子代理只读与 diff 触及面匹配的路由——这是"按需加载规则"的最后一环,与 review prompt 中"routed references 必须全文读、外部规则源只读相关小节"的要求一致。
Step 2 — 构建自包含 prompt
对每个非空分组,实例化统一的评审 prompt 模板 .agents/skills/deep-review/references/review-prompt.md,填入四个占位符:
{dimensions}→ 分配的维度 id,单一维度(Claude Code 一代理一维度)或复合组(performance, security, compatibility这种 Codex 打包形式)都适用;{dimension_files}→ 维度规则文件路径列表,扩展包对应文件必须一并列出;{scope_summary}→ Step 0 的范围摘要;{changes}→ 小 diff 的全量文本(```diff围栏包裹)或大型 diff 的取数命令。
模板的硬性要求是:替换后的文本就是子代理的全部 prompt,子代理与主代理之间不共享任何上下文,所以 prompt 必须自包含。模板同时内置了三条评审纪律:Calibration(按代码库现有标准而非理想标准衡量,广泛存在且本次未恶化的模式不算发现;声明为临时的代码按生命周期评判,calibration_exempt 维度如 security 除外)、Review scope(发现位置默认必须落在 + 行;遗留代码区分 triggered 与 bystander 两种 exposure)、以及严格的 JSON 返回格式(每条 issue 必含 id、dimension、issue_type、nature、severity、likelihood、location、summary、core_problem、fix_cost、至少一条 fix_options 与 need_test)。Codex 手册在实例化时额外要求:把探测到的继承控制设为 none。
Step 3 — 运行工作队列
这是 Codex 手册区别于 Claude Code 手册的核心:由于槽位有限,Deep 模式被建模为一个显式的工作队列。主代理在整个运行期间维护八类状态:
pendingWork:尚未 spawn 的 review / review-retry / verify / verify-retry 项;active:已 spawn 的工作,以代理 id 为键;reportPool:进入最终报告的已确认发现;releaseChecks:release-risk 的部署前确认项;missingSources:子代理读不到的规则文件路径;workflowFeedback:子代理对评审工作流本身的反馈;needsContext:验证结论为need_more_context的项;- 验证统计(确认真假阳性等计数)。
pendingWork 按固定顺序播种:release → correctness → quality → process → extras,然后填满每个可用槽位。此后进入完成驱动循环:每当一个代理完成,依次执行:
- 调用
release(agent); - 将其从
active移除; - 用校验脚本验证其围栏 payload:
bun run .agents/skills/deep-review/scripts/validate-output.ts <review|verify>,响应经 stdin 或任务级临时文件传入; - 无效 review 输出 → 把完全相同的 review 重试项前插到
pendingWork头部;无效 verify 输出 → 为未解决的原始 id 前插一个重试项(前插保证重试优先于后续新工作); - 有效输出按下述规则处理;
- 从
pendingWork补满每个空槽位。
循环结束的唯一条件:active 与 pendingWork 同时为空。
有效 review 输出的处理
先追加 missing_sources、release_checks、workflow_feedback 到对应累加器,再分区发现:
verify: false维度(workflow、skill-freshness 等客观状态检查/建议型维度)的发现 → 直接进reportPool,不做验证;- 可验证发现 → 按 .agents/skills/deep-review/references/verify-prompt.md 实例化一个 verify 项加入队列,只附带该 payload 需要的维度验证附录(含 release-risk 发现则附 verification/release-risk.md,含 reuse-architecture 发现则附 verification/reuse-architecture.md);
- 零个可验证发现 → 不产生 verify 项。
有效 verify 输出的处理
verify 子代理独立证伪候选发现,且评审与验证永远不得共用一个代理。处理顺序:
- 输入 id 与输出 id 一一比对:缺失、重复或凭空捏造的 id 使对应条目无效,为未解决的原始 id 前插新 verify 项;
- 先应用 override 再交叉检查不变式:应用
severity_override以及 nature/exposure override 后,有效 P0 必须blocks_release、有效 P2 不得 block、有效的release-risk或exposed_legacy发现不得成为 auto-fix;只有 effective 值仍违背不变式才把该 id 退回 verify 队列; - 追加验证器的
workflow_feedback; confirmed→ 应用 override 后入reportPool;false_positive→ 仅记统计;need_more_context→needsContext。
手册最后一条铁律:主代理永不重新验证候选。从设计上看,这把"最终裁判"职能完整交给独立验证代理,验证模板 verify-prompt.md 中规定的 can_auto_fix 判据(低修复成本 + 唯一明显修法 + 无需外部决策 + 少于 3 文件且不触及架构层/数据库 schema/外部契约/用户可见行为/路由/热键/文案/权限边界)与 blocks_release 判据(P0 必 block、P2 必不 block、low 概率除非灾难性不可逆否则不 block)正是主代理在 Step 6 划分"安全修复批次"的依据。
校验脚本:子代理返回契约的机器守门人
队列中每一次 payload 验证都由 .agents/skills/deep-review/scripts/validate-output.ts 执行,它是"规则优于模型"原则的最后一道硬闸门。脚本用 zod 定义了三个 strict schema:
ReviewOutputSchema:顶层issues数组(每条 issue 为 strict 对象,含上节列出的必填字段)+ 可选missing_sources/release_checks/workflow_feedback;superRefine强制四条跨字段规则——exposed_legacy必须带exposure与scenario、introduced必须省略exposure、likelihood: low必须带scenario、reuse-architecture 发现必须带existing_implementations;并检查 issue id 唯一;VerificationOutputSchema:以verdict为判别键的 discriminated union,三个分支(confirmed/false_positive/need_more_context)各自 strict,字段互不越界(例如false_positive不允许出现evidence);confirmed分支若can_auto_fix为 false 必须给出auto_fix_reason;ConsolidationOutputSchema:same_root数组,{id, same_root_as},id 唯一。
入口逻辑(run())支持 review / verify / consolidate 三种 kind,输入可以来自参数指定的文件路径或 stdin,先经 extractJsonPayload 提取 payload——该函数接受围栏内外两种形态:无 ```json 围栏时按裸 JSON 处理,有围栏时要求围栏闭合且全文只有一个 JSON 围栏(多个围栏直接抛 Multiple JSON fences found),然后 JSON.parse + schema parse,失败时把 zod issues 以 JSON 打印到 stderr 并置退出码 1。对应的单测 .agents/skills/deep-review/scripts/validate-output.test.ts 覆盖了:围栏提取与拒绝未闭合/多围栏、裸 JSON 输入、severity: "p3" 被拒、exposed_legacy 缺 exposure 被拒、false_positive 携带越界字段 evidence 被拒、confirmed 携带 severity_override 被接受、consolidate 重复 id 被拒——正好对应队列重试机制所依赖的每一类"无效输出"。
Step 4 — 合并重复根因
队列排空后,若仍有至少两条 confirmed 发现,spawn 一个全新代理,使用 .agents/skills/deep-review/references/consolidate-prompt.md。输入是应用验证器 override 之后、按报告顺序排列的 confirmed 发现(id、dimension、location、summary、evidence、fix options)。合并的判定标准极严:两条发现共享根因当且仅当一个具体修法能同时解决两者,位置相近、主题相近或维度相同都不算;根因选输入序中最早的一条,只返回后续重复 id。
用 validate-output.ts consolidate 校验结果,并额外拒绝四类结构性错误:捏造 id、self-map(指向自身)、环、以及根因晚于其重复项出现;重试合并直至有效,校验通过后才应用映射。0 或 1 条 confirmed 发现直接跳过本步骤。
Step 5 — 渲染报告
渲染严格遵循 .agents/skills/deep-review/references/report-template.md。该模板是 Deep 模式的输出契约,优先级高于任何环境默认评审格式,且结构不可压缩:标题、头部元数据(范围/背景/执行模式与被剪枝维度)、TL;DR、Findings、Statistics 永远渲染——即使零确认发现也要显式写"no confirmed findings"。渲染规则中的关键条款包括:
- 只渲染
confirmed发现;排序为 severity p0 → p1 → p2,同级内按 SKILL.md 维度表顺序分组; - 每个发现必须同时呈现
nature(是否本改动引入)与likelihood(触发概率)——severity 单独从不决定合并门禁; exposed_legacy发现默认不渲染 Fix options、不进"Safe to fix now",而是渲染到Hand off to owner并附 Linear issue 草稿;唯一例外是exposure: triggered的 P0,按正常发现渲染并阻断合并;- P2 超过 6 条时只完整渲染前 6 条,其余折叠为
More P2单行(low likelihood 优先折叠); - PR 模式下按决策表给出 Merge verdict:
isDraft/ 冲突 / 任一 check FAILURE → do not merge yet;in-scope P0 或 P1 confirmed > 0 → fix before merge;否则 good to merge。in-scope 仅指introduced,或 triggered 且 P0 的 legacy;low likelihood 且非阻断的发现不计入前置条件,归入 Follow-ups。
渲染完成后必须执行模板的 pre-send self-check(逐条核对标题/元数据、每个严重度桶内发现的必备字段、legacy 发现的归属唯一性、release_checks 未被计入发现统计、out-of-scope 与 low-likelihood 项未出现在合并前置条件中),任何缺失都要修复后重渲染。
Step 6–8 — 交互式修复流
队列与报告之后是三段受控的交互:
Step 6 — 提供安全批次。当 Safe to fix now 非空时,用 request_user_input 恰好一次询问:"Safe to fix now" has N low-risk findings — apply them all in one pass?,选项为 Fix all / Not now,自由文本可表达部分选择;对 need_test: true 的项同步应用回归测试。批次判据就是 verify 阶段写入的 can_auto_fix: true(单一明显修法、低风险、无产品决策、仅本改动引入)。
Step 7 — 逐条走过剩余决策。对 confirmed 且 can_auto_fix: false 的项与 needsContext 项一次只问一个发现,顺序 P0 → P1 → P2、阻断项优先;排除所有 legacy 交接项;复看(repeat review)时跳过 low likelihood 且非阻断的项,除非用户要求。
Step 8 — 提供遗留交接 issue。当存在 legacy hand-off 时,只询问一次是否创建 all / some / no Linear issue;批准前不创建任何东西;批准后使用 linear 技能(.agents/skills/linear/SKILL.md),issue 内容须包含 location、culprit、scenario、likelihood 与验证证据。culprit 来自 verify 阶段用 git log -L / git blame 归因的字段,渲染阶段不重跑 blame。
边界条件与扩展性说明
手册末尾的 Notes 给出三条补充边界:
- 小 diff 判定:≤ 200 行且 ≤ 5 文件时内联 diff 文本进 prompt;否则只传取数命令,由子代理自行执行(与 scoping.md §3 的分级完全对应);
- PR 模式触发:GitHub URL 或无歧义的
PR #123/pr 123/pull request 123;裸#123有歧义,不触发 PR 模式,也就不渲染 Merge verdict; - 提高并发上限时的行为:若并发槽位增加到 4 个,四个内置分组可以一起启动——同一个队列算法依然成立,因为算法只依赖"任意完成 → release → 补槽"这一不变式,而不假设具体槽位数。
从源码结构看,这三点共同保证了手册的可移植性:队列状态机、schema 校验、override 不变式与渲染契约全部与槽位数解耦,环境差异被压缩到"运行时契约"一节的能力探测与 release(agent) 定义中。这也解释了为什么 SKILL.md 可以为新环境增加手册时只需编写"环境分支"而无需改动维度规则、prompt 模板与校验脚本——这些共享工件(scoping.md、review-prompt.md、verify-prompt.md、consolidate-prompt.md、report-template.md、validate-output.ts)在 Codex 与 Claude Code 两条手册中被原样引用,形成"一份规则、多份编排"的分层设计。
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 StartedRust0623
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