OmX `omx autoresearch` 命令全面校验:Thin-Supervisor 平价运行模型剖析
2026/9/10 7:11:37 网站建设 项目流程

OmXomx autoresearch命令全面校验:Thin-Supervisor 平价运行模型剖析

【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex

omx autoresearch是 OmX(Oh My codeX)中用于驱动“多轮 Codex 实验迭代”的命令面,其核心设计是薄监督器(thin supervisor)模式:每次迭代只启动一个 Codex 实验会话,而保持(keep)、丢弃(discard)、回滚(reset)的决策闭环由 OmX 运行时自己持久化。本指南以 docs/contracts/autoresearch-command-review.md 的校验记录为主线,结合 docs/contracts/autoresearch-command-contract.md 的契约、src/autoresearch/runtime.ts 的实现与配套测试,完整还原这条命令的 CLI 形态、运行时状态权威分层、决策策略、恢复语义与验证方法,帮助你在自己的仓库里复现这套“一个会话一次实验、监督器掌管持久循环”的平价模型。

背景:为什么需要 Thin-Supervisor 模型

在 Agent 驱动的自动化研究中,最典型的失控场景是:启动一个长期存活的 Codex 会话让它“一直改进”,会话内部反复自我循环,既没有明确的停止条件,也没有可审计的迭代记录。OmX 的 autoresearch 采用相反的思路——把循环的控制权从 Agent 会话手里拿回运行时。

其核心约定一句话可以概括:每一次迭代,Codex 会话只做一轮实验并写一个候选产物(candidate artifact),随后立即退出;是否保留这次改动、是否回滚、是否启动下一轮,全部由 OmX 运行时依据持久化的账本和评估器(evaluator)的 JSON 输出决定。

这条命令面由两份文档共同锚定:

  • docs/contracts/autoresearch-command-contract.md:定义 CLI、mission/sandbox 契约、运行时模型、候选产物契约、决策策略与 resume 语义;
  • docs/contracts/autoresearch-command-review.md:2026-03-14 由 worker-3 评审车道完成的全面校验记录,确认实现与 PRD/测试规格在平价语义上已对齐,并给出剩余的可选优化点。

CLI 形态与参数面

命令形式

契约文档定义了三种入口:

omx autoresearch <mission-dir> [codex-args...] omx autoresearch --resume <run-id> [codex-args...] omx autoresearch --help

参数解析逻辑位于 src/cli/autoresearch.ts 的parseAutoresearchArgs,其解析分支如下:

首个参数行为
(空)进入 guided 引导流程(guided: true),不直接启动
init解析为 guided 引导 + 透传initArgs
--help/-h/help输出帮助文本
--resume <run-id>恢复指定 run-id,其余参数作为 codex 透传参数
--resume=<run-id>等价于上者
run <mission-dir>显式 run 子命令形态
-开头按引导参数解析(seed args)
其他首参作为missionDir,其余作为 codex 透传参数

值得注意的是normalizeAutoresearchCodexArgs(src/cli/autoresearch.ts)会做 codex 参数规整:把MADMAX_FLAGCODEX_BYPASS_FLAG去重,并确保最终一定注入 bypass 标志——这保证了每次启动的会话都是受控的独立实验会话,而不是递归触发外部钩子。

关于命令面的现状说明

需要澄清一个容易混淆的时点问题:评审文档(2026-03-14)记录的是一次已完成的平价校验,当时的命令面处于活跃可用状态;而在当前仓库的源码里,src/cli/autoresearch.ts顶部已经带有 hard-deprecation 消息(src/cli/autoresearch.ts),指向迁移路径:

  • $autoresearchskill 使用 hook-native 的持久循环;
  • $deep-interview --autoresearch在执行前创建/打磨 mission 产物(规范产物写入.omx/specs/autoresearch-{slug}/)。

因此,本文描述的命令形态属于该功能的历史契约与实现语义,可用于理解底层运行时模型与迁移背景;新项目应优先采用 skill 入口。这与评审文档“reviewer lane 校验通过、后续仅剩可选清理项”的结论并不冲突——它正是平价模型曾被打通的证据。

Mission / Sandbox 契约:一次迭代的实验边界

<mission-dir>必须位于 git 仓库内,且必须包含两个文件:

  • mission.md:任务说明,随每次迭代写入会话指令;
  • sandbox.md:沙箱策略 + 评估器契约,YAML frontmatter 必须定义:
--- evaluator: command: node scripts/eval.js format: json keep_policy: score_improvement # 可选:score_improvement | pass_only --- <沙箱边界说明>

契约与解析逻辑在 src/autoresearch/contracts.ts:

  • evaluator.command:必填,评估器命令行(以 shell 方式在 worktree 内执行);
  • evaluator.format:必填且当前版本只接受json(src/autoresearch/contracts.ts 定义format: 'json'常量校验);
  • evaluator.keep_policy:可选,取值score_improvement(默认)或pass_only,由parseKeepPolicy严格校验(src/autoresearch/contracts.ts)。

