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

总览 · ← 返回运行 20261003-094242-search-t2-embryo-interp-g24-D-s2

节点 n10

T2EI-01:类型组成 logit 插值 + 类型内残差保持的强度有界伪批量表达位移(s=5),坐标 procrustes3d 对齐后按阻尼 log-RMS 缩放,细胞按目标组成分层抽取,表达/坐标配对原样保留。

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

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

来自 programs.git 8d7ac0cf1e:solution/METHOD.md

T2EI-01:类型组成 logit 插值 + 类型内残差保持的强度有界伪批量表达位移(s=5),坐标 procrustes3d 对齐后按阻尼 log-RMS 缩放,细胞按目标组成分层抽取,表达/坐标配对原样保留。

方法(family_id: T2EI-01,按 PLAN 实现)

  1. 视图无关地从 manifest["inputs"] 按时间排序取目标的括号阶段 (a, b),t=(target−a)/(b−a),只用时间差,不看绝对时间/视图字段。无括号(单输入或外推)时退路 = 锚阶段细胞按类型分层抽到 [min_cells, max_cells] 原样输出(copy_last 式)。
  2. 组成机制(T2EI_COMPOSITION,默认开):共有类型 q=expit((1−t)·logit(p_a)+t·logit(p_b)),logit 前 p clip 到 [0.005,0.995];仅一端有的类型按该端权重保留((1−t)p_a 或 t·p_b);归一化后按 q 分配 n 个细胞,共有类型内部按 (1−t,t) 分到两端,无放回抽取。n = log 线性插值(n_a,n_b,t) 夹到榜的 [min,max](proxy 上 = 5000)。
  3. 表达机制(T2EI_STRENGTH,默认 s=5.0):共有类型 Δ=μ_b−μ_a(全阶段伪批量均值),只保留 |Δ|≥0.25(T2EI_DELTA_MIN)的基因;a 侧细胞 x+=s·t·Δ、b 侧 x−=s·(1−t)·Δ,只作用于 x>0 项、结果 clip≥0。型内残差 (x−μ) 在正项上原样保留(加的是型级常向量)。
  4. 坐标:procrustes3d 对齐(共有类型质心 Kabsch,z 符号随旋转),两朵云缩到 target RMS = exp(log rms_a + 0.5·t·Δlog rms)(T2EI_SCALE_DAMP=0.5);抽样细胞的坐标原样携带(不插值坐标点),重复坐标加 1e-4·RMS 抖动,最后整体恢复到 target RMS。表达与位置的配对因此保持真实。
  5. 确定性:np.random.default_rng(seed),无全局随机状态;纯 CPU(EXECUTION.json gpu=false),proxy 视图全程 <10 s。

机制生效的证据(proxy,E6.75+E8.0→E7.25,t=0.4,stderr 打印)

  • 组成:输出 q 与线性 (1−t)p_a+t·p_b 明显不同(Unknown −0.034、EXE-Endoderm +0.013、Caudal Epiblast −0.008 等);两侧抽样数 2739/2261,偏离 mix 的 3000/2000。
  • 表达:11 个共有类型全部位移,|Δ|₁ 137–254;a 侧权重 s·t=2、b 侧 s·(1−t)=3,伪批量移到并越过型中点(s>1 部分被 x>0/clip≥0 截断)。
  • 残差保持:位移是型级常向量,正项残差不变(结构性保证,未逐型打印相关系数)。
  • 四组分(A 半,seed 0):对照→开启 = cell_state 36.54→47.37、expression_change 59.8→62.08、shape_scale 74.91→76.42、local_spatial 54.38→57.99。

关闭机制对照(同一程序,T2EI_COMPOSITION=0 T2EI_STRENGTH=0)

  • 输出退回 mix 式 (1−t,t) 分层混抽、表达不动:总分 56.40(cell_state 36.54),复现 mix 种子画像(~57、cell_state ~37)。
  • 开启(默认):总分 60.97;seed 1 复核 60.71。两机制分解:只开组成 55.19(组成机制单独反而略降,主要伤 mmd_u/邻域),只开表达 s=5 60.62;合开 60.97 ≈ 加性。

验证过 / 没验证

  • 验证(proxy A 半,共 9 次查分):s∈{0,1,3,5,6,8} 扫描,峰值平台 s=5–6(s=1 55.99→s=5 60.97→s=8 60.06);Δ_min 0.25 vs 0.1 无差(60.97 两者);seed 0/1 差 0.26(噪声内);vec-check 通过;默认输出与显式参数输出逐字节一致(确定性)。
  • 没验证:B 半与正式分;多输入阶段(final 视图 3 输入)实际运行——代码按括号选取应成立但未跑过该视图;无括号的 copy_last 退路未在真实外推榜上跑过;s>8、λ 型逐细胞加权(节点 8 的机制,本 draft 未混入)。

