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

总览 · ← 返回运行 20261003-004922-search-t2-embryo-interp-g24

节点 n10 在终选来历上

mix 基座上实现 T2EI-01 按型组成线性插值:目标比例 p_T=(1−t)p_A+t·p_B 分配型配额,型内两阶段按 t·adj 分配(提交 adj=0,共享型细胞全取早期),去掉父节点的 τ 相似度偏置;表达与坐标不修改。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-004922-search-t2-embryo-interp-g24
父节点n8
子节点n12
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 60.29(-0.1) · proxy 60.29(-0.1) · 3 次复测均分 60.34
审查未审查
用时?从运行开始到结束(或到现在)的挂钟时间。19 分
程序版本819069b545d21a5b9ce2603d58843e66ccae25df (programs.git)

方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。

来自 programs.git 819069b545:solution/METHOD.md

mix 基座上实现 T2EI-01 按型组成线性插值:目标比例 p_T=(1−t)p_A+t·p_B 分配型配额,型内两阶段按 t·adj 分配(提交 adj=0,共享型细胞全取早期),去掉父节点的 τ 相似度偏置;表达与坐标不修改。

方法

基座 = 父节点 2/8(seed mix):括号 E6.75+E8.0 → E7.25(t=0.4),procrustes3d 对齐, scale_damp=0.5,log 线性 RMS,n=5000(manifest min/max 内)。

PLAN 机制(family T2EI-01,组成插值,实现完整):替换 mix_indices——

  1. 按两阶段型比例线性插值得目标组成 p_T=(1−t)·p_A[T]+t·p_B[T](单阶段型自然退化为 (1−t)p_A 或 t·p_B);
  2. 总配额 n 按 p_T 最大余数法分配 c_T,超出可用数时封顶并把余额重分给有余量的型;
  3. 型内两阶段分配 n_B,T=round(c_T·t·ADJ)(单阶段型全取该阶段,不足从另一阶段补);
  4. 型内均匀无放回抽样;坐标与表达取被抽细胞自身值。

τ 偏置已按 PLAN 删除(无偏路径)。常数 COMPOS_ADJ=0.0(环境变量 VEC_COMPOS_ADJ 仅本地测试);VEC_COMPOS_INTERP=0 走关闭对照。

单阶段退路:目标无括号时 = seed(最后观测阶段分层抽样),未改动。

机制生效证据(proxy, seed 0)

  • 实际型组成 vs 目标 p_T 的 Pearson = 0.99999(>0.99 达标)。
  • vs 父节点 8(frac=0.5 统一抽取):后期(B)细胞 1000→1049(adj=0);其中共享型 B 细胞 519→86,B-only 15 型 481→963(恢复完整插值丰度,如 Forebrain 344→…按 c_T 配额), A-only 7 型 1139→854(回到插值丰度)。不同型的 delta 方向不同(非全局重加权)。
  • 四组分随 ADJ(A 半,见下表):shape_scale 随 adj 单调升(66.7→77.3),cell_state 单调降(50.4→33.0),expression_change/local_spatial 在 adj≤0.2 时优于父。

机制关闭对照(mechanism_off_control)

VEC_COMPOS_INTERP=0(统一 frac=0.5、τ=0)输出与父节点 8 以 VEC_BIAS_TAU=0 VEC_T_DRAW_FRAC=0.5 运行逐位相同(X、coords、genes 全等已验证); 该对照 A 半 59.88 {cs 52.56, ec 60.17, ls 58.27, ss 68.53}(父节点 8 已测)。 机制开启(提交配置 adj=0)A 半 59.40:未达 PLAN 预期(ss 未回升至 71+, 反而 −1.8;cs −2.2)。如实报告:组成插值在本代理上没有净胜父节点,差距在噪声(~2 分)内。

查分记录(A 半,proxy,seed 0,共 4/20 次)

配置boardcell_stateexpr_changelocal_spatialshape_scale
父 8 对照 τ=0,frac0.559.8852.5660.1758.2768.53
compos adj=1.055.6332.9560.7951.5077.28
compos adj=0.557.7242.2659.8457.5471.25
compos adj=0.259.1948.0261.4659.4767.81
compos adj=0.0(提交)59.4050.3661.1959.3366.72

关键发现(供后续节点):① PLAN 假设"按型组成插值回升 shape_scale"被证伪——ss 由共享型 的 B 细胞量驱动(adj 单调),全局组成换成插值丰度反而略降 ss;② cell_state 主要由 总 B 细胞量与 A-only 过采样驱动,父节点 frac=0.5 的近统一抽取已接近 cs/ss 权衡前沿; ③ 组成插值稳定带来 ec(+1.0~1.4) 与 ls(+1.1~1.2),但 cs 损失更大。

验证过 / 没验证

  • 验证:关闭对照逐位等于父 8 对照;seed 0 重跑逐位确定;adj=0 输出与查分文件逐位一致; n=5000、X 有限、vec-check ok;运行 ~2s。
  • 没验证:B 半分;adj∈(0,0.2) 细扫(前沿单调,预期不超父);组成阻尼 d(t_comp=t·d) 与型内 split 解耦的第二自由度(时间不足未实现);真实括号(t=1/3、共有型 11)上 adj=0 使共享型几乎全取 E7.25 之前的早期细胞,方向与代理一致但未直接检验。
  • 生物学知识来源:无外部先验,仅用视图内数据(型计数、时间差)现场计算。
  • 视图无关:不读 board/mode/路径/绝对时间;t、括号、n 均由 manifest 现场算出; adj 为常数。

