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

总览 · ← 返回运行 20261003-172000-search-t2-heart-extrap-chain-12h

节点 n3

T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-172000-search-t2-heart-extrap-chain-12h
父节点n1
子节点n7、n9、n12
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 50.00(+0.0) · proxy_noscale 50.00(+0.0)
审查通过 1 越界读取:未发现问题。全部 I/O 都拼在 --data 视图根下:run.py:59 读 prior/go/gene_sets_bp.gmt(view_manifest.json prior 清单内的 id 'go'),run.py:99 只读 manifest['external'] 给出的 entry['path'](qiu2024_heart_early_v1/E8.75.h5ad);无绝对路径、'..'、/mnt、/home、data/raw、downloads、src/common/evaluation 的读取,全文无 requests/urllib/socket/subpr…
用时?从运行开始到结束(或到现在)的挂钟时间。18 分
程序版本a0271985a8e37de4a6303042b6ee8b12c2c65146 (programs.git)
导入自20261003-105537-search-t2-heart-extrap-g24-D#3
备注re-scored at launch (origin 20261003-105537-search-t2-heart-extrap-g24-D node 3, score there 50.00)

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

来自 programs.git a0271985a8:solution/METHOD.md

T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。

方法

在父节点(copy_last)之上加一个位移层,管线(全部只读 manifest 的相对时间与区间字段,无绝对阶段/尺寸常数,伪装视图安全):

  1. 细胞选择与坐标和父节点完全相同:anchor=最后观测阶段,n≤max_cells 整份输出,超过则按型分层抽样;坐标一律不动(保 neighborhood_mmd 与结构门)。
  2. 位移方向按优先级:
    • (a) 外部前向靶:manifest.external 中存在区间 (e_lo, e_hi) 满足 e_lo > 末输入时间且 e_hi ≤ 目标时间的样本时,加载并对齐到面板(<50 共有基因则放弃;X 若像原始计数则重算 log1p(CP10k));anchor 各细胞型与外部型在共有基因伪批量上算 Pearson r,r≥0.5 才配对;每细胞 shift = α·[β·型级差 + (1−β)·(匹配型内最近邻外部细胞 − 本细胞)],α=0.5、β=1(默认)。
    • (b) 两输入速度回退:型级伪批量差 × α_vel × dt_ratio。默认 α_vel=0(关),理由见下。
    • (c) 都没有 → 输出逐位等于 copy_last。
  3. shift 逐基因截断在 ±2·std(基因 in anchor),X+shift 后截 0。异常时 (a) 路径 try/except 回退,绝不崩。

机制对照与验证(proxy_noscale,5 次查分)

  • α=0 对照(mechanism_off_control):默认配置在代理上的输出与父节点逐位相同(X、坐标 array_equal 验证),vec-score 实测 50.00,四组全 50。✓
  • 速度回退 (b) 的方向质量(这是代理上唯一可测的方向):
    • 型级伪批量速度 α_eff=0.45/0.9/1.5:49.0 / 48.7 / 48.3。de_score 原始值 −0.056(低于 chance),de_direction ≈ −0.003~−0.007:E8.25→E8.75 的型级速度与真值 E8.75→E9.5 变化不相关甚至反相关,且 DE 两项对 α 近似不变(秩/符号指标),所以任何 α 都拿不到 DE 收益,只赔 variogram(skill 0.36–0.44)。与方法卡"α 网格单调低于地板"一致。
    • 去掉增殖模块(GO BP 名字含 cell cycle/mitotic/DNA replication 等的 44 个面板基因置零,通用基因功能注释,来自视图 prior/go)α_eff=0.45:49.05。de_direction 转微正(+0.015,skill 0.504)但 de_score 更差(−0.139),variogram 仍赔 0.8 分。
  • 结论:代理上速度外推方向无信号,(b) 默认关(α_vel=0);代理行为 = copy_last = 50.00。
  • 外部路径 (a) 冒烟测试(把末输入时间假装提前以触发):加载 qiu E8.75、27883 基因对齐、33 个 anchor 型中 1 个(心脏谱系)r≥0.5 配对成功、shift 逐型非零——机械上可运行;代理视图内没有真正"晚于末输入"的外部样本,故该路径的科学效果未能在本地验证(这正是方法卡指出的外推盲区:本地尺子无法检验方向,且外推榜本地分历史上高估官网分)。
  • vec-check 对本 board 返回 "not allowed for this client"(客户端限制,非格式问题);vec-score 正常接收并打分同一文件,格式合规。