参数与知识来源

  • 关键默认:align=procrustes3d、scale_damp=0.5(方法卡胚插值推荐值)、s=5.0、Δ_min=0.25、组成 logit clip 0.005。环境变量 T2EI_{COMPOSITION,STRENGTH,SCALE_DAMP,DELTA_MIN} 可覆盖(提交时默认=开启)。
  • 生物学知识来源:仅方法卡/实验表内的既有事实(z 为离散切片轴、procrustes3d 在胚插值代理上形状最好、mix 的邻域稳定 52–55、|Δ|≥0.25 阈值沿用节点 5);未使用任何保留阶段/基因型信息、外部文献数据。s=5 过冲优于 s=1 中点是纯经验结果(与节点 5/8 的 α=5 一致),与 PLAN 默认 s=1 不同,已按扫描数据改为 5。

调研员的计划

名称组成 logit 插值 + 类型内残差保持表达插值(T2EI-01)
动机mix 种子(节点 2)总分 57.23 但 cell_state 仅 37.49,低于地板(~50):mmd_u raw 0.01657(skill 0.521)、variogram raw 0.02952(skill 0.228)都很差——把两端真实细胞按 (1−t,t) 混抽产生双峰分布,不像中间阶段。节点 5 用类型级常数收敛位移把 cell_state 提到 49.28,但它保留 mix 的组成、且 α=5 过冲;组成插值在全树中从未试过。本 draft 按控制器指定实现 T2EI-01:用 logit 线性插值定类型组成(新机制),配类型内残差保持的有界表达插值。
做法1) 以 agent/seeds/T2__embryo__val_interp/mix 为基座(procrustes3d 对齐、scale_damp=0.5、分层抽样、n=5000),先复现 ~57 分确认管线正确。2) 视图文本无关地按时间排序取目标前后两个括号阶段,t=(target−a)/(b−a),不硬编码时间标签。3) 组成插值:各类型比例 p_a、p_b,共有类型做 logit 插值 logit(q)=(1−t)·logit(p_a)+t·logit(p_b)(logit 前把 p clip 到 [0.005,0.995]),仅一端有的类型按该端权重保留,最后归一化得目标组成;按 q 分配 n 个细胞,共有类型内部再按 (1−t,t) 分到两端。4) 类型内表达插值:共有类型 Δ=μ_b−μ_a,仅保留 |Δ|≥0.25 基因;a 侧细胞 x+=s·t·Δ、b 侧 x−=s·(1−t)·Δ,只作用于 x>0 项、clip≥0(保留细胞残差);强度 s 默认 1.0(恰好移到类型中点),环境变量 T2EI_STRENGTH 覆盖,搜索 [0.5,1.5]。组成开关 T2EI_COMPOSITION(0=退回 mix 的 (1−t,t) 分层组成)。5) 坐标完全不动(保形状/邻域)。6) 先 ~2000 细胞小样 vec-score 看 mmd_u 走向,再全量;cell_state 增益 <1 分时复查一次确认(T2 噪声 ~1)。7) 单输入阶段退路:括号阶段 <2 时关闭两机制,直接 copy_last 最近观测阶段。
风险1) logit 组成插值与线性差异可能很小(类型比例中等时两者接近)→ cell_state 增益落在噪声内;Engineer 应先打印输出类型组成与 (1−t,t) mix 的差值,若几乎不变说明机制没咬合。2) 有界强度 s=1 可能比节点 5 的 α=5 过冲位移在 DE(秩/方向型)上吃亏,若 expression_change 低于节点 5 可试 s→1.5。3) 组成变化会改变坐标云抽样,可能扰动当前很高的 shape_scale(74.43),需盯 d2_shape/occupancy_dice。4) 两端类型标签词表不一致时只取交集做共有类型。5) 小样本先跑,避免全量超时(30 分钟、20 次查分)。

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

对比:这个提交的上一版(种子程序:相对空仓库)。改动的文件:solution/EXECUTION.json +1 −0、solution/METHOD.md +31 −0、solution/run.py +254 −0

