单 Agent 运行
20261003-155754-t3-gata4-komix-a
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-155754-t3-gata4-komix-a |
|---|---|
| 方式?自动搜索:ERA 式搜索树,多个节点不断改进程序;单 Agent:一个 Agent 会话从头做到尾。 | 单 Agent |
| 框架 / 模型 | opencode / alibaba-token-plan-cn/qwen3.8-max |
| 题目?比赛的哪道题、哪个阶段,例如 T1:val 是第 1 题的验证阶段。 | T3:gata4 |
| 状态 | 已结束 |
| 后台服务?在 Spark 上以 systemd 用户服务运行的程序,例如每次运行和这个看板本身。 | vec-t3-gata4-komix-a-20261003-155754 |
| 开始 / 结束 | 10-03 15:57 / 10-03 17:15 |
| 预算 | 4 小时,最多 400 轮 |
| 启动时代码有未提交改动?启动时代码仓库有未提交的修改,这次运行不能完全按 git 版本复现。 | 否 |
| 最终文件 | T3__gata4.h5ad |
最终选择说明 SELECTION.md
终选说明 — run 20261003-155754-t3-gata4-komix-a
本 run 只做 boards: T3:gata4。
proxy_score T3:gata4 66.60
1. 交了什么
| 项 | 值 |
|---|---|
| 文件 | final/T3__gata4.h5ad(3.5 MB) |
| 方法 | komix(方法卡 v2 主线)+ self_zero 部件(--zero-gene Gata4) |
| 参数 | beta=0.55(卡起点)、k=0.65(卡起点)、seed=0、max_cells=7449(manifest 上限)、zero_gene=Gata4 |
| 组成 | 7449 细胞 = 4842 个 WT E8.75 真实细胞(按 WT 自身细胞类型分层无放回抽)+ 2607 个 Mab21l2 KO E9.5 真实细胞(类型名经 celltype_synonyms.json 映射后按 p^0.55 配额抽) |
| Gata4 列 | 全部置零(只把非零改成零;显式零已消除,.X nnz = 370,299) |
| 坐标 | 每个细胞带自己原来的 spatial_3D,(7449, 3),全有限(T3 坐标不排名) |
| 非零比例 | 0.09942,WT 输入 0.10498,比值 0.947(硬检查 0.8–1.25 通过) |
obs | 空(不带细胞类型列,见 §5) |
| 格式检查 | python scripts/verify_submission.py --input final/T3__gata4.h5ad --board T3:gata4 → SUCCESS |
final/proxy/T3__gata4.h5ad:同一方法、同一参数,在本地尺子的输入上生成,另加 --ko-exclude-half B
(尺子的真值是训练敲除样本 split_half(seed=0) 的第二半;不排除就等于把真值细胞交上去,分数没有意义)。
提交文件不加这个参数。
2. 替代评测(只记录,不作选择依据)
命令:python scripts/score_proxy.py --board T3:gata4 --pred final/proxy/T3__gata4.h5ad --name t3_komix_b055_k065_zGata4_exclB
| 组 | 权重 | skill | 原始指标 |
|---|---|---|---|
response_genes (de_score) | 30 | 0.598 | 0.3143(raw 0.4667,chance 0.2222,n_up 63 / n_dn 27) |
direction (de_direction) | 25 | 0.659 | 0.4782 |
magnitude (severity_slope) | 25 | 0.955 | −0.3167(r² 0.2475) |
cell_state (mmd_u,variogram) | 20 | 0.416 | 0.02308 / 0.026477 |
| 合计 | 100 | — | 66.60 |
这个数字不是官网分的估计。它是 lgo 尺子(参考 = WT E9.5,目标 = 官方训练数据里的 Mab21l2 KO 样本), 换了基因、换了阶段;方法卡已确认它与官网反序,所以只按任务书要求记录一次,不用来选参数、不用来选版本。 尺子的真值细胞与我们混进去的敲除细胞来自同一个样本,即使排除了第二半,阶段与批次成分仍然是循环的。
同一流程的对照(方法卡"读分要点"第 4 条:比较对象应是同流程的 wt_identity 程序):
komix k=1.0(只抽 WT E8.75、不混敲除细胞、不做任何编辑)在同一把尺子上 = 48.61
(response_genes 55.4 / direction 57.3 / magnitude 50.0 / cell_state 25.8)。
方法卡允许把 lgo875(参考与预测输入都换成 WT E8.75 的变体)记录一次作参考。我没有记录它:
本提交的 dp 与 lgo875 的 dt 是同一个量(lgo875 的 dt = pb(Mab21l2 KO E9.5) − pb(WT E8.75) = s + d_ko,
而 komix 的 dp = (1−k)·(s + d_ko)),即使加了 --ko-exclude-half B 排除真值细胞,阶段与批次成分仍然是
逐基因成比例的,记录出来必然贴近天花板,对本榜没有任何判别力;方法卡自己也说它"只有三个点、
与打分服务的视图机制相同,不是独立证据"。选择完全按 §3 的机制论证。
另外做了一次官方打分器的装载冒烟测试(veckit.score(task=T3, input=final/T3__gata4.h5ad, ...)):
提交文件的原始字节能被官方打分器读入,500 基因 / 7449 细胞 / 全部指标有限、.X 无负值无 NaN。
该次运行的目标用的是训练敲除样本本身,数字循环、无意义,没有记录成分数。
3. 为什么选这个版本
(a) 主线与参数按 run 任务书。 komix,β=0.55、k=0.65,是方法卡 v2 的起点,也是本 run(变体 a)被指派
去官网配额上检验的点。按方法卡"本地尺子"一节,β、k run 内不选,只能跨 run 比较。我另外做了一次
敏感性分析(analysis/t3_sensitivity.py、analysis/t3_sensitivity2.py,只用允许的训练数据构造替代真值,
不碰任何保留基因型)确认起点没有付出代价:在 dt = cos t·(−阶段方向) + sin t·(同阶段 KO 效应) + Gata4 完全丢失、
t = 0°…90° 的扫描上,k ∈ {0.5, 0.65, 0.8}、β ∈ {0.4, 0.55, 0.75} 的总分彼此相差都在 ±0.6 分以内
(k=0.5 均值 49.9,k=0.65 均值 49.7,k=0.8 均值 49.3),β 几乎不影响任何指标。
k 的作用还是不对称的:两项 DE 是秩指标,对 dp 整体缩放不变,所以 k 在 0.5–0.8 之间几乎不改变它们;
severity_slope 在 β ≤ 0 时被截到地板值,所以方向猜错时更小的 k 不会更差,方向猜对时更小的 k 让 β 更接近 1
(循环的装载测试里 β ≈ 0.94·(1−k),k=0.65 → β ≈ 0.33 → log β ≈ −1.1 → 强度组约 0.85 skill);
代价是 cell_state 更差(E9.5 细胞更多、与 E8.75 的真值阶段更不匹配)。三者相抵,所以 β、k 都留在卡起点,
不做 run 内选择。
(b) 打开 --zero-gene Gata4(卡的可选部件)——理由是机制,不是尺子分。
- 本榜被敲的基因是 Gata4,"被敲的基因不产生转录本"是敲除的定义性后果,不是文献推断。
- 官方训练数据里唯一的敲除样本直接给出了这套数据的敲除样本里被敲基因长什么样:Mab21l2 在同阶段 WT E9.5 的 pseudobulk = 0.976,在 KO 样本 = 0.008(99.2% 丢失;非零细胞比例 18.7% → 0.2%)。 据此真值里 dt(Gata4) ≈ −pb_WT875(Gata4) = −0.918,几乎肯定是响应基因中最大的下调之一 (阈值 |dt| ≥ 0.25 远超)。
- 不开这个部件时 komix 把唯一符号确定的基因预测反了:KO 细胞来自 E9.5,而 Gata4 从 E8.75 到 E9.5 上升 +1.166,混合后 dp(Gata4) = +0.18(上调)。开了以后 dp(Gata4) = −0.918,与真值同号同量级。
- 对三项响应指标都是正贡献:Gata4 在 pb(WT E8.75) 里排 85/500,不落在
de_score的表达量零假设 (±pb(ref))的下调集合里(n_dn 取 27/50/90/150 都不在),所以把它排成最下调是一次超出 chance 的命中;de_direction的秩偏相关里多一个符号正确的极端点;severity_slope只在真值响应基因上回归, Gata4 这一个点的局部斜率≈1(= 天花板),权重 dt²/Σdt² ≈ 2–4%,把 β 往上拉,同时抬高 r²(0.01 门槛)。 - 不稠密化:只把非零改成零,比值 0.947。
- 风险上界(反向证据,不是选择依据):在 lgo 尺子里被敲的基因是 Mab21l2,不是 Gata4,所以"置零 Gata4" 在那把尺子上是一次纯粹的错基因编辑。它的总分从 66.73 → 66.60(−0.13),两项 DE 完全不变 (
de_score0.3143、de_direction0.4782 一模一样),severity_slope反而更好 (−0.3486 → −0.3167,r² 0.2296 → 0.2475),只有 cell_state 略降(42.7 → 41.6)。 我的替代真值扫描里把 dt(Gata4) 设成 0(真值转录本没丢)也一样:61.2 → 61.3、42.9 → 43.0。 即:万一 Gata4 的等位基因不删转录本,代价约 0.1 分;如果删(同数据里的敲除样本就是这么表现的), 收益在扫描的各角度上从 +0.2 到 +27 分。 - 附带好处:真值细胞的 Gata4 列(近)全零,而不开部件的预测在这一维上比 WT 高 +0.18。Gata4 是高变异基因, 置零让
mmd_u/variogram在这一维上与真值一致(在 lgo 尺子上因为真值的 Gata4 正常表达,反而略差, 这与真值被敲基因不同是同一件事)。
(c) 没做的事。 全局位移迁移(把"敲除 − WT"的平均差加到 WT 上)、逐基因编辑(共表达 / 调控网络 / 手写靶基因表)、任何稠密化——方法卡禁做,本提交只有真实细胞拼接 + 单基因置零。 没有读、没有使用任何保留基因型(Gata4、β-catenin 敲除及表型相似扰动)的数据或由其得出的信息; 没有从 Mab21l2 尺子学"敲除应该怎么改 WT"的形状或方向。
4. 已知弱点(诚实记录,供跨 run 比较时读分)
- 主要风险:阶段漂移。 komix 的 dp = (1−k)·(s + d_ko),其中 s = pb(WT E9.5) − pb(WT E8.75)(阶段漂移), d_ko = pb(Mab21l2 KO E9.5) − pb(WT E9.5)(同阶段 KO 效应)。实测 |s| = 9.84 > |d_ko| = 5.64, corr(dp, s) = +0.76~0.83,即输出的变化量以"往 E9.5 走"为主。而这套数据里唯一能测到的同阶段 KO 效应 与阶段方向反相关(corr(s, d_ko) = −0.297;按细胞类型对照后 −0.462,"敲除看起来像发育延迟")。 Gata4 敲除的心脏表型(心肌变薄、分化受阻)更偏"延迟",所以 dp 与真值 dt 的符号相关不确定。 扫描下:真值以延迟为主(t≈0°)时本提交约 43 分(低于 50);以 KO 响应为主(t≈90°)时约 63 分。 这是方法卡主线自带的风险,本 run 的设计目的就是让官网配额来判它。
- 真实细胞混合下这个污染无法消除:任何非负权重组合都满足 dp = a·d_ko + (a+b)·s,b = 0(komix 的做法) 已经是每单位 KO 信号里阶段污染最小的选择;调 k 只改幅度不改方向。
- cell_state(20 分):输出含 35% 的 E9.5 细胞,真值是 E8.75 的突变体,阶段不匹配,
mmd_u/variogram很可能低于地板(lgo 尺子上 cell_state = 41.6,即使真值与混入细胞同阶段同样本)。 - Mab21l2 一列:混入的 KO 细胞里 Mab21l2 ≈ 0,混合后 dp(Mab21l2) ≈ −0.18,是真值里不存在的假下调 (幅度小,未必进 bottom-n_dn)。修它需要逐基因编辑(禁做),所以留着。
5. 提交格式的一个偏离(已核实无指标影响)
方法卡脚本 scripts/t3_komix.py 会在输出里写 obs["celltype"](同义表用于分组抽样与输出标签)。
任务书的"所有榜共同要求"写着不要带细胞类型列(主办方用自己的冻结分类器打标签),所以提交前用
analysis/strip_pred_labels.py 把 obs 列去掉。核实过这不改变任何指标:veckit score_h5ad.py 把预测的
obs["celltype"] 读进 pred_ct,而 T3/metrics_v2.score_task3_v2 从不使用 pred_ct
(composition_JSD 用的是在真值上训练的冻结探针作用于 .X)。脚本打印 nnz 前后一致
(370,299 → 370,299),.X / obsm["spatial_3D"] / var_names / uns["t3_komix"] 原样保留。
6. 外部数据披露
无。 只读了 data/raw/official/t3/{WT_E8.75,WT_E9.5,E9.5_mab21l2_ko}.h5ad(其中 WT_E8.75.h5ad、
WT_E9.5.h5ad 与 data/raw/official/t2_heart/E8.75.h5ad、E9.5.h5ad 是同一批文件的软链接)和
data/reference/panels/;另外读了 downloads/veckit/(官方本地打分器)与 workspace 自带的
modeling/、scripts/ 代码,用来确认指标定义和格式要求。
没有使用任何外部数据集、公开资源或预训练模型;没有联网;没有使用禁用时间窗内的数据;
没有使用任何保留基因型(Gata4、β-catenin 敲除,或表型相似的扰动)的数据或由其得出的信息。
输出含训练敲除样本(Mab21l2 KO E9.5,官方训练数据)的真实细胞:2607 / 7449 = ko_fraction 0.34998
(写在 final/T3__gata4.h5ad 的 uns["t3_komix"]:n、n_wt、n_ko、ko_fraction、ko_types、params)。
这些细胞保留自己的表达值和自己的坐标,不平均、不位移、不插值。
7. 复现
# 提交文件(final/T3__gata4.h5ad)
python scripts/t3_komix.py \
--wt data/raw/official/t3/WT_E8.75.h5ad \
--ko data/raw/official/t3/E9.5_mab21l2_ko.h5ad \
--out out/komix_b055_k065_zGata4_s0.h5ad \
--beta 0.55 --k 0.65 --seed 0 --max-cells 7449 --zero-gene Gata4
python analysis/strip_pred_labels.py --in-out out/komix_b055_k065_zGata4_s0.h5ad
cp out/komix_b055_k065_zGata4_s0.h5ad final/T3__gata4.h5ad
python scripts/verify_submission.py --input final/T3__gata4.h5ad --board T3:gata4
# 本地尺子文件(final/proxy/T3__gata4.h5ad),同一方法同一参数 + --ko-exclude-half B
python scripts/t3_komix.py \
--wt data/raw/official/t3/WT_E8.75.h5ad \
--ko data/raw/official/t3/E9.5_mab21l2_ko.h5ad \
--out final/proxy/T3__gata4.h5ad \
--beta 0.55 --k 0.65 --seed 0 --max-cells 7449 --zero-gene Gata4 --ko-exclude-half B
python analysis/strip_pred_labels.py --in-out final/proxy/T3__gata4.h5ad
python scripts/verify_submission.py --input final/proxy/T3__gata4.h5ad --board T3:gata4
python scripts/score_proxy.py --board T3:gata4 --pred final/proxy/T3__gata4.h5ad \
--name t3_komix_b055_k065_zGata4_exclB # -> 66.60(lgo 尺子,只记录)
# 机制与敏感性分析(不用任何保留数据)
python analysis/t3_diag.py # dp 分解、被敲基因在本数据里的表现、非零比例
python analysis/t3_gata4_mech.py # Gata4 的符号、chance 零假设、阶段漂移占比
python analysis/t3_sensitivity.py # 4 个替代真值 x beta/k/zero_gene 网格
python analysis/t3_sensitivity2.py # 角度扫描 + "真值 Gata4 没丢"的风险上界
python analysis/t3_stability.py # seed 稳定性(seed 0/1/2/3/7)与输出的类型组成上面两条生成命令已经原样重跑过一次(输出写到临时目录):.X、obsm["spatial_3D"]、var_names
与 final/ 里的两个文件逐元素相同,所以 komix 在给定参数与 seed 下是确定的,final/ 里的文件就是这两条命令的产物。
实验逐行记录见 workspace 根的 experiments.tsv(另有 score_proxy.py 自动追加的
notes/changelogs/experiments.tsv 和 modeling/experiments/logs/proxy/*.json)。
出处?这次运行用的代码、配置、数据和模型的指纹,靠它们可以原样找回并复现。
| 代码版本?运行锁定时代码仓库的 git 提交号;带 +dirty 表示当时有未提交的改动。 | bc1f100a4d3d9e4d4e1ee7eb6f5c2826c75710db |
|---|---|
| 版本标签?可提交运行在锁定的提交上打的 git 标签 run/<运行编号>,以后能原样找回代码。 | — |
| 配置文件 | agent/configs/experiments/g24_t2_t3/t3_komix_a.yaml 配置指纹 060ff0b14ec77b35 |
| 锁定指纹?启动时把配置、代码、提示词等全部锁定后算出的总指纹。 | 23e82c19aba2902d 锁定格式 v4 |
| 运行专用代码副本?启动时为这次运行单独检出的一份只读代码;运行全程只读它,不受主副本更新影响。 | 没有(这次运行早于运行专用代码副本功能,读的是启动时的代码副本) |
| 大模型?每个角色用的大模型;括号里是接口实际报告的模型名。 | Agent:alibaba-token-plan-cn/qwen3.8-max |
| 运行目录 | /home/spark-longxinyang/vec/runs/formal/20261003-155754-t3-gata4-komix-a 主机 spark-ad3f |
| 提交账本?notes/changelogs/submissions.tsv:每次上传官网的记录和返回的官网分。 | 这次运行没有提交过官网 |
| 迭代报告?运行结束后自动生成的中文复盘报告(notes/reports/runs)。 | 还没有迭代报告 |