知识来源

  • GO BP 注释(视图 prior/go/gene_sets_bp.gmt):增殖模块(细胞周期/有丝分裂/DNA 复制)是瞬态程序,其早期轨迹不可靠外推——通用基因功能知识,非任何保留阶段测量。
  • 细胞型配对用表达相关而非标签名(外部数据标签词汇可能不同)——PLAN T2HX-01 规定。

已知弱点 / 未验证

  • (a) 路径在真实 final 视图(可能挂 MOSTA E9.5 等前向外部样本)上的效果无法在本地检验;若方向错会低于地板。终选护栏(proxy_noscale 种子均值需超 copy_last 1 分)在本节点上不会通过,正式提交会回落到基线预测。
  • 未做:STRING/通路平滑速度、t 统计加权、逐细胞 OT 位移(方法卡已证 OT 伤邻域)。

调研员的计划

名称表达匹配型伪批量位移外推(保坐标,T2HX-01)
动机父节点 1(copy_last)50.00,全部八项 skill=0.5 即地板,其中 de_score/de_direction 原始值为 0(被无变化保护击中:dp≡0,两项合计 12.5/25 分处于地板且毫无信息);兄弟节点 2 的朴素 damped_shift 49.51 反而低于地板,说明无方向的位移会伤 mmd_u(48.41)而不产生 DE 收益。外推榜的 dt = pb(E9.5)−pb(E8.5) 非零,唯一能拉开表达变化组的是让 dp 与真实变化同向同序。方向库 T2HX-01 正是为此:按表达匹配而非标签名做型间伪批量位移,并加收缩保住型内方差。坐标不动可保住 local_spatial(方法卡已证 OT 插值坐标会把邻域组砸到 23–41,而本榜邻域+结构门最多影响 50 分)。
做法在父节点 run.py 上加位移层,管线:1) 读 anchor 阶段(外推榜=最后观测阶段)。2) 目标位移来源按优先级回退:(a) external/ 里选一个阶段不超过靶时间、且区间完全落在心脏保留窗 (8.25,8.75)、(9.5,13.5] 之外的外部样本(如 E9.5 心脏),用其作为靶;(b) 若视图给两个输入阶段(final 情形),用两阶段按型伪批量差/时间间隔作为速度外推;(c) 都没有则原样输出=copy_last(proxy 单阶段时的退路,输出逐位等于父节点)。程序只读 manifest 的相对时间与区间字段,不写任何绝对阶段常数,伪装视图安全。3) 细胞配对按表达而非标签名:输入型与外部型用共有面板基因(要求≥50 个共有基因)上的伪批量 Pearson 相关匹配,阈值 r≥0.5,匹配失败即回退 (c)。4) 每个输入细胞 i:shift_i = α·[(1−β)·(x_ext_matched(i) − pb_t(i)) + β·(pb_ext_T(i) − pb_t(i))];X_i ← X_i + shift_i,负值截 0,|shift| 按基因上限取该基因输入标准差的 2 倍(防极端值打爆 mmd_u/variogram)。坐标一律不动——这是保邻域、保 d2_shape/occupancy_dice 的关键。5) 参数初值 α=0.7、β=0.5;网格 α∈{0.3,0.5,0.7,1.0}×β∈{0.3,0.5,0.7}。6) 流程:先跑 α=0 对照复现父节点 50.00;检查 manifest 确认外部样本存在、面板重叠与区间合规;先在 30% 分层子样本上粗筛网格,再用全量 vec-score 复核,预算≤20 次查分;选定参数后用 seed 1 复跑确认 >1 分优势(T2 噪声约 1 分,终选护栏要求种子均值超基线 1 分)。
风险1) 视图内可能没有可用外部样本,或外部面板/细胞类型与输入重叠太少 → 机制静默退化回 copy_last;Engineer 第一步就查 manifest 并打印匹配报告,尽早发现。2) 表达匹配把型配错 → 位移反向,DE 掉到 chance 附近;看 de_direction 是否低于 6.25 地板分即可发现。3) 过冲伤 mmd_u/neighborhood_mmd(重蹈节点 2 覆辙);每次查分都读 score_parts,邻域得分 <12.4/25 或 mmd_u 变差就降 α、增 β、收紧位移上限。4) 在 A 半过拟合参数;要求相邻网格点分数平滑、且 seed 1 复跑仍 >1 分。5) 本地小幅领先未必兑现,故只把目标定在 ≥52 而非贪大。

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