diff --git a/solution/EXECUTION.json b/solution/EXECUTION.jsonnew file mode 100644index 0000000..9d5125c--- /dev/null+++ b/solution/EXECUTION.json@@ -0,0 +1 @@+{"gpu": false}diff --git a/solution/METHOD.md b/solution/METHOD.mdnew file mode 100644index 0000000..065ffcc--- /dev/null+++ b/solution/METHOD.md@@ -0,0 +1,31 @@+T2EI-01:类型组成 logit 插值 + 类型内残差保持的强度有界伪批量表达位移(s=5),坐标 procrustes3d 对齐后按阻尼 log-RMS 缩放,细胞按目标组成分层抽取,表达/坐标配对原样保留。++## 方法(family_id: T2EI-01,按 PLAN 实现)++1. 视图无关地从 `manifest["inputs"]` 按时间排序取目标的括号阶段 (a, b),t=(target−a)/(b−a),只用时间差,不看绝对时间/视图字段。无括号(单输入或外推)时退路 = 锚阶段细胞按类型分层抽到 [min_cells, max_cells] 原样输出(copy_last 式)。+2. **组成机制(T2EI_COMPOSITION,默认开)**:共有类型 q=expit((1−t)·logit(p_a)+t·logit(p_b)),logit 前 p clip 到 [0.005,0.995];仅一端有的类型按该端权重保留((1−t)p_a 或 t·p_b);归一化后按 q 分配 n 个细胞,共有类型内部按 (1−t,t) 分到两端,无放回抽取。n = log 线性插值(n_a,n_b,t) 夹到榜的 [min,max](proxy 上 = 5000)。+3. **表达机制(T2EI_STRENGTH,默认 s=5.0)**:共有类型 Δ=μ_b−μ_a(全阶段伪批量均值),只保留 |Δ|≥0.25(T2EI_DELTA_MIN)的基因;a 侧细胞 x+=s·t·Δ、b 侧 x−=s·(1−t)·Δ,只作用于 x>0 项、结果 clip≥0。型内残差 (x−μ) 在正项上原样保留(加的是型级常向量)。+4. 坐标:procrustes3d 对齐(共有类型质心 Kabsch,z 符号随旋转),两朵云缩到 target RMS = exp(log rms_a + 0.5·t·Δlog rms)(T2EI_SCALE_DAMP=0.5);抽样细胞的坐标原样携带(不插值坐标点),重复坐标加 1e-4·RMS 抖动,最后整体恢复到 target RMS。表达与位置的配对因此保持真实。+5. 确定性:`np.random.default_rng(seed)`,无全局随机状态;纯 CPU(EXECUTION.json gpu=false),proxy 视图全程 <10 s。++## 机制生效的证据(proxy,E6.75+E8.0→E7.25,t=0.4,stderr 打印)++- 组成:输出 q 与线性 (1−t)p_a+t·p_b 明显不同(Unknown −0.034、EXE-Endoderm +0.013、Caudal Epiblast −0.008 等);两侧抽样数 2739/2261,偏离 mix 的 3000/2000。+- 表达:11 个共有类型全部位移,|Δ|₁ 137–254;a 侧权重 s·t=2、b 侧 s·(1−t)=3,伪批量移到并越过型中点(s>1 部分被 x>0/clip≥0 截断)。+- 残差保持:位移是型级常向量,正项残差不变(结构性保证,未逐型打印相关系数)。+- 四组分(A 半,seed 0):对照→开启 = cell_state 36.54→47.37、expression_change 59.8→62.08、shape_scale 74.91→76.42、local_spatial 54.38→57.99。++## 关闭机制对照(同一程序,T2EI_COMPOSITION=0 T2EI_STRENGTH=0)++- 输出退回 mix 式 (1−t,t) 分层混抽、表达不动:总分 56.40(cell_state 36.54),复现 mix 种子画像(~57、cell_state ~37)。+- 开启(默认):总分 60.97;seed 1 复核 60.71。两机制分解:只开组成 55.19(组成机制单独反而略降,主要伤 mmd_u/邻域),只开表达 s=5 60.62;合开 60.97 ≈ 加性。++## 验证过 / 没验证++- 验证(proxy A 半,共 9 次查分):s∈{0,1,3,5,6,8} 扫描,峰值平台 s=5–6(s=1 55.99→s=5 60.97→s=8 60.06);Δ_min 0.25 vs 0.1 无差(60.97 两者);seed 0/1 差 0.26(噪声内);vec-check 通过;默认输出与显式参数输出逐字节一致(确定性)。+- 没验证:B 半与正式分;多输入阶段(final 视图 3 输入)实际运行——代码按括号选取应成立但未跑过该视图;无括号的 copy_last 退路未在真实外推榜上跑过;s>8、λ 型逐细胞加权(节点 8 的机制,本 draft 未混入)。++## 参数与知识来源++- 关键默认:align=procrustes3d、scale_damp=0.5(方法卡胚插值推荐值)、s=5.0、Δ_min=0.25、组成 logit clip 0.005。环境变量 T2EI_{COMPOSITION,STRENGTH,SCALE_DAMP,DELTA_MIN} 可覆盖(提交时默认=开启)。+- 生物学知识来源:仅方法卡/实验表内的既有事实(z 为离散切片轴、procrustes3d 在胚插值代理上形状最好、mix 的邻域稳定 52–55、|Δ|≥0.25 阈值沿用节点 5);未使用任何保留阶段/基因型信息、外部文献数据。s=5 过冲优于 s=1 中点是纯经验结果(与节点 5/8 的 α=5 一致),与 PLAN 默认 s=1 不同,已按扫描数据改为 5。diff --git a/solution/run.py b/solution/run.pynew file mode 100644index 0000000..8b85989--- /dev/null+++ b/solution/run.py@@ -0,0 +1,254 @@+"""T2 interpolation: logit composition interpolation + bounded type-midpoint+expression interpolation on top of a mix-style coordinate frame (family T2EI-01).++Mechanism switches (env):+  T2EI_COMPOSITION  1 (default) = logit-interpolated type composition;+                    0 = mix-style (1-t, t) stratified draw of real cells.+  T2EI_STRENGTH     s (default 1.0) = bounded per-type expression displacement;+                    0 = no displacement (cells carried unchanged).+  T2EI_SCALE_DAMP   default 0.5, damping of the log-linear RMS interpolation.+"""++from __future__ import annotations++import argparse+import os+import sys++import numpy as np++from src.task2_spatial.view_io import (+    anchor_entry,+    interp_bracket,+    load_manifest,+    panel_genes,+    read_stage,+    write_t2,+)+from src.task2_spatial.frame import align_pair, log_interp, rms_radius, scale_to_rms+from src.task2_spatial.sample import interp_count, mix_indices, take+from src.task2_spatial.shift import type_means+from src.task2_spatial.transport import as_dense+++def _env_float(name: str, default: float) -> float:+    raw = os.environ.get(name)+    if raw is None or raw.strip() == "":+        return default+    return float(raw)+++def _env_flag(name: str, default: bool) -> bool:+    raw = os.environ.get(name)+    if raw is None or raw.strip() == "":+        return default+    return raw.strip().lower() not in ("0", "false", "no", "off")+++def _fractions(labels: np.ndarray, types: list[str]) -> np.ndarray:+    n = max(len(labels), 1)+    return np.array([(labels == t).sum() / n for t in types], dtype=np.float64)+++def _logit(p: np.ndarray, eps: float = 0.005) -> np.ndarray:+    p = np.clip(p, eps, 1.0 - eps)+    return np.log(p / (1.0 - p))+++def _expit(z: np.ndarray) -> np.ndarray:+    return 1.0 / (1.0 + np.exp(-z))+++def main() -> None:+    ap = argparse.ArgumentParser()+    ap.add_argument("--data", required=True)+    ap.add_argument("--out", required=True)+    ap.add_argument("--seed", type=int, default=0)+    args = ap.parse_args()++    strength = _env_float("T2EI_STRENGTH", 5.0)+    comp_on = _env_flag("T2EI_COMPOSITION", True)+    scale_damp = _env_float("T2EI_SCALE_DAMP", 0.5)+    delta_min = _env_float("T2EI_DELTA_MIN", 0.25)++    view = args.data+    manifest = load_manifest(view)+    genes = panel_genes(view, manifest)+    lo = int(manifest["min_cells"])+    hi = int(manifest["max_cells"])+    rng = np.random.default_rng(int(args.seed))++    a_entry, b_entry, t = interp_bracket(manifest)++    # Fallback: no bracketing pair (e.g. single input stage) -> carry the anchor stage.+    if b_entry is None:+        stage = read_stage(view, a_entry, genes)+        n = int(np.clip(stage.n, min(lo, stage.n), hi))+        idx = take(stage.labels, n, rng) if n < stage.n else np.arange(stage.n)+        write_t2(args.out, as_dense(stage.X, idx), stage.coords[idx], genes, seed=args.seed)+        print(f"[T2EI] no bracket -> copy anchor stage, n={len(idx)}", file=sys.stderr)+        return++    stage_a = read_stage(view, a_entry, genes)+    stage_b = read_stage(view, b_entry, genes)+    la = np.asarray(stage_a.labels).astype(str)+    lb = np.asarray(stage_b.labels).astype(str)++    n = interp_count(stage_a.n, stage_b.n, t, lo, hi)++    # Coordinates: procrustes3d frame, both clouds scaled to a damped log-linear RMS.+    al_a, al_b, info = align_pair(stage_a.coords, stage_b.coords, la, lb, "procrustes3d")+    rms_a = rms_radius(stage_a.coords)+    rms_b = rms_radius(stage_b.coords)+    target_rms = log_interp(rms_a, rms_b, t, scale_damp)+    ca = scale_to_rms(al_a, target_rms)+    cb = scale_to_rms(al_b, target_rms)++    types = sorted(set(la.tolist()) | set(lb.tolist()))+    pa = _fractions(la, types)+    pb = _fractions(lb, types)+    in_a = pa > 0+    in_b = pb > 0+    shared = in_a & in_b++    if comp_on:+        q = np.zeros_like(pa)+        q[shared] = _expit((1.0 - t) * _logit(pa[shared]) + t * _logit(pb[shared]))+        q[in_a & ~in_b] = (1.0 - t) * pa[in_a & ~in_b]+        q[~in_a & in_b] = t * pb[~in_a & in_b]+        q = q / q.sum()+    else:+        q = None++    idx_a_list, idx_b_list = [], []+    if q is None:+        ia, ib = mix_indices(la, lb, t, n, rng)+        idx_a_list.append(ia)+        idx_b_list.append(ib)+    else:+        counts = np.floor(q * n).astype(int)+        pools_a = {ty: np.flatnonzero(la == ty) for ty in types if (la == ty).any()}+        pools_b = {ty: np.flatnonzero(lb == ty) for ty in types if (lb == ty).any()}+        # first pass, capped by pool sizes+        ka = np.zeros(len(types), dtype=int)+        kb = np.zeros(len(types), dtype=int)+        for i, ty in enumerate(types):+            k = int(counts[i])+            if k <= 0:+                continue+            if shared[i]:+                k_a = int(round((1.0 - t) * k))+                k_a = min(k_a, pools_a[ty].size)+                k_b = min(k - k_a, pools_b[ty].size)+                if k_a + k_b < k:+                    k_a = min(k - k_b, pools_a[ty].size)+                ka[i], kb[i] = k_a, k_b+            elif in_a[i]:+                ka[i] = min(k, pools_a[ty].size)+            else:+                kb[i] = min(k, pools_b[ty].size)+        deficit = int(n - ka.sum() - kb.sum())+        # redistribute the floor/deficit surplus to types with spare pool capacity+        spare_a = np.array([max(pools_a.get(ty, np.empty(0)).size - ka[i], 0) for i, ty in enumerate(types)])+        spare_b = np.array([max(pools_b.get(ty, np.empty(0)).size - kb[i], 0) for i, ty in enumerate(types)])+        order = np.argsort(-(q + 1e-12))+        guard = 0+        while deficit > 0 and guard < 4 * len(types) + 8:+            progressed = False+            for i in order:+                if deficit <= 0:+                    break+                if spare_b[i] > 0 and (not shared[i] or spare_a[i] <= 0):+                    kb[i] += 1+                    spare_b[i] -= 1+                    deficit -= 1+                    progressed = True+                elif spare_a[i] > 0:+                    ka[i] += 1+                    spare_a[i] -= 1+                    deficit -= 1+                    progressed = True+            if not progressed:+                break+            guard += 1+        for i, ty in enumerate(types):+            if ka[i] > 0:+                idx_a_list.append(rng.choice(pools_a[ty], int(ka[i]), replace=False))+            if kb[i] > 0:+                idx_b_list.append(rng.choice(pools_b[ty], int(kb[i]), replace=False))++    idx_a = np.concatenate(idx_a_list) if idx_a_list else np.array([], dtype=int)+    idx_b = np.concatenate(idx_b_list) if idx_b_list else np.array([], dtype=int)+    idx_a = np.sort(idx_a)+    idx_b = np.sort(idx_b)++    # Expression: bounded, residual-preserving per-type displacement towards the type midpoint.+    Xa = as_dense(stage_a.X, idx_a) if idx_a.size else np.empty((0, len(genes)), dtype=np.float32)+    Xb = as_dense(stage_b.X, idx_b) if idx_b.size else np.empty((0, len(genes)), dtype=np.float32)+    labels_a_sel = la[idx_a] if idx_a.size else np.array([], dtype=str)+    labels_b_sel = lb[idx_b] if idx_b.size else np.array([], dtype=str)++    shift_report = []+    if strength != 0.0 and shared.any():+        means_a = type_means(stage_a.X, la)+        means_b = type_means(stage_b.X, lb)+        wa = float(strength) * float(t)+        wb = float(strength) * (1.0 - float(t))+        for ty in types:+            if not (ty in means_a and ty in means_b):+                continue+            d = (means_b[ty] - means_a[ty]).astype(np.float32)+            d = np.where(np.abs(d) >= delta_min, d, 0.0).astype(np.float32)+            if not np.any(d):+                continue+            ma = labels_a_sel == ty+            if ma.any():+                blk = Xa[ma]+                db = np.broadcast_to(d, blk.shape)+                pos = blk > 0+                upd = np.clip(blk[pos] + wa * db[pos], 0.0, None)+                new = blk.copy()+                new[pos] = upd+                Xa[ma] = new+            mb = labels_b_sel == ty+            if mb.any():+                blk = Xb[mb]+                db = np.broadcast_to(d, blk.shape)+                pos = blk > 0+                upd = np.clip(blk[pos] - wb * db[pos], 0.0, None)+                new = blk.copy()+                new[pos] = upd+                Xb[mb] = new+            shift_report.append((ty, int(ma.sum()), int(mb.sum()), float(np.abs(d).sum())))++    expr = np.vstack([Xa, Xb])+    coords = np.vstack([ca[idx_a], cb[idx_b]])++    # jitter exact-duplicate coordinates, then restore the target RMS+    rounded = np.round(coords, 5)+    _, inv, cnt = np.unique(rounded, axis=0, return_inverse=True, return_counts=True)+    if cnt.max() > 1:+        coords = coords.copy()+        dup = cnt[inv] > 1+        coords[dup] = coords[dup] + rng.normal(0.0, 1e-4 * (target_rms + 1e-8), size=(int(dup.sum()), 3))+    coords = scale_to_rms(coords, target_rms)++    write_t2(args.out, expr, coords.astype(np.float32), genes, seed=args.seed)++    # ---- mechanism evidence ----+    lin = (1.0 - t) * pa + t * pb+    print(f"[T2EI] t={t:.4f} n={expr.shape[0]} (from a: {len(idx_a)}, from b: {len(idx_b)}) "+          f"rms_a={rms_a:.1f} rms_b={rms_b:.1f} target_rms={target_rms:.1f} out_rms={rms_radius(coords):.1f} "+          f"z_dot={info.get('z_dot'):.3f} n_shared={int(shared.sum())}", file=sys.stderr)+    print(f"[T2EI] comp_on={comp_on} strength={strength} scale_damp={scale_damp}", file=sys.stderr)+    if comp_on:+        print("[T2EI] composition: type q_logit q_linear diff", file=sys.stderr)+        for i, ty in enumerate(types):+            if q[i] > 1e-4 or lin[i] > 1e-4:+                print(f"[T2EI]   {ty:<24s} {q[i]:.4f} {lin[i]:.4f} {q[i] - lin[i]:+.4f}", file=sys.stderr)+    for ty, na, nb, dmag in shift_report:+        print(f"[T2EI]   shift {ty:<24s} n_a={na} n_b={nb} |delta|_1={dmag:.2f}", file=sys.stderr)+++if __name__ == "__main__":+    main()

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

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k023Time-split validation with a held-out intermediate or next time pointnotes/handover/02_知识学习路线.md
k009Conditional / OT flow matching for population transportarXiv:2210.02747 (Lipman et al., Flow Matching for Generative Modeling)

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