调研员的计划

名称按型组成线性插值替代统一frac抽样,修复shape_scale同时保持cell_state
动机父节点8(60.43)中cell_state 53.16最弱,但shape_scale从父2的74.43降至68.99(−5.44),原因是t_draw_frac=0.5统一削减后期细胞,丢失了后期阶段的空间覆盖。ANALYSIS建议2/3均指向解耦或按型组成插值。节点5(60.63)与节点8差距0.2在噪声内,说明frac=0.5的cell_state增益已饱和,下一步收益在恢复shape_scale。节点3/4(型内表达插值)gen_failed、节点7(1-NN位移)退化为常数位移、节点6(伪时间ramp)净负——这些方向不再重复。本方案实现T2EI-01的组成插值核心(尚未被任何节点实现过),放弃已证无效的τ偏置。
做法基座=父节点8的run.py,删除τ偏置(设τ=0,走无偏路径)。核心改动在mix_indices替换函数内:
1. 读入stage_a、stage_b的labels,计算每型在两阶段的比例 p_A[T]=n_A,T/N_A, p_B[T]=n_B,T/N_B。
2. 目标比例 p_T=(1−t)·p_A[T]+t·p_B[T](仅存在于至少一个阶段的型;两阶段都有的型正常插值,单阶段型按其在的那个阶段的比例乘(1−t)或t)。
3. 总配额 n=5000(与父相同),按 p_T 分配 c_T=round(n·p_T/Σp),余数按最大余数法补齐(复用现有_alloc逻辑)。
4. 型T内从A、B两阶段的分配:n_B,T=round(c_T·t),n_A,T=c_T−n_B,T;若某阶段该型细胞不足则从另一阶段补足。
5. 型内均匀抽样(无τ偏置),用现有_weighted_stratified但logw全零即退化为均匀。
6. 坐标与表达均取被抽细胞自身的值,不做额外修改。scale_damp=0.5、procrustes3d不变。

关键参数:无新超参(t由manifest算出,n=5000不变)。如需微调可试n_B,T=round(c_T·t·adj),adj∈{0.8,1.0,1.2},但首轮用adj=1.0。

单阶段退路:目标无括号时与父相同(最后观测阶段分层抽样)。

vec-score筛选:先跑adj=1.0(1次),对比四组分与父节点8(59.63 A半);若shape_scale回升≥2且cell_state不降≥1,再试adj=0.8/1.2(最多再2次)。总查分≤5次。
风险1) 按型插值后总后期细胞数可能与frac=0.5时不同(可能更多),cell_state可能回落——Engineer应在第一次查分后对比cell_state,若降>2分则提高adj或回退。2) 某些型在一阶段极少(<5个),配额分配可能产生0或过抽样——需clip到[0, stage_count]。3) 型标签在两阶段不完全一致(新型出现/旧型消失),单阶段型的处理需明确。4) 30分钟时限紧——代码改动集中在biased_mix函数内约30行,不需要新依赖;先在小数据上验证型配额正确性再全量跑。

代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。