对比:父节点版本 6b3812a495。改动的文件:solution/METHOD.md +32 −0、solution/run.py +228 −8

diff --git a/solution/METHOD.md b/solution/METHOD.mdnew file mode 100644index 0000000..6640572--- /dev/null+++ b/solution/METHOD.md@@ -0,0 +1,32 @@+T2HX-01 位移层:外推时优先用视图内"晚于末输入、不晚于目标"的外部样本按伪批量相关匹配细胞型做阻尼位移(保坐标);两输入速度回退在代理上验证有害、默认关;无可用方向时逐位等于 copy_last。++## 方法++在父节点(copy_last)之上加一个位移层,管线(全部只读 manifest 的相对时间与区间字段,无绝对阶段/尺寸常数,伪装视图安全):++1. 细胞选择与坐标和父节点完全相同:anchor=最后观测阶段,n≤max_cells 整份输出,超过则按型分层抽样;坐标一律不动(保 neighborhood_mmd 与结构门)。+2. 位移方向按优先级:+   - (a) **外部前向靶**:`manifest.external` 中存在区间 (e_lo, e_hi) 满足 e_lo > 末输入时间且 e_hi ≤ 目标时间的样本时,加载并对齐到面板(<50 共有基因则放弃;X 若像原始计数则重算 log1p(CP10k));anchor 各细胞型与外部型在共有基因伪批量上算 Pearson r,r≥0.5 才配对;每细胞 shift = α·[β·型级差 + (1−β)·(匹配型内最近邻外部细胞 − 本细胞)],α=0.5、β=1(默认)。+   - (b) 两输入速度回退:型级伪批量差 × α_vel × dt_ratio。**默认 α_vel=0(关)**,理由见下。+   - (c) 都没有 → 输出逐位等于 copy_last。+3. shift 逐基因截断在 ±2·std(基因 in anchor),X+shift 后截 0。异常时 (a) 路径 try/except 回退,绝不崩。++## 机制对照与验证(proxy_noscale,5 次查分)++- **α=0 对照(mechanism_off_control)**:默认配置在代理上的输出与父节点逐位相同(X、坐标 array_equal 验证),vec-score 实测 **50.00**,四组全 50。✓+- **速度回退 (b) 的方向质量**(这是代理上唯一可测的方向):+  - 型级伪批量速度 α_eff=0.45/0.9/1.5:**49.0 / 48.7 / 48.3**。de_score 原始值 −0.056(低于 chance),de_direction ≈ −0.003~−0.007:E8.25→E8.75 的型级速度与真值 E8.75→E9.5 变化**不相关甚至反相关**,且 DE 两项对 α 近似不变(秩/符号指标),所以任何 α 都拿不到 DE 收益,只赔 variogram(skill 0.36–0.44)。与方法卡"α 网格单调低于地板"一致。+  - 去掉增殖模块(GO BP 名字含 cell cycle/mitotic/DNA replication 等的 44 个面板基因置零,通用基因功能注释,来自视图 prior/go)α_eff=0.45:**49.05**。de_direction 转微正(+0.015,skill 0.504)但 de_score 更差(−0.139),variogram 仍赔 0.8 分。+- 结论:代理上速度外推方向无信号,(b) 默认关(α_vel=0);代理行为 = copy_last = 50.00。+- **外部路径 (a) 冒烟测试**(把末输入时间假装提前以触发):加载 qiu E8.75、27883 基因对齐、33 个 anchor 型中 1 个(心脏谱系)r≥0.5 配对成功、shift 逐型非零——机械上可运行;代理视图内没有真正"晚于末输入"的外部样本,故该路径的科学效果**未能在本地验证**(这正是方法卡指出的外推盲区:本地尺子无法检验方向,且外推榜本地分历史上高估官网分)。+- vec-check 对本 board 返回 "not allowed for this client"(客户端限制,非格式问题);vec-score 正常接收并打分同一文件,格式合规。++## 知识来源++- GO BP 注释(视图 prior/go/gene_sets_bp.gmt):增殖模块(细胞周期/有丝分裂/DNA 复制)是瞬态程序,其早期轨迹不可靠外推——通用基因功能知识,非任何保留阶段测量。+- 细胞型配对用表达相关而非标签名(外部数据标签词汇可能不同)——PLAN T2HX-01 规定。++## 已知弱点 / 未验证++- (a) 路径在真实 final 视图(可能挂 MOSTA E9.5 等前向外部样本)上的效果无法在本地检验;若方向错会低于地板。终选护栏(proxy_noscale 种子均值需超 copy_last 1 分)在本节点上不会通过,正式提交会回落到基线预测。+- 未做:STRING/通路平滑速度、t 统计加权、逐细胞 OT 位移(方法卡已证 OT 伤邻域)。diff --git a/solution/run.py b/solution/run.pyindex 0595dc9..196e6b2 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,20 +1,181 @@ #!/usr/bin/env python3-"""copy_last (T2): the latest input at or before the target, with its own coordinates.+"""T2 extrapolation: expression-matched pseudobulk displacement on the anchor stage. -Interpolation boards take the lower bracket stage, extrapolation boards the-last input; this is the floor's reference stage on the proxy. Cells are drawn-stratified by cell type only when the stage exceeds the board's max_cells.-Expression and coordinates are unchanged.+Mechanism (family T2HX-01): shift each anchor-stage cell's expression toward a+forward target while keeping coordinates untouched (preserves local spatial+pairing). Target priority, computed only from view data and relative times:++  (a) an external sample whose whole stage interval lies strictly after the+      last input and at/before the target: per-cell type of the anchor is+      matched to external types by pseudobulk Pearson correlation on shared+      panel genes (r >= 0.5); shift blends the matched type-level difference+      (weight beta) with a nearest-neighbour cell-level difference (1 - beta).+  (b) else with >= 2 inputs: per-type pseudobulk velocity between the last two+      inputs, extrapolated over (target - last) time; type-level shift.+  (c) else: copy_last exactly (alpha also forces this when set to 0).++Shifts are per-gene capped at cap * std(gene in anchor), values clipped at 0.+No absolute stage names, times or sizes are hardcoded; only relative time+differences from the manifest are used, so the program is view-independent. """  from __future__ import annotations  import argparse+import os+import sys  import numpy as np  from src.task2_spatial.sample import take-from src.task2_spatial.view_io import anchor_entry, load_manifest, panel_genes, read_stage, write_t2+from src.task2_spatial.view_io import (+    anchor_entry,+    extrap_step,+    load_manifest,+    panel_genes,+    read_stage,+    target_time,+    write_t2,+)++ALPHA = float(os.environ.get("VEC_ALPHA", "0.5"))  # external-forward path+ALPHA_VEL = float(os.environ.get("VEC_ALPHA_VEL", "0.0"))  # two-input velocity fallback (proxy-validated: harmful, kept off)+BETA = float(os.environ.get("VEC_BETA", "1.0"))+CAP = float(os.environ.get("VEC_CAP", "2.0"))+TIME_SCALE = bool(int(os.environ.get("VEC_TS", "1")))+CC_ZERO = bool(int(os.environ.get("VEC_CC", "0")))+MATCH_R = 0.5+MIN_SHARED = 50++_CC_KEYWORDS = ("cell cycle", "mitotic", "meiotic", "dna replication", "chromosome segregation", "cytokinesis")+++def _cell_cycle_genes(view: str) -> set[str]:+    """Genes in GO BP terms whose name indicates proliferation programs (generic+    gene-function annotation from the view's prior/; transient modules whose+    early trajectory is not trusted for forward extrapolation)."""+    out: set[str] = set()+    try:+        path = os.path.join(view, "prior", "go", "gene_sets_bp.gmt")+        with open(path) as fh:+            for line in fh:+                parts = line.rstrip("\n").split("\t")+                if len(parts) < 3:+                    continue+                name = parts[1].lower()+                if any(k in name for k in _CC_KEYWORDS):+                    out.update(parts[2:])+    except OSError:+        pass+    return out+++def _pb(X: np.ndarray, labels: np.ndarray) -> tuple[list[str], np.ndarray]:+    types = sorted(set(labels.tolist()))+    out = np.zeros((len(types), X.shape[1]), dtype=np.float64)+    for k, t in enumerate(types):+        m = labels == t+        if m.any():+            out[k] = X[m].mean(axis=0)+    return types, out+++def _external_forward_entry(manifest: dict, last_time: float, tt: float) -> dict | None:+    for e in manifest.get("external") or []:+        try:+            lo = float(e.get("e_lo", -np.inf))+            hi = float(e.get("e_hi", lo))+        except (TypeError, ValueError):+            continue+        if lo > last_time + 1e-6 and hi <= tt + 1e-6:+            return e+    return None+++def _load_external(view: str, entry: dict, genes: list[str]):+    import anndata as ad+    from scipy import sparse++    ad_obj = ad.read_h5ad(os.path.join(view, entry["path"]))+    ext_genes = [str(g) for g in ad_obj.var_names]+    pos = {g: i for i, g in enumerate(ext_genes)}+    shared = [g for g in genes if g in pos]+    if len(shared) < MIN_SHARED:+        return None, None+    cols = np.array([pos[g] for g in shared])+    X = ad_obj.X+    X = X.toarray() if sparse.issparse(X) else np.asarray(X)+    X = np.nan_to_num(np.asarray(X, dtype=np.float64))+    if "log1p" not in ad_obj.uns and X.max() > 30.0:  # looks like raw counts+        tot = X.sum(axis=1, keepdims=True)+        tot[tot <= 0] = 1.0+        X = np.log1p(X / tot * 10000.0)+    X = X[:, cols]+    labels = (+        np.asarray(ad_obj.obs["celltype"]).astype(str)+        if "celltype" in ad_obj.obs+        else np.array(["ext"] * X.shape[0])+    )+    return shared, (X, labels)+++def _direction_external(view, manifest, genes, X_a, lab_a, pb_a, last_time, tt):+    entry = _external_forward_entry(manifest, last_time, tt)+    if entry is None:+        return None+    try:+        shared, loaded = _load_external(view, entry, genes)+        if loaded is None:+            return None+        X_e, lab_e = loaded+        gidx = np.array([genes.index(g) for g in shared])+        types_e, pb_e = _pb(X_e, lab_e)+        # match anchor types to external types by pseudobulk Pearson r on shared genes+        A = pb_a[:, gidx]+        B = pb_e+        A = A - A.mean(axis=1, keepdims=True)+        B = B - B.mean(axis=1, keepdims=True)+        na = np.linalg.norm(A, axis=1, keepdims=True)+        nb = np.linalg.norm(B, axis=1, keepdims=True)+        na[na == 0] = 1.0+        nb[nb == 0] = 1.0+        C = (A / na) @ (B / nb).T+        best = C.argmax(axis=1)+        ok = C[np.arange(len(best)), best] >= MATCH_R+        print(f"[diag] external target {entry.get('id')}: matched {ok.sum()}/{len(ok)} anchor types", file=sys.stderr)+        if not ok.any():+            return None+        # type-level difference on full panel (external genes only)+        diff_t = np.zeros_like(pb_a)+        for k in range(len(ok)):+            if ok[k]:+                diff_t[k, gidx] = pb_e[best[k]] - pb_a[k, gidx]+        # cell-level: nearest external neighbour within matched type+        from sklearn.neighbors import NearestNeighbors++        shift = np.zeros_like(X_a)+        d_sub = X_a[:, gidx]+        types_a = sorted(set(lab_a.tolist()))+        for k in range(len(ok)):+            if not ok[k]:+                continue+            m = lab_a == types_a[k]+            if not m.any():+                continue+            tgt_m = lab_e == types_e[best[k]]+            if not tgt_m.any():+                continue+            nn = NearestNeighbors(n_neighbors=1).fit(X_e[tgt_m][:, : len(shared)])+            _, ind = nn.kneighbors(d_sub[m])+            cell_diff = np.zeros((m.sum(), X_a.shape[1]))+            cell_diff[:, gidx] = X_e[tgt_m][ind[:, 0]] - d_sub[m]+            type_diff = np.zeros((m.sum(), X_a.shape[1]))+            type_diff[:, gidx] = diff_t[k, gidx]+            shift[m] = BETA * type_diff + (1.0 - BETA) * cell_diff+        return shift+    except Exception as exc:  # never crash on the optional external path+        print(f"[diag] external path failed: {exc}", file=sys.stderr)+        return None   def main() -> None:@@ -26,14 +187,73 @@ def main() -> None:      manifest = load_manifest(args.data)     genes = panel_genes(args.data, manifest)+    prev, last, dt_ratio = extrap_step(manifest)+    tt = target_time(manifest)     stage = read_stage(args.data, anchor_entry(manifest), genes)     n = int(np.clip(stage.n, manifest["min_cells"], manifest["max_cells"]))     rng = np.random.default_rng(args.seed)     if n <= stage.n:         rows = np.sort(take(stage.labels, n, rng))-    else:  # fewer cells than min_cells: resample with replacement+    else:         rows = np.sort(rng.choice(stage.n, size=n, replace=True))-    write_t2(args.out, stage.X[rows].toarray(), stage.coords[rows], genes, seed=args.seed)++    X = stage.X[rows].toarray().astype(np.float32)+    coords = stage.coords[rows]++    if ALPHA > 0.0 or ALPHA_VEL > 0.0:+        lab = stage.labels[rows]+        types, pb_a = _pb(X.astype(np.float64), lab)+        shift = None+        src = "none"+        if ALPHA > 0.0:+            shift = _direction_external(+                args.data, manifest, genes, X.astype(np.float64), lab, pb_a, float(last["time"]), tt+            )+            if shift is not None:+                shift *= ALPHA+                src = "external"+        if shift is None and prev is not None and ALPHA_VEL > 0.0:+            src = "velocity"+            pstage = read_stage(args.data, prev, genes)+            Xp = pstage.X.toarray().astype(np.float64)+            _, pb_p = _pb(Xp, pstage.labels)+            tmap_p = {t: i for i, t in enumerate(_pb(Xp, pstage.labels)[0])}+            glob = pb_a.mean(axis=0) - Xp.mean(axis=0)+            v = np.tile(glob, (len(types), 1))+            for k, t in enumerate(types):+                if t in tmap_p:+                    v[k] = pb_a[k] - pb_p[tmap_p[t]]+            scale = ALPHA_VEL * (dt_ratio if (TIME_SCALE and dt_ratio) else 1.0)+            per_type = {t: scale * v[k] for k, t in enumerate(types)}+            shift = np.zeros_like(X, dtype=np.float64)+            for t in types:+                m = lab == t+                if m.any():+                    shift[m] = per_type[t]+            del Xp+        if shift is None:+            src = "copy_last(no usable forward direction)"+        if shift is not None:+            if CC_ZERO:+                cc = _cell_cycle_genes(args.data)+                idx = [i for i, g in enumerate(genes) if g in cc]+                if idx:+                    shift[:, idx] = 0.0+                print(f"[diag] cc-zero: {len(idx)} genes zeroed", file=sys.stderr)+            sd = X.astype(np.float64).std(axis=0)+            capv = CAP * np.maximum(sd, 1e-3)+            shift = np.clip(shift, -capv, capv)+            X = np.clip(X.astype(np.float64) + shift, 0.0, None).astype(np.float32)+            norms = np.linalg.norm(shift, axis=1)+            print(f"[diag] src={src} shift norm mean/p50/p95: {norms.mean():.3f} "+                  f"{np.percentile(norms,50):.3f} {np.percentile(norms,95):.3f}", file=sys.stderr)+            gmag = np.abs(shift).mean(axis=0)+            top = np.argsort(-gmag)[:20]+            print("[diag] top shifted genes: " + ", ".join(f"{genes[i]}({gmag[i]:.2f})" for i in top), file=sys.stderr)+        else:+            print(f"[diag] src={src}: no shift applied", file=sys.stderr)++    write_t2(args.out, X, coords, genes, seed=args.seed)   if __name__ == "__main__":

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