评估器的 stdout 必须是合法 JSON 对象,包含必填布尔pass与可选数值scoreparseEvaluatorResult(src/autoresearch/contracts.ts)会逐项校验:必须是 JSON 对象、pass必须是布尔、score出现则必须是数字,任何一项不满足都会抛出带明确诊断信息的错误。

从源码结构看,frontmatter 解析采用轻量的逐行 YAML 子集实现(parseSimpleYamlFrontmatter,src/autoresearch/contracts.ts),支持顶层键与二级 section(如evaluator块),不支持数组等复杂结构,这提醒你在编写sandbox.md时保持 frontmatter 的扁平简单。

运行时模型:Repo-Root 权威 vs Worktree 本地状态

运行时实现位于 src/autoresearch/runtime.ts,采用清晰的“状态权威分层”:

一次全新启动创建的结构

对象位置职责
分支autoresearch/<mission-slug>/<run-tag>run-tagged 实验分支
worktree<repo>.omx/worktrees/autoresearch-<mission-slug>-<run-tag>隔离实验工作区
活跃运行锁.omx/state/autoresearch-state.json仅作为 active-run 指针/锁
run 目录.omx/logs/autoresearch/<run-id>/权威 per-run 产物

run 目录内包含(见prepareAutoresearchRuntime中 src/autoresearch/runtime.ts 的路径构造):

  • manifest.json:权威 per-run 状态(schema_version、run_id、mission 路径、baseline/last_kept commit、keep_policy、status 等完整字段,见 src/autoresearch/runtime.ts 的AutoresearchRunManifest);
  • candidate.json:刚结束的 Codex 会话写回的候选产物(交接点);
  • iteration-ledger.json:可持久化的迭代历史账本(entries数组,schema_version: 1);
  • latest-evaluator-result.json:最近一次评估器输出;
  • bootstrap-instructions.md:每次启动/恢复时生成的会话指令快照。

worktree 本地则只保留两类运行时产物:results.tsv与可选评估日志(如run.log),且这些运行时生成的文件必须通过 worktree 本地的.git/info/exclude排除(AUTORESEARCH_WORKTREE_EXCLUDES = ['results.tsv', 'run.log', 'node_modules', '.omx/'],src/autoresearch/runtime.ts)。ensureRuntimeExcludes(src/autoresearch/runtime.ts)会在启动与恢复时把上述模式写入git info/exclude,确保 reset 安全检查不会把运行时产物误判为污染。

results.tsv 的格式

AUTORESEARCH_RESULTS_HEADER = 'iteration\tcommit\tpass\tscore\tstatus\tdescription\n'(src/autoresearch/runtime.ts)。每一轮迭代追加一行,其中 iteration 从 0 开始,第 0 行是 baseline 记录,后续行对应各次候选评估。

模式状态(mode state)集成

autoresearch 是 OmX 模式生命周期体系的一员——src/modes/base.ts 的ModeName类型明确列出autoresearchprepareAutoresearchRuntime会调用startMode('autoresearch', taskDescription, 1, projectRoot)并把current_phase依次置为evaluating-baselinerunning,同时把 mission、run、各产物路径、keep_policy 等写入模式状态(src/autoresearch/runtime.ts)。模式状态记录在仓库根的.omx/state下,与 active-run 锁配合实现互斥。

单次迭代的指令快照

每次启动或恢复都会由writeInstructionsFile生成bootstrap-instructions.md,内容由buildAutoresearchInstructions(src/autoresearch/runtime.ts)拼装,包含:

  • Run ID、mission/sandbox 文件路径、mission slug、迭代号;
  • baseline commit、last kept commit、last kept score;
  • results 文件与 candidate 产物路径;
  • keep policy;
  • 迭代状态快照(JSON):iterationbaseline_commitlast_kept_commitlast_kept_scoreprevious_iteration_outcomerecent_ledger_summarykeep_policy
  • 明确的“薄监督器”操作指令:“恰好执行一轮实验周期(exactly one experiment cycle),最多产生一个候选 commit,写完 candidate artifact JSON 后退出,禁止在会话内无限循环”
  • 候选产物契约字段说明;
  • 评估器契约(command、format=json、输出 pass 布尔与可选 score);
  • mission 内容与 sandbox 策略正文(超长内容被截断到 4000 字符,trimContent,src/autoresearch/runtime.ts)。

previous_iteration_outcomerecent_ledger_summarybuildAutoresearchInstructionContext从账本读取(最近最多 3 条,reason 截断 160 字符、description 截断 120 字符),保证每个新会话都知道上一轮发生了什么。

候选产物契约:会话与监督器的交接点

Codex 会话退出前必须把 JSON 写到candidate.json,字段契约(src/autoresearch/runtime.ts):

字段类型说明
statuscandidate \| noop \| abort \| interrupted会话侧结论
candidate_commitstring \| nullstatus=candidate 时必填非 null
base_commitstring编辑前的基线提交
descriptionstring一句话摘要
notesstring[]备注数组
created_atISO 时间戳创建时间

完整性校验由parseAutoresearchCandidateArtifactvalidateAutoresearchCandidate(src/autoresearch/runtime.ts)双重把关,核心不变量:

  • candidate_commit必须在 git 中可解析(git rev-parse --verify <ref>^{commit}),且必须等于会话退出时 worktree 的HEAD
  • base_commit必须在 git 中可解析,且必须等于监督器提供的last_kept_commit

这两条规则杜绝了“谎报 commit”与“在错误基线上提交”两类作弊路径。

决策策略:keep / discard / reset 闭环

decideAutoresearchOutcome(src/autoresearch/runtime.ts)是决策核心,完整策略如下:

输入决策行为
status=abortabort停止运行,不 reset,run 状态置为stopped
status=noopnoop记录 noop 迭代,默认继续启动下一轮
status=interruptedinterrupted检查 worktree:脏则停止等待人工介入;干净则记录后继续
评估器 error/崩溃discard回滚
pass=falsediscard回滚
pass_onlypass=truekeep直接保留
score_improvement且 pass 无可比数值 scoreambiguous回滚(要求可比数值分数)
score_improvement且 score 提升keep保留并更新last_kept_commit/last_kept_score
score_improvement且 score 未提升discard回滚

关键点:

  • baseline 行永远被记录seedBaseline(src/autoresearch/runtime.ts)在启动时对初始提交跑一次评估器,写入results.tsv第 0 行与账本 baseline 条目,last_kept_score只在 baseline pass 且带数值时记录;
  • 所有 discard / ambiguous / error 路径都reset --hardlast_kept_commitresetToLastKeptCommit(src/autoresearch/runtime.ts)在 reset 前先执行assertResetSafeWorktree,只允许排除清单内的运行时产物存在,否则报autoresearch_reset_requires_clean_worktree:<path>:<blocking lines>并终止。

processAutoresearchCandidate(src/autoresearch/runtime.ts)串起完整流程:读候选 → 校验 → 非 candidate 状态走recordNonEvaluatedCandidateStatus→ candidate 状态跑评估器 → 决策 → keep 则推进 last_kept,否则 reset → 写 results/ledger → 写回 manifest → 生成下一轮指令。

并发锁与 Fresh-Run 语义

  • 活跃运行锁.omx/state/autoresearch-state.json保存{active, run_id, mission_slug, ...}assertAutoresearchLockAvailable(src/autoresearch/runtime.ts)在启动与恢复前都会检查,若state.active && state.run_id存在则直接抛autoresearch_active_run_exists:<run-id>,阻止并发二次启动;
  • fresh-run 语义:每次全新启动都会由buildAutoresearchRunTag(src/autoresearch/runtime.ts,ISO 时间戳去符号化)生成 run-tag,再由buildRunId组合成${missionSlug}-${runTag.toLowerCase()}。run 目录、分支、worktree 全部按 run-id/run-tag 命名,因此不会静默复用一条长期存活的 lane
  • 命名规划的统一入口src/team/worktree.ts的规划函数按 scope 区分命名(src/team/worktree.ts):scope === 'autoresearch'时分支为autoresearch/<sanitized-name>/<runTag>、worktree 为.omx/worktrees/autoresearch-<sanitized-name>-<runTag>。配套测试 src/team/tests/worktree.test.ts 明确断言分支名autoresearch/demo-mission/20260314t000000z与 worktree 路径后缀autoresearch-demo-mission-20260314t000000z
  • 模式互斥:启动前还会检查readModeState('autoresearch', projectRoot),若已有 active 模式则抛autoresearch_active_mode_exists:<run-id>,与锁文件形成双重保护。

Resume 契约与失败条件

resumeAutoresearchRuntime(src/autoresearch/runtime.ts)从--resume <run-id>恢复运行,先加载manifest.jsonloadAutoresearchRunManifest,src/autoresearch/runtime.ts),随后必须通过以下失败检查,每种都给出可操作的错误码:

失败条件错误
manifest 缺失autoresearch_resume_manifest_missing:<run-id>
worktree 缺失autoresearch_resume_missing_worktree:<path>
worktree 在排除清单外存在脏改动autoresearch_reset_requires_clean_worktree:...
manifest 已终结(非runningautoresearch_resume_terminal_run:<run-id>

恢复成功后,从last_kept_commit与既有 results 历史继续推进,并重新生成带最新账本摘要的指令文件。运行终结统一走finalizeRun(src/autoresearch/runtime.ts):写回status/stop_reason/completed_at,模式状态置非活跃,active-run 锁解除(deactivateAutoresearchRun)。

测试验证:平价语义如何被钉死

评审记录列出的验证命令如下:

npm run build node --test dist/autoresearch/__tests__/runtime.test.js \ dist/cli/__tests__/autoresearch.test.js \ dist/cli/__tests__/index.test.js \ dist/cli/__tests__/nested-help-routing.test.js \ dist/team/__tests__/worktree.test.js \ dist/modes/__tests__/base-autoresearch-contract.test.js

src/autoresearch/tests/runtime.test.ts 是核心覆盖,值得重点阅读的用例:

  1. 指令构建:断言buildAutoresearchInstructions包含“exactly one experiment cycle”、pass/score输出契约、迭代状态快照等关键语义(src/autoresearch/tests/runtime.test.ts);
  2. reset 安全检查:验证.omx下的 untracked 运行时文件不会阻断 reset-safe 检查(src/autoresearch/tests/runtime.test.ts);
  3. 运行时产物与模式状态:验证 manifest、ledger、latest-evaluator、results、指令文件全部落盘,baseline 行0\t...\ttrue\t1\tbaseline\tinitial baseline evaluation正确写入,模式状态active=true / current_phase=running(src/autoresearch/tests/runtime.test.ts);
  4. keep/discard 闭环(最关键的端到端用例,src/autoresearch/tests/runtime.test.ts):先提交 score=2 的改进候选 →processAutoresearchCandidate返回keeplast_kept_commit前进到改进提交;再提交 score=1 的回退候选 → 返回discard,worktreeHEADreset --hard回改进提交;最终 results 出现1\t...\ttrue\t2\tkeep\timproved score2\t...\ttrue\t1\tdiscard\tworse score两行,账本顺序为baseline → keep → discard,且下一轮指令的previous_iteration_outcome正确携带discard:score did not improve

此外还有src/autoresearch/__tests__/runtime-parity-extra.test.tssrc/autoresearch/__tests__/contracts.test.ts以及 eval 脚本src/scripts/eval/eval-parity-smoke.tssrc/scripts/eval/eval-candidate-handoff.tssrc/scripts/eval/eval-fresh-run-tagging.tssrc/scripts/eval/eval-resume-dirty-guard.ts等,覆盖 fresh-run 标签、候选交接、恢复脏保护等平价面。

评审结论与遗留风险

评审记录(docs/contracts/autoresearch-command-review.md)给出的结论是:实现已不再是早期 v1 scaffold,与 thin-supervisor 平价模型大体一致,共享的 help/测试措辞不一致问题已解决。同时留下三条可选跟进项:

  1. runAutoresearchLoop()每轮迭代通过execFileSync('cat', ...)+JSON.parse从 manifest 回读 run-id,功能正确但略显笨拙,可简化以避免 shell 调cat
  2. 焦点测试覆盖了主要平价面,但noopabortinterrupted与显式pass_only策略分支仍有扩展空间;
  3. 该车道只验证了焦点平价覆盖与构建状态,未跑完整仓库级测试/lint 套件。

对照当前源码,第一点在现有processAutoresearchCandidate流程中已通过函数参数直传 manifest 的方式得到缓解(不再依赖 shell 回读),说明这些遗留项属于演进中的常规打磨。

结语:平价模型的三条启示

omx autoresearch的完整评审链条(契约 → 评审 → 实现 → 测试)对设计任何 Agent 自动化循环都有借鉴价值:

  1. 循环归监督器:会话只负责“一轮实验 + 写产物”,循环、决策、回滚全部由外部运行时掌控,天然可审计、可中断、可恢复;
  2. 状态权威分层:repo-root 的manifest.json是权威真相,autoresearch-state.json只是锁,worktree 只留运行时产物并显式排除——层次清晰,冲突面最小;
  3. 决策可验证:候选产物有完整性校验(commit 可解析、与 HEAD/last_kept 对齐),决策策略有显式表格(keep/discard/ambiguous/noop/abort/interrupted),每轮结果都落进results.tsv与账本,形成可回放的历史。

若要继续深入,建议阅读 docs/contracts/autoresearch-command-contract.md 获取契约原文,配合 src/autoresearch/runtime.ts 与 src/autoresearch/tests/runtime.test.ts 逐行对照;迁移到新命令面时,参考 src/cli/autoresearch.ts 顶部的弃用指引,改用$autoresearchskill 与$deep-interview --autoresearch

【免费下载链接】oh-my-codexOmX - Oh My codeX: Your codex is not alone. Add hooks, agent teams, HUDs, and so much more.项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-codex

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

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

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

立即咨询