改了什么从零实现 T2EI-01:类型组成 logit 插值 + 类型内残差保持的伪批量表达位移(只作用 x>0 项、|Δ|≥0.25 基因),坐标 procrustes3d 对齐 + scale_damp=0.5 的 RMS 缩放、按目标组成分层抽 n=5000。注意实际默认 s=5(过冲),与 PLAN 声称的 s=1(恰好移到型中点)不符,Engineer 依 proxy 扫描改了参数并在 METHOD.md 注明——因此真正驱动增益的是类节点5 的大强度型级位移,而非'有界移到中点'。
各组分数的变化cell_state:明显变好 +11.63(37.49→49.12):mmd_u raw 0.01657→0.01148(skill 0.521→0.612,得分 +1.13)、variogram raw 0.02952→0.01502(skill 0.228→0.371,得分 +1.78),但 49.12 仍略低于地板 50
expression_change:变好 +2.88(59.72→62.60):de_score raw 0.2069→0.3448(skill 0.562→0.614,得分 +0.64)、de_direction 0.3757→0.3899(+0.08);组增益主要来自 de_score,远超 T2 ~1 分噪声
local_spatial:变好 +3.46(57.27→60.73):neighborhood_mmd raw 0.05791→0.0503(skill 0.573→0.607,得分 +0.86,超过噪声),坐标不动而表达位移改善了邻域平均表达的配对
shape_scale:噪声内 -0.39(74.43→74.04):d2_shape/scale_log_ratio 得分不变,occupancy_dice raw 0.7735→0.7646(-0.10),坐标未动,符合预期
family_idT2EI-01
假设是否成立是
经验
  1. 在 mix 种子(cell_state 低于地板)上,对两端共有类型做大强度型级伪批量位移(s=5,过冲、只作用 x>0 项、clip≥0、保留细胞残差)能把 cell_state 从 37 拉到 ~49 且连带 expression_change、local_spatial 一起升、shape_scale 不动——坐标不动的表达位移不伤邻域和形状。
  2. 本节点的消融显示:只开 logit 组成插值 55.19(比关闭对照 56.40 还低,单独为负,主要伤 mmd_u/邻域),只开表达位移 s=5 得 60.62,合开 60.97——增益几乎全部来自表达位移机制,PLAN 的核心新机制(组成 logit 插值)单独无效,仅合成时有 ~0.35(噪声内)的边际。
  3. s=5 过冲第三次优于 s=1 移到型中点(节点 5、8 的 α=5 与本次 s 扫描峰值 5–6 一致):在该胚插值数据上,型级位移宁可过冲也不要恰好停在中点。
  4. 布尔掩码索引拿到的是副本,对 Xa[ma] 的就地修改不会写回原数组——Engineer 修过这个 bug,向量化按掩码改数组时必须显式赋值回写并验证输出确实变了。
