news 2026/9/13 11:38:53

OpenObserve 双 AI 代码审查循环 o2-loop 实战:review.md 审查提示词的设计、优先级清单与工程化验证机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenObserve 双 AI 代码审查循环 o2-loop 实战:review.md 审查提示词的设计、优先级清单与工程化验证机制

OpenObserve 双 AI 代码审查循环 o2-loop 实战:review.md 审查提示词的设计、优先级清单与工程化验证机制

【免费下载链接】openobserveOpen source observability platform for logs, metrics, traces, RUM, Session replay, pipelines, SLO and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.项目地址: https://gitcode.com/GitHub_Trending/op/openobserve

OpenObserve 仓库的.claude/skills/o2-loop技能实现了一套"规划—编码—独立审查—修复—验证"的双 AI 循环(two-AI loop):主会话(orchestrator)只编排,o2-coder子代理实现变更,一个独立审查进程逐轮对冻结的 WIP 提交做代码审查并返回结构化 verdict。本文以该技能的核心审查提示词 review.md 为骨架,结合 verify.md、review.json、review.sh 与 loop-state.py 等配套文件,完整拆解审查提示词的设计原则、八类审查优先级、结构化输出协议,以及围绕它的沙箱、快照与状态机机制。读完本文,你将理解如何为"AI 写代码、AI 审代码"的工作流设计一套不依赖模型记忆、可逐轮收敛、可审计的审查协议,并可直接复用这套模式到自己的仓库。

一、o2-loop 整体架构:四个角色与一份账本(Ledger)

在深入 review.md 之前,先建立上下文。根据 SKILL.md,o2-loop 刻意将四个角色分开,每个角色只做自己那一份工作,价值正来自于"不越界":