用到的知识库条目

编号标题出处
k016Degenerate-solution checks for population predictionsnotes/handover/02_知识学习路线.md
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k003Fused Gromov-Wasserstein mapping for spatial snapshots10.1038/s41586-024-08453-2

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

改了什么在父节点 copy_last 之上实现 T2HX-01 位移层(外部前向靶表达匹配位移 + 两输入速度回退),但代理视图内没有满足时间窗的外部样本、速度回退经验证有害而默认关(α_vel=0),实际提交的输出与父节点逐位相同。
各组分数的变化cell_state:噪声内(无变化):mmd_u 0.05832、variogram 0.05806 与父节点相同,得分各 6.25
expression_change:噪声内(无变化):de_score、de_direction 原始值均仍为 0,得分各 6.25,与父节点完全相同
local_spatial:噪声内(无变化):neighborhood_mmd 0.1126、得分 12.50,与父节点相同
shape_scale:噪声内(无变化):三项原始值与得分均与父节点相同(4.17×3)
family_idT2HX-01
假设是否成立否
经验
  1. 在代理视图内不存在'晚于末输入且不晚于目标'的外部样本时,按时间窗筛选外部靶的机制会静默退化为 copy_last,榜分 50.00 与父节点逐位相同,无法验证机制效果
  2. 代理上实测:E8.25→E8.75 的型级伪批量速度与真值 E8.75→E9.5 变化不相关甚至反相关(de_score 原始 −0.056 低于 chance,de_direction ≈0),且 DE 两项只看秩和符号、对 α 近似不变,所以速度外推任何 α 都拿不到 DE 收益、只赔 variogram(α_eff=0.45/0.9/1.5 → 49.0/48.7/48.3,全低于地板)
  3. 用 GO BP 关键词过滤增殖模块(44 基因置零)后 de_direction 转微正(+0.015,skill 0.504)但 de_score 更差(−0.139),总分 49.05 仍低于地板:去掉一个不可靠模块不足以把无信号的方向变成有信号
  4. 机制关闭对照(α=0)按 PLAN 复现了 50.00 且输出逐位等于父节点,说明管线在位移之外无副作用,对照本身是干净的
  5. 外推榜的本地代理无法检验位移方向的科学性,继续在代理上调参没有出路;方向来源必须换(外部前向数据或先验知识),而不是换阻尼系数