mechanism_active是
下一步建议
  1. cell_state(49.12)仍是唯一低于地板(50)的组:在 s=5 表达位移之上叠加型内分布收窄(把细胞残差 x−μ 向 0 收缩,系数 ~0.2–0.4 扫描),直接针对 mmd_u/variogram 的'型内宽度'分量——注意全局加独立噪声会伤这两项,收缩比加噪更可能有效。
  2. 组成 logit 插值单独为负,可试阻尼混合 q=expit((1−λ)·linear_logit+λ·logit_logit) 或直接 T2EI_COMPOSITION=0 只保留 s=5 表达位移(预期 60.62 上下,省掉一个无效自由度);若要救组成机制,与节点 8 的逐细胞投影加权(λ=6)组合而不是与型级位移组合。
  3. s 峰值平台在 5–6(proxy A 半),在正式评测/全量数据上复核 s=6 与 s=5 的差异再定默认值,避免 proxy 半集上过拟合。

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

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

分析员

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

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数26
工具调用共 32 次:bash 25、write 3、edit 3、read 1
用时14 分
token 数输入 71,432 · 输出 11,678 · 思考 11,322
任务(第一行)按计划修改程序:组成 logit 插值 + 类型内残差保持表达插值(T2EI-01)
最后的回答(摘录)
Done. Summary:

