AI DAILY / 2026-09-19
Repopilot:基于 Codex SDK 的验证驱动型 AI 软件迭代工具
indada/repopilot
全文中文翻译 · AI 生成,仅供学习交流
indada/repopilot
RepoPilot 把 GitHub Issue(议题)和 PR(Pull Request,拉取请求)塞进一个有边界的循环里,跑测试生成、复现失败、修复代码、独立验证这几步。它用 Codex 审查仓库规则、按需求生成测试,再拿出修复方案。一个独立的 Docker runner(运行器)会先检查代码,控制器才会发布修复分支和草稿 PR。合并这件事,最后还是维护者说了算。
为什么是 RepoPilot?
我们觉得,软件开发正在靠近一个新时代。AI 在自动化迭代和更新里会越来越重要。智能体(Agent)会接手更多活儿,从理解问题、补测试,到改代码、检查结果、再提改进。开发者可以把精力放在产品方向、架构权衡和质量标准上,智能体就在明确的目标和约束里干活儿。
但要让这个未来靠谱,工程流程就得让人信得过。变更要有理有据,失败能复现,修复有独立验证,干不成就停下来,决策还要可追溯。关键判断始终在人手里。自动化担子越重,这些底子就越重要。
RepoPilot 就是在往那个方向走一步。它从 GitHub Issue 和 PR 入手,把 Codex 的代码理解与修复能力,跟测试、仓库规则、人工评审串起来,摸索一种可验证、可控的迭代方式。现在这版聚焦在维护者挑选的问题和有边界的修复尝试。更大范围的自主迭代是愿景,无人值守的产品开发、自动合并、自动部署,都不在当前能力里。
它解决了什么问题?
现有的测试套件就算全绿,也可能漏掉新需求或者没覆盖到的边界。维护者还要核对仓库自己的约定、复现上报的失败,再确认提的修复没破坏老行为。RepoPilot 把这些步骤拢成一个可以重复跑的工作流。
| 维护者的痛点 | RepoPilot 怎么应对 |
| --- | --- |
| Issue 只描述了 bug,没有回归测试(regression test) | Codex 提出与 Issue 描述绑定的测试,修复前必须先有可复现的失败。 |
| PR 改了现有测试没覆盖到的行为 | Codex 根据 PR 描述和变更代码生成新测试,runner 比较 base 和 head 的结果。 |
| 项目约定写在 AGENTS.md 里,容易被忽略 | 静态规则加 Codex 语义审查,套用受信任的基础分支策略,附带规则引用和代码证据。 |
| 提议的修复没法复现验证 | 修复前先把测试冻结,候选方案必须保留测试标识(identity),过独立执行和策略复核。 |
| 环境故障或不稳定的测试被当成代码缺陷 | 环境失败走有限重试,不稳定或证据不全就拦下自动修复。 |
| 评审证据散落在日志和补丁里 | 本地 JSON/Markdown 报告把发现、测试结果、修复尝试、发布状态都留底。 |
它面向谁?
- 想找人帮看同仓库 PR、检查贡献规则、产出回归证据的开源维护者。
- 需要补测试覆盖和修复方案,又不想自己搭智能体控制器的小开发团队。
- 维护 JavaScript、Python、Go、Java 测试套件,搞 monorepo(单体仓库),还带着数据库或 Redis 依赖的测试环境的 QA 和开发者工具工程师。
- 拿 Codex 做开发,想要一个能拆开看的示例,看看 SDK(软件开发工具包)编排、结构化模型输出、独立验证、有边界修复怎么落地的开发者。
这些是目标用户,不是已经有人用了的声明。当前范围是公开的、纯文本的仓库;1.3.0 支持 Node、Vitest、pytest、Go,以及兼容的 JUnit XML 证据。Fork PR 执行、浏览器 E2E、托管仪表盘都不在当前实现里。
它如何使用 OpenAI Codex
RepoPilot 直接依赖 @openai/codex-sdk。OpenAI 把这个 SDK 定位成把 Codex 嵌入应用和工程工作流的工具;RepoPilot 用它的 TypeScript 接口做评审、测试规划和修复提议。详情看官方 Codex SDK 文档。
智能体入口拿 OPENAI_API_KEY 创建 Codex,开一个 thread(线程),然后用 JSON 输出 schema 调 thread.run()。容器适配器喂给它限定范围的仓库上下文,并核算模型上报的用量。整条流水线会校验提议的变更,把测试执行委托给独立的 runner。
| Codex 的职责 | RepoPilot 控制器的职责 |
| --- | --- |
| 审查自然语言写的仓库规则,并指出违规 | 从固定的基础版本加载受信规则,比对历史发现 |
| 给要的行为和边界情况设计测试 | 冻结生成的测试,在固定快照上执行 |
| 提生产代码的替换方案 | 守住受保护路径,校验候选方案,只发合格的结果 |控制器、测试执行、报告都跑在你自己的机器或 worker 上。模型调用走 OpenAI 服务,会把选中的仓库文本和任务上下文发出去;自托管(self-hosting)不等于离线跑模型推理。GitHub 凭证留在控制器里。这是个 MIT 许可证(MIT licensed)的独立项目,靠 Codex 搭出来,但不是 OpenAI 官方产品。
自动化迭代工作流
假设有个 PR 加了一条输入校验规则,Codex 可以提几条绑在需求上的边界测试。RepoPilot 在两个版本上都跑一遍。在 base 失败、在 head 过的「新行为」测试,需要一段原文引用做支撑;在 base 过、在 head 挂的「现有行为」测试,就是回归候选。只有可复现的回归,或者合格的策略违规,才会进到修复这一步。
flowchart LR
A[PR code and description] --> B[Pin commits and load trusted rules]
I[Selected GitHub Issue] --> J[Pin target branch and reproduce bug]
B --> C[Codex review and test plan]
C --> D[Independent base and head tests]
D --> E[Report evidence]
D --> F[Eligible defect: Codex repair proposal]
J --> F
F --> G[Verify frozen tests and policy]
G -->|Verified| H[Optional repair branch and draft PR]
G -->|Eligible retry within limits| F
H --> R[Maintainer review and merge decision]先从本地 check 起步;想让校验过的方案提交给人工评审时,再开 watch 让它轮询 GitHub,同时打开 publish。智能体评审、修复、发布是分开配的,示例配置里默认全关。
对于 Issue,跑 fix --issue 123 --config config.local.json,先立一个能过的原始基线,用一个新的冻结测试复现上报的 bug,再试着修。迭代卡在配好的尝试次数、调用次数、时间预算里,证据不足就把任务停下来等评审。Issue 的挑选是显式的,RepoPilot 不会自己去定产品路线图,也不会自己合并变更。
已实现的功能
1.3.0 加了目标驱动的迭代,包括明确验收标准和路径范围、可恢复的步骤计划、功能实现、有边界的验证反馈、可选的 Issue 队列、PR 跟进、版本隔离的体验、基于证据的改进提议、隔离的预览/回滚健康检查。这些能力都装在可移植包和配套的 1.3.0 Agent 镜像里。维护者保留任务挑选、合并、部署的决定权。
1.3.0 还包含通过 fix --issue 走完 Issue → 复现 → 修复 PR 的整条路,pytest、Go test、JUnit XML 报告器,以及自有资源的崩溃恢复。控制器和 Agent 镜像记得用配套的 1.3.0 版本。
- 固定 base/head 的 SHA(Git 里的提交哈希)和标题/正文摘要,持续做新鲜度检查,支持取消。
- 限定范围的字面规则,加上 JavaScript/TypeScript 的 AST(抽象语法树)调用规则,带冲突检测和可过期的例外。
- 嵌套 AGENTS.md 的语义审查,原文逐字引用规则和代码出处,比对历史发现。
- 主动给测试计划和新建的测试文件,在生产代码修复前冻结。
- 结构化的 Node、Vitest、pytest、Go 和兼容 JUnit XML 结果,包括测试发现、稳定标识、重复失败的指纹(fingerprint)、同用例验证。
- Monorepo 工作目录、多个具名测试命令、一次性依赖服务,见 test environments。
- 修复尝试、任务重试、发布重试、调用/token 预算、进程树清理,都卡在有边界的范围里。
- 失败分类,加上阶段级环境有限重试。不稳定失败或测试发现变了,就拦下自动修复。
- 独立的 autofix 分支/草稿 PR,保留可执行模式,发布恢复避开冲突。
- 原子化的 JSON 报告、Markdown 证据摘要、历史执行归档、独占的控制器锁。
> 开发者预览版(Developer preview)。当前验证范围看 verification coverage;执行边界看 security。
安装
1.3.0 有面向 Linux、Windows、macOS 的可移植发行版,不用装 Node.js 就能跑,见 portable quickstart。下面这些命令是给源码安装用的。
需要 Node.js 22、npm、Git。跑测试和智能体得有支持 Linux 容器的 Docker。
npm ci
npm run check
npm test
npm run build
cp repopilot.example.json config.local.jsonPowerShell 可以用 Copy-Item 代替 cp。本地配置里设仓库和受信测试命令,这部分要落在被评审的快照之外。
npm run dev -- check --config config.local.json --repo /path/to/project --base main --head feature
npm run dev -- watch --config config.local.json --once
npm run dev -- watch --config config.local.json本地 check 不会发布,也不会改源码 checkout。watch 轮询同仓库的非草稿 PR,跳过 autofix 分支。要发布得设 publish=true。
默认的 reporter 是 node,跑 node --test。先 build 一下,把受信 reporter 准备好。用 Vitest 就设 reporter=vitest,配一条显式的 vitest run 命令,靠带固定依赖的受信镜像撑着。测试默认不走网络;配好的服务走一次性的内部 Docker 网络。镜像和依赖得提前备好。reporter 的 flag 归控制器管。reporter=command 只收输出,不能验证也不能发布。
只想跑策略评审可以省掉 runner,测试状态就是 not_run。零通过/全跳过(zero/all-skipped)的测试、格式乱的报告、缺测试标识的,一律不算过。
受信规则
把 .repopilot/policy.json 提交到目标基础分支,看示例。
{"rules":[{"id":"no-disabled-tests","kind":"forbid-call","extensions":[".ts",".js"],"callee":"test.skip","message":"Keep regression tests enabled.","severity":"error"}],"exceptions":[]}规则类型有字面规则(forbiddenText)、forbid-call、require-call(带 callee)。AST 规则检查直接调用、限定调用,还有字符串形式的属性访问,不解析别名,也不做全程序分析。字面规则可以匹配注释。互相重叠的 require/forbid 规则会冲突,评审就停下。
例外要写明 ruleId、精确路径、reason、expiresAt(UTC ISO 时间戳),还能附精确的 evidence。例外只能来自基础策略,过期例外压不住发现。嵌套的基础 AGENTS.md 规则按作用域(scope)给语义审查用。文字层面有冲突,还得人来看。
改受信规则文件的 PR 必须由维护者审,不能授权自身的修复。
Codex 与修复
docker build -f Dockerfile.agent -t repopilot-agent:local控制器环境里设 OPENAI_API_KEY,只有智能体容器能拿到。GITHUB_TOKEN 或 GH_TOKEN 留在控制器里。发布要仓库的 Contents 和 Pull requests 写权限。桌面版 ChatGPT 的凭证不会拿来用。
agent.enabled 开语义审查和测试规划。agent.repair 开修复提议。SDK 跑在独立的容器里,对宿主 checkout 没写权限;控制器把校验过的文件替换写到独立快照上。
自动修复要有过的原始基线证据。生成的场景分 regression(默认)和 new_behavior,放在不同文件里。新行为要求 PR 标题/正文里有精确的 requirementQuote。同一个执行过的用例,base 过 / head 挂是回归;base 挂 / head 过只有在引用了新行为时才接受。两侧都挂、跳过/缺失、执行报错、改了原测试结果的,都得人工看。光看模型标签压不过 runner 证据。
一个 PR 可能既有验证过的新行为,又有回归。回归必须带着一模一样的失败标识/指纹重复出现。修复候选必须保留并通过原始的 base/head/generated 用例,还得过静态/语义复核。base 缺导出,要在执行的测试用例内部检查,不能让顶层 import 直接崩。报告里会留着意图、需求引用、按用例的分类。现有测试、清单、配置、策略、隐藏路径都受保护。
发布时会重新核 SHA 和描述。已有的分支/PR,只有父提交/文件树跟校验过的结果一致时才能复用。不强制推送(force push),也不自动合并。
运维与限制
1.3.0 带 recover 预览,会显式清理自家的崩溃残留,留住被打断的任务证据。锁状态、预览令牌、遗留资源处理看 recovery。
任务管理命令:
npm run dev -- tasks list --config config.local.json --status running --limit 20 --offset 0
npm run dev -- tasks show TASK_ID --config config.local.json --format markdown
npm run dev -- tasks cancel TASK_ID --config config.local.json
npm run dev -- tasks resume TASK_ID --config config.local.json
npm run dev -- tasks rerun TASK_ID --config config.local.jsonlist/show/cancel 在控制器持写入锁(writer lock)的时候生效。cancel 会注册一个持久化请求,验证/发布期间每 250 ms 检查一次;这个命令只是确认收到了请求,真正完成会记在报告里。已经写出去的远程内容,cancel 撤销不了。取消标记还在的话,watcher 不会重启这个任务。取消只针对当前任务,不影响该 PR 后续的修订。
resume/rerun 需要控制器锁。resume 保留任务身份、配置和执行上限;rerun 要么从头跑验证,要么接着发已经验证过的任务。重试延迟照样生效。处于 permanent/terminal/exhausted 的任务得 rerun。rerun 用原固定提交和当前配置建一个新的关联任务,保留之前的报告和取消标记。
replay 需要录好的本地仓库或 git-cache。PR 输入在 replay 前后都会再核一遍;PR 更新了得重新 watch。老报告没带 replay 元数据的,可以重跑最初的 check/watch 来补。失效的崩溃锁在移除前要先确认旧进程已经停了。
报告和快照都在 .repopilot-data。每个任务都有 JSON 和 Markdown;重试会把之前的证据归档成 TASK.execution-N.json。JSON 留着有边界的完整输出和候选补丁;Markdown/PR 输出是简版。
task timeout、maxCalls、maxAttempts、maxTaskExecutions 都卡在边界里。maxTokens 在每次模型调用之后按上报用量核算,单次调用可以超。它不是硬性的钱袋子。
适用范围,公开的、纯文本的仓库,最多 10,000 个文件 / 16 MiB。符号链接(symlink)、子模块、二进制文件、大小写冲突一律 fail-closed(默认拒绝)。上下文按变更文件加相关 import/测试分批,单个太大的文件会显式挂掉。一个控制器串行跑。崩了之后,用恢复预览和校验过的 apply 流程;遗留锁和资源要人工看一眼。
不提供仪表盘、Webhook 服务、分布式队列、浏览器 E2E、自动装依赖、fork 执行。测试执行只是证据,不是针对恶意代码的防篡改证明(tamper-proof attestation)。看 SECURITY.md。
开发
npm run check
npm run test
npm run build测试用 mock 的 API/智能体/runner,加上合成的本地 Git/Node fixture(测试装置)。不用模型额度,不起 Docker,也不写 GitHub 内容。MIT 许可证,独立项目,不是 OpenAI 官方产品。