oh-my-pi Autoresearch 第一阶段实战编写符合规范的 autoresearch.sh 基准测试 Harness【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-piAutoresearch 是 oh-my-picoding-agent内置的自主实验模式Agent 在一个独立 Git 分支上自动运行「改代码 → 跑基准 → 记录结果」的迭代循环直到达成优化目标。本篇文章聚焦其Phase 1Harness Setup这是整个流程的起点Agent 本轮的全部任务就是搭建一个可复现的基准测试入口autoresearch.sh并调用init_experiment完成基线快照。读完本文你将掌握 autoresearch harness 的四大硬性规范、METRIC输出协议、init_experiment的完整参数语义以及从 Phase 1 平滑过渡到 Phase 2 迭代循环的底层机制。一、Autoresearch 的两阶段流程与 prompt-setup.md 的定位Autoresearch 是 coding-agent 包内实现的一个内置扩展扩展注册入口在 autoresearch/index.ts。它把一次优化任务拆成两个阶段Phase 1Harness Setup搭台——会话尚未建立时Agent 只负责把基准测试环境搭好明确禁止做任何优化。Phase 2Iteration Loop迭代——调用init_experiment之后Agent 进入「理解目标 → 建立基线 → 单次实验 → 诚实记录」的循环直到用户打断或达到最大迭代次数。两个阶段分别对应两份系统提示词模板prompt-setup.mdPhase 1本文主角prompt.mdPhase 2从源码看这两份模板的注入时机在before_agent_start事件中当当前 Git 分支上不存在活跃会话时渲染并注入 setup 模板存在会话时则注入 Phase 2 模板见 index.ts。也就是说prompt-setup.md 只在「没有会话、模式刚开启」的那一轮生效一旦init_experiment成功后续每一轮进入的都是 Phase 2 提示词。两份模板都使用 Handlebars 渲染{{working_dir}}、{{branch}}、{{goal}}、{{baseline_warning}}等占位符由运行时填充。例如当用户尚未记录目标时setup 模板会输出「There is no goal recorded yet. Infer what to optimise from the latest user message...」要求 Agent 从最新消息推断优化对象并在init_experiment调用时捕获该目标prompt-setup.md。二、核心交付物autoresearch.sh 的四大硬性要求Phase 1 唯一必须产出的文件是工作目录下的./autoresearch.sh它是整个会话的「规范基准入口」canonical benchmark entrypoint。模板给出了四条硬性要求prompt-setup.md要求说明退出码语义正确成功退出码为 0失败为非 0输出主指标以单行METRIC namevalue打印主指标输出次要指标以额外的METRIC namevalue行打印任何次要指标确定性运行每次运行同一工作负载无实时网络、无时间依赖、适用处使用固定种子这四条不是建议而是协议——run_experiment工具正是靠解析这些METRIC行来获取实验数值的见下文第三节。模板同时明确Agent 可以修改任何必要的东西让 harness 跑通——基准二进制、Cargo.toml、package.json、辅助脚本、fixtures。这些修改都属于 harness 基线的一部分会在调用init_experiment时被自动提交prompt-setup.md。为什么「确定性」如此重要run_experiment的输出被截断后只有约 10 行 / 4KB 会回传给 LLMEXPERIMENT_MAX_LINES 10、EXPERIMENT_MAX_BYTES 4 * 1024见 helpers.ts而置信度计算见第七节假设同一基线下的多次运行差异来自真实改动而非噪声。如果 harness 每次运行结果受网络或时钟影响整个「基线 → 最优」的数值比较就失去了意义。因此模板要求固定种子、禁用实时网络与时间依赖正是为了保证观察到的指标变化 ≈ 代码变化。三、METRIC 输出协议Agent 如何「读到」你的基准结果Phase 1 的 harness 输出格式必须与run_experiment的解析逻辑严格一致否则即使脚本退出码为 0指标也无法被识别。解析实现在 helpers.ts^METRIC\s([\w.µ-])(\S)\s*$要点行首必须是METRIC 空白不能有缩进或前缀指标名允许的字符集是[\w.µ-]单词字符、点、希腊字母 µ、连字符常见命名如latency_ms、throughput_mb、p50_µs指标值必须是有限数值Number.isFinite校验非数字会被静默丢弃同一行内namevalue中间可以有空白但行尾不能有多余内容__proto__、constructor、prototype三个键名会被拒绝防止原型污染。此外 harness 还可以输出ASI keyvalue行携带任意结构化元数据helpers.ts值支持true/false/null、数字、JSON 字符串和普通字符串Phase 2 中常用来记录hypothesis、rollback_reason、next_action_hint等学习笔记。不过 ASI 在 Phase 1 并非必需——init_experiment只校验主指标的METRIC行。单位推断也有现成约定helpers.ts指标名以µs/ms/_s/_kb/_mb等结尾时会自动附带对应单位因此建议指标命名直接带上单位后缀让仪表盘与日志显示更友好。四、Phase 1 的四个标准步骤模板给出的操作流程是四步prompt-setup.md第 1 步检查目标Inspect the target。读源码确定要衡量什么、选什么工作负载。这一步决定了主指标与次要指标的定义——它们必须能真实反映优化目标而不是方便测量的值。第 2 步编写 harness。在工作目录写下autoresearch.sh以及配套的基准二进制、fixtures、辅助脚本。这些文件都将作为基线的一部分被提交。第 3 步验证Validate。通过常规bash工具执行bash autoresearch.sh确认退出码为 0 且至少输出一条METRIC行不通过就迭代修改直到通过。第 4 步调用init_experiment。传入目标、主指标名必须与METRIC行的名称一致和 scope。这一步把当前 worktree 快照为基线并正式开启 Phase 2。第 3 步的验证在源码层面有强制兜底init_experiment执行时会先检查./autoresearch.sh是否存在不存在则直接报错并返回提示「Phase 1 of autoresearch is harness setup — write ./autoresearch.sh so it exits 0 and prints METRIC , validate it via bash autoresearch.sh, then call init_experiment again」见 init-experiment.ts。也就是说harness 未就绪时init_experiment会拒绝继续从机制上保证了 Phase 1 不会被跳过。五、一个符合规范的 autoresearch.sh 示例以下示例仅用于演示协议并非仓库内既有文件展示如何满足四条硬性要求#!/usr/bin/env bash set -euo pipefail # 确定性固定种子禁实时网络 export SEED42 export NO_NETWORK1 # 构建基准二进制幂等 cargo build --release --quiet # 运行同一工作负载 N 次取中位数作为主指标 results() for i in 1 2 3 4 5; do v$(./target/release/bench --seed $SEED --input fixtures/workload.txt 2/dev/null) results($v) done median$(printf %s\n ${results[]} | sort -n | awk {a[NR]$1} END {print (NR%2 ? a[(NR1)/2] : (a[NR/2]a[NR/21])/2)}) # 主指标 次要指标行首必须是大写 METRIC printf METRIC latency_ms%s\n $median printf METRIC peak_memory_mb%s\n $(./target/release/bench --seed $SEED --stats mem 2/dev/null)要点回看set -euo pipefail保证失败时非 0 退出所有METRIC行无前缀、无尾随内容种子固定、无网络调用。把它放到工作目录后用bash autoresearch.sh验证一次确认既能 exit 0 又能打印至少一行METRICPhase 1 的体力活就完成了。六、init_experiment 参数全景Phase 1 → Phase 2 的交接仪式init_experiment是四个实验工具之一另三个是run_experiment、log_experiment、update_notes均在 tools 目录。它的参数 schema 定义在 init-experiment.ts完整语义如下参数类型必填说明namestring是实验会话名称goalstring否会话目标Phase 1 未记录时在此捕获primary_metricstring是主指标名必须与 harness 打印的METRIC名称一致metric_unitstring否指标单位如ms、µs、mbdirectionlower \| higher否越优方向默认lower越小越好secondary_metricsstring[]否次要指标名列表scope_pathsstring[]否预期会被修改的路径白名单语义见下off_limitsstring[]否禁止修改的路径constraintsstring[]否自由格式约束如不得改动公共 APImax_iterationsnumber否每个 segment 的软迭代上限正整数new_segmentboolean否在既有会话中开启新 segment、建立新基线调用后init_experiment会做四件关键的事init-experiment.ts检查并提交 harness若已在autoresearch/*分支上且有未提交改动自动以「autoresearch: harness setup」为题提交一次提交信息含入口命令与目标见 buildHarnessCommitMessage并把提交哈希记为基线baselineCommit。建会话或更新会话首次调用创建会话后续调用更新配置传new_segment: true时废弃 pending 运行并推进到新 segment。计算实验状态通过 state.ts 从已记录运行重建当前 segment、基线指标、置信度等。返回交接摘要输出 session 编号、指标方向与单位、基准入口bash autoresearch.sh、scope/off-limits、基线提交短哈希并提示「Phase 2: iteration loop is active. Run the baseline experiment with run_experiment and log it.」关于scope_paths的语义需要特别注意它是一个软约束——Agent 可以修改任何文件编辑不被阻断但修改了 scope 之外或 off-limits 之内的文件会被记录为scope_deviations若保留这类运行却不给justification下一轮提示词会把它标记为「unjustified」见 log-experiment.ts 与 prompt.md。路径匹配支持目录前缀语义specsrc/会匹配src/下所有文件helpers.ts。七、四条红线Phase 1 阶段的禁止事项模板末尾列了三条明确规则加上 Phase 1 的定位其实还有一条隐含红线合起来是禁止提前调用实验工具。在init_experiment之前调用run_experiment、log_experiment、update_notes都会报错「no active autoresearch session」因为会话尚未建立三个工具的入口都有相同的守卫逻辑例如 run-experiment.ts。禁止把「编译通过」当基准。harness 必须真正执行工作负载并输出METRIC。这是为了防止 Agent 拿cargo build/tsc之类的结果糊弄过去——它们既不产生指标也无法度量性能。禁止创建会话状态文件。autoresearch.md、autoresearch.checks.sh、autoresearch.program.md、autoresearch.ideas.md、autoresearch.jsonl、.autoresearch/、autoresearch.config.json都不得创建——会话状态由运行时用 SQLite 存储自动跟踪openAutoresearchStorage系列函数见 storage.ts。这解释了为什么init_experiment之前不能碰这些工具状态与工件管理完全托管Agent 只需聚焦「改代码 跑基准 记录」。隐含Phase 1 不做优化。模板开宗明义「Your job in this turn is to build the benchmark harness, not to optimise anything. Optimisation starts only after you call init_experiment.」——搭好台、验证通过、完成交接本轮即告结束。这些红线的设计意图很清晰把「测量环境」与「被测量的改动」彻底分离。harness 基线一旦建立后续每个keep提交只包含当次实验的代码改动discard回退也只影响当次改动历史实验因此完全可追溯。八、Phase 2 预览harness 交付后的运转方式init_experiment成功的那一刻起Agent 就进入了 prompt.md 描述的自主任循环。理解 Phase 2 有助于你在 Phase 1 就把 harness 设计对run_experiment固定执行bash autoresearch.shDEFAULT_HARNESS_COMMAND见 init-experiment.ts默认超时 600 秒完整输出写入runs/0001/benchmark.log之类的按运行编号组织的日志目录回传给 LLM 的是截断后的尾部run-experiment.ts。log_experiment按四种状态记录结果keep指标改善提交改动、discard回退或持平回退改动、crash运行失败、checks_failed验证失败。在autoresearch/*分支上discard执行git reset --hard HEAD clean只回退当次迭代、不回退之前的keep提交log-experiment.ts。置信度computeConfidence用中位数绝对偏差MAD估算噪声底confidence |best - baseline| / MAD至少需要 3 次运行≥2 视为「likely real」、≥1 视为「marginal」、更低视为「within noise」state.ts。这再次印证了 Phase 1「确定性 harness」的价值——噪声越小同样大小的改进越容易被判定为真实。update_notes维护持久化的会话手册body整体替换或想法清单append_idea追加到## Ideas区块每轮迭代注入回系统提示词update-notes.ts。九、分支与环境的边界情况Phase 1 对运行环境有几个前提值得在动手前确认实现见 git.ts建议在专用分支autoresearch/goal-slug-日期上运行。/autoresearch命令会尽量自动创建该分支见 ensureAutoresearchBranch分支名由目标文本 slug 化并截断到 48 字符冲突时自动加后缀。只有在这种分支上harness 自动提交、keep提交、discard回退到基线等能力才完整生效。启动前工作区必须干净。存在未提交改动时会直接报错「Worktree is dirty... Commit or stash these changes before starting autoresearch」因为新分支需要一个干净基线。纯 Jujutsu无 colocated Git环境会被拒绝提示先执行jj git init --colocate非 Git 目录则降级运行——没有分支隔离、基线重置与自动提交discard只能回退运行改动的文件。若在非autoresearch/*分支上完成 Phase 1setup 提示词会注入baseline_warningharness 文件可能在discard时无法完整回退提示先清理工作区再重跑/autoresearch渲染逻辑见 index.ts。十、总结Phase 1 的自检清单完成 Phase 1 前可以对照这份清单逐项确认工作目录下存在autoresearch.sh退出码语义正确成功 0 / 失败非 0bash autoresearch.sh至少打印一行METRIC namevalue主指标名与后续init_experiment的primary_metric一致harness 确定性可复现无实时网络、无时间依赖、固定种子未调用run_experiment/log_experiment/update_notes未创建任何autoresearch.*/.autoresearch/状态文件已通过常规bash工具实际执行并确认输出而非仅编译通过init_experiment返回成功输出了 session 编号、指标方向、基线提交哈希并提示进入 Phase 2。至此harness 已经成为整个 Autoresearch 会话的「标尺」后续每一次run_experiment的读数、每一次keep/discard的决策、每一次置信度评估都建立在这条标尺的确定性之上。想要深入验证本文提到的解析与提交细节可以直接阅读 helpers.ts、run-experiment.ts 与 log-experiment.ts 的对应实现。【免费下载链接】oh-my-pi⌥ Coding agent with the IDE wired in项目地址: https://gitcode.com/GitHub_Trending/oh/oh-my-pi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考