mechanism_active否
下一步建议
  1. 针对 expression_change / cell_state:把位移方向来源从'上一段速度'换成不依赖速度的先验——如用视图 prior(Reactome/TF 调控)构造分化程序的定性方向约束,只做符号一致的秩级调整,避免幅度位移赔 variogram
  2. 针对 expression_change:若正式 final 视图挂有前向外部样本(区间落在末输入与目标之间),直接在真实视图上启用 (a) 路径并用 1/33 型配对的匹配率做前置检查——匹配型数过低(<30%)时应放弃位移而非硬做
  3. 针对 cell_state:任何位移实验都先读 score_parts 的 variogram 与 mmd_u 原始值,型级常数位移(每型一个向量)会坍缩型内离散;如再做位移,须保留型内非零离散(β<1 混入细胞级差或加型内扰动),并以 variogram skill 不低于 0.48 为护栏

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

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

分析员

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

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数29
工具调用共 42 次:—
用时14 分
token 数输入 69,086 · 输出 12,370 · 思考 17,778
任务(第一行)按计划修改程序:表达匹配型伪批量位移外推(保坐标,T2HX-01)
最后的回答(摘录)
**做了什么**:在父节点(copy_last)上实现 PLAN 的 T2HX-01 位移层:优先用视图内"晚于末输入、不晚于目标"的外部样本做表达相关匹配(r≥0.5)的型级阻尼位移(坐标不动、逐基因 ±2σ 截断),两输入速度回退默认关,无可用方向时逐位等于 copy_last;含 α=0 对照与 GO 增殖模块过滤变体。