对比:父节点版本 e3fd3c0ce1。改动的文件:solution/METHOD.md +42 −43、solution/run.py +116 −78

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 0724725..ff2eb07 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,61 +1,60 @@-mix 基座上实现 T2EI-01 型内跨阶段相似度加权抽样(τ=0.2 保持打开);对照显示该机制在本榜中性偏负,主要增益来自组合 node 5 已验证的 t_draw=0.5·t 后抽减半。+mix 基座上实现 T2EI-01 按型组成线性插值:目标比例 p_T=(1−t)p_A+t·p_B 分配型配额,型内两阶段按 t·adj 分配(提交 adj=0,共享型细胞全取早期),去掉父节点的 τ 相似度偏置;表达与坐标不修改。  ## 方法 -基座 = 父节点 2(seed mix):括号 E6.75+E8.0 → E7.25(t=0.4),procrustes3d 对齐,-scale_damp=0.5,log 线性 RMS,按型分层抽 n=5000。+基座 = 父节点 2/8(seed mix):括号 E6.75+E8.0 → E7.25(t=0.4),procrustes3d 对齐,+scale_damp=0.5,log 线性 RMS,n=5000(manifest min/max 内)。 -**PLAN 机制(family T2EI-01,实现完整)**:分层抽样中,型 T 内每个细胞的抽样权重-w_i = exp(cos(x_i, μ_{T,other}) / τ),μ 为另一阶段该型的均值表达(`type_means`),-按权重无放回抽取(`rng.choice(..., p=w)`);另一阶段没有该型时权重均匀。型配额分配-逐行复刻 `transport.stratified_choice`,只改型内选择。不修改任何表达值或坐标——-改变的是哪些细胞进入输出。常数 `BIAS_TAU=0.2`(环境变量 `VEC_BIAS_TAU` 仅本地测试用)。+**PLAN 机制(family T2EI-01,组成插值,实现完整)**:替换 `mix_indices`——+1. 按两阶段型比例线性插值得目标组成 p_T=(1−t)·p_A[T]+t·p_B[T](单阶段型自然退化为+   (1−t)p_A 或 t·p_B);+2. 总配额 n 按 p_T 最大余数法分配 c_T,超出可用数时封顶并把余额重分给有余量的型;+3. 型内两阶段分配 n_B,T=round(c_T·t·ADJ)(单阶段型全取该阶段,不足从另一阶段补);+4. 型内均匀无放回抽样;坐标与表达取被抽细胞自身值。+τ 偏置已按 PLAN 删除(无偏路径)。常数 `COMPOS_ADJ=0.0`(环境变量 `VEC_COMPOS_ADJ`+仅本地测试);`VEC_COMPOS_INTERP=0` 走关闭对照。 -**组合部件**:`T_DRAW_FRAC=0.5`,即 t_draw = 0.5·t = 0.2,后期阶段抽 1000/5000 而非-2000/5000(node 5 已验证的组成修复,非本 PLAN 机制)。+**单阶段退路**:目标无括号时 = seed(最后观测阶段分层抽样),未改动。 -**单阶段退路**:目标无括号时退化为最后观测阶段分层抽样(与 seed 相同,无偏置)。+## 机制生效证据(proxy, seed 0) -## 机制生效证据(τ=0.2, t_draw_frac=0.5, proxy)--- 被抽细胞的跨阶段余弦 vs 全体:A 侧 0.4337 vs 0.4188,B 侧 0.5220 vs 0.5128-  (右移,偏置确实选中了更接近另一阶段的细胞;τ=0.05 时右移更大:0.4667/0.5439)。-- 四组分随 τ(frac=1,A 半):τ=0(父) cell_state 37.49 → τ=0.2: 35.91 → τ=0.05: 33.39;-  τ=−0.05: 39.43、τ=−0.2: 37.08。正偏置单调伤 cell_state。-- frac=0.5 时:τ=0(对照) 59.88 {cs 52.56, ec 60.17, ls 58.27, ss 68.53};-  τ=0.2 59.63 {cs 51.65, ec 60.04, ls 58.24, ss 68.59};τ=−0.05 58.35。-  **机制净效应 ≈ −0.25(噪声内),未达 PLAN 预期的 cell_state +2**。+- 实际型组成 vs 目标 p_T 的 Pearson = 0.99999(>0.99 达标)。+- vs 父节点 8(frac=0.5 统一抽取):后期(B)细胞 1000→1049(adj=0);其中共享型 B 细胞+  519→86,B-only 15 型 481→963(恢复完整插值丰度,如 Forebrain 344→…按 c_T 配额),+  A-only 7 型 1139→854(回到插值丰度)。不同型的 delta 方向不同(非全局重加权)。+- 四组分随 ADJ(A 半,见下表):shape_scale 随 adj 单调升(66.7→77.3),cell_state+  单调降(50.4→33.0),expression_change/local_spatial 在 adj≤0.2 时优于父。  ## 机制关闭对照(mechanism_off_control) -τ=0(等价权重全相等)且 frac=1 时走原库 `interpolate`,输出与父节点 2 **逐位相同**-(已验证 X、coords、genes 全等)。τ=0 且 frac=0.5 的对照分 59.88 vs 机制开 59.63:-按 PLAN 风险条款 1(cell_state 差 <1 分即放弃),该机制应判无效;提交按"机制保持-打开"惯例取 τ=0.2(差值在噪声内),但如实说明:**本节点分数增益主要来自 t_draw_frac-组成部件,不是 T2EI-01 偏置机制**。不冒充。+`VEC_COMPOS_INTERP=0`(统一 frac=0.5、τ=0)输出与父节点 8 以+`VEC_BIAS_TAU=0 VEC_T_DRAW_FRAC=0.5` 运行**逐位相同**(X、coords、genes 全等已验证);+该对照 A 半 59.88 {cs 52.56, ec 60.17, ls 58.27, ss 68.53}(父节点 8 已测)。+机制开启(提交配置 adj=0)A 半 59.40:**未达 PLAN 预期**(ss 未回升至 71+,+反而 −1.8;cs −2.2)。如实报告:组成插值在本代理上没有净胜父节点,差距在噪声(~2 分)内。 -## 查分记录(A 半,proxy,seed 0)+## 查分记录(A 半,proxy,seed 0,共 4/20 次)  | 配置 | board | cell_state | expr_change | local_spatial | shape_scale | |---|---:|---:|---:|---:|---:|-| 父节点 2 | 57.23 | 37.49 | 59.72 | 57.27 | 74.43 |-| τ=0.05 | 54.57 | 33.39 | 60.78 | 50.59 | 73.50 |-| τ=0.2 | 56.43 | 35.91 | 60.92 | 53.34 | 75.53 |-| τ=−0.05 | 57.80 | 39.43 | 59.80 | 56.72 | 75.27 |-| τ=−0.2 | 57.24 | 37.08 | 60.57 | 55.46 | 75.86 |-| τ=−0.05, frac0.5 | 58.35 | 51.68 | 58.40 | 54.21 | 69.11 |-| τ=0, frac0.5(对照) | 59.88 | 52.56 | 60.17 | 58.27 | 68.53 |-| **τ=0.2, frac0.5(提交)** | **59.63** | 51.65 | 60.04 | 58.24 | 68.59 |+| 父 8 对照 τ=0,frac0.5 | 59.88 | 52.56 | 60.17 | 58.27 | 68.53 |+| compos adj=1.0 | 55.63 | 32.95 | 60.79 | 51.50 | 77.28 |+| compos adj=0.5 | 57.72 | 42.26 | 59.84 | 57.54 | 71.25 |+| compos adj=0.2 | 59.19 | 48.02 | 61.46 | 59.47 | 67.81 |+| **compos adj=0.0(提交)** | **59.40** | 50.36 | 61.19 | 59.33 | 66.72 | -用了 7/20 次查分。+关键发现(供后续节点):① PLAN 假设"按型组成插值回升 shape_scale"被证伪——ss 由共享型+的 B 细胞量驱动(adj 单调),全局组成换成插值丰度反而略降 ss;② cell_state 主要由+总 B 细胞量与 A-only 过采样驱动,父节点 frac=0.5 的近统一抽取已接近 cs/ss 权衡前沿;+③ 组成插值稳定带来 ec(+1.0~1.4) 与 ls(+1.1~1.2),但 cs 损失更大。  ## 验证过 / 没验证 -- 验证:off 对照逐位等于父节点;seed 0 重跑逐位确定;seed 0/1 输出过 `vec-check`;-  提交文件与查分 59.63 的配置逐位相同;运行 ~2s、内存远低于限额。-- 没验证:B 半分与多种子均值(无权限);τ 的 Pearson/欧氏距离备选(正余弦方向均-  已显示机制无效,换度量预期同样无效,未耗查分额度);frac 的 finer 扫描(0.45/0.55)。-- 生物学知识来源:无外部生物学先验,仅用视图内数据(型均值、余弦相似度)现场计算。-- 视图无关:不读 board/mode/路径/绝对时间;τ、frac 为常数;t 与括号由 manifest 时间差-  现场算出。风险:frac=0.5 使真实括号(t=1/3)的后期抽取从 ~1667 降到 ~833,代理上-  该方向已验证(node 5 与本节点),但真实目标 E7.25 的细胞状态无法直接检验。+- 验证:关闭对照逐位等于父 8 对照;seed 0 重跑逐位确定;adj=0 输出与查分文件逐位一致;+  n=5000、X 有限、vec-check ok;运行 ~2s。+- 没验证:B 半分;adj∈(0,0.2) 细扫(前沿单调,预期不超父);组成阻尼 d(t_comp=t·d)+  与型内 split 解耦的第二自由度(时间不足未实现);真实括号(t=1/3、共有型 11)上+  adj=0 使共享型几乎全取 E7.25 之前的早期细胞,方向与代理一致但未直接检验。+- 生物学知识来源:无外部先验,仅用视图内数据(型计数、时间差)现场计算。+- 视图无关:不读 board/mode/路径/绝对时间;t、括号、n 均由 manifest 现场算出;+  adj 为常数。diff --git a/solution/run.py b/solution/run.pyindex ca6559a..3f037a7 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,20 +1,28 @@ #!/usr/bin/env python3-"""mix (T2 interpolation) + type-internal cross-stage similarity-biased draws.+"""mix (T2 interpolation) + per-type compositional interpolation (T2EI-01).  Base pipeline is the seed ``mix`` (parent node 2): bracket the target with the nearest inputs, align frames (procrustes3d), rescale both clouds to-exp(log r_a + SCALE_DAMP·t·Δlog r), draw cells stratified by type —-round(t·n) from the later stage, the rest from the earlier one.--Mechanism (T2EI-01): inside each cell type's stratified draw, replace the-uniform choice with a weighted choice where cell i of stage S with type T gets-log-weight cos(x_i, mu_{T,other}) / BIAS_TAU, mu being the other stage's-type-mean expression. Types absent from the other stage keep uniform weights.-Expression values and coordinates are never modified — only *which* cells are-drawn changes.--Mechanism-off control: BIAS_TAU <= 0 routes to the untouched library-``interpolate``, producing output bit-identical to the parent seed.+exp(log r_a + SCALE_DAMP*t*dlog r), draw n cells stratified by type.++Mechanism (family T2EI-01, compositional interpolation): instead of drawing a+uniform fraction t from the later stage with each stage's own type profile,+build the target type composition p_T = (1-t)*p_A[T] + t*p_B[T], allocate the+output quota per type (largest remainder), then split each type's quota between+stages as n_B,T = round(c_T * t * ADJ) (all from the stage that has the type+when the other lacks it; deficits are filled from the other stage). Within a+type, cells are drawn uniformly without replacement. The tau similarity bias+of parent node 8 is removed (tau = 0 path). Expression values and coordinates+are never modified — only *which* cells are drawn changes.++ADJ controls how many of a shared type's cells come from the later stage:+ADJ=1 reproduces (in expectation) the plain mix stage totals with the exact+interpolated per-type composition; ADJ<1 keeps shared types "younger" while+late-only types still get their full interpolated abundance.++Mechanism-off control: VEC_COMPOS_INTERP=0 routes to parent node 8's uniform+stratified draw with T_DRAW_FRAC=0.5 and tau=0 (bit-identical to parent 8 run+with VEC_BIAS_TAU=0 VEC_T_DRAW_FRAC=0.5).  Single-stage fallback (target not bracketed): unchanged from the seed. """@@ -31,35 +39,88 @@ import numpy as np import src.task2_spatial.methods as methods_mod from src.task2_spatial.methods import interpolate from src.task2_spatial.sample import take-from src.task2_spatial.shift import type_means-from src.task2_spatial.transport import as_dense from src.task2_spatial.view_io import board_params, interp_bracket, load_manifest, panel_genes, read_stage, write_t2  PARAMS = {"align": "procrustes3d", "scale_damp": 0.5}-BIAS_TAU = 0.2-T_DRAW_FRAC = 0.5  # draw fraction of later-stage cells: t_draw = T_DRAW_FRAC * t---def _log_weights(stage, means_other: dict[str, np.ndarray], tau: float) -> np.ndarray:-    labels = np.asarray(stage.labels).astype(str)-    Xd = as_dense(stage.X).astype(np.float64)-    norms = np.linalg.norm(Xd, axis=1)-    logw = np.zeros(len(labels), dtype=np.float64)-    for lab, mu in means_other.items():-        idx = np.flatnonzero(labels == lab)-        if idx.size == 0:-            continue-        mu = mu.astype(np.float64)-        nmu = float(np.linalg.norm(mu))-        if nmu < 1e-12:+COMPOS_INTERP = True+COMPOS_ADJ = 0.0  # later-stage share of a shared type's quota: t * COMPOS_ADJ+T_DRAW_FRAC = 0.5  # only used by the mechanism-off control path+++def _compos_mix(labels_a, labels_b, tt: float, n: int, rng: np.random.Generator, adj: float, diag: dict | None = None):+    la = np.asarray(labels_a).astype(str)+    lb = np.asarray(labels_b).astype(str)+    na_tot, nb_tot = len(la), len(lb)+    n = int(min(max(int(n), 1), na_tot + nb_tot))+    ta_u, ca_u = np.unique(la, return_counts=True)+    tb_u, cb_u = np.unique(lb, return_counts=True)+    ma = {str(k): int(v) for k, v in zip(ta_u, ca_u)}+    mb = {str(k): int(v) for k, v in zip(tb_u, cb_u)}+    types = sorted(set(ma) | set(mb))+    tt = float(tt)+    p = np.array(+        [(1.0 - tt) * (ma.get(T, 0) / max(na_tot, 1)) + tt * (mb.get(T, 0) / max(nb_tot, 1)) for T in types],+        dtype=np.float64,+    )+    s = float(p.sum())+    if s <= 0.0:+        p = np.ones(len(types), dtype=np.float64)+        s = float(len(types))+    raw = p / s * n+    alloc = np.floor(raw).astype(int)+    rem = int(n - alloc.sum())+    order = np.argsort(-(raw - alloc), kind="stable")+    for i in range(rem):+        alloc[order[i % len(order)]] += 1+    avail = np.array([ma.get(T, 0) + mb.get(T, 0) for T in types], dtype=int)+    excess = int(np.maximum(alloc - avail, 0).sum())+    alloc = np.minimum(alloc, avail)+    while excess > 0:+        head = avail - alloc+        cand = np.flatnonzero(head > 0)+        if cand.size == 0:+            break+        cand = cand[np.argsort(-head[cand], kind="stable")]+        add = int(min(excess, len(cand)))+        for j in range(add):+            alloc[cand[j]] += 1+        excess -= add+    ia_parts, ib_parts = [], []+    for T, cT in zip(types, alloc):+        cT = int(cT)+        if cT <= 0:             continue-        s = (Xd[idx] @ mu) / np.maximum(norms[idx] * nmu, 1e-12)-        logw[idx] = s / tau-    return logw---def _weighted_stratified(labels, n: int, rng: np.random.Generator, logw: np.ndarray) -> np.ndarray:-    """Same type allocation as transport.stratified_choice, weighted within type."""+        aa, ab = ma.get(T, 0), mb.get(T, 0)+        if ab == 0:+            nbT = 0+        elif aa == 0:+            nbT = cT+        else:+            nbT = int(np.clip(int(round(cT * tt * adj)), 0, cT))+        nbT = min(nbT, ab)+        naT = min(cT - nbT, aa)+        nbT = min(cT - naT, ab)+        if naT > 0:+            ia_parts.append(rng.choice(np.flatnonzero(la == T), naT, replace=False))+        if nbT > 0:+            ib_parts.append(rng.choice(np.flatnonzero(lb == T), nbT, replace=False))+    ia = np.concatenate(ia_parts) if ia_parts else np.array([], dtype=int)+    ib = np.concatenate(ib_parts) if ib_parts else np.array([], dtype=int)+    if diag is not None:+        achieved = alloc / max(int(alloc.sum()), 1)+        target = p / s+        diag["pearson_compos"] = float(np.corrcoef(achieved, target)[0, 1]) if len(types) > 1 else 1.0+        diag["n_shared_types"] = int(sum(1 for T in types if T in ma and T in mb))+        diag["n_b_only_types"] = int(sum(1 for T in types if T not in ma))+        diag["n_a_only_types"] = int(sum(1 for T in types if T not in mb))+        bmass_bonly = float(sum(alloc[i] for i, T in enumerate(types) if T not in ma))+        diag["b_mass_bonly"] = bmass_bonly+        diag["b_mass_shared"] = float(len(ib)) - bmass_bonly+    return ia, ib+++def _weighted_stratified(labels, n: int, rng: np.random.Generator) -> np.ndarray:+    """Same uniform type allocation as transport.stratified_choice (off-control)."""     labels = np.asarray(labels).astype(str)     n = int(min(max(n, 1), len(labels)))     if n >= len(labels):@@ -86,13 +147,7 @@ def _weighted_stratified(labels, n: int, rng: np.random.Generator, logw: np.ndar         if k <= 0:             continue         idx = np.flatnonzero(labels == lab)-        lw = logw[idx]-        if float(lw.max() - lw.min()) < 1e-12:-            picks.append(rng.choice(idx, int(k), replace=False))-        else:-            w = np.exp(lw - lw.max())-            w /= w.sum()-            picks.append(rng.choice(idx, int(k), replace=False, p=w))+        picks.append(rng.choice(idx, int(k), replace=False))     return np.concatenate(picks)  @@ -103,7 +158,8 @@ def main() -> None:     parser.add_argument("--seed", type=int, default=0)     args = parser.parse_args() -    tau = float(os.environ.get("VEC_BIAS_TAU", BIAS_TAU))+    compos = os.environ.get("VEC_COMPOS_INTERP", "1" if COMPOS_INTERP else "0") not in ("0", "", "false")+    adj = float(os.environ.get("VEC_COMPOS_ADJ", COMPOS_ADJ))     t_draw_frac = float(os.environ.get("VEC_T_DRAW_FRAC", T_DRAW_FRAC))      manifest = load_manifest(args.data)@@ -119,46 +175,28 @@ def main() -> None:     stage_b = read_stage(args.data, b, genes)     params = board_params(manifest, "mix", PARAMS, args.seed) -    diag: dict = {"bias_tau": tau, "t_draw_frac": t_draw_frac}-    if tau != 0 or t_draw_frac != 1.0:-        if tau != 0:-            means_a = type_means(stage_a.X, stage_a.labels)-            means_b = type_means(stage_b.X, stage_b.labels)-            logw_a = _log_weights(stage_a, means_b, tau)-            logw_b = _log_weights(stage_b, means_a, tau)-        else:-            logw_a = np.zeros(stage_a.n)-            logw_b = np.zeros(stage_b.n)+    diag: dict = {"compos_interp": bool(compos), "adj": adj, "t_draw_frac": t_draw_frac}+    orig_mix = methods_mod.mix_indices+    if compos: -        orig_mix = methods_mod.mix_indices+        def patched(labels_a, labels_b, tt, n, rng):+            ia, ib = _compos_mix(labels_a, labels_b, tt, n, rng, adj, diag)+            return ia, ib -        drawn: dict = {}+    else: -        def biased_mix(labels_a, labels_b, tt, n, rng):+        def patched(labels_a, labels_b, tt, n, rng):             n_b = int(np.clip(int(round(float(tt) * t_draw_frac * n)), 0, n))             n_a = int(n) - n_b-            ia = _weighted_stratified(labels_a, n_a, rng, logw_a) if n_a > 0 else np.array([], dtype=int)-            ib = _weighted_stratified(labels_b, n_b, rng, logw_b) if n_b > 0 else np.array([], dtype=int)-            drawn["ia"], drawn["ib"] = ia, ib+            ia = _weighted_stratified(labels_a, n_a, rng) if n_a > 0 else np.array([], dtype=int)+            ib = _weighted_stratified(labels_b, n_b, rng) if n_b > 0 else np.array([], dtype=int)             return ia, ib -        methods_mod.mix_indices = biased_mix-        try:-            expr, coords, info = interpolate(stage_a, stage_b, t, params)-        finally:-            methods_mod.mix_indices = orig_mix-        # Evidence: mean cross-stage cosine of drawn vs all cells per stage.-        sa = logw_a * tau-        sb = logw_b * tau-        ia, ib = drawn.get("ia", np.array([], int)), drawn.get("ib", np.array([], int))-        for tag, s, idx in (("a", sa, ia), ("b", sb, ib)):-            nz = s[s != 0]-            nzd = s[idx][s[idx] != 0] if idx.size else np.array([])-            diag[f"cos_{tag}_all"] = float(nz.mean()) if nz.size else None-            diag[f"cos_{tag}_drawn"] = float(nzd.mean()) if nzd.size else None-            diag[f"n_from_{tag}"] = int(idx.size)-    else:+    methods_mod.mix_indices = patched+    try:         expr, coords, info = interpolate(stage_a, stage_b, t, params)+    finally:+        methods_mod.mix_indices = orig_mix      keep = {k: info.get(k) for k in ("t", "n", "rms_a", "rms_b", "out_rms", "n_shared_types", "z_dot", "z_flipped", "align")}     print(json.dumps({"bracket": [a["stage"], b["stage"]], **keep, **diag}, default=float), file=sys.stderr)

