windmill 仓库本地 Codex 代码审查:local-review-codex Skill 使用与原理全解析
【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmill
导读
本文围绕 windmill 仓库中面向 Codex CLI 的本地代码审查技能 .agents/skills/local-review-codex/SKILL.md 展开,讲解如何在本机、在 push 之前,用与 CI 中codex-pr-reviewGitHub Action 完全一致的审查策略与推理强度,对你尚未推送的改动(已提交 + 未提交)执行一次独立的 Codex 审查。读完本文,你将掌握该技能的前置条件、运行命令、run.sh脚本的实现原理、共享审查策略REVIEW.md的裁决与分级规则,以及如何把审查结果无失真地转述给团队成员。
一、背景:CI 中的 Codex 自动 PR 审查
windmill 仓库在 CI 中部署了 Codex 自动审查流水线,定义于 .github/workflows/codex-pr-review.yml。该工作流在 PR 满足条件时(ready_for_review/opened/synchronize事件,非 draft、非 fork),执行以下关键步骤:
- 配置认证:优先使用
OPENAI_API_KEY,其次使用CODEX_AUTH_JSON,二者都未配置则跳过审查; - 检出 PR merge 分支,并在非 fork 场景下通过 backend/substitute_ee_code.sh 注入 EE 私有代码;
- 安装
@openai/codex@0.153.4并写入CODEX_HOME/config.toml; - 由 Node 脚本生成
pr-review-context.md,内含仓库名、PR 号、Base/Head SHA、PR 标题与正文、变更提交与变更文件命令(git log --oneline、git diff --stat、git diff --unified=0),以及最多 20 条历史评论; - 调用
codex exec,使用模型gpt-5.6-sol、model_reasoning_effort="xhigh",非 fork 场景沙箱为danger-full-access,fork 场景降级为workspace-write并在无网络沙箱中运行; - 最后通过
actions/github-script将审查输出以 PR 评论形式发布,并做凭据脱敏(对 API Key、auth JSON 中的嵌套 token 做[REDACTED]处理)。
CI 侧的提示词由 REVIEW.md(共享策略)与 .github/codex/pr-review.prompt.md(输出格式)拼接而成。这条流水线的问题在于:它只在 PR 创建之后运行,发现问题时修改成本已较高。
二、local-review-codex:把 CI 审查搬到 push 之前
local-review-codex技能正是为解决上述痛点而设计:它在本地运行与 CI 完全相同的审查,但范围限定为你尚未推送的工作,从而在 PR 存在之前就捕获 CI 会标记的问题。正如 AGENTS.md 中 "Code review" 一节所述:对于「镜像codex-pr-reviewGitHub Action、针对未推送工作(已提交 + 未提交)的 Codex 审查」,应使用/local-review-codex技能;它与 CI Action 共用同一份REVIEW.md策略与xhigh推理强度,模型为gpt-6-astra而非 Action 的gpt-5.6-sol,且要求codexCLI >= 0.153.4。
该技能在技能目录中有两个等价入口:.agents/skills/local-review-codex/SKILL.md与 .claude/skills/local-review-codex/SKILL.md(后者为符号链接指向前者,Claude Code 与 Codex 各自按目录自动发现同一份技能)。
2.1 与 CI 完全一致的部分
技能文档明确列出了与 CI 的「一致性」,这是它价值的前提:
- 策略:使用仓库根目录的 REVIEW.md(严重性分级、公开表面检查清单、AGENTS.md 合规、测试覆盖评估);
- 推理强度:
model_reasoning_effort="xhigh"; - 输出格式:以
## Codex Review开头的 Markdown,每条发现以 P0 / P1 / P2 分级并携带 file:line 定位。
2.2 与 CI 的差异(本地独有)
| 维度 | CI(codex-pr-review.yml) | 本地(local-review-codex) |
|---|---|---|
| 模型 | gpt-5.6-sol | gpt-6-astra |
| 审查范围 | 已推送的 PR diff | 当前分支 vs main 的 merge-base,包含未提交改动 |
| 沙箱 | danger-full-access(临时 runner) | read-only(只读,不修改工作区) |
| 上下文 | 冷启动的 GitHub Action 进程 | codex exec独立冷进程,不锚定当前对话 |
模型差异并非疏漏:gpt-6-astra已确认在codex login使用的 ChatGPT 认证上可用,而 CI 使用OPENAI_API_KEY认证(codex-pr-review.yml 中它优先于CODEX_AUTH_JSON),该认证层级对gpt-6-astra尚未验证,因此 CI 继续使用gpt-5.6-sol,待 API 访问确认后再迁移。CLI 版本两边相同(均为 0.153.4),只有模型不同。
三、前置条件
运行该技能前需要满足:
codexCLI >= 0.153.4,并通过codex login完成认证。注意:环境中若存在OPENAI_API_KEY,其优先级高于codex login存储的 ChatGPT 凭据,可能无法触达gpt-6-astra(详见下文脚本原理)。旧版 CLI 会以 "requires a newer version of Codex" 拒绝该模型;run.sh会在执行前先做版本检查。升级命令:npm install --global @openai/codex@0.153.4全局安装可能需要在前面加
sudo。该版本号与 .github/workflows/codex-pr-review.yml 中的 pin 保持一致。git fetch基础分支:如果 base ref 已过期,先拉取,确保 merge-base 计算准确。
四、运行方法
bash .agents/skills/local-review-codex/run.sh # 默认以 main 为基准审查 bash .agents/skills/local-review-codex/run.sh <base> # 以其他 base ref 为基准审查两个必须注意的细节:
- 必须用
bash调用(或直接执行脚本本身),因为脚本依赖set -o pipefail;在 Debian/Ubuntu 上sh实际是 Dash,会导致脚本失败。 main不是本地分支时的回退:在全新的单分支检出(例如 CI 检出的工作区)中通常只有origin/main而没有本地main,runner 会自动回退到origin/main。
脚本整体流程:计算BASE_SHA = git merge-base HEAD <base>,将REVIEW.md连同指向git diff <BASE_SHA>的 diff 上下文(会折叠进未提交的编辑)喂给 Codex,输出审查结果。脚本只写临时文件,工作区不留任何痕迹。
五、run.sh 脚本实现原理
实现位于 .agents/skills/local-review-codex/run.sh,约 114 行 Bash,以下按执行顺序拆解其关键设计。
5.1 版本前置检查
CODEX_VER="$(codex --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || true)" if [ -n "$CODEX_VER" ] && [ "$(printf '%s\n%s\n' "$CODEX_MIN" "$CODEX_VER" | sort -V | head -1)" != "$CODEX_MIN" ]; then echo "codex $CODEX_VER is too old for $MODEL (need >= $CODEX_MIN)..." >&2 exit 1 fi旧版 CLI 拒绝模型时的报错信息从不点名「CLI 版本过旧」这一真实原因,因此脚本在 exec 之前先做版本检查,避免错误以难以诊断的形式暴露。|| true的用意是:当--version输出格式无法解析时(此时无法判断版本),必须放行到 exec 而不是在set -e下中止整个审查。
5.2 OPENAI_API_KEY 冲突警告
if [ -n "${OPENAI_API_KEY:-}" ]; then echo "warning: OPENAI_API_KEY is set and takes priority over 'codex login' credentials; $MODEL may be unavailable on that tier." >&2 ficodex优先使用OPENAI_API_KEY而非codex login存储的 ChatGPT 凭据,而该认证层级对gpt-6-astra未确认可用——失败信息会指向模型而不是真正选中它的认证方式,所以脚本提前给出显式警告。
5.3 base ref 解析与 merge-base
if git rev-parse --verify --quiet "${BASE_REF}^{commit}" >/dev/null; then BASE_COMMITISH="$BASE_REF" elif git rev-parse --verify --quiet "origin/${BASE_REF}^{commit}" >/dev/null; then BASE_COMMITISH="origin/${BASE_REF}" else echo "Base ref '$BASE_REF' not found as '$BASE_REF' or 'origin/$BASE_REF'. Try: git fetch origin $BASE_REF" >&2 exit 1 fi优先解析本地 ref,回退到 remote-tracking ref;两者都不存在时提示先git fetch origin <base>。
BASE_SHA="$(git merge-base HEAD "$BASE_COMMITISH")" HEAD_SHA="$(git rev-parse HEAD)" UNTRACKED="$(git ls-files --others --exclude-standard)"从 merge-base 计算 diff,保证只审查本分支的改动。使用 base SHA 配合单 ref 的git diff会把未提交的工作区编辑一并纳入——但git diff永远看不到未跟踪文件,因此脚本单独通过git ls-files --others --exclude-standard收集未跟踪文件,避免整个新模块、新技能目录被静默跳过。
5.4 无变更短路
if [ "$BASE_SHA" = "$HEAD_SHA" ] && git diff --quiet "$BASE_SHA" && [ -z "$UNTRACKED" ]; then echo "No changes vs $BASE_REF — nothing to review." >&2 exit 0 fi基准与 HEAD 相同、无已跟踪改动、且无未跟踪文件时,直接宣告「无变更可审查」并正常退出。
5.5 提示词组装与执行
脚本用mktemp创建临时文件并用trap ... EXIT保证清理。提示词由三部分组成:
cat REVIEW.md:共享审查策略全文;- 内联追加的「Codex output format」段:说明这是 PR 之前的本地审查、未跟踪文件不出现在
git diff中需逐个cat阅读、输出必须以## Codex Review开头、每条发现标注 P0/P1/P2 与 file:line; - 「Review context」段:base/head SHA,以及三条审查命令——
git log --oneline $BASE_SHA..HEAD(变更提交)、git diff --stat $BASE_SHA(变更文件)、git diff --unified=0 $BASE_SHA(完整审查 diff,含未提交编辑),最后列出所有未跟踪文件路径。
CI 侧这些内容来自生成的 context 文件;本地采用内联追加的方式,保证工作区干净——没有任何草稿文件落入仓库。
执行调用:
codex exec \ -C "$REPO_ROOT" \ -m "$MODEL" \ -c 'model_reasoning_effort="xhigh"' \ -s read-only \ -o "$OUT" \ - < "$PROMPT"参数含义:-C指定仓库根目录、-m指定模型(gpt-6-astra)、-c传入推理强度配置、-s read-only声明只读沙箱(Codex 可以读 diff 和文件,但不能修改工作区)、-o指定输出文件、-从 stdin 读入提示词。最后把审查结果原样打印到 stdout。
六、共享审查策略 REVIEW.md
REVIEW.md 是 CI 与本地共用的策略文件,值得单独理解,因为它决定了 Codex 的输出形态与分级标准。
6.1 首行裁决
审查必须从单行裁决开始,三选一:
- Good to merge:无阻断问题且无值得提出的 nit;
- Mergeable, but should ideally address nits: <短列表>:无阻断项但有值得一看的 P2;
- Should address issues before merging: <短列表>:至少一个 P0 或 P1。
列表中的每一项必须与正文中的发现一一对应,不得虚构、不得把阻断项只埋在正文里。
6.2 严重性分级
- P0:RCE、认证绕过、数据丢失、代码中的密钥、SQL 注入、路径穿越、公开表面上的认证破坏;
- P1:显著 bug、新公开表面缺少认证/授权检查、可能在异步路径上阻塞 I/O、竞态条件、对调用方可控参数缺少输入校验、可观察的性能回退;
- P2:模块放置错误、文档与代码不一致、半成品公开抽象(
pub fn+#[allow(dead_code)]+TODO)、AGENTS.md 风格违规、命名与函数行为相悖。
P0/P1 必须报告;P2 仅在 diff「邀请」时报告(新pub fn、新模块、新导出组件、有意义的重构)。
6.3 新公开表面检查清单
对于 PR 引入的新pub fn/pub async fn/ 导出的 Svelte 组件 / 导出 prop,需逐项核验:认证/授权期望是否在文档注释中说明或在函数体内强制;模块定位是否与其职责匹配(检查//!模块注释);是否半成品;每个可能由调用方控制的参数是否有注入/穿越/溢出/NUL 字节防护。
6.4 测试覆盖评估
审查以「Test coverage」小节收尾,按 diff 实际触碰的层级校准:
- 后端(
backend/下 Rust):新逻辑期待 Rust 单元测试;新增/修改 API handler、worker 步骤、队列/cron 行为或 DB 访问时,还期待或注明集成测试的缺失; - 前端(
frontend/下 Svelte/TS):仓库一般不为 Svelte 组件写测试,不要索要组件测试;仅对新增纯逻辑工具类(已有*.test.ts兄弟文件的类型,如flowDiff、previousResults、copilot 逻辑)标记测试缺失; - CI / 工作流 / 文档 / 纯配置:不期待自动化测试,并应明说,让读者知道你考虑过这一点。
随后说明合并前仍需哪些手动验证(以段落描述场景与可观察结果);若 diff 无可操作的应用内表面,则如实说明。
七、结果转述原则
技能文档强调:原样打印 Codex 输出,不要重新总结或过滤——冷启动 Codex 一轮的价值恰恰在于浮现当前对话会话会「理性化掉」的问题。然后与用户共同决定是否在 push 之前处理发现。
若需要 Claude 原生的审查视角,可改用local-review技能(.agents/skills/local-review/SKILL.md,使用 branch-diff-reviewer 子代理);本技能是其 Codex 对应物,两者可以各跑一遍以获得相互独立的视角。local-review强调审查必须在全新上下文的子代理中运行(而非当前会话内联执行),其子代理提示词模板同样要求先读 REVIEW.md 与相关AGENTS.md,再取 diff(gh pr diff或git diff main...<branch>),最后按固定输出格式给出## Code review与 P0/P1/P2 列表——与 local-review-codex 的输出约定同源,便于两侧结果相互对照。
八、最佳实践小结
- 在非平凡改动上、push 之前运行:
bash .agents/skills/local-review-codex/run.sh,让 CI 在 PR 阶段会标记的问题在提交前暴露。 - 确认认证层可达模型:以
codex login的 ChatGPT 认证为主;若环境变量中存在OPENAI_API_KEY,留意脚本警告并确认该层级能访问gpt-6-astra。 - 保持 base ref 新鲜:必要时先
git fetch origin main,确保 merge-base 准确;单分支检出下脚本会自动回退到origin/main。 - 原样转述、独立决策:将
## Codex Review输出逐字呈现,不替 Codex 过滤结论,再与用户共同决策;需要不同视角时与local-review(Claude 子代理)并行运行。
通过本地提前审查,配合 CI 中 codex-pr-review.yml 的双保险,可以让每次 PR 进入人工评审前就已通过一致策略的机器审查,显著压缩评审轮次与返工成本。
【免费下载链接】windmillOpen-source developer platform to power your entire infra and turn scripts into webhooks, workflows and UIs. Fastest workflow engine (13x vs Airflow). Open-source alternative to Retool and Temporal.项目地址: https://gitcode.com/GitHub_Trending/wi/windmill
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考