**做了什么**:从零实现 PLAN 的 T2EI-01 家族——类型组成 logit 插值(q=expit((1−t)logit(p_a)+t·logit(p_b)),单端类型按端权重保留)+ 类型内残差保持的有界伪批量表达位移(只移 x>0 项、|Δ|≥0.25 基因),坐标 procrustes3d 对齐 + scale_damp=0.5 的 RMS 缩放,细胞按目标组成分层无放回抽取(n=5000)。修复了一个关键 bug(布尔掩码索引副本导致表达位移原本未写回)。强度扫描 s∈{0,1,3,5,6,8} 峰值在 5–6,默认 s=5(与 PLAN 的 s=1 不同,扫描数据支持,METHOD.md 已注明)。

**查分结果**(proxy A 半,9/20 次):关闭对照(COMPOSITION=0, STRENGTH=0)56.40,复现 mix 种子画像(cell_state 36.5);默认开启 **60.97**(cell_state 47.4、expr 62.1、shape 76.4、local 58.0),seed 1 复核 60.71。分解:只开组成 55.19(单独略伤 mmd_u/邻域),只开表达 60.62,合开 ≈ 加性。确定性、vec-check、单输入退路均通过。

**下一步最值得试**:组成 logit 机制单独为负、与表达位移合成为正但幅度在噪声边缘——可试组成阻尼 λ(linear↔logit 混合)或把 logit 组成与节点 8 的逐细胞投影加权(λ=6)组合;cell_state 仍是四组最弱(47 vs 地板 50),压缩型内分布宽度(而非刚性平移)是最可能的增益点。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-094242-search-t2-embryo-interp-g24-D-s2/nodes/10/engineer.jsonl 201 KB
/home/spark-longxinyang/vec/runs/formal/20261003-094242-search-t2-embryo-interp-g24-D-s2/nodes/10/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时7 分
token 数输入 9,736 · 输出 9,670 · 思考 8,192
任务(第一行)为节点 n10(草稿,父节点 nNone)写改进计划 PLAN.json,思路 T2EI-01
最后的回答(摘录)
28,但它保留 mix 的组成、且 α=5 过冲;组成插值在全树中从未试过。本 draft 按控制器指定实现 T2EI-01:用 logit 线性插值定类型组成(新机制),配类型内残差保持的有界表达插值。",
 "approach": "1) 以 agent/seeds/T2__embryo__val_interp/mix 为基座(procrustes3d 对齐、scale_damp=0.5、分层抽样、n=5000),先复现 ~57 分确认管线正确。2) 视图文本无关地按时间排序取目标前后两个括号阶段,t=(target−a)/(b−a),不硬编码时间标签。3) 组成插值:各类型比例 p_a、p_b,共有类型做 logit 插值 logit(q)=(1−t)·logit(p_a)+t·logit(p_b)(logit 前把 p clip 到 [0.005,0.995]),仅一端有的类型按该端权重保留,最后归一化得目标组成;按 q 分配 n 个细胞,共有类型内部再按 (1−t,t) 分到两端。4) 类型内表达插值:共有类型 Δ=μ_b−μ_a,仅保留 |Δ|≥0.25 基因;a 侧细胞 x+=s·t·Δ、b 侧 x−=s·(1−t)·Δ,只作用于 x>0 项、clip≥0(保留细胞残差);强度 s 默认 1.0(恰好移到类型中点),环境变量 T2EI_STRENGTH 覆盖,搜索 [0.5,1.5]。组成开关 T2EI_COMPOSITION(0=退回 mix 的 (1−t,t) 分层组成)。5) 坐标完全不动(保形状/邻域)。6) 先 ~2000 细胞小样 vec-score 看 mmd_u 走向,再全量;cell_state 增益 <1 分时复查一次确认(T2 噪声 ~1)。7) 单输入阶段退路:括号阶段 <2 时关闭两机制,直接 copy_last 最近观测阶段。",
 "expected_groups": ["cell_state", "expression_change"],
 "risks": "1) logit 组成插值与线性差异可能很小(类型比例中等时两者接近)→ cell_state 增益落在噪声内;Engineer 应先打印输出类型组成与 (1−t,t) mix 的差值,若几乎不变说明机制没咬合。2) 有界强度 s=1 可能比节点 5 的 α=5 过冲位移在 DE(秩/方向型)上吃亏,若 expression_change 低于节点 5 可试 s→1.5。3) 组成变化会改变坐标云抽样,可能扰动当前很高的 shape_scale(74.43),需盯 d2_shape/occupancy_dice。4) 两端类型标签词表不一致时只取交集做共有类型。5) 小样本先跑,避免全量超时(30 分钟、20 次查分)。",
 "family_id": "T2EI-01",
 "mechanism": "用 logit 空间线性插值重排输出细胞类型组成(比例走平滑轨迹而非 (1−t,t) 直混),再对两端共有类型做残差保持的有界伪批量表达插值,把细胞推向类型中点。",
 "vs_constant_shift": "每型常数位移(如节点 5)不改变输出类型组成——组成仍停在 mix 的 (1−t,t);全局组成重加权改组成却不改单细胞表达。本方案核心新机制是 logit 组成插值(重排各型细胞数量这一群体结构),并同时对每个细胞做有界、保留残差的表达插值;类型内分量虽是型级向量,但强度有界(移到中点而非 α=5 过冲)且与组成变化耦合,非单纯加常数。",
 "mechanism_evidence": "1) 打印输出类型组成,证明其偏离 (1−t,t) mix 且落在两端 logit 插值处;2) 逐类型报告伪批量均值位移≈s·t·Δ(向中点靠拢);3) 细胞残差 (x−μ_self) 与原始相关≈1,证明残差保留;4) 四组分分解:cell_state(mmd_u/variogram skill)上升、expression_change 持平或升、local_spatial(neighborhood_mmd)不塌、shape_scale 基本不变(坐标未动)。",
 "mechanism_off_control": "同一程序设 T2EI_COMPOSITION=0 且 T2EI_STRENGTH=0:组成退回 mix 的 (1−t,t) 分层抽样、表达位移为 0,应逐位(或分数上)复现 mix 种子(~57 分、cell_state ~37)。预期差别:开启后 cell_state(mmd_u、variogram)明显上升而形状组不变;若关闭后输出与开启完全相同,说明机制未运行。",
 "sources": []}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-094242-search-t2-embryo-interp-g24-D-s2/nodes/10/researcher.jsonl 39 KB
/home/spark-longxinyang/vec/runs/formal/20261003-094242-search-t2-embryo-interp-g24-D-s2/nodes/10/researcher.stderr