调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k024World-model evaluation dimensions for state-transition predictorsnotes/competition/07_biomedical_world_models.md
k026Canonicalise predicted 3D coordinates before submissionnotes/pitfalls/04_scorer_invariance.md

分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。

改了什么在父8基座上删除τ相似度偏置,将mix_indices替换为按型组成线性插值:目标比例p_T=(1−t)p_A+t·p_B分配型配额(最大余数+封顶重分),型内两阶段按n_B,T=round(c_T·t·ADJ)分配;PLAN首试ADJ=1.0,扫描后实际提交ADJ=0.0(共享型全取早期细胞),仅改抽样组成,不改表达与坐标。
各组分数的变化cell_state:变坏:51.65 vs 53.16,−1.51(超噪声,ADJ=0使共享型后期细胞519→86所致)
expression_change:变好:62.09 vs 60.05,+2.04(超出T2约1分噪声,与代理上ec+1.0~1.4方向一致)
local_spatial:噪声内偏正:60.27 vs 59.53,+0.74(接近1分噪声)
shape_scale:变坏:67.14 vs 68.99,−1.85(超噪声,PLAN预期的'回升≥2'被证伪)
榜分:噪声内:60.29 vs 60.43,−0.14
family_idT2EI-01
假设是否成立否
经验
  1. 在T2 mix基座上,shape_scale主要由共享型中后期(B)阶段细胞的绝对数量驱动(代理上随ADJ单调66.7→77.3),而非由逐型组成是否等于插值丰度p_T驱动;把组成换成插值丰度(ADJ=1.0)反而使ss降到代理55.63/榜上方向一致,PLAN的'组成插值修复shape_scale'假设被证伪。
  2. 按型组成插值(ADJ≤0.2)稳定带来expression_change +1.0~2.0与local_spatial +0.7~1.2,但代价是cell_state下降(B细胞主要来自B-only型、共享型几乎全取早期);ec增益不足以抵消cs/ss损失,净榜分在噪声内。
  3. 父8的统一frac=0.5抽取已接近cs/ss权衡前沿:单一组成维度的改动(本节点及节点5)都无法同时改善两组,改进需要引入第二自由度(如组成目标阻尼与型内split解耦)。
  4. Engineer做法可取:ADJ扫描(1.0/0.5/0.2/0.0共4次查分)后提交最佳值而非PLAN原定值,且关闭对照逐位等于父8、如实报告未达预期,未夸大机制效果。