**查分结果**(proxy_noscale,用 5/20 次):默认输出 50.00(与父节点逐位相同,对照通过);型级速度 α_eff=0.45/0.9/1.5 → 49.0/48.7/48.3,de_score 原始 −0.056、de_direction ≈0——E8.25→E8.75 速度方向与真值不相关,任何 α 都无 DE 收益只赔 variogram;去掉增殖基因(44 个)后 49.05,de_direction 转微正但 de_score 更差。代理上速度外推确认无信号,故 (b) 默认关,节点行为 = 50.00 保底;外部前向路径 (a) 冒烟测试可运行(qiu E8.75 对齐、1/33 型配对成功),其效果本地不可验证。

**下一步最值得试**:代理无法检验外推方向(方法卡+本节点双重确认),本地继续调参没有出路;值得试的是不依赖"上一段速度"的方向来源——例如用 prior(Reactome/TF 调控)构造分化程序的定性方向约束,或在真实 final 视图上(若挂有前向外部样本如 MOSTA E9.5)直接评估 (a) 路径。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/3/engineer.jsonl (文件不在)

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时3 分
token 数输入 8,825 · 输出 1,410 · 思考 5,750
任务(第一行)为节点 n3(改进,父节点 n1)写改进计划 PLAN.json
最后的回答(摘录)
atial(方法卡已证 OT 插值坐标会把邻域组砸到 23–41,而本榜邻域+结构门最多影响 50 分)。",
 "approach": "在父节点 run.py 上加位移层,管线:1) 读 anchor 阶段(外推榜=最后观测阶段)。2) 目标位移来源按优先级回退:(a) external/ 里选一个阶段不超过靶时间、且区间完全落在心脏保留窗 (8.25,8.75)、(9.5,13.5] 之外的外部样本(如 E9.5 心脏),用其作为靶;(b) 若视图给两个输入阶段(final 情形),用两阶段按型伪批量差/时间间隔作为速度外推;(c) 都没有则原样输出=copy_last(proxy 单阶段时的退路,输出逐位等于父节点)。程序只读 manifest 的相对时间与区间字段,不写任何绝对阶段常数,伪装视图安全。3) 细胞配对按表达而非标签名:输入型与外部型用共有面板基因(要求≥50 个共有基因)上的伪批量 Pearson 相关匹配,阈值 r≥0.5,匹配失败即回退 (c)。4) 每个输入细胞 i:shift_i = α·[(1−β)·(x_ext_matched(i) − pb_t(i)) + β·(pb_ext_T(i) − pb_t(i))];X_i ← X_i + shift_i,负值截 0,|shift| 按基因上限取该基因输入标准差的 2 倍(防极端值打爆 mmd_u/variogram)。坐标一律不动——这是保邻域、保 d2_shape/occupancy_dice 的关键。5) 参数初值 α=0.7、β=0.5;网格 α∈{0.3,0.5,0.7,1.0}×β∈{0.3,0.5,0.7}。6) 流程:先跑 α=0 对照复现父节点 50.00;检查 manifest 确认外部样本存在、面板重叠与区间合规;先在 30% 分层子样本上粗筛网格,再用全量 vec-score 复核,预算≤20 次查分;选定参数后用 seed 1 复跑确认 >1 分优势(T2 噪声约 1 分,终选护栏要求种子均值超基线 1 分)。",
 "expected_groups": ["expression_change", "cell_state"],
 "risks": "1) 视图内可能没有可用外部样本,或外部面板/细胞类型与输入重叠太少 → 机制静默退化回 copy_last;Engineer 第一步就查 manifest 并打印匹配报告,尽早发现。2) 表达匹配把型配错 → 位移反向,DE 掉到 chance 附近;看 de_direction 是否低于 6.25 地板分即可发现。3) 过冲伤 mmd_u/neighborhood_mmd(重蹈节点 2 覆辙);每次查分都读 score_parts,邻域得分 <12.4/25 或 mmd_u 变差就降 α、增 β、收紧位移上限。4) 在 A 半过拟合参数;要求相邻网格点分数平滑、且 seed 1 复跑仍 >1 分。5) 本地小幅领先未必兑现,故只把目标定在 ≥52 而非贪大。",
 "family_id": "T2HX-01",
 "mechanism": "按表达相关把输入细胞型与外部(或更早阶段的)靶数据配对,计算型间伪批量差,逐细胞做 α 阻尼、β 型内收缩的位移,外推一天的心脏表达变化;坐标保持不动以维持表达—位置配对。",
 "vs_constant_shift": "每细胞位移取决于其所在型与表达匹配到的靶细胞/型,幅度与方向逐型逐细胞不同,β 收缩保留型内方差;全局常数位移对全体细胞相同,会被无变化保护(std(dp)<1%·std(dt) 时 DE 记 0)击中、且坍缩型内离散度伤 mmd_u。节点 2 的朴素 damped_shift(49.51)正是无匹配、无收缩的反例。",
 "mechanism_evidence": "打印诊断:逐细胞位移范数的分布(应远大于 0 且型间有差异,型内非零离散);位移最大的前 20 个基因与前几个细胞型;score_parts 前后对比——de_score/de_direction 原始值应脱离 0、mmd_u 原始值应下降;四组分中 expression_change 与 cell_state 上升而 local_spatial 保持 ≥50。若位移分布全零或各组纹丝不动,即机制未运行,先查匹配环节。",
 "mechanism_off_control": "同一程序以 α=0 运行:所有位移归零,输出应逐位等于父节点 copy_last,vec-score 应复现 50.00 且四组全 50;同时打印的位移诊断应全零。若 α=0 时分数偏离 50.00,说明管线在位移之外引入了副作用(如抽样、截断顺序变化),必须先修。"}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/3/researcher.jsonl (文件不在)

审查员

角色审查员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数16
工具调用共 15 次:—
用时2 分
token 数输入 28,424 · 输出 2,511 · 思考 4,217
任务(第一行)审查节点 n3 的程序是否越界读取、写死目标、钻评分器漏洞
最后的回答(摘录)
REVIEW.json written
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/3/reviewer.jsonl (文件不在)