Virtual Embryo Challenge更新于 10-03 20:13(北京时间) / 每 5 分钟更新

← 工作原理 · 原文件 notes/reports/dev/2026-10-03_G39_search_fixes.md(Markdown 源文件已渲染;链接到其他文档的会跳转,指向源码的只显示路径)

G39 搜索循环修正:代码部分(2026-10-03)

依据任务书 §1(G39.1–39.8)和 §9 定稿(Engineer 不设固定时限,覆盖 §1 的 39.4①);另含 G45.2 平台期策略、stop_reason 和协调方追加的 knowledge_attachments。没有改动 agent/prompts/(提示词另由其他 agent 修改),只改了代码、配置模板、CONTRACT.md 和测试。没有提交,没有连 Spark,也没有启动任何 run。

改动与 §1 的对照

#内容文件
39.19 个现行 D 模板(t1_round2/D*.yaml、g24_t2_t3/*_D*.yaml)设 tune.p: 0;tune.py 保留,没有改动配置模板
39.2候选键 = 可执行代码树哈希(runtime_key,不含 METHOD.md)或目标视图上 seed-0 预测的 digest;两者任一相同即为同一候选,分组可传递(union-find)。用在三处:终选 FinalSelector.candidates()(与已选候选比较)、晋级 scoring_def.promotion_candidates(rows, k, env=)(新增去重,已晋级的成员代表整组)、无进展规则(drafts.no_progress 增加 same_as_parent)。Controller.evaluate 现在给每个目标分量的 seed-0 预测都算 digest,以前只给视图盲检查用的尺子算candidates.py、final.py、scoring_def.py、drafts.py、controller.py
39.3两类节点写 refuted_direction(PLAN.name + METHOD 首行)进 archive 并记 refuted_direction 事件:输出与父节点相同的(same_candidate,包括 39.6 判为 gen_empty 的),以及 METHOD 首行以 NO_CHANGE: 开头的。Researcher 和 Engineer 的父节点块里加一段程序生成的“该父节点下已被证否的方向”(refuted_lines)。新列也随 insert_imported 带入续跑(为 G45.3 准备)controller.py、archive.py
39.4① Engineer 不设固定时限(§9):配置里没有 engineer_minutes 时,时限 = 截止 − node_tail 的剩余时间;新增 engineer_stall: {seconds: 180, strikes: 3},run_group 把连续 180 s 无活动记一次停顿,连续 3 次才结束会话,之后不重试;有任何活动就重新计数。显式写了 engineer_minutes 的旧配置和 fake 配置照旧当作上限。② 会话开始前 harness 预写 solution/METHOD.md 占位(首行 [auto: Engineer 未完成] <PLAN.name>,下面附 family_id / mechanism / approach / 关闭机制对照)。会话结束时 METHOD 仍是占位:有 run.py → 照常执行打分,标 method_auto;没有 run.py → gen_failed。method_auto 节点要过 Reviewer 才能晋级:promotion_gate 挡住,needs_auto_review 在它进入晋级前 k 名时触发审查;终选本来就要求非种子节点审查通过。③ drafts.py:失败的 draft(gen_failed / gen_empty / crash / oom / timeout / invalid_format)不再占方法族的覆盖名额,只有进行中和已打分的算数;同一族失败满 draft.failed_cap(默认 2)次后,覆盖阶段不再抽它。覆盖后的 bandit 序号和“最少 draft”仍按全部尝试计controller.py、roles.py、runenv.py、drafts.py、scoring_def.py
39.6Engineer 提交的 runtime_key 与父节点相同(只改了 METHOD.md)→ 直接 gen_empty,不执行、不打分,同时记 same_as_parent 和 refuted_directioncontroller.py
39.7CONTRACT.md 加入可选参数 --ablate <name>。新模块 ablation.py:权威执行之后,在 Analyst 之前,用 --ablate <name> 在目标各视图上再跑一次(seed 0,B 半),比较 digest 和分项,结果写进 mechanism_active(yes / no / unclear)、ablation_json、nodes/<id>/ABLATION.json 和变化量表(context.delta_table,Analyst 读的就是这张表)。程序不支持该参数(退出码非 0、unrecognized arguments)、对照运行失败或被打断,都记 unclear。<name> 的取法:PLAN.ablate → 为标识符时取 mechanism_off_control 本身 → 其中第一个反引号标识符 → mechanism。seed 和 tune 节点不做这项对照。execute.run_program / execute_and_score 增加 extra_args。DRAFT_COVERAGE.json 增加 harness_mechanism_activeablation.py、execute.py、controller.py、context.py、CONTRACT.md
39.8D 模板删除 search: strategy: kind: futs 块(缺省即 FUTS,主线不再 import openevolve_adapter);新建 openevolve_adapter/README.md,一行写明“已停止投入”。compare_abc/、screen_abcd/ 的历史 B/C 配置保留,用于复现(adapter 的测试会引用它们)配置模板、openevolve_adapter/README.md
G45.2新模块 plateau.py:本 run 最近连续 8 个已打分节点都没有刷新前 5(seed-0 分数没超过此前第 5 名的排名分)时判为平台期。此时 draft.p 临时升到 0.5(上限 1 − p_debug − tune.p),draft 优先抽还没有已打分 draft 的族(失败次数少的在前;没有 draft: 块的 T2 取已打分 draft 最少的方向);blocked_parents 只挡 reference_only,capped 的 exploration 种子回到父节点池。有节点刷新前 5 即恢复。状态每次选择时从 archive 重算,不依赖内存,resume 也安全;状态变化时记 plateau 事件,选择理由后面附上 plateauplateau.py、drafts.py、controller.py
stop_reasonstop_manifest.json 和 run_meta.json 增加 stop_reason ∈ {budget, plateau, infra, agent_early_exit, operator}。对应关系:max_nodes 或墙钟到 → budget;无可选父节点且无在跑节点 → agent_early_exit;异常或重启次数用尽 → infra;SIGTERM / SIGINT → operator;launch 或 resume 被拒 → infra。plateau 先保留不用:平台期策略本身不会停止 runcontroller.py、ops.py
追加knowledge_attachments:(接线方式同 scoring_rules):可分别给 researcher / engineer 列文件;省略时 T1 默认给这两个角色附 agent/prompts/dev_events_t1.md,写 null 关闭,T2/T3 默认不附。附件排在 scoring_rules 之后,走现有的存在检查和 prompt_hashes 锁定controller.py

各 D 模板同时加入 engineer_stall、plateau: {enabled: true, ...}、ablation: {enabled: true},并删除 engineer_minutes: 30。代码里这些块默认关闭,没有这些块的配置决策与以前一致。

archive 新增列:same_as_parent、refuted_direction、method_auto、mechanism_active、ablation_json(旧 archive 打开时用 ALTER 补上;只读打开时取默认值)。

测试

新文件 agent/search/tests/test_g39_search_fixes.py,37 个用例。用的都是 fake 行、临时 programs.git 和临时 archive,不起沙箱、服务或 LLM。覆盖:模板、候选身份(代码 / 输出 / 传递 / 晋级 / 终选 / 晋级 sweep)、archive 新列与导入、execute_node 上的 refuted 记录与 ablation(结果在 Analyst 之前写入)、_engineer(无上限、strikes 参数、占位、method_auto、无 run.py、相同代码树 gen_empty)、run_group 真实子进程的停顿计数与活动重置、draft 覆盖与 failed_cap、平台期(streak、p_draft、idea_pick、select_and_create 端到端)、--ablate 名字与判定、stop_reason 与 manifest、knowledge_attachments。另有一个 LoadConfigTest 读取完整模板,只能在 Spark 上跑(VM 上没有 data/external/test,会跳过)。

为配合新语义改了 3 处已有测试(都是让它们符合新语义,没有放宽检查):

  • test_drafts.py::test_round_robin_without_replacement:原来断言“失败的 draft 也占覆盖名额”,现在改成“进行中和已打分的占名额”,并加一条断言:失败的不占;
  • test_execution_contract.py::MethodGate(其他人未提交的文件):harness 现在会预写占位,测试改成由“Engineer”删除或清空 METHOD.md,原意“缺失或为空的 METHOD 不提交”不变;
  • test_harness_teardown.py:_stop_manifest 的替身改为接受 stop_reason 关键字。

VM 上的运行结果(PYTHONPATH=.:downloads/veckit ~/.venvs/vec/bin/python -m unittest ...):

模块结果
test_g39_search_fixes37 OK(LoadConfigTest 跳过)
test_drafts38 OK
test_engineering_limits17 OK
test_execution_contract5 OK
test_select9 OK
test_tune30 OK
test_roles_controller 16 / test_continuation_promotion 16 / test_score_parts 18 / test_objective_ops 20 / test_run_correctness 30 / test_proxy10 18(跳过 1)/ test_x3_guard 24全部 OK

所有改动文件都通过了 py_compile。

遗留

  1. 回放验收没有做(需要 Spark 上的 archive 副本):§1 的验收项还没验证,包括 scr-D 终选前 5 去重后 ≥ 3 个不同程序、B #8/#11 合并、3 个超时 draft 中至少 2 个能打分、覆盖报告里失败的族可以再抽。注意:旧 archive 里 digest 只有视图盲检查尺子(T1 是 X3)的,回放时按输出判同一候选只能看 X3。
  2. --ablate 需要程序配合:现有种子都还没有实现 --ablate,所以 ablation 打开后它们一律记 unclear;任务书里“现有种子加 --ablate”这一项没有做。另外 ablation 每个节点多跑一次全部目标视图,节点执行时间约增加一倍,要在 Spark 上量一下。
  3. 提示词侧(其他 agent 负责):search_spec / researcher_spec / analyst_spec 需要写明 NO_CHANGE: 的写法、METHOD 占位必须改写、--ablate 的实现方式、Analyst 改读 mechanism_active,以及 39.5 的 queries_before_refute。本次只改了程序生成的文本(时限说明、已证否方向列表、变化量表)。
  4. method_auto 的审查时机:节点结束时如果在晋级前 k 名,会当场审查。如果它是后来因排名变化才进入前 k 名,晋级会一直被挡住,直到终选时审查(不会误晋级,但可能少晋级一次)。
  5. stop_reason 的 plateau 暂不产生:G45 如果加入“平台期停止”规则,再接到 stop_kind。agent 模式(T3,agent/harness.py)没有 stop_manifest,所以 agent_early_exit 目前只用在搜索 run 上(“没有可选父节点”)。
  6. 文档 10 的 §4.6(Engineer 30 min)、§4.7(tune 0.25)、§4.3(无进展访问)还没有同步,按约束本次没有改 notes/architecture。
  7. 平台期判断用的是“此前节点当前的排名分”(晋级后是 3 seed 均值),不是当时的快照,属于近似。