mechanism_active是
下一步建议
  1. 针对expression_change+cell_state:解耦表达与坐标的来源——表达矩阵走组成插值(ADJ=0,捕获已验证的ec+2),坐标仍走父8的frac=0.5抽取,检验ec增益能否在cs不受损时转化为净榜分(Engineer建议②,即前ANALYSIS建议2)。
  2. 针对cell_state/shape_scale前沿:引入组成目标阻尼d,令t_comp=t·d只改逐型目标组成的插值强度、型内阶段split保持父8的frac=0.5,扫d∈{0.3,0.6}看能否在cs不降的前提下微调组成。
  3. 不要再扫ADJ∈(0.2,1.0):代理上cs/ss随ADJ单调且方向相反,前沿内部无更优点;也不要回到τ偏置(节点8已证中性偏负)、型内表达插值(节点3/4失败)、伪时间ramp(节点6净负)。

对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。

只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。

分析员

角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。分析员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数?大模型一共回复了几轮(每轮可以调用多个工具)。4
工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。共 3 次:bash 2、write 1
用时不到 1 分
token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。输入 14,184 · 输出 1,081 · 思考 1,027
任务(第一行)分析节点 n10 的打分结果,写 ANALYSIS.json
最后的回答(摘录)
ANALYSIS.json written
原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/analyst.jsonl 9 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/analyst.stderr

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数21
工具调用共 24 次:bash 18、write 3、edit 2、read 1
用时16 分
token 数输入 62,381 · 输出 10,598 · 思考 20,198
任务(第一行)按计划修改程序:按型组成线性插值替代统一frac抽样,修复shape_scale同时保持cell_state
最后的回答(摘录)
**节点 10 完成**(improve,父 8 = 60.43)。