角色执行者职责
orchestrator(编排者)主会话与用户讨论方案、写spec.md、拉起 coder、运行 reviewer、按loop-state.py推进、转发 verdict、写报告
coder(编码者)o2-coder子代理(定义见 o2-coder.md)实现 spec、运行门禁(gate)、逐条回应 findings;跨轮次用 SendMessage 延续上下文
reviewer(审查者)每轮一个全新进程(Codex CLI 或沙箱化claude -p审查冻结的 WIP 提交、验证此前 findings、返回verdict.json
user(用户)确认方案、观看进度、裁决延后或有争议的条目、做最终审查

关键约束是:orchestrator 不编辑代码、不审查代码coder 永不提交(WIP 提交由 review.sh 冻结);reviewer 永不写入(只在一次性 worktree 中只读审查)。循环的"记忆"不依赖任何会话上下文,而是落在一份位于仓库之外的账本目录中:

~/.claude/o2-loop/<repo>/<branch-slug>/ spec.md # 编排者写的确认方案 round-N/evidence.md # coder 本轮的门禁运行结果 round-N/commit, backend # 本轮被审查的 WIP 提交 SHA 与后端类型 round-N/verdict.json # 审查者的结构化 verdict round-N/coder-response.json # coder 对每条 finding 的 fix/dispute/partial/defer 回应 round-N/prompt.md, diff.patch, delta.patch # review.sh 生成 round-N/also/<repo>/ # 配对仓库(如 o2-enterprise)的同类产物 report.md # 循环结束时编排者写的报告

账本必须位于 checkout 之外,否则会被扫进 WIP 提交;同一 checkout 同一分支同时只允许一个循环。

二、review.md 提示词解析:第一轮审查者的行为准则

review.md 是审查提示词的本体,它定义了第一轮审查者("two-AI loop 中的第二个 reviewer")的完整行为协议。全文分为四部分:审查前的准备、审查什么、不报告什么、输出规则。

2.1 审查前准备:仓库规则与证据文件

提示词要求审查者在看 diff 之前做两件事:

  1. 读仓库根目录的 CLAUDE.md。它对 item ordering(条目排序)、注释(comments)、clippy 阈值的规定是"本仓库的硬性要求"(hard requirements)。CLAUDE.md 中确实如此:Rust 文件内条目自上而下必须按mod/use/macro/const/static/类型/impl/函数排列;注释"一行或没有"、只解释 WHY、禁止叙述性注释;#[cfg(test)] mod tests永远是文件最后一个条目;函数长度、认知复杂度、嵌套深度由 clippy.toml 的阈值封顶(too-many-lines-threshold = 1024cognitive-complexity-threshold = 100excessive-nesting-threshold = 10),且这些阈值只降不升。

  2. 读 evidence 文件(build、clippy、test 结果,由 coder 提前写入round-N/evidence.md)。提示词明确写道:不要重跑 cargo,沙箱是只读的——审查者信任 coder 的 evidence,把算力花在代码逻辑上,而非重复编译。

2.2 审查范围:只审变更集

提示词强调"Only the change set described in the 'Change set' section":只审查变更集。可以读周边代码来判断变更是否正确,但不得报告 diff 之外的历史问题,除非这个 diff 使问题恶化("do not report pre-existing problems outside the diff unless the diff makes them worse")。这保证了审查产出聚焦、可操作,不会被存量债务淹没。

2.3 八类审查优先级清单

这是 review.md 的核心资产,按优先级排序:

  1. 正确性(Correctness):错误逻辑、off-by-one、未处理的边界情况、被破坏的不变量、错误的 SQL 或时间范围数学(time-range math)。这是第一优先级,对应 review.json 中的correctnesscategory。
  2. 并发与资源处理(Concurrency and resource handling):跨await持有锁(lock held across await)、死锁、泄漏、无界增长(unbounded growth)、缺失取消处理(missing cancellation handling)。
  3. 安全(Security):路径遍历、注入、认证或 org 作用域绕过(auth or org-scoping bypass)、用户输入未转义进入 headers 或 logs。对于 OpenObserve 这种多租户可观测性平台,org 作用域是核心安全边界。
  4. 错误处理(Error handling):吞掉的错误、可失败路径上的unwrap、错误的状态码、结果静默截断。
  5. API 与兼容性契约(API and compatibility contracts):wire-format 变更、enterprisecfg门(feature gate)、OSS 与 enterprise 构建之间的行为差异。这与 CLAUDE.md 的"Enterprise-gated code"一节呼应:默认 features 不编译#[cfg(feature = "enterprise")]代码,本地绿色检查证明不了 enterprise 代码正确,需要换入 o2-enterprise 仓库的Cargo.toml.openobserve验证。
  6. 热路径性能回归(Performance regressions on hot paths):循环内多余的分配或 clone、O(n²)、不必要的全表扫描、高基数标签的指标(metrics with high-cardinality labels)。
  7. 仓库约定(Repo conventions from CLAUDE.md):多行或叙述性注释、函数放在常量或类型定义之上、测试模块不是最后一个、pub与私有函数交错排列。
  8. 缺失测试(Missing tests):新分支没有测试,或"不可能失败的测试"(tests that cannot fail)。

2.4 不报告什么:反模式清单

提示词同样明确划出红线,避免审查者刷噪音:

  • 格式问题、命名品味(formatting, naming taste);
  • 任何cargo fmtcargo clippy已经强制的内容(机器能抓的,人不报);
  • 无法指向具体代码行的推测性问题(speculative issues you cannot point to a concrete line for)。

2.5 输出规则:结构化 verdict

第一轮输出必须遵守:

  • 每条 finding 必须命名repo(变更集或配对仓库给出的仓库名)、引用该 checkout 中真实的fileline,并在detail中说明"触发输入或状态 + 错误结果"。line仅允许在文件级 finding(如缺失测试文件)时为 null,且永远不允许出现在 low 以上严重级别中。
  • 每个 finding 有稳定 idF<n>(F1 起),后续轮次引用这些 id——这就是跨轮次追踪的基础。
  • verdict:只要存在 critical、high 或 medium 的 finding 就是request_changes;只剩 low 时为approve,findings 保留为可选项。
  • prior_findings在第一轮必须为空数组。
  • summary用两三句话概括变更的整体质量与主要风险。

三、结构化输出协议:review.json Schema 详解

reviewer 的结果不是自由文本,而是受 review.json JSON Schema 约束的结构化文档,顶层四个必填字段:verdictsummaryfindingsprior_findings

  • verdict:枚举approve/request_changes
  • findings:数组,每条必含idseveritycategoryrepofilelinetitledetailsuggestion九个字段:
    • severity枚举critical/high/medium/low
    • category枚举correctness/concurrency/security/performance/error-handling/api-contract/convention/test-coverage/other,正好覆盖 review.md 的八类优先级加一个兜底;
    • line类型为整数或 null。
  • prior_findings:数组,每条含idstatusnote,其中status枚举resolved/still_open/withdrawn

Codex 后端通过--output-schema直接约束模型输出(见 review.sh 中codex exec ... --output-schema ...的调用),Claude 后端则通过--json-schema施加同样的约束,确保无论用哪个模型的审查结果都能被下游脚本无歧义解析。

四、多轮验证:verify.md 与 prior findings 的生命周期

第一轮之后,审查循环进入"修复—验证"阶段。审查者是一个每轮全新、无记忆的进程,因此 verify.md 必须把"上下文"全部内联进提示词。它定义了两个步骤:

Step 1:验证每一条 prior finding。任何 id 只要其最新状态不是resolvedwithdrawn就视为 open。对每条 open finding,审查者必须输出prior_findings条目,三种状态:

  • resolved:coder 改了代码且缺陷已消失——必须读当前代码确认,而不是相信 coder 的回应("Confirm by reading the current code, not by trusting the response");
  • still_open:缺陷仍在、修复不完整或引入了新问题,须说明具体仍错在哪;
  • withdrawn:coder 驳回了 finding 且论证正确——只被代码说服,不被语气说服;仍不信服就标still_open并给出带 file 和 line 的具体反驳。

Step 2:只审查自上一轮以来的 delta。用与第一轮相同的优先级(correctness、concurrency、security、error handling、API contracts、performance、CLAUDE.md conventions、missing tests)审查上一轮提交与本轮提交之间的差异;新 finding 的 id 必须接在历史最高 id 之后连续编号。

verdict 判定:仅当没有still_open的 critical/high/medium 级 prior finding、且没有新的 critical/high/medium 级 finding 时,才允许approve。这个规则与 review.md 的规则(有任何中高严重级就 request_changes)完全对齐。

五、工程化封装:review.sh 的快照、沙箱与多后端合并

提示词只是协议,真正的执行引擎是 review.sh(用法见 SKILL.md 与脚本内置--help)。它的几个关键机制让"独立审查"名副其实:

不可变快照。每轮先记录工作树为本地 WIP 提交wip(o2-loop): round N,审查者看到的是一份不可变的提交(round-N/commit),调用方事后可验证 HEAD 仍等于该提交且git status --porcelain为空,从而证明审查期间无任何变更。Round 1 审查相对 base 的完整 diff(diff.patch);Round N>1 审查相对上一轮提交的 delta(delta.patch),同时验证此前 findings 的修复。

一次性 worktree + 沙箱。审查者在git worktree add --detach创建的一次性 checkout 中运行,结束后移除。Claude 后端额外由 macOS seatbelt(sandbox-exec)包裹:默认拒绝一切写入,仅放行 worktree 的 git 元数据、临时目录和 claude 自身状态,且显式 deny 被审查 checkout 本身——审查者物理上无法污染被审查代码。每次审查进程结束后还要校验 worktree 仍等于提交,漂移即作废 verdict(check_drift)。在无sandbox-exec的主机上必须显式传--unsandboxed,此时审查者没有 Bash、读不到 ledger,patch 以内联形式放进提示词(每个 200 KB,整份提示词最多 600 KB)。

多后端与并行合并。--backend auto默认优先 Codex(不同厂商模型,是比"Claude 审 Claude"更强的第二意见),找不到 Codex CLI 才回退到沙箱化claude -p并给出警告;--backend both让 Codex 与 Claude 并行审查同一提交,由 merge-verdicts.py 合并:任一方 request_changes 即 request_changes,finding 重新编号为CX<round>-<n>/CL<round>-<n>,近似重复合并,prior finding 任一方认为仍开就保持 open。Claude 后端还会先用一半预算跑一个/code-review预扫描生成候选 findings(见 candidates.py),审查者必须逐条对照代码确认后才能采纳——候选只是线索,不是结论。

预算与超时。--max-budget-usd默认 15 美元封顶整轮(Claude 后端),预扫描最多花一半;--timeout默认 1800 秒,预扫描耗掉的时间从审查者配额中扣除。退出码约定:0 = approve,10 = request_changes,1 = 任何错误。

六、状态机:loop-state.py 如何判定"下一件只做一件事"

循环推进由 loop-state.py 单点裁决,每步执行后都运行它并严格照ACTION:行事,不允许自己决定下一步。状态机逻辑(decide函数)要点:

  • 没有任何轮次:start,先写 spec.md 与 round-1/evidence.md;
  • 有轮次但缺 evidence / 无 verdict:evidence/review
  • verdict 存在但 coder 未回应(缺 coder-response.json 或仍有 finding 未应答):respond
  • 达成**一致(agreed)**需同时满足:最后 verdict 是approve、没有 critical/high/medium 原始严重级的 open finding、每个 open low 都以defer应答、coder 的open_items为空、HEAD 等于被审查提交且工作树干净——approve 之后任何编辑都会使一致失效,需要再来一轮
  • 未达成一致:next(coder 修复并写 evidence 后进入下一轮)、cap(达到轮次上限,默认 5,先写 interim report 再问用户是否续最多 3 轮)。

BLOCKING = {"critical", "high", "medium"}直接编码了 review.md 的 verdict 规则;finding_registry用"id → 最新状态"的注册表追踪每条 finding 从报告轮次、严重级到最新状态的完整生命周期,alias 机制则让both模式下合并出的 id 也能被回溯。配套的 selftest.py 为状态机与 verdict 合并维护回归用例,改动脚本后必须先跑它。

七、闭环中的另一半:o2-coder 的回应协议与报告收尾

审查循环的另一半是 o2-coder.md 定义的 coder 行为。coder 对每条归属自己仓库的 finding 必须四选一:fix(真实缺陷,改代码并说明改了什么)、dispute(finding 错误,给出引用代码/不变式/测试的具体理由,禁止"看起来没问题")、partial(真实但完整修复超出范围,说明做了什么、剩什么)、defer(仅限 approve verdict 上的 low finding,且编排者明确要求)。回应写入round-(N-1)/coder-response.json,格式如:

{ "round": 1, "responses": [ {"id": "F1", "action": "fix", "note": "what changed and why", "files": ["src/..."]}, {"id": "F2", "action": "dispute", "note": "why the finding is wrong, with file:line evidence", "files": []} ], "open_items": [] }

coder 每轮还要按仓库门禁顺序跑通并写 evidence:cargo fmt --all,再跑 CI 的 clippy 命令(cargo clippy --workspace --all-targets -- -W clippy::too_many_lines -W clippy::cognitive_complexity -W clippy::excessive_nesting -D warnings);若改动触及 enterprise 代码,按 CLAUDE.md 的 enterprise 验证规则处理或在 evidence 中如实声明未验证。

循环结束时编排者写report.md,按固定八段顺序:Outcome → Change summary → Rounds(每轮一行:backend、verdict、新 finding、修复内容)→ Fixed → Disputed/partial/deferred(即使为空也要列出,供用户裁决)→ Unverified edits(git status --shortgit log,非 none 则 outcome 不得为 agreed)→ Residual risk → Files changed(git diff --stat与 WIP 提交列表)。之后只推送通知,不 push、不开 PR;只有用户最终审查后明确要求,才用git reset --soft <merge-base> && git commit把 WIP 提交压成一个规范提交。

八、把这套模式移植到你的仓库:设计要点总结

o2-loop 是 OpenObserve 这个大型 Rust 仓库的工程实践,但其设计原则完全可以复用到其他项目:

  1. 审查提示词即契约:把"审什么、按什么优先级、输出什么结构"全部写进提示词(review.md),用 JSON Schema(review.json)硬约束输出,模型换了、进程重启了,协议不变。
  2. 优先级清单要贴仓库实际:OpenObserve 的清单把 org 作用域绕过、enterprise cfg 门、热路径分配列为专项,是因为它们就是这个仓库的真实风险点;移植时应替换为自家仓库的痛点(如多租户、插件体系、嵌入式安全边界)。
  3. 规则文件先行:审查者先读仓库规则文件(CLAUDE.md),把"哪些机器已强制、哪些人工强制"划清界限,避免人机重复报同一类问题。
  4. 跨轮次记忆靠账本而非模型:finding 用稳定 id 追踪,每轮 verdict 与 coder-response 落盘为 JSON,无记忆的审查进程靠内联历史完成验证——这比指望模型记住上一轮可靠得多。
  5. 物理隔离审查环境:一次性 worktree + seatbelt 沙箱 + 事后漂移校验,保证审查者"看得到、改不了",也让 approve 的意义可审计。
  6. 状态机单点裁决:每一步只做一件事(evidence → review → respond → next/cap/agreed),人只裁决有争议的条目,循环才能收敛。

这套机制的完整实现都保留在本仓库的 .claude/skills/o2-loop 目录下:从 review.md 与 verify.md 两套提示词,到 review.json 协议、review.sh 执行器与 loop-state.py 状态机,再到 o2-coder.md 的角色定义,是一套可直接对照阅读、按需裁剪复用的完整参考实现。

【免费下载链接】openobserveOpen source observability platform for logs, metrics, traces, RUM, Session replay, pipelines, SLO and LLM observability. A sophisticated, simple and highly performant alternative to Datadog, Splunk, and Elasticsearch with 140x lower storage costs and single binary deployment.项目地址: https://gitcode.com/GitHub_Trending/op/openobserve

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 11:38:05

构网型逆变器VSG仿真与光储系统设计实践

1. 项目概述&#xff1a;构网型逆变器的光储VSG仿真实践在新能源电力系统领域&#xff0c;构网型逆变器正逐渐成为解决高比例可再生能源接入问题的关键技术。这个仿真项目聚焦于采用虚拟同步机(VSG)技术的三相共直流母线式光储系统&#xff0c;通过Matlab/Simulink搭建完整仿真…

作者头像 李华