☰
Plannotator AI Code Review 实战指南:用 Codex 与 Claude Code 在 Diff 视图中启动结构化代码审查
2026/9/26 7:43:13 网站建设 项目流程

【免费下载链接】plannotator

Annotate and review coding agent plans and code diffs visually, share with your team, send feedback to agents with one click.

项目地址:https://gitcode.com/gh_mirrors/pl/plannotator
点击查看免费下载

在 Plannotator 的代码审查工作流中,你可以直接从 Diff 查看器启动 AI 审查 Agent,让 Codex CLI 或 Claude Code 在后台分析你的变更,并把结构化发现(findings)以内联注释的形式直接呈现出来。本文以 ai-code-review.md 为骨架,结合仓库源码(packages/server/codex-review.ts、packages/server/claude-review.ts、packages/server/marker-review.ts等)完整讲解:两种提供者的审查模型与严重性/优先级体系、Layer 与 Full stack 两种审查范围、临时工作树机制、引擎权限透明度,以及可完整复制的 Prompt、命令与 JSON Schema,并给出如何用CLAUDE.md/REVIEW.md与自定义 Review Skill 定制审查规则。

整体流程:从点击到内联注释

Plannotator 的 AI 代码审查遵循一条清晰的流水线,文档中概括为四个步骤:

  1. 在Agents标签页点击Run Agent(选择 Codex 或 Claude);
  2. 服务端根据所选提供者构建命令,拼装对应的 Prompt 与输出 Schema;
  3. Agent 在后台运行,实时日志流式输出到Logs标签页;
  4. 运行完成后,结果被解析成结构化的 findings,以内联注释的形式出现在 Diff 视图中。

从源码结构看,这一流水线由packages/server/agent-jobs.ts中的AgentJobHandler承担:它管理后台 Agent 进程的 spawn、监控与终止,并通过 SSE(/api/agents/jobs/stream)广播任务状态。其中关键的设计是SERVER_BUILT_PROVIDERS集合——claude、codex、tour、guide、cursor、opencode、pi、copilot这些提供者的命令一律由服务端构建(buildCommand),客户端传入的 argv 永远不会被直接 spawn,这从机制上保证了命令的可信与可审计。buildCommand返回的对象还携带engine、model、effort(Claude 推理档位)、reasoningEffort(Codex 推理档位)、prUrl、diffScope("layer"或"full-stack")等元数据,这些信息会存储到AgentJobInfo上,供 UI 展示与按任务导出。

两种审查模型:Claude 严重性与 Codex 优先级

文档明确指出两种提供者的核心差异:

  • Codex CLI:采用基于优先级的 findings(P0 至 P3);
  • Claude Code:采用多 Agent 流水线,产出基于严重性的 findings(Important、Nit、Pre-existing)。

两者的接入都派生自官方工具链:Claude 的审查模型基于 Anthropic 的 Claude Code Review 服务与开源 code-review 插件;Codex 使用 OpenAI Codex CLI 的结构化输出。对应地,仓库在packages/server/codex-review.ts与packages/server/claude-review.ts中各维护一套独立的 Schema 与 Prompt,最终由一个共享的 transform 层归一化到统一的外部注释格式。

Severity(Claude)

级别含义
Important合并前必须修复。构建失败、逻辑错误、安全问题。
Nit值得修复但不阻塞。风格、边界情况、代码质量。
Pre-existing周边代码中的既有 Bug,非本次 PR 引入。

Priority(Codex)

级别含义
P0阻塞。放下一切立即处理。
P1紧急。下一轮迭代处理。
P2常规。最终修复。
P3低。锦上添花。

这套"共享 finding 模型 + 各自 Schema + 统一归一化"的结构在源码中有清晰体现:packages/server/review-findings.ts定义了唯一的ReviewFinding形状(severity、可空的file/line/end_line、description、reasoning),Claude 与 marker 类引擎(Cursor/OpenCode/Pi/Copilot)都复用它;而 Codex 因携带priority与code_location,在packages/server/codex-review.ts中单独映射。两类 findings 最终都经过transformSeverityFindings/transformReviewFindings转成ReviewAnnotationInput,再由packages/shared/external-annotation.ts的classifyFindingPlacement路由为行级注释、整文件注释或通用(review 级)注释——任何 finding 都不会被丢弃,只是按携带信息量选择落点。

Findings 的呈现与交互

每个 finding 包含文件路径、行范围、描述,以及严重性或优先级。Claude 的 finding 还额外带有一段reasoning(推理轨迹),说明该问题是如何被验证确认的。

在 UI 中:

  • 点击任意 finding 即可跳转到对应文件与行;
  • 单个 finding 上有复制按钮,可单独复制为 Markdown;
  • Copy All可将全部 findings 一次性导出为 Markdown。

这一交互建立在归一化后的注释层之上:ReviewAnnotationInput携带source(引擎来源)、filePath、lineStart/lineEnd、type: "comment"、side: "new"(注释锚定在新变更侧)、scope、text与author。其中side: "new"意味着注释始终落在 Diff 的新版本一侧,与平台行内注释的锚定方式一致。

审查范围:Layer 与 Full stack

对于堆叠式 PR(stacked PRs)和 MR,审查头(review header)允许你选择 Agent 看到什么:

  • Layer:只审查当前 PR 或 MR 相对于其父分支的变更;
  • Full stack:审查从仓库默认分支到当前 head 的累计 Diff。

文档给出的选型建议非常明确:Layer 审查最适合避免对父 PR 产生重复反馈;Full stack 审查适合处理只有在整条链一起考虑时才会出现的集成问题。同时有一个硬性约束:向 GitHub 或 GitLab 回贴内联评论时始终限制为 Layer,因为平台评论必须锚定在平台 Diff 上,full-stack 的累计变更无法一一对应到平台视图。

从packages/server/review.ts的源码可以印证这一机制的实现:currentPRDiffScope: PRDiffScope = "layer"是会话级状态,pr-layer:<url>与 full-stack fingerprint 分别计算 Diff 指纹;在 full-stack 范围下,launch patch 是对本地 checkout 的default branch...HEAD的完整重算,而 layer 范围的初始 patch 可能因平台 API 对超大 PR 隐藏逐文件 patch 而标记为:incomplete,待 checkout 预热完成后升级为完整 patch(layerUpgradeAvailable,由 worktree pool 提供能力)。Agent 任务的diffScope字段("layer"或"full-stack")也在启动时快照,用于把 findings 归属到正确的 PR。

Local worktree:让 Agent 拥有文件访问能力

PR 和 MR 审查默认会自动创建临时检出(temporary checkout),使 Agent 能读取文件、追踪 import 关系、理解代码库上下文。两种实现路径:

  • 同仓库(Same-repo):git worktree,共享对象库,速度快;
  • 跨仓库(Cross-repo):浅克隆(shallow clone)并定向 fetch PR head。

这些临时检出在会话结束时自动清理。如果希望纯远程模式审查,可以传入--no-local跳过本地检出。

源码层面,packages/server/review.ts通过WorktreePool(packages/shared/worktree-pool.ts)管理一组按 PR 隔离的 git worktree:创建/删除 worktree、定向fetchRef(fetch PR head 与 base branch)、ensureObjectAvailable保证对象可达。由于FETCH_HEAD是仓库级共享状态,所有创建操作会被串行化以避免并发冲突。PR 审查默认运行在一次性 worktree 中,因此即使引擎在极端情况下执行了越权操作,爆炸半径也被限制在可丢弃的目录内——这是安全模型的重要组成部分。

权限与透明度:每个引擎的边界

文档专门用一节阐明各引擎的审查权限边界,核心信息如下:

  • Claude:获得 Read、Glob、Grep、Agent 以及面向检查用途的命令模式(git、gh、glab、jj、wc);直接文件写入工具、WebFetch、WebSearch、通用 shell、curl、wget 全部被拒绝。部分允许模式(如glab api、git -C)比严格的逐子命令只读列表更宽。
  • GitHub Copilot CLI:写入工具被拒绝;Plannotator 额外拒绝高风险 Git 操作与对外 GitHub/GitLab 写入,允许git、gh、glab、jj、wc命令族,并依赖 Copilot 的非交互模式拒绝其他 shell 工具。
  • Codex:以--approve-for-me运行,使用 Codex 的 workspace-write 沙箱与自动审批机制——它不是只读文件沙箱。
  • Cursor:以 ask 模式运行,默认启用其沙箱;设置PLANNOTATOR_CURSOR_SANDBOX=0可移除显式沙箱标志,改由用户自己的 Cursor 配置决定。
  • OpenCode:运行其 plan agent,但 Plannotator 不追加 shell 限制标志,权限来自用户自己的 OpenCode 配置。
  • Pi:排除直接编辑与写入工具,但保留 Bash 及其在 Pi 运行时控制下的其他检查路径。

需要特别强调的透明性结论:Plannotator 的 Prompt 会告诉每个引擎不要修改文件或回贴评论,该指令在审查 UI 中可见,但对 Codex、Cursor、OpenCode、Pi 而言不是结构性强制;Claude 与 Copilot 增加了结构性限制,但应理解为"上述精确规则",而非笼统的只读沙箱。PR/MR 审查默认运行在可丢弃的 worktree 中,本地工作树审查则不然。所选 AI 提供者只会收到审查所需的 Prompt 与仓库/Diff 上下文,不会经过 Plannotator 运营的模型服务器;数据保留与账户控制权属于你配置的 CLI 与提供者。

这一节在源码中可以得到逐条印证。packages/server/claude-review.ts的buildClaudeCommand显式拼装--tools Agent,Bash,Read,Glob,Grep、长长的--allowedTools(gh/glab 检查命令、git 只读子命令、jj 只读子命令、wc:*)与--disallowedTools(Edit/Write/NotebookEdit/WebFetch/WebSearch 及 python/node/npx/bun/sh/bash/zsh/curl/wget 等 shell 族)。packages/server/marker-review.ts则通过MarkerEngine描述符统一封装其余引擎:Cursor 以agent -p --mode ask --sandbox enabled --trust运行;OpenCode 以opencode run --format json --agent plan运行;Pi 以pi --mode json --no-session --no-approve --exclude-tools edit,write运行(--no-approve是安全要求——防止非交互模式静默套用项目信任);Copilot 以--deny-tool=write加一系列--deny-tool=shell(...)(git push/reset/clean/checkout/restore、gh/glab 的写入与评论命令)构成结构防线,并开放git:*、gh:*、glab:*、jj:*、wc只读命令族。

Claude Code 完整接入

Claude Code:完整 Prompt

仓库在 claude-review.ts 中保存了完整系统提示词,以下为文档提供的原版全文:

# Claude Code Review System Prompt ## Identity You are a code review system. Your job is to find bugs that would break production. You are not a linter, formatter, or style checker unless project guidance files explicitly expand your scope. ## Pipeline Step 1: Gather context - Retrieve the PR diff (gh pr diff or git diff) - Read CLAUDE.md and REVIEW.md at the repo root and in every directory containing modified files - Build a map of which rules apply to which file paths - Identify any skip rules (paths, patterns, or file types to ignore) Step 2: Launch 4 parallel review agents Agent 1 — Bug + Regression (Opus-level reasoning) Scan for logic errors, regressions, broken edge cases, build failures, and code that will produce wrong results. Focus on the diff but read surrounding code to understand call sites and data flow. Flag only issues where the code is demonstrably wrong — not stylistic concerns, not missing tests, not "could be cleaner." Agent 2 — Security + Deep Analysis (Opus-level reasoning) Look for security vulnerabilities with concrete exploit paths, race conditions, incorrect assumptions about trust boundaries, and subtle issues in introduced code. Read surrounding code for context. Do not flag theoretical risks without a plausible path to harm. Agent 3 — Code Quality + Reusability (Sonnet-level reasoning) Look for code smells, unnecessary duplication, missed opportunities to reuse existing utilities or patterns in the codebase, overly complex implementations that could be simpler, and elegance issues. Read the surrounding codebase to understand existing patterns before flagging. Only flag issues a senior engineer would care about. Agent 4 — Guideline Compliance (Haiku-level reasoning) Audit changes against rules from CLAUDE.md and REVIEW.md gathered in Step 1. Only flag clear, unambiguous violations where you can cite the exact rule broken. If a PR makes a CLAUDE.md statement outdated, flag that the docs need updating. Respect all skip rules — never flag files or patterns that guidance says to ignore. All agents: - Do not duplicate each other's findings - Do not flag issues in paths excluded by guidance files - Provide file, line number, and a concise description for each candidate Step 3: Validate each candidate finding For each candidate, launch a validation agent. The validator: - Traces the actual code path to confirm the issue is real - Checks whether the issue is handled elsewhere (try/catch, upstream guard, fallback logic, type system guarantees) - Confirms the finding is not a false positive with high confidence - If validation fails, drop the finding silently - If validation passes, write a clear reasoning chain explaining how the issue was confirmed — this becomes the reasoning field Step 4: Classify each validated finding Assign exactly one severity: important — A bug that should be fixed before merging. Build failures, clear logic errors, security vulnerabilities with exploit paths, data loss risks, race conditions with observable consequences. nit — A minor issue worth fixing but non-blocking. Style deviations from project guidelines, code quality concerns, edge cases that are unlikely but worth noting, convention violations that don't affect correctness. pre_existing — A bug that exists in the surrounding codebase but was NOT introduced by this PR. Only flag when directly relevant to the changed code path. Step 5: Deduplicate and rank - Merge findings that describe the same underlying issue from different agents — keep the most specific description and the highest severity - Sort by severity: important → nit → pre_existing - Within each severity, sort by file path and line number Step 6: Return structured JSON output matching the schema. If no issues are found, return an empty findings array with zeroed summary. ## Hard constraints - Never approve or block the PR - Never comment on formatting or code style unless guidance files say to - Never flag missing test coverage unless guidance files say to - Never invent rules — only enforce what CLAUDE.md or REVIEW.md state - Never flag issues in skipped paths or generated files unless guidance explicitly includes them - Prefer silence over false positives — when in doubt, drop the finding - Do NOT post any comments to GitHub or GitLab - Do NOT use gh pr comment or any commenting tool - Your only output is the structured JSON findings

该 Prompt 在源码中与文档保持逐字一致(CLAUDE_REVIEW_PROMPT),体现了"多 Agent 分工 + 独立验证 + 分级 + 去重排序"的审查方法论,这正是 Claude findings 自带reasoning推理轨迹的来源——它是 Step 3 验证 Agent 的输出。

Claude Code:命令

claude -p \ --permission-mode dontAsk \ --output-format stream-json \ --verbose \ --json-schema '{"type":"object","properties":{"findings":{"type":"array","items":{"type":"object","properties":{"severity":{"type":"string","enum":["important","nit","pre_existing"]},"file":{"type":"string"},"line":{"type":"integer"},"end_line":{"type":"integer"},"description":{"type":"string"},"reasoning":{"type":"string"}},"required":["severity","file","line","end_line","description","reasoning"],"additionalProperties":false}},"summary":{"type":"object","properties":{"important":{"type":"integer"},"nit":{"type":"integer"},"pre_existing":{"type":"integer"}},"required":["important","nit","pre_existing"],"additionalProperties":false}},"required":["findings","summary"],"additionalProperties":false}' \ --no-session-persistence \ --model opus \ --tools Agent,Bash,Read,Glob,Grep \ --allowedTools Agent,Read,Glob,Grep,Bash(gh pr view:*),Bash(gh pr diff:*),Bash(gh pr list:*),Bash(gh issue view:*),Bash(gh issue list:*),Bash(gh api repos/*/*/pulls/*),Bash(gh api repos/*/*/pulls/*/files*),Bash(gh api repos/*/*/pulls/*/comments*),Bash(gh api repos/*/*/issues/*/comments*),Bash(glab mr view:*),Bash(glab mr diff:*),Bash(glab mr list:*),Bash(glab api:*),Bash(git status:*),Bash(git diff:*),Bash(git log:*),Bash(git show:*),Bash(git blame:*),Bash(git branch:*),Bash(git grep:*),Bash(git ls-remote:*),Bash(git ls-tree:*),Bash(git merge-base:*),Bash(git remote:*),Bash(git rev-parse:*),Bash(git show-ref:*),Bash(jj status:*),Bash(jj diff:*),Bash(jj log:*),Bash(jj show:*),Bash(jj file show:*),Bash(jj cat:*),Bash(jj bookmark list:*),Bash(wc:*) \ --disallowedTools Edit,Write,NotebookEdit,WebFetch,WebSearch,Bash(python:*),Bash(python3:*),Bash(node:*),Bash(npx:*),Bash(bun:*),Bash(bunx:*),Bash(sh:*),Bash(bash:*),Bash(zsh:*),Bash(curl:*),Bash(wget:*)

Prompt 通过 stdin 写入(--permission-mode dontAsk保证后台任务不被交互打断;--no-session-persistence让每次审查保持独立)。从源码看,buildClaudeCommand还会在模型非默认时追加--effort <level>(Claude 推理档位),且命令中--json-schema的值来自仓库内嵌的CLAUDE_REVIEW_SCHEMA_JSON字符串,并通过--output-format stream-json获取 JSONL 实时流。

Claude 输出解析管线

由于 Claude 以stream-json输出 JSONL,parseClaudeStreamOutput从最后一个type: "result"事件中提取structured_output(即经过内联 JSON Schema + Ajv 验证的 findings);is_error或形状非法时返回 null。与此同时,formatClaudeLogEvent把流中的assistant文本消息与tool_use事件转成人类可读的日志行,供 Logs 标签页实时展示(result事件被跳过,因为它由解析器单独处理)。

Codex 完整接入

Codex:完整 Prompt

仓库在 codex-review.ts 中保存了与官方codex-rs/core/review_prompt.md逐字一致的系统提示词,以下为文档提供的全文:

# Review guidelines: You are acting as a reviewer for a proposed code change made by another engineer. Below are some default guidelines for determining whether the original author would appreciate the issue being flagged. These are not the final word in determining whether an issue is a bug. In many cases, you will encounter other, more specific guidelines. These may be present elsewhere in a developer message, a user message, a file, or even elsewhere in this system message. Those guidelines should be considered to override these general instructions. Here are the general guidelines for determining whether something is a bug and should be flagged. 1. It meaningfully impacts the accuracy, performance, security, or maintainability of the code. 2. The bug is discrete and actionable (i.e. not a general issue with the codebase or a combination of multiple issues). 3. Fixing the bug does not demand a level of rigor that is not present in the rest of the codebase. 4. The bug was introduced in the commit (pre-existing bugs should not be flagged). 5. The author of the original PR would likely fix the issue if they were made aware of it. 6. The bug does not rely on unstated assumptions about the codebase or author's intent. 7. It is not enough to speculate that a change may disrupt another part of the codebase; to be considered a bug, one must identify the other parts of the code that are provably affected. 8. The bug is clearly not just an intentional change by the original author. Comment guidelines: 1. Clear about why the issue is a bug. 2. Appropriately communicates severity. Does not overclaim. 3. Brief. Body is at most 1 paragraph. 4. No code chunks longer than 3 lines. 5. Clearly communicates the scenarios or inputs necessary for the bug to arise. 6. Tone is matter-of-fact, not accusatory or overly positive. 7. Written so the original author can immediately grasp the idea. 8. Avoids flattery ("Great job ...", "Thanks for ..."). Output all findings that the original author would fix if they knew about it. If there is no finding that a person would definitely love to see and fix, prefer outputting no findings. Priority tags: [P0] Blocking. [P1] Urgent. [P2] Normal. [P3] Low. At the end, output an overall correctness verdict.

源码版CODEX_REVIEW_SYSTEM_PROMPT还包含更详细的补充规则:finding 标题需带[P0]–[P3]优先级标签且 JSON 中提供数值型priority字段(0–3,无法判定时为 null);落点按精确度路由——行级问题给出code_location与line_range、整文件问题line_range置 null、全局问题code_location置 null;行范围尽量短(5–10 行内),不确定时降级为整文件或全局;末尾输出 overall correctness 判定。

Codex:命令

codex exec \ --output-schema ~/.plannotator/codex-review-schema.json \ -o /tmp/plannotator-codex-<uuid>.json \ --approve-for-me \ --ephemeral \ -C <working-directory> \ "<system-prompt>\n\n---\n\n<user-message>"

参数语义:--output-schema指向物化到磁盘的 JSON Schema 文件;-o指定结构化输出文件(UUID 命名,避免并发冲突);--approve-for-me启用 Codex 的 workspace-write 沙箱与自动审批;--ephemeral保证会话不留痕;-C指定工作目录;Prompt 由系统提示词 +---分隔 + 用户消息组成,作为单个位置参数传入。

从源码可以补充一个重要的实现细节:Schema 物化机制。CODEX_REVIEW_SCHEMA内嵌在代码中,首次使用时通过ensureSchemaFile()写入~/.plannotator/codex-review-schema.json(getCodexReviewSchemaPath())。原因在注释中说明:Bun 编译后的二进制使用虚拟文件系统,外部进程(codex)无法读取,因此必须把 Schema 落成真实文件;同时按解析后的数据目录路径做防重复写入守卫,确保旧二进制留下的过期 Schema 会被覆盖,Codex 每次拿到的都是当前版本。buildCodexCommand还支持可选扩展:-m <model>、-c model_reasoning_effort=<effort>、-c service_tier=fast(fast 模式)。输出路径由generateOutputPath()生成/tmp/plannotator-codex-<uuid>.json。

Codex:输出 Schema

{ "type": "object", "properties": { "findings": { "type": "array", "items": { "type": "object", "properties": { "title": { "type": "string" }, "body": { "type": "string" }, "confidence_score": { "type": "number" }, "priority": { "type": ["integer", "null"] }, "code_location": { "type": "object", "properties": { "absolute_file_path": { "type": "string" }, "line_range": { "type": "object", "properties": { "start": { "type": "integer" }, "end": { "type": "integer" } }, "required": ["start", "end"] } }, "required": ["absolute_file_path", "line_range"] } }, "required": ["title", "body", "confidence_score", "priority", "code_location"] } }, "overall_correctness": { "type": "string" }, "overall_explanation": { "type": "string" }, "overall_confidence_score": { "type": "number" } }, "required": ["findings", "overall_correctness", "overall_explanation", "overall_confidence_score"] }

注意仓库内嵌版本(CODEX_REVIEW_SCHEMA)在细节上更严格:priority、code_location、line_range均声明为可空(["integer","null"]/["object","null"])且每个属性都出现在required中——这是 OpenAI 严格结构化输出(strict structured output)的要求:所有属性必须出现在 required 里,整文件 finding 把line_range置 null,全局 finding 把code_location置 null,并统一additionalProperties: false。解析端parseCodexOutput读取-o输出文件,校验findings数组形状后返回,并在成功或失败后都清理临时文件。

Marker 引擎:Cursor、OpenCode、Pi 与 Copilot

除 Claude 与 Codex 外,Plannotator 还支持四类不提供 Schema 校验标志的审查 CLI——Cursor(agent二进制)、OpenCode(opencode run)、Pi(pi --mode json)与 Copilot CLI。它们无法被指示输出"经校验的结构化 JSON",因此采用标记分隔的 JSON 块方案:Prompt 中嵌入带随机 nonce 的标签<plannotator-review-json:NONCE>…</plannotator-review-json:NONCE>,模型复制该标签输出 JSON 块,解析端从重建的规范文本中提取最后一个完整块(packages/server/marker-review.ts)。

nonce 的设计非常关键:在 review 模式下,被审查的 Diff(以及模型自己的散文)是不可信文本,其中可能反复出现字符串plannotator-review-json(例如正在审查该模块本身,或模型回显了契约示例)。静态标签会让这些回显被误认为真实分隔符,导致提取到散文而非负载。nonce 在 Prompt 构建时生成、嵌入输出契约、并在解析时从存储的 Prompt 中恢复——只有模型真实负载才能匹配。解析端还有手写的validateMarkerReviewOutput校验器:file/line/end_line可空(对应整文件/全局 finding),非法坐标(小数、NaN、Infinity)被拒绝,confidence 被钳制在 [0,1] 区间。

各引擎的命令形态(均可在packages/server/marker-review.ts中核对):

  • Cursor:agent -p --mode ask --output-format stream-json --stream-partial-output --trust [--sandbox enabled] [--model <m>] <prompt>。只读姿态完全来自--mode ask+--sandbox enabled且不带--force/--yolo;--trust是 headless 打印模式的硬性要求(否则会在无法回答的工作区信任交互处卡住)。
  • OpenCode:opencode run --format json --agent plan [--model provider/model] [--dir <cwd>] <prompt>。--agent plan是 OpenCode 的只读导向 agent。
  • Pi:pi --mode json --no-session --no-approve --exclude-tools edit,write [--model <m>] [--thinking <level>] -p <prompt>。--no-approve是安全硬性要求(防止非交互模式静默应用defaultProjectTrust,避免不可信 checkout 的.pi/settings.json/ 项目扩展 / 项目技能被加载);--exclude-tools edit,write移除变更工具但保留 Bash 等全部检查路径。
  • Copilot:copilot [-C <cwd>] --output-format json --no-ask-user --no-auto-update --disable-builtin-mcps --deny-tool=write --deny-tool=shell(...) --allow-tool=shell(git:*) … -p <prompt>。deny 规则优先于 allow 规则,结构性地挡掉远程写入(push)、工作树破坏(reset/clean/checkout/restore)与对外 forge 写入(gh/glab 的 comment/create/merge/close/review/edit),同时开放 git/gh/glab/jj/wc 检查命令族。

这四类引擎的 finding 同样复用ReviewFinding形状与transformSeverityFindings归一化管线,作者(author)字段分别为 "Cursor"、"OpenCode"、"Pi"、"Copilot"。

定制审查:CLAUDE.md / REVIEW.md 与自定义 Review Skill

通过仓库内的指南文件定制 Claude

在你的仓库根目录或任意子目录添加CLAUDE.md或REVIEW.md,Claude Agent 会在 Step 1 收集上下文时读取它们,以理解项目规则:

# Review Rules - Check for SQL injection in database queries - Skip files in test-fixtures/ - Enforce snake_case in Python

两个文件是叠加(additive)关系:REVIEW.md在CLAUDE.md基础上扩展审查专属规则。Prompt 的 Hard constraints 也要求 Agent 只执行CLAUDE.md或REVIEW.md中明确陈述的规则,不自行发明规则,并遵守其中的 skip rules(跳过路径、模式或文件类型)。

通过自定义 Review Skill 替换审查方法论

更彻底的定制方式是使用 Agent Skill。仓库文档 custom-reviews.md 说明:一个自定义审查就是一个 Agent Skill——把想要执行的审查指令写入全局 skill 文件夹(~/.claude/skills、~/.codex/skills、~/.agents/skills)的SKILL.md,然后在~/.plannotator/review-skills.json中启用:

{ "version": 1, "enabled": ["security-review", "api-contracts"] }

被选中的 skill完全取代提供者的系统提示词(默认审查指令被丢弃),用户消息被裁剪为 Agent 定位变更所需的 git/PR 上下文;findings 仍以同样方式返回。skill 的读取是实时生效的,编辑后下一次审查即生效,不复制任何内容;带references/、scripts/、assets/的 skill,Plannotator 会告知 Agent skill 文件夹位置,让 Agent 按需打开。仅全局 skill 有效——入库的 skill 会被忽略(防止来自 fork 的 PR 直接把指令注入审查器)。

组合机制在 review-profiles.ts 中有精确实现:composeReviewPrompt在遇到携带指令且非builtin:default的 profile 时,输出<skill instructions> + ## Returning your findings(输出契约,即 REPORTING_INSTRUCTIONS)+ --- + <user message>;内置默认 profile(BUILTIN_DEFAULT_ID)不携带指令,回退到提供者原始 Prompt,保证默认审查与既有行为逐字节一致。REPORTING_INSTRUCTIONS专门解决一个已知问题:skill 自带方法论但不知道 Plannotator 期望的结果形状,若不追加输出契约,擅长"结论式"输出的 skill 会把可定位的行级 findings 压成一个大块。

小结与适用前提

Plannotator 的 AI 代码审查本质上是"引擎无关的统一 finding 模型 + 每引擎精确的命令/Schema/权限封装":Claude 的多 Agent 严重性模型、Codex 的优先级模型,以及 Cursor/OpenCode/Pi/Copilot 的标记块方案,最终都归一化为带side: "new"的行内注释。使用前提需要明确:审查依赖本机安装且已认证的 CLI(claude、codex、agent、opencode、pi、copilot),任务以后台进程形式在本地运行;PR/MR 审查默认落在可丢弃的 worktree 中,本地工作树审查则直接作用于你的真实工作区——这正是权限透明度一节反复强调的边界。完整接入细节可继续查阅 claude-review.ts、codex-review.ts、marker-review.ts 与 agent-jobs.ts 的实现。

【免费下载链接】plannotator

Annotate and review coding agent plans and code diffs visually, share with your team, send feedback to agents with one click.

项目地址:https://gitcode.com/gh_mirrors/pl/plannotator
点击查看免费下载
上一篇:为什么semantic-segmentation-pytorch是语义分割的首选框架:终极指南
下一篇:Gatsby 基准测试指南:用 gabe-fs-mdx 量化单文件级 MDX 构建性能

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

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询