**做了什么**:按 PLAN 实现 T2EI-01 按型组成线性插值(p_T=(1−t)p_A+t·p_B 配额 + 型内 t·ADJ 两阶段分配,删 τ 偏置),关闭对照逐位等于父 8 对照(已验证)。扫描 ADJ∈{1.0, 0.5, 0.2, 0.0},提交最佳 ADJ=0.0。

**查分**(A 半,4/20 次):adj=1.0→55.63、0.5→57.72、0.2→59.19、**0.0→59.40** {cs 50.4, ec 61.2, ls 59.3, ss 66.7};父对照 59.88。PLAN 的"组成插值回升 shape_scale"假设被证伪:ss 由共享型 B 细胞量单调驱动,组成插值稳定带来 ec/ls +1 但 cs 损失更大,未超父(差距在噪声内),已如实写入 METHOD.md。

**下一步最值得试**:① cs/ss 前沿上父的 frac=0.5 近最优,改进需第二自由度——组成目标阻尼 d(t_comp=t·d)与型内 split 解耦,保持父的全局组成、只改共享型的型内阶段配比;② ec 对组成插值敏感(+1.4),可试仅对表达走组成插值、坐标走 frac=0.5 抽取的解耦方案(ANALYSIS 建议 2)。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/engineer.jsonl 119 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时2 分
token 数输入 10,733 · 输出 1,428 · 思考 3,867
任务(第一行)为节点 n10(改进,父节点 n8)写改进计划 PLAN.json
最后的回答(摘录)
至68.99(−5.44),原因是t_draw_frac=0.5统一削减后期细胞,丢失了后期阶段的空间覆盖。ANALYSIS建议2/3均指向解耦或按型组成插值。节点5(60.63)与节点8差距0.2在噪声内,说明frac=0.5的cell_state增益已饱和,下一步收益在恢复shape_scale。节点3/4(型内表达插值)gen_failed、节点7(1-NN位移)退化为常数位移、节点6(伪时间ramp)净负——这些方向不再重复。本方案实现T2EI-01的组成插值核心(尚未被任何节点实现过),放弃已证无效的τ偏置。",
  "approach": "基座=父节点8的run.py,删除τ偏置(设τ=0,走无偏路径)。核心改动在mix_indices替换函数内:\n1. 读入stage_a、stage_b的labels,计算每型在两阶段的比例 p_A[T]=n_A,T/N_A, p_B[T]=n_B,T/N_B。\n2. 目标比例 p_T=(1−t)·p_A[T]+t·p_B[T](仅存在于至少一个阶段的型;两阶段都有的型正常插值,单阶段型按其在的那个阶段的比例乘(1−t)或t)。\n3. 总配额 n=5000(与父相同),按 p_T 分配 c_T=round(n·p_T/Σp),余数按最大余数法补齐(复用现有_alloc逻辑)。\n4. 型T内从A、B两阶段的分配:n_B,T=round(c_T·t),n_A,T=c_T−n_B,T;若某阶段该型细胞不足则从另一阶段补足。\n5. 型内均匀抽样(无τ偏置),用现有_weighted_stratified但logw全零即退化为均匀。\n6. 坐标与表达均取被抽细胞自身的值,不做额外修改。scale_damp=0.5、procrustes3d不变。\n\n关键参数:无新超参(t由manifest算出,n=5000不变)。如需微调可试n_B,T=round(c_T·t·adj),adj∈{0.8,1.0,1.2},但首轮用adj=1.0。\n\n单阶段退路:目标无括号时与父相同(最后观测阶段分层抽样)。\n\nvec-score筛选:先跑adj=1.0(1次),对比四组分与父节点8(59.63 A半);若shape_scale回升≥2且cell_state不降≥1,再试adj=0.8/1.2(最多再2次)。总查分≤5次。",
  "expected_groups": ["shape_scale", "cell_state"],
  "risks": "1) 按型插值后总后期细胞数可能与frac=0.5时不同(可能更多),cell_state可能回落——Engineer应在第一次查分后对比cell_state,若降>2分则提高adj或回退。2) 某些型在一阶段极少(<5个),配额分配可能产生0或过抽样——需clip到[0, stage_count]。3) 型标签在两阶段不完全一致(新型出现/旧型消失),单阶段型的处理需明确。4) 30分钟时限紧——代码改动集中在biased_mix函数内约30行,不需要新依赖;先在小数据上验证型配额正确性再全量跑。",
  "family_id": "T2EI-01",
  "mechanism": "将mix的统一后期抽取比例(frac·t)替换为按型线性插值组成:每型的目标比例p_T=(1−t)·p_A+t·p_B,型内再按t分配两阶段细胞数。改变的是每种细胞类型在输出中的数量配比,而非表达值或坐标。",
  "vs_constant_shift": "常数位移对每个细胞加同一向量,不改变细胞类型组成;本方案改变各型在输出中的相对数量(有的型增加、有的减少),从而改变群体组成结构。全局组成重加权是对所有型乘同一系数;本方案是逐型独立插值,不同型的变化方向和幅度不同。",
  "mechanism_evidence": "1) 输出中每型的实际比例与目标p_T的Pearson相关(应>0.99);2) 对比父节点8:列出后期细胞数变化最大的前5个型及其delta;3) 四组分各自变化:预期shape_scale回升≥2、cell_state变化在±1内;4) 总后期细胞数与父节点(1000/5000)的对比。",
  "mechanism_off_control": "设VEC_COMPOS_INTERP=0(或代码内标志),此时回退到父节点8的抽样逻辑(统一frac=0.5、τ=0),输出应与父节点8逐位相同。Engineer验证:关闭后运行,比较X矩阵和坐标数组的np.array_equal。预期差别:关闭时shape_scale≈68.6(父8水平),开启后shape_scale应回升至71+。",
  "sources": []
}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/researcher.jsonl 6 KB
/home/spark-longxinyang/vec/runs/formal/20261003-004922-search-t2-embryo-interp-g24/nodes/10/researcher.stderr