AI 自主开发
本文面向使用、部署和维护 Open ACE AI 自主开发功能的用户与开发者,说明当前实现的功能边界、工作流生命周期、会话线设计、CI 自愈、合并后验收核对、隔离执行、用量统计和前端可观测性。
本文描述的是仓库当前实现。修改自主开发代码时,应同时更新本文、英文版文档和相应回归测试。
1. 功能概览
AI 自主开发把一条需求或一个 GitHub Issue 转换为可审计的软件交付流程:
- 准备独立分支和工作树;
- 生成方案并独立审查方案;
- 根据审查意见收敛最终方案;
- 实现代码并运行定向测试;
- 创建或更新 Pull Request;
- 独立审查代码,按意见修复并复审;
- 生成最终报告;
- 等待并检查 GitHub CI,必要时自动修复;
- 处理主分支同步或合并冲突,合并 PR,并清理分支和工作树;
- 合并后由无凭据、只读的独立验收 Agent 在合并后的 main SHA 上核对验收清单;confirmed 才自动关闭 Issue,rejected/indeterminate 暂停等待人工复核。
工作流的目标不是让一个 Agent 连续执行一段不可见的脚本,而是把关键决策、AI 会话、代码变更、测试、审查、重试和失败原因记录为可恢复的里程碑。
1.1 适用范围
适合:
- 需求边界明确、可以通过代码和测试验证的 GitHub Issue;
- 需要方案审查、代码审查和 CI 闭环的中小型改动;
- 多 Issue 串行批处理;
- 需要在时间线中查看 Token、请求数、会话和代码差异的受控自动化。
不适合:
- 需要生产环境凭据或任意管理员权限的任务;
- 无法通过仓库内测试、CI 或明确验收条件判断完成度的任务;
- 要求 Agent 直接修改受保护 Git 元数据、绕过分支保护或自行合并未通过检查的代码。
2. 用户操作
2.1 创建工作流
在 AI 自主开发页面中选择项目、CLI 工具、模型和需求来源。需求可以是文本,也可以是 GitHub Issue URL 或编号。
创建时会固化一份 definition_snapshot,用于保留当时的需求、工具、模型、分支策略和批次信息。后续配置变化不应偷偷改变已运行工作流的定义。
分支策略包括独立 worktree、新分支和当前分支。批处理会强制使用独立 worktree,并为同一批次锁定共同的 origin/main 基线,避免后创建的工作流看到前一个工作流尚未合并的中间状态。
2.2 暂停、恢复与停止
- 暂停:冻结正在运行的 Agent 进程并保留工作流状态;人工暂停不会被调度器自动恢复。
- 恢复:继续被冻结的进程,或按当前阶段重新进入调度。
- 停止:终止当前 Agent,并把工作流置为
cancelled;同一批次中尚未开始的后续工作流也会取消。 - 失败后重试:仅适用于
failed或planning_timeout,从持久化的当前阶段恢复。
暂停和停止不是同义操作。新增状态或错误分支时,不得破坏这两个按钮在活动状态下的可用性。
2.3 里程碑操作
- 查看定义/方案/审查/报告:打开持久化内容;
- 查看代码变更:按里程碑或整个 PR 查看 diff 和增删统计;
- 查看会话:打开该里程碑所属的稳定会话线(完整 transcript,含时间戳与 Markdown 渲染);
- 取消轮次:取消目标里程碑之后的步骤,进入
wait,等待用户反馈; - 从此处分叉:复制分叉点之前的历史,创建独立工作流和工作树;
- 反馈后继续:把用户反馈记录为新里程碑,再回到对应流程。
3. 领域模型
3.1 Workflow
autonomous_workflows 是流程级状态,保存:
- 当前阶段、状态、开发轮次和错误;
- 项目、分支、worktree、PR 和批次信息;
main_session_id、review_session_id、test_session_id、verification_session_id;- Token、输入/输出 Token 和请求数汇总;
- CI 修复次数、失败指纹和诊断状态;
- 验收核对状态(
verification_status)、尝试次数、Issue 验收快照哈希和人工改判上下文; - 暂停、超时、用户反馈和恢复上下文。
3.2 Milestone
workflow_milestones 是时间线中的审计单元。一个里程碑只描述一次明确事件,例如方案生成、方案审查、实现、测试、PR 审查、CI 诊断或冲突修复。
里程碑保存自己的增量用量 phase_*,以及会话、内容、提交、diff 统计和错误。它不是工作流累计用量的副本。
验收核对里程碑有自己的行生命周期:verifier 启动时先创建 in_progress 的 “Acceptance verification: running” 行并承载实时活动,结算时在同一行上写入终态结论,而不是另起新行。
3.3 Agent session
agent_sessions 保存 Open ACE 的稳定会话身份和 CLI/模型提供商的实际会话 ID。恢复会话时可能替换底层 provider transcript,但不应替换工作流的稳定会话线身份。
4. 生命周期和状态机
正常阶段顺序为:
preparation → planning → development → pr_review → report → merge → acceptance_verification
wait 是用户反馈等待阶段,不属于线性 PHASE_ORDER;它可以从取消轮次或反馈流程进入,再返回合适的业务阶段。
acceptance_verification 是合并后的独立验收核对阶段(#2335,默认启用,可通过配置 autonomous.acceptance_verification_enabled 关闭)。verdict 为 confirmed、或人工把 rejected/indeterminate 改判为 confirmed 后,工作流才进入 completed;关闭该功能时合并后直接完成。
主要状态:
| 状态 | 含义 |
|---|---|
queued | 批处理中等待前序工作流 |
pending | 可由调度器启动 |
preparing | 准备仓库、分支和 worktree |
planning | 方案生成、审查和定稿 |
developing | 实现与测试 |
pr_review | PR 审查、修复和复审 |
reporting | 生成最终报告 |
waiting | 等待用户反馈 |
merging | CI 检查、修复、同步和合并 |
verification_pending | 合并后的独立验收核对进行中 |
paused | 人工暂停、应用配额暂停、上游硬配额暂停或验收暂停(rejected/indeterminate/重试耗尽) |
planning_timeout | 方案阶段超时,等待延时或重试 |
completed | PR 已合并、收尾完成,且(启用验收时)验收 confirmed 后 Issue 已关闭 |
failed | 自动恢复边界已耗尽,需要人工处理 |
cancelled | 用户停止或批次级取消 |
持久化状态是恢复依据 。进程重启后不得仅依赖内存中的 Agent、锁或 SSE 连接来判断下一步。
5. 稳定的会话线设计
每个工作流只维护四条稳定会话线:
| 会话线 | 持久化字段 | 覆盖里程碑 |
|---|---|---|
main | main_session_id | 方案生成、方案收敛、开发、PR 修复、最终总结和 CI 修复 |
review | review_session_id | 方案审查和 PR 代码审查 |
test | test_session_id | 各开发轮次的测试与验证 |
verification | verification_session_id | 合并后的独立验收核对 |
这些会话线在多个里程碑间通过 resume 复用,目的是:
- 让实现 Agent 保留需求、方案和已做改动的连续上下文;
- 让审查 Agent 独立于实现者,避免同一上下文自我确认;
- 让测试 Agent 独立设计验证矩阵,而不是只接受实现者声明;
- 让 UI、用量统计和问题排查有稳定身份。
5.1 上下文溢出
底层模型会话达到上下文上限时,系统会:
- 识别 provider 的 input/context overflow 错误;
- 清除该稳定会话线与旧 provider transcript 的绑定;
- 使用自包含、精简的提示重新调用;
- 把新 provider 会话重新绑定到同一个 Open ACE 会话行;
- 保留失败尝试已经产生的用量。
因此上下文恢复不会创建新的会话线。任何修改都必须保持 main / review / test / verification 四字段是工作流的唯一稳定拓扑。
6. 调度、并发和批处理
AutonomousScheduler 周期性扫描活动工作流,并发上限分两层:
- 全局上限:所有用户合计同时推进的工作流数,默认 10(
MAX_CONCURRENT_WORKFLOWS,见app/services/autonomous_scheduler.py),可用/etc/openace/agent-launcher.conf的agent_max_concurrent_workflows覆盖;调度器每个周期重新读取配置,修改后无需重启服务。 - 每用户上限:单个用户同时推进的工作流数 = 其所属租户的
max_sessions_per_user(默认 5),在调度选择时强制,与创建工作流时的并发检查口径一致。
调度同时执行三层互斥:
- 数据库锁:防止多实例同时推进同一工作流;
- 工作空间锁:防止两个工作流修改同一实际 checkout;
- 分支锁:防止同一分支被两个 worktree 同时使用。
waiting 会占用用户的活动工作流额度,但不会作为批次中“正在执行”的 Agent。批处理同一时间只推进一个工作流;前序 paused 或 cancelled 会阻塞队列,前序完成、失败或进入可 推进的等待状态后才评估下一项。
服务停止时,调度器先通知正在运行的 orchestrator 收尾;启动时会清理上次遗留的 Agent 进程并把不确定状态置为可检查状态,避免重复推进。
7. Git、PR 和变更边界
7.1 Worktree 优先
独立 worktree 是默认的隔离策略。工作流保存 preferred_worktree_path,即使冲突处理临时移除了原 worktree,后续 CI 修复也必须先恢复同一 PR 分支的 worktree,再消耗修复次数。
7.2 Agent 不直接管理受保护 Git 元数据
Agent 负责修改工作树文件。创建分支、提交、推送、PR、同步主分支、冲突提交和合并由受控的 GitHubOps 完成。提示词和命令过滤都不能作为唯一安全边界,操作系统权限才是最终边界。
7.3 有效变更范围
验证不能只比较 Agent 启动前后的本地 HEAD。本地 worktree 可能已经包含:
- 上一次推送失败留下的未推送提交;
- 冲突解析产生的临时提交;
- 被中断轮次留下的文件;
- 主分支同步提交。
当前实现以远端 PR head 和合并前有效 PR diff 为基线:
- 保留远端 PR 已有的合法变更;
- 只接受本轮范围内的新修改;
- 拒绝超出需求或文件数上限的扩散;
- 主分支同步本身不算一次 AI 修复;
- Agent 没有产生新改动时,不能把“命令运行过”当作修复成功;
- 若本地已有待推送合法提交,仍需验证并推送,不能误报“无代码变更”。
8. 开发、测试与独立审查
开发阶段由 main 会话实现最终方案。随后 test 会话根据方案和实际 diff 设计定向验证矩阵,并运行仓库可用的检查。
PR 审查由 review 会话执行。审查结论是结构化信号,而不是仅凭自然语言长度判断。存在实质问题时,main 修复后再次由 review 复审;最终摘要应反映实际落地情况和仍然存在的风险。
仓库声明的运行时优先于 Open ACE 服务自身的运行时。例如服务进程使用 Python 3.9,不代表 Agent 可以把声明 Python 3.11 的目标仓库降级为 3.9 语法。
9. 合并阶段和 CI 自动修复
9.1 检查顺序
合并阶段按以下顺序处理:
- 获取 PR 和检查状态;
- 如果 PR 分支落后于
main,先同步主分支并等待新一轮 CI; - 对失败检查收集完整、可操作的日志;
- 构造本地复现要求和仓库运行时契约;
- 由
main会话修复; - 运行对应命令和隔离的 pre-commit 收敛;
- 验证有效变更范围,提交并推送;
- 等待下一轮 CI;
- 检查失败指纹是否真正变化;
- 检查通过后合并并清理。
主分支同步、worktree 恢复和等待 CI 日志都不消耗 AI 修复次数。只有具备可操作日志、真正启动 Agent 的修复才计数。
9.2 诊断与重试边界
- CI 日志暂不可用时最多轮询 6 次,不让 Agent 盲猜;
- 自动 CI 修复最多 5 次;
- pre-commit 最多收敛 3 轮;
- 同一失败指纹在代码已变化后仍完全不变,会提前停止;
- 没有日志时的降级指纹不能触发“失败未变化”误判;
- cancelled check 不作为需要修复的代码失败;
- runner 失败、无输出、上下文溢出和“无新代码”必须分别记录,不能都折叠成同一个提示。
CI 修复提示要求 Agent 先查看 .github/workflows/、package.json、Makefile、tox.ini、pytest.ini 和 scripts/,用 CI 实际命令复现,而不是只跑它认为相关的少量测试。
9.3 合并就绪判定与真实冲突
gh pr merge 会把真实 Git 冲突、必需检查未完成、必需更新分支、审查规则和其他仓库规则统一返回为非零退出码。编排器不能把所有合并拒绝都交给冲突解析 Agent,否则分支保护会被误报成冲突,并在已经同步主分支后产生“没有新提交”的伪失败。
当前判定顺序为:
- 最终合并前先用受控路径检查并同步落后于
main的 PR 分支;同步会触发新 CI,本轮直接返回等待,不消耗 CI repair attempt; - 合并调用被拒绝后,重新查询检查结果和 GitHub REST
mergeable/mergeable_state,避免使用调用前的过期状态; - 新出现的失败检查进入 CI 修复;pending 检查属于已确认的瞬时状态,继续等待;
- 没有 pending 检查时,先判定真实冲突:
mergeable_state=dirty、明确的 conflict 错误,或 GitHub 只返回mergeable=false且没有更具体状态时进入 resolver;权威的dirty优先于同一次响应里的通用 repository-rule 文本; - 没有失败/pending/冲突证据,但错误明确表示 repository rules、required checks、review、draft 或 branch protection 时,工作流进入可人工恢复的
paused;用户满足仓库要求后再恢复; blocked、behind、unstable、has_hooks、draft等 merge state 只用于补充诊断,不能单独吞掉权限、API 或基础设施错误;未知错误保留原始原因并失败可见。
真实冲突解析在临时隔离 worktree 中进行,并绑定当前 PR 分支。解析结果仍需经过范围校验,不能把主分支或其他工作树中的无关变化带入 PR。成功推送后会等待新 CI,再恢复常规合并流程。
10. 错误分类和恢复策略
错误分类必须基于 runner 的结构化错误和零 Token 错误信封,不能扫描正常方案正文中的关键词,否则文档里提到 “rate limit” 也会误触发重试。
| 类型 | 示例 | 行为 |
|---|---|---|
| 瞬时网络/Git 错误 | TLS、连接重置、DNS、临时 push 失败 | 保持当前阶段,短周期重试;达到上限后失败 |
| 瞬时 API 错误 | 429、5xx、overloaded | 指数退避重试,最长约 30 分钟 |
| 百炼分配限速 | usage allocated quota exceeded | 按瞬时限速重试,不得转人工暂停 |
| 上游硬配额耗尽 | platform quota exceeded 等明确硬配额错误 | paused,标记为可人工恢复;恢复额度后人工继续 |
| Open ACE 应用配额 | 用户 Token/请求/费用配额超限或配额检查失败 | fail-closed 暂停;额度恢复后调度器自动恢复 |
| 上下 文溢出 | maximum context/input length | 在同一稳定会话线上换新 provider transcript 重试 |
| CI 证据不足 | Actions 日志尚未生成或无权限 | 等待诊断;达到上限后失败并提示检查权限 |
| 仓库完整性异常 | .git 内容、inode、所有者或 ACL 被篡改 | fail-closed,退出码 68,要求人工检查 |
| 验收 verifier 基础设施失败 | 运行器失败、验收输出不可解析 | 同阶段自动重试,最多尝试 3 次(确定性解析失败最多 2 次);耗尽后暂停等待人工 |
人工暂停、应用配额暂停和上游硬配额暂停虽然都使用 paused,但通过错误原因区分。只有应用配额暂停允许自动恢复;人工暂停和上游硬配额暂停必须由用户决定何时继续。
11. 跨用户隔离与安全边界
11.1 专用 Agent 账户
当前实现使用专用、无登录凭据的低权限账户 openace-agent(可通过 OPENACE_AUTONOMOUS_AGENT_ACCOUNT 或 autonomous.agent_system_account 配置),而不是以项目所有者或 Open ACE 服务账户运行代码 Agent。
该账户必须:
- 非 root;
- 不属于
root、wheel、sudo或admin等管理组; - 与项目所有 者和服务账户不同;
- 只能通过受限的
openace-run-as --isolatedsudoers 规则启动。
/usr/local/libexec/openace-agent-bin 中的受控命令守卫会约束 Agent 对 git、gh、Python 和 pytest 等关键命令的调用,避免把受限 sudo 入口变成绕过编排层的任意 Git/运行时操作入口。
11.2 文件权限
启动器:
- 从空环境开始,仅注入必要的 HOME、用户、语言、临时目录、Git safe.directory 和显式代理变量;
- 只给工作树文件授予 Agent 写 ACL;
- 给普通 clone 或 linked worktree 的 Git 元数据只读/遍历 ACL;
- 保留项目所有者对新文件的访问;
- 串行化同一隔离账户的启动;
- 无论正常结束、信号退出或下次恢复,都撤销临时 ACL 并杀死遗留 Agent 进程。
11.3 Git 完整性注册表
运行前,root 启动器把 .git 入口的类型、设备/inode、mode、owner/group、内容摘要和精确 ACL 快照原子写入 /run。运行后:
- 先检查结构、内容、所有权以及 owner/other 权限未变化;
- 只允许启动器自身可能引起的 POSIX ACL
mask::表示变化; - 验证所有基础和命名 ACL 项完全一致;
- 恢复原 ACL 后再次做原始签名和 ACL 精确比较。
任何内容、inode、类型、owner、other 权限或非 mask ACL 改动都会 fail-closed。旧版两行注册表只在确实存在 ACL mask 的情况下允许一次兼容恢复,成功后立即升级到精确格式。
不要为“恢复运行”直接删除 /run/openace-agent-* 注册表。出现 OPENACE_REPO_INTEGRITY_VIOLATION 时,应先核对 worktree 注册、远端 PR head、.git 指针/目录和 ACL,再决定是否归档旧注册表并重建 worktree。
12. 用量统计和 AI Activity
12.1 用量
工作流总用量从每个里程碑自己的 phase_total_tokens、phase_input_tokens、phase_output_tokens 和 phase_request_count 重算。不能把跨里程碑复用会话的累计总量逐次相加,否则会重复计费。
runner 对 provider 的累计计数维护基线,只保存本次增量。上下文恢复和 API 重试产生的真实用量也必须合并到当前里程碑。
验收核对用量记在验收里程碑自己的 phase_* 上:跨尝试复用 verification 会话线时以已记录用量为基线(prior_usage)折算,只保存本次增量;运行中的验收里程碑行同时接收实时用量写入。