乐于分享
好东西不私藏

autozyme-cli 源码解读

autozyme-cli 源码解读

引言

AutoZyme[1] 是一个自动加速科学计算函数的框架,保证优化后的结果和原版一模一样。它由两部分组成:autozyme_r / autozyme_py 负责生成加速补丁,autozyme-cli(命令行工具叫 zyme)负责驱动整个优化流程——初始化任务、测量基准、迭代加速、验证正确性。

本文聚焦 autozyme-cli,以一次真实的 Seurat NormalizeData 加速任务为线索,边讲实战边拆源码。

预印本:https://www.biorxiv.org/content/10.64898/2026.06.12.731250v1[2]

快速上手

安装

git clone https://github.com/ElliotXie/autozyme.gitcd autozyme && pip install -e autozyme_cli/

安装后获得 zyme 命令:

zyme --version   # zyme 0.3.1

两种使用方式

AutoZyme 的优化流程由编程代理(Claude Code、Codex、Cursor 等)驱动,CLI 负责执行和测量。有两种跑法:

自主模式:把一段提示词粘贴给代理,它自己跑完全流程:

Clone https://github.com/ElliotXie/autozyme.git,install the CLI (pip install -e autozyme/autozyme_cli/).I want to optimize FindAllMarkers from Seurat.Repo: https://github.com/satijalab/seuratRead and follow autozyme/autozyme_cli/zyme/prompts/manager/0_pipeline.md

管理器代理自动跑完脚手架 → 初始化 → 迭代 → 验证 → 打包,典型耗时 4–10 小时。

手动模式:自己建目录、跑 zyme init,然后逐阶段把提示词粘贴给代理:

mkdir test_normalizedata && cd test_normalizedatazyme init https://github.com/satijalab/seurat NormalizeData

我这次跑的是自主模式,目标就是 Seurat::NormalizeData

实战:加速 Seurat::NormalizeData

任务长什么样

zyme init 会在当前目录生成一组模板文件。init 代理填完内容后,核心的 task.yaml 长这样:

# task.yamltask: seurat_NormalizeDatatarget_repo: https://github.com/satijalab/seurattarget_function: Seurat::NormalizeDatasignature: NormalizeData(object seurat_obj, normalization.method "LogNormalize"scale.factor 10000)datasets:- {tier: small,  name: pbmc3k,  path: ./data/pbmc3k.rds}- {tier: mediumname: pbmc8k,  path: ./data/pbmc8k.rds}- {tier: large,  name: pbmc10kpath: ./data/pbmc10k.rds}- {tier: ood_large,  name: neuron10k,           path: ./data/neuron10k.rds}- {tier: ood_xlargename: tabula_muris_mergedpath: ./data/tabula_muris_merged.rds}metrics:- {name: pearson_datathreshold: 0.999comparator: gte}      # 归一化后的数据 Pearson 相关必须 >= 0.999- {name: max_abs_diff_datathreshold: 0.001comparator: lte}  # 逐元素最大差异 <= 0.001baseline_threads: [148]

几个关键信息:

  • 三个开发数据集(small/medium/large)用来做迭代优化,还有两个 OOD(out-of-distribution)数据集用来做最终验证。
  • 两个正确性指标:Pearson 相关系数和逐元素最大差异。LogNormalize 是确定性算术,理论上加速后的结果应该和原版完全一致。
  • 三个线程点(1/4/8):验证在不同并行度下加速是否稳定。

任务目录的完整结构:

seurat_NormalizeData/├── task.yaml              # 上面这个├── reference.R            # 基准脚本:用原版 Seurat 跑,产出参考输出├── evaluate.R             # 评估脚本:对比 pipeline 输出和参考输出├── pipeline/run.R         # 优化脚本:每一轮编辑的目标├── results.tsv            # 结果日志:每一轮的速度和指标├── reference_output_<tier>/ # 各数据层的参考输出(如 reference_output_small/)├── data/                   # 数据集├── memory/                 # 代理的"记忆"(发现、死胡同)└── .zyme/                  # 框架内部状态    ├── best.ref             # 当前最佳提交的 SHA    └── round.counter        # 轮次计数器

基准与剖析

优化前先得知道基准是多少、时间花在哪。zyme baseline reference 负责前者,zyme profile 负责后者。

基准行(round 0)由 zyme baseline reference 跑原版代码测得。它会运行 reference.R,用 Sys.time() 计时原版 Seurat::NormalizeData,同时把结果矩阵存到 reference_output_<tier>/(如 reference_output_small/)供后续对比:

round  commit    dataset  speed_sec  speedup_pct  status0      upstream  pbmc3k   1.046      0.0          baseline0      upstream  pbmc8k   1.832      0.0          baseline0      upstream  pbmc10k  2.841      0.0          baseline

pbmc3k(2700 个细胞)跑一次 1.046 秒,看起来不慢。但 1 秒里到底在算什么?代理接着跑了 zyme profile --backend full,这会启用 Rprof(R 内置采样式剖析器)记录整个调用栈,然后把结果归一化成 profile_history/<run-id>/profile.json。profile 实际耗时 1.7s,比基准的 1.046s 略高,这是 profiling 自身的采样开销。

profile.json 里最有用的是 layer_breakdown——按可编辑层次汇总时间分布:

层次
自耗时
占比
含义
library
0.63s
47%
Matrix 下标操作 + paste 命令日志
base-r
0.35s
26%
gc(中间拷贝触发的垃圾回收)
primitive
0.35s
26%
.Call
——真正的 C++ LogNorm 计算

library + base-r 加起来 74%,全是 R 层面的开销。再往下看 per_layer_top(每层的头号函数),能定位到具体是什么在吃时间:

函数
层次
自耗时
占比
在干什么
.Call
primitive
0.35s
26%
C++ LogNorm,真正的数学计算
..subscript.2ary
library:Matrix
0.33s
25%
SetAssayData
/LayerData 的矩阵下标拷贝
paste
library:backports
0.29s
22%
LogSeuratCommand
 格式化命令日志
gc
base-r
0.27s
20%
中间拷贝产生的垃圾回收

这就是那张 74% 表的由来。问题很清楚了:Seurat v5 的 NormalizeData 调用链是 NormalizeData(泛型)→ NormalizeData.Seurat → NormalizeData.Assay → NormalizeData.V3Matrix → LogNormalize.V3Matrix → LogNorm(C++),每一跳都触发 S3 方法分派、Matrix 下标操作和校验。真正的计算只占 26%。

优化迭代

知道时间花在哪之后,整个优化的核心就是一个循环:编辑 pipeline/run.R → zyme run 提交并测量 → 根据结果 zyme accept(保留)或 zyme reject(丢弃)。让我用这次实际的 results.tsv 来讲这个过程。

以下是 results.tsv 完整记录的每次提交与测量结果:

Round
Commit
Dataset
sec
∆%
Peak
Status
Hypothesis
0
upstream
pbmc3k
1.046
522M
baseline
upstream reference
0
upstream
pbmc8k
1.832
1066M
baseline
upstream reference
0
upstream
pbmc10k
2.841
1812M
baseline
upstream reference
1
2dc6ca5
pbmc3k
crash
crash
direct LogNorm C++ (patch_namespace 参数错)
2
a0af459
pbmc3k
crash
crash
direct LogNorm C++ (LogNorm 参数不匹配)
3
c5079d9
pbmc3k
crash
crash
direct LogNorm C++ (match.arg 校验没绕过)
4
99cc40f
pbmc3k
0.632
40.4%
538M
keep
bypass S3 dispatch + direct LogNorm
5
91a8c08
pbmc3k
0.325
69.4%
512M
keep
direct slot read, bypass LayerData
6
426fc62
pbmc3k
1.465
−38.1%
562M
discard
future_lapply 并行 (fork 开销 > 收益)
7
1ad2399
pbmc3k
0.328
69.1%
514M
discard
fused LogNormFast (噪声内)
7.1
91a8c08
pbmc8k
0.595
68.5%
947M
第 5 轮候选在 medium 验证
7.2
91a8c08
pbmc10k
1.318
59.5%
1544M
第 5 轮候选在 large 验证
8
f4769b1
pbmc3k
crash
crash
OpenMP-parallel (nbrOfWorkers 找不到)
9
ec471cf
pbmc3k
0.327
69.2%
516M
keep
OpenMP-parallel (修好)
9.1
ec471cf
pbmc8k
0.543
71.3%
951M
OpenMP 在 medium +3%
9.2
ec471cf
pbmc10k
1.263
61.2%
1548M
OpenMP 在 large +2%
10
92a5a42
pbmc3k
0.339
68.0%
516M
discard
-march=native -O3
 (噪声内)
11
c3ca3f5
pbmc3k
0.336
68.3%
515M
keep
float-precision LogNormOMP
11.1
c3ca3f5
pbmc8k
0.527
72.1%
951M
float 在 medium −2.9%
11.2
c3ca3f5
pbmc10k
1.040
68.0%
1548M
float 在 large −17.7%
12
044b09b
pbmc3k
0.338
68.1%
516M
discard
fused-pass (large 退步 +3.7%)
13
52fd7e3
pbmc3k
0.348
67.2%
516M
discard
raw CSC pointer (Eigen 已内联)
14
6a95be4
pbmc3k
0.340
68.0%
513M
keep
wire ZYME_THREADS via get_threads()
neuron10k
1.435
58.3%
OOD
OOD validate
tabula_muris
3.636
52.2%
OOD
OOD validate

对比 baseline,最终整体加速比如下:

数据集
基准
优化后
加速比
pbmc3k
1.046s
0.340s
3.16×
pbmc8k
1.832s
0.527s
3.59×
pbmc10k
2.841s
1.040s
3.13×
neuron10k (OOD)
3.444s
1.435s
2.40×
tabula_muris_merged (OOD)
7.606s
3.636s
2.09×

关键解读:

  • 3 crash → 1 keep:前 3 轮同一个 hypothesis 试了三次才跑通——LLM 写代码就是反复试错的过程。第 4 轮(99cc40f)首次成功绕过 S3 分派,加速 40.4%。
  • 峰值在第 5 轮:91a8c08 直接读 a@layers[["counts"]] 绕过 LayerData.Assay5 分派,0.632s → 0.325s(69.4%),之后所有轮次都在此基础上微调。
  • 跨层验证的价值:7.1/7.2 等行显示,在 small 上效果不明显的优化(如 OpenMP 在第 9 轮的 small 上 0.327s 没变化),在 medium/large 上可能有收益(+2~3%)。反之,small 上看似有益的优化,在 large 上可能退步(第 12 轮 fused-pass +3.7%)。
  • float 精度赢得 large:第 11 轮 c3ca3f5 在 small 上只是噪声水平,但在 large 上额外 −17.7%(1.263s → 1.040s),AVX2 的 2× SIMD 宽度在大数据量时才显优势。
  • OOD 泛化:neuron10k 58.3%、tabula_muris 52.2%,加速比从 development 的 ~70% 下降到 ~55%。bit-exact 全部通过。

验证可视化

zyme verify 在优化完成后生成验证报告,汇总速度、加速比、内存和正确性指标:

验证结果汇总

四面板解读(全部基于 small/pbmc3k 数据集,线程 1/4/8):

  • A. Wall time(左上):优化后(蓝色)从 1.1s 降到 0.34s,三个线程点一致的 ~3.2× 加速。注意 gray 条高度完全相同——基准测量在不同线程数下一致,说明 NormalizeData 原版本身就是单线程的,OpenMP/MKL 线程预算不影响原版时间。
  • B. Speedup factor(右上):三个线程点稳定在 3.2× 加速。虚线 1× 是"无加速"参考线。一致性说明优化没有引入线程竞争——LogNormOMPf 的 OpenMP 并行在 2700 列上可预测。
  • C. Peak memory(左下):优化后内存 514–515 MB 相比基准 522 MB 还低 ~1–2%,因为跳过了 LogSeuratCommand 的中间字符串拷贝和 LayerData 的临时矩阵分配。没有内存回退。
  • D. Correctness(右下):pearson_data = 1.000(阈值 ≥ 0.999),max_abs_diff_data = 0.00e+00(阈值 ≤ 0.001)。所有指标全绿,bit-exact 正确。

验证确认:加速是真实的(非作弊)、正确的(bit-exact)、在不同并行度下稳定的(线程无关)、且没有引入内存回归。

源码解读

CLI 入口与命令分发

入口定义在 pyproject.toml

[project.scripts]zyme = "zyme.cli:main"

cli.py 用 argparse 构建了一个子命令树。命令很多(40+),但按生命周期分成了清晰的五组:

# cli.py_TOP_LEVEL_GROUPS = [    ("Core loop",   ["init""run""dryrun""accept""reject""rollback""iterate"]),    ("Measurement", ["baseline""verify""attest""attest-sweep""backfill""validate"]),    ("Analysis",    ["status""plot""scan""registry""audit""cost""cost-capture"]),    ("Workflow",    ["dispatch""bench""prompt"]),    ("Packaging",   ["package"]),    ("Utility",     ["inspect-parallelism""datasets""publish-speedups"]),]

每个子命令通过 set_defaults(func=cmd_xxx) 绑定到处理函数。main() 只需要读 args.func 就能分发。commands/__init__.py 把所有实现重新导出,cli.py 统一导入。

::: {.callout-note} _GroupedHelpFormatter 拦截了 argparse 的子命令列表渲染,按生命周期分组显示。20 个命令挤成一堆没人看得下去,分组后一眼就能找到自己要的。 :::

任务脚手架:zyme init

cmd_init 做的事情很确定:把模板复制到目录、克隆上游仓库、检测语言、创建目录结构。它不生成任何内容——内容由 init 代理填充。

我跑 zyme init https://github.com/satijalab/seurat NormalizeData 时,它做了这些事:

# commands/init.py (核心逻辑)def cmd_init(args):    task_dir = Path(os.getcwd()).resolve()    task_name = task_dir.name  # seurat_NormalizeData# 1. 复制模板文件    template = FRAMEWORK_ROOT / "templates" / "task_template"for item in template.iterdir():        shutil.copy2(item, task_dir / item.name)  # 或 copytree# 2. 克隆上游仓库    git("clone", args.target_repo, str(task_dir / "upstream_repo"))# 3. 嗅探语言:DESCRIPTION → R, pyproject.toml → Python    language = _detect_language(upstream_repo_dir)# Seurat 有 DESCRIPTION → language = "R"# 4. 重命名模板:run.R.template → run.R,删掉 run.py.template# 5. 创建 data/、setup/、reference_output_<tier>/、memory/ 目录# 6. 初始化 git 仓库

这个设计的关键是确定性——所有脚手架工作由 CLI 完成,init 代理只需要关注"选择哪些数据集、写什么参考脚本、怎么评估正确性"这些需要判断的事情。

优化循环:zyme run → accept / reject

这是框架的心脏。用我跑的第 4 轮来举例——代理第一次成功绕过 S3 分派链:

# commands/run.py (简化)def cmd_run(args):    task_dir = task_dir_from_args(args)    _, best_ref, round_counter_file = zyme_state(task_dir)    hypothesis = args.hypothesis# "bypass S3 dispatch + direct LogNorm call + slot assignment"# 反作弊:提交前检查 pipeline/run.R 有没有"计时外提升"for _pipe_name in ("pipeline/run.R""pipeline/run.py"):        _violations = scan_pipeline_hoist(task_dir / _pipe_name)if _violations and not _hoist_exempt_reason:            sys.exit(2)  # 阻断,不会留下幽灵提交# 提交 pipeline 改动    git("add""pipeline/", cwd=task_dir)    git("commit""-m", hypothesis, cwd=task_dir)  # commit 99cc40f# 执行 pipeline + evaluate    log_content = run_task(task_dir, dataset_entry=tier_entry, thread=1)    speed_sec, peak_mb, metrics, status = parse_log(log_content)# 计算加速比    baseline_speed = get_baseline_speed(task_dir, "pbmc3k", thread=1)  # 1.046    speedup_pct = (1 - speed_sec / baseline_speed) * 100.0# 40.4# 写入 results.tsv,状态 = pending    append_results_row(results_tsv, {"round""4""commit""99cc40f","speed_sec""0.632""speedup_pct""40.4","status""pending","metrics_json"'{"pearson_data": 1.0, "max_abs_diff_data": 0.0}',        ...    })

代理看到结果后决定 zyme accept -m "bypassed S3 dispatch, 1.06s→0.63s"

# commands/run.pydef cmd_accept(args):# 验证 HEAD 匹配 pending 行的提交# (防止共享仓库中其他任务插入提交导致 best.ref 指错)    head_full = git("rev-parse""HEAD", cwd=task_dir)if not head_short.startswith(expected):        die("HEAD 与 pending 轮次不匹配")    best_ref.write_text(head_full)          # .zyme/best.ref → 99cc40f 的完整 SHA    update_last_status(results_tsv, "keep", args.description)# 额外检查:内存有没有回退、该不该重新 profile    _maybe_memory_regression_warning(...)    _maybe_reprofile_hint(...)

第 6 轮的 future_lapply 并行尝试被 reject 了:

# commands/run.pydef cmd_reject(args):# 脏树安全:有未提交改动就拒绝默认的 --hard resetif has_uncommitted and not args.keep_tree and not args.force:        die("工作树有未提交改动,选择 --keep-tree 或 --force")# 共享仓库安全:防止 reset 越过兄弟任务的提交    cross_task = _cross_task_commits_between(task_dir, best_sha)if cross_task and not args.force:        die("reject 会越过其他任务的提交...")    update_last_status(results_tsv, "discard", args.description)    git("reset""--hard", best_sha, cwd=task_dir)  # 回到 best.ref

reject 做了 git reset --hard,回到 best.ref 指向的提交。被拒绝的代码不会从历史中消失——它保存在 artifacts/006_426fc62_small/run.R 里,描述记录在 results.tsv 的 description 列。

::: {.callout-tip} accept 和 reject 中大量代码在处理共享仓库安全。当多个任务共用一个 git 仓库时,盲目的 git reset --hard 可能越过兄弟任务的提交。框架通过检测 best.ref..HEAD 区间内是否有任务目录之外的文件改动来防护。 :::

流水线执行器:runner.py

run_task() 负责实际运行 pipeline/run.R 并测量。以我的任务为例,它做的事情是:

# runner.py (简化)def run_task(task_dir, dataset_entry, thread=None, ...):    lang = detect_lang(task_dir)  # "R"# 1. 通过环境变量传递执行参数    env["ZYME_TIER"] = "small"    env["ZYME_DATA_PATH"] = "/path/to/data/pbmc3k.rds"    env["ZYME_REFERENCE_DIR"] = "/path/to/reference_output_small"if thread is not None:        env["ZYME_THREADS"] = "1"# 同步 BLAS/OMP/MKL 线程上限,避免不公平比较        env["OMP_NUM_THREADS"] = "1"        env["OPENBLAS_NUM_THREADS"] = "1"        env["MKL_NUM_THREADS"] = "1"# 2. 执行 pipeline/run.R(带内存 watchdog 和运行时间超时)    rc, stdout, stderr, peak_gb, timed_out, ... = _run_with_watchdog(        ["Rscript""run.R"], cwd=pipeline_dir, env=env,        mem_cap_gb=mem_cap_gb,   # 超内存就 SIGKILL 进程组        wall_cap_s=wall_cap_s,   # 按 tier 设置运行时间上限    )# 3. 执行 evaluate.R(对比 pipeline 输出和参考输出)    rc_eval, stdout_eval, _ = _run_evaluate(...)# 4. 汇总日志:提取 speed_sec / peak_mb / pearson_data / max_abs_diff_datareturn "\n".join(log_parts) + _summary(speed, peak, status)

::: {.callout-note} run_task 通过环境变量而非命令行参数传递执行参数。pipeline/run.R 读 Sys.getenv("ZYME_TIER") 就能知道自己在跑哪个数据层,读 Sys.getenv("ZYME_THREADS") 就知道线程预算。这让 pipeline 代码保持简洁。 :::

看看优化后的代码长什么样

14 轮迭代后,最终保留的 pipeline/run.R 里的核心逻辑是这样的:

# pipeline/run.R — 最终优化版本# 用 sourceCpp 编译一个 OpenMP 并行 + float 精度的 C++ 函数Rcpp::sourceCpp(code '#include <RcppEigen.h>#include <omp.h>// [[Rcpp::depends(RcppEigen)]]// [[Rcpp::plugins(openmp)]]// float 精度:AVX2 一次处理 8 个 float vs 4 个 double// [[Rcpp::export]]SparseMatrix<double> LogNormOMPf(SparseMatrix<double> data,                                  double scale_factor, int n_threads) {  int n = data.outerSize();  float sf = (float)scale_factor;  #pragma omp parallel for num_threads(n_threads)  for (int k = 0; k < n; ++k) {    float colSum = 0.0f;    for (SparseMatrix<double>::InnerIterator it(data, k); it; ++it)      colSum += (float)it.value();    float norm = sf / colSum;    for (SparseMatrix<double>::InnerIterator it(data, k); it; ++it)      it.valueRef() = (double)log1pf(v * norm);  }  return data;}')# 覆盖 Seurat 的 NormalizeData.Seurat 方法NormalizeData.Seurat <- function(object, assay NULL,    normalization.method "LogNormalize", scale.factor 1e4, ...{  a <- object[[assay]]  counts <- a@layers[["counts"]]# 直接读 slot,跳过 LayerData 分派  n_threads <- get_threads(default 1L)# 从框架获取线程数if (n_threads 1L && ncol(counts1000L{    norm.data <- LogNormOMPf(counts, scale.factor, n_threads)else {# 小数据集用原版 LogNorm    LogNorm_fn <- getFromNamespace("LogNorm""Seurat")    norm.data <- LogNorm_fn(counts, scale_factor = scale.factor, ...)}  a@layers[["data"]<- norm.data          # 直接写 slot,跳过 SetAssayData  object@assays[[assay]<- areturn(object)}# 注册覆盖patch_namespace("NormalizeData.Seurat""Seurat", NormalizeData.Seurat)# 执行(和 reference.R 完全一样的调用方式)t0 <- Sys.time()result <- NormalizeData(obj, normalization.method "LogNormalize",                        scale.factor 10000, verbose FALSE)

优化做的事情可以概括为:绕过 5 层 S3 方法分派,直接调 C++ 的 LogNorm,用 slot 赋值替代 Matrix 下标操作,跳过 LogSeuratCommand 命令日志,再叠加 OpenMP 并行和 float 精度 SIMD

状态管理:.zyme/ 目录

zyme accept 和 zyme reject 为什么能精确地推进或回退?秘密在 .zyme/ 目录。整个优化过程的状态都集中在这里:

文件
用途
我任务里的值
best.ref
当前最佳提交的完整 SHA,accept 推进、reject 回退就靠它
d89f20d5...
round.counter
决策轮次计数,每次 accept/reject 自增
14
audit.jsonl
每条 zyme 调用的审计日志(97KB)
50+ 条记录
baselines_history.tsv
基准测量史:每次 record/rebench 都追加一行
22 行
baseline_noise.json
基准运行时间噪声校准
small CV=1.78%, medium CV=0.50%
version_check.json
上游包版本校验,确保优化的版本和实际使用的一致
Seurat 5.5.1.9000
setup_audit.log
setup 阶段提交审计
记录线程策略和 OOD 数据集选择

其中最重要的是 best.ref 和 baseline_noise.json

best.ref 存的就是一个 git SHA。zyme accept 把当前 HEAD 写进去,zyme reject 读出来做 git reset --hard。一个文件、一个 SHA,就是整个状态机的核心。

baseline_noise.json 记录基准运行的测量噪声——同一段代码跑 5 次,每次时间不会完全一样,这个波动就是噪声:

{"tiers"{"small"{"1"{"dataset_name""pbmc3k","n_reps"5,"speed_mean"1.061,"speed_stdev"0.019,"speed_cv"0.018}}}}

5 次基准测试的 CV = 标准差/均值 = 1.8%,即单次测量有约 ±1.8% 的随机波动。差异需超过 3×CV ≈ 5.4% 才可信。第 7 轮 0.328s 反而比第 5 轮 0.325s 慢了 0.9%,在噪声窗口内,无法判断真实变化,故 discard。

反作弊:怎么防止代理"作弊"

AutoZyme 最大的挑战不是让代理写出更快的代码,而是防止代理制造不真实的加速。这次任务里,反作弊系统真的抓到了问题。

静态检查:三道防线

第一道fingerprint.py 检查 reference.R 有没有合成数据膨胀(比如 [expr] * 10000 把小数据重复放大来制造虚假加速)。用 Python AST 检查列表重复、np.tile、重复循环三种模式。

第二道hoist_audit.py 检查有没有把工作移出计时器。比如这种作弊:

# 在 t0 之前预计算上游的内部函数.precomputed <- getFromNamespace(".decontxInitializeZ""celda")(counts, ...)install_override(".decontxInitializeZ""celda"function(...) .precomputed)t0 <- Sys.time()res <- decontX(counts, ...)# init 现在是 O(1),但真实用户收不到这个加速

这道检查在 zyme run提交之前运行,违规直接 exit 2,不留下幽灵提交。我的任务里 pipeline 通过了这道检查。

第三道argdiff.py 检查 pipeline 传给目标函数的参数有没有和基准调用不同(比如偷偷把 .tsv 换成 .pickle)。

LLM 驱动的对抗性审计:zyme validate

静态检查之外,框架还会在阶段结束时跑一个独立的 LLM 代理来审查整个任务。这就是 zyme validate

我的任务在 iterate 阶段结束后跑了验证,结果抓出了一个 LIKELY_HACK

# validate.tsvseverity     category                                    mechanism_summaryWEAK         Threshold margin                            max_abs_diff=1e-3 太宽松,bfloat16 降精度可能通过WEAK         No OOD tier                                 三个数据集都是 PBMC(后来加了 OOD)LIKELY_HACK  Fixture-only behavior                       normalization.method 参数被接受但从不读取WEAK         Output contract gap                         跳过了 LogSeuratCommand,但 evaluator 不检查命令日志

LIKELY_HACK 的发现是:我的 NormalizeData.Seurat 覆盖函数在参数列表里接受 normalization.method,但函数体里从来不读这个参数——无论传什么值都走 LogNormalize 路径。如果用户传 normalization.method = "RC",上游会走完全不同的归一化逻辑,但我的覆盖函数会悄悄忽略这个参数。

这个发现是合理的。虽然在我的测试场景里不会触发(因为只用 LogNormalize),但对于一个要发布给所有人用的加速补丁来说,忽略参数确实是 hack 行为。

审计结果按严重程度排序:PASS < WEAK < LIKELY_HACK < FAILLIKELY_HACK 和 FAIL 会阻断流程,需要修复后才能继续。

多代理调度:dispatch

前面讲的都是单个任务怎么跑。如果你要同时优化多个函数——比如先 NormalizeData,再 FindAllMarkers——zyme dispatch 就是一个队列管理器,按顺序逐个跑完。

它的工作方式很简单:找到机器上安装的 agent CLI(支持 Claude Code、Codex、Cursor,自动检测),以子进程的方式启动它,把任务目录作为工作目录。然后逐行读 agent 的输出,检测它是不是卡住了(默认 15 分钟没输出就标记停滞),等它跑完再启动下一个任务。

flowchart TD    A["构建任务队列"] --> B{"--detach?"}    B -->|是| C["双 fork 守护化"]    B -->|否| D["前台运行"]    C --> D    D --> E{"有待处理任务?"}    E -->|是| F["等待 RAM + 磁盘释放"]    F --> G["启动 agent CLI<br/>cwd=task_dir"]    G --> H["逐行读取 stdout<br/>停滞检测"]    H --> I{"结果"}    I -->|停滞| J["标记停滞"]    I -->|完成| K["标记 done/failed"]    J --> K    K --> L["重算 ETA"]    L --> E    E -->|否| M["退出"]

我的任务在 pipeline_runs/ 下留了一份调度日志,记录了各阶段的推进:

## Log- Run created. Starting scaffold via zyme init.- Scaffold completed: tasks/seurat_NormalizeData- Init phase completed: datasets=3, refs_present, pipeline+evaluate real.- Validate init: 2 WEAK findings (non-blocking)- Iterate phase completed: 14 rounds (5 accepts, 9 rejects). Best: 72.5% (pbmc8k).- Validate gate: PASS (no hacks detected). Advancing to scaling.

::: {.callout-tip} dispatch 的崩溃恢复策略很实用:主控崩溃时,先检查工作 agent 还在不在跑——如果还在跑,直接重新等它;如果已经跑完了,推进到下一阶段;最后才考虑恢复会话。因为工作 agent 跑了几十轮迭代积累的状态是没法重建的,保护它比保护主控重要。 :::

优化流水线全景

阶段
做了什么
1. Scaffold
zyme init
 克隆 Seurat、复制模板、检测 R 语言
2. Init
选 3 个 PBMC 数据集,写 reference.R / evaluate.R / run.R,跑基准(1.046s),profile 发现 74% 是 R 开销
3. Validate Init
LLM 审计发现 2 个 WEAK:指标阈值太宽、缺 OOD 数据集
4. Iterate
14 轮 run → accept/reject 循环,5 轮保留 / 9 轮丢弃,反作弊全程拦截,最终 0.336s、3.16× 加速
5. Validate Gate
LLM 审计抓到 LIKELY_HACK(参数被忽略)和 1 个 WEAK(命令日志缺失)
6. Scaling
OOD 数据集 neuron10k/tabula_muris 验证 2-2.4×,线程矩阵 1/4/8 验证稳定性
7. Package
提取补丁到 autozyme_r,跨平台验证

设计哲学

代理决策 + CLI 执行

框架的一个核心设计是把决策和执行分开。代理负责想:提出假设、写代码、看结果好不好;CLI 负责做:git 提交、跑基准、记数据、做安全检查。这些操作不可逆,不能让代理自己来。“该绕什么、不该绕什么”的判断是代理做的,而 git 提交、跑 pipeline、算加速比、写 results.tsv 这些都由 CLI 确定性地完成,代理不用操心。

去掉 S3 分派虽然能加速,但降低了代码可读性。实际代码中需要权衡利弊,而不是一味绕过。

防御性编程

代码库里有大量防御性编程。以 reject 为例:

  • 脏树安全git reset --hard 前检查工作树有没有未提交改动
  • 共享仓库安全:检测 reset 会不会越过兄弟任务的提交
  • 崩溃行安全:崩溃行不携带 speed/metrics 数据,防止 speed_sec=0 被误算成 100% 加速

这些边界情况看似琐碎,但它们防止的是"加速看起来很好、实际是 bug"这类最难发现的问题。

记忆系统

这次任务让我印象深刻的是 memory/ 目录的设计。代理在迭代过程中把发现写到 discoveries.md,下次会话开始时先读这个文件,跳过重复的探索成本。

比如代理发现"LogNorm 没有从 Seurat 命名空间导出,需要 getFromNamespace"这个坑后,把它记在 discoveries.md 里。如果会话中断重开,新的代理不需要重新踩这个坑。

dead_ends.md 记录被证伪的方向("future_lapply 并行在 2700 个细胞上因 fork 开销而更慢"),防止后续轮次重复尝试。

参考资料

[1] https://github.com/ElliotXie/autozyme

[2] https://www.biorxiv.org/content/10.64898/2026.06.12.731250v1

基本 文件 流程 错误 SQL 调试
  1. 请求信息 : 2026-06-30 10:14:48 HTTP/1.1 GET : https://www.yeyulingfeng.com/a/817566.html
  2. 运行时间 : 0.513203s [ 吞吐率:1.95req/s ] 内存消耗:4,924.87kb 文件加载:145
  3. 缓存信息 : 0 reads,0 writes
  4. 会话信息 : SESSION_ID=5dfc7eb960afaecd553934a85f335e5c
  1. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/public/index.php ( 0.79 KB )
  2. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/autoload.php ( 0.17 KB )
  3. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_real.php ( 2.49 KB )
  4. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/platform_check.php ( 0.90 KB )
  5. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/ClassLoader.php ( 14.03 KB )
  6. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/composer/autoload_static.php ( 6.05 KB )
  7. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper.php ( 8.34 KB )
  8. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/helper.php ( 2.19 KB )
  9. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/ralouphie/getallheaders/src/getallheaders.php ( 1.60 KB )
  10. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/helper.php ( 1.47 KB )
  11. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/stubs/load_stubs.php ( 0.16 KB )
  12. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Exception.php ( 1.69 KB )
  13. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Facade.php ( 2.71 KB )
  14. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/deprecation-contracts/function.php ( 0.99 KB )
  15. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap.php ( 8.26 KB )
  16. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/polyfill-mbstring/bootstrap80.php ( 9.78 KB )
  17. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/Resources/functions/dump.php ( 1.49 KB )
  18. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-dumper/src/helper.php ( 0.18 KB )
  19. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/symfony/var-dumper/VarDumper.php ( 4.30 KB )
  20. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions_include.php ( 0.16 KB )
  21. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/guzzlehttp/guzzle/src/functions.php ( 5.54 KB )
  22. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/App.php ( 15.30 KB )
  23. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-container/src/Container.php ( 15.76 KB )
  24. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/container/src/ContainerInterface.php ( 1.02 KB )
  25. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/provider.php ( 0.19 KB )
  26. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Http.php ( 6.04 KB )
  27. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Str.php ( 7.29 KB )
  28. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Env.php ( 4.68 KB )
  29. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/common.php ( 0.03 KB )
  30. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/helper.php ( 18.78 KB )
  31. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Config.php ( 5.54 KB )
  32. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/alipay.php ( 3.59 KB )
  33. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Env.php ( 1.67 KB )
  34. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/app.php ( 0.95 KB )
  35. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cache.php ( 0.78 KB )
  36. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/console.php ( 0.23 KB )
  37. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/cookie.php ( 0.56 KB )
  38. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/database.php ( 2.48 KB )
  39. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/filesystem.php ( 0.61 KB )
  40. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/lang.php ( 0.91 KB )
  41. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/log.php ( 1.35 KB )
  42. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/middleware.php ( 0.19 KB )
  43. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/route.php ( 1.89 KB )
  44. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/session.php ( 0.57 KB )
  45. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/trace.php ( 0.34 KB )
  46. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/config/view.php ( 0.82 KB )
  47. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/event.php ( 0.25 KB )
  48. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Event.php ( 7.67 KB )
  49. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/service.php ( 0.13 KB )
  50. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/AppService.php ( 0.26 KB )
  51. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Service.php ( 1.64 KB )
  52. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Lang.php ( 7.35 KB )
  53. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/lang/zh-cn.php ( 13.70 KB )
  54. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/Error.php ( 3.31 KB )
  55. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/RegisterService.php ( 1.33 KB )
  56. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/services.php ( 0.14 KB )
  57. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/PaginatorService.php ( 1.52 KB )
  58. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ValidateService.php ( 0.99 KB )
  59. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/service/ModelService.php ( 2.04 KB )
  60. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Service.php ( 0.77 KB )
  61. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Middleware.php ( 6.72 KB )
  62. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/initializer/BootService.php ( 0.77 KB )
  63. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Paginator.php ( 11.86 KB )
  64. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-validate/src/Validate.php ( 63.20 KB )
  65. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/Model.php ( 23.55 KB )
  66. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Attribute.php ( 21.05 KB )
  67. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/AutoWriteData.php ( 4.21 KB )
  68. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/Conversion.php ( 6.44 KB )
  69. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/DbConnect.php ( 5.16 KB )
  70. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/ModelEvent.php ( 2.33 KB )
  71. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/concern/RelationShip.php ( 28.29 KB )
  72. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Arrayable.php ( 0.09 KB )
  73. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/contract/Jsonable.php ( 0.13 KB )
  74. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/model/contract/Modelable.php ( 0.09 KB )
  75. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Db.php ( 2.88 KB )
  76. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/DbManager.php ( 8.52 KB )
  77. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Log.php ( 6.28 KB )
  78. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Manager.php ( 3.92 KB )
  79. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerTrait.php ( 2.69 KB )
  80. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/log/src/LoggerInterface.php ( 2.71 KB )
  81. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cache.php ( 4.92 KB )
  82. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/psr/simple-cache/src/CacheInterface.php ( 4.71 KB )
  83. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/helper/Arr.php ( 16.63 KB )
  84. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/driver/File.php ( 7.84 KB )
  85. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/cache/Driver.php ( 9.03 KB )
  86. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/CacheHandlerInterface.php ( 1.99 KB )
  87. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/Request.php ( 0.09 KB )
  88. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Request.php ( 55.78 KB )
  89. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/middleware.php ( 0.25 KB )
  90. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Pipeline.php ( 2.61 KB )
  91. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/TraceDebug.php ( 3.40 KB )
  92. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/middleware/SessionInit.php ( 1.94 KB )
  93. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Session.php ( 1.80 KB )
  94. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/driver/File.php ( 6.27 KB )
  95. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/SessionHandlerInterface.php ( 0.87 KB )
  96. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/session/Store.php ( 7.12 KB )
  97. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Route.php ( 23.73 KB )
  98. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleName.php ( 5.75 KB )
  99. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Domain.php ( 2.53 KB )
  100. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleGroup.php ( 22.43 KB )
  101. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Rule.php ( 26.95 KB )
  102. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/RuleItem.php ( 9.78 KB )
  103. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/route/app.php ( 3.94 KB )
  104. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/Route.php ( 4.70 KB )
  105. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/dispatch/Controller.php ( 4.74 KB )
  106. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/route/Dispatch.php ( 10.44 KB )
  107. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Index.php ( 9.87 KB )
  108. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/BaseController.php ( 2.05 KB )
  109. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/facade/Db.php ( 0.93 KB )
  110. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/connector/Mysql.php ( 5.44 KB )
  111. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/PDOConnection.php ( 52.47 KB )
  112. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Connection.php ( 8.39 KB )
  113. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/ConnectionInterface.php ( 4.57 KB )
  114. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/builder/Mysql.php ( 16.58 KB )
  115. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Builder.php ( 24.06 KB )
  116. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseBuilder.php ( 27.50 KB )
  117. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/Query.php ( 15.71 KB )
  118. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/BaseQuery.php ( 45.13 KB )
  119. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TimeFieldQuery.php ( 7.43 KB )
  120. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/AggregateQuery.php ( 3.26 KB )
  121. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ModelRelationQuery.php ( 20.07 KB )
  122. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ParamsBind.php ( 3.66 KB )
  123. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/ResultOperation.php ( 7.01 KB )
  124. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/WhereQuery.php ( 19.37 KB )
  125. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/JoinAndViewQuery.php ( 7.11 KB )
  126. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/TableFieldInfo.php ( 2.63 KB )
  127. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-orm/src/db/concern/Transaction.php ( 2.77 KB )
  128. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/driver/File.php ( 5.96 KB )
  129. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/LogHandlerInterface.php ( 0.86 KB )
  130. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/log/Channel.php ( 3.89 KB )
  131. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/event/LogRecord.php ( 1.02 KB )
  132. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-helper/src/Collection.php ( 16.47 KB )
  133. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/facade/View.php ( 1.70 KB )
  134. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/View.php ( 4.39 KB )
  135. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/app/controller/Es.php ( 3.30 KB )
  136. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Response.php ( 8.81 KB )
  137. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/response/View.php ( 3.29 KB )
  138. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/Cookie.php ( 6.06 KB )
  139. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-view/src/Think.php ( 8.38 KB )
  140. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/framework/src/think/contract/TemplateHandlerInterface.php ( 1.60 KB )
  141. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/Template.php ( 46.61 KB )
  142. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/driver/File.php ( 2.41 KB )
  143. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-template/src/template/contract/DriverInterface.php ( 0.86 KB )
  144. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/runtime/temp/c935550e3e8a3a4c27dd94e439343fdf.php ( 31.50 KB )
  145. /yingpanguazai/ssd/ssd1/www/wwww.yeyulingfeng.com/vendor/topthink/think-trace/src/Html.php ( 4.42 KB )
  1. CONNECT:[ UseTime:0.001021s ] mysql:host=127.0.0.1;port=3306;dbname=wenku;charset=utf8mb4
  2. SHOW FULL COLUMNS FROM `fenlei` [ RunTime:0.001409s ]
  3. SELECT * FROM `fenlei` WHERE `fid` = 0 [ RunTime:0.015323s ]
  4. SELECT * FROM `fenlei` WHERE `fid` = 63 [ RunTime:0.020772s ]
  5. SHOW FULL COLUMNS FROM `set` [ RunTime:0.001665s ]
  6. SELECT * FROM `set` [ RunTime:0.005942s ]
  7. SHOW FULL COLUMNS FROM `article` [ RunTime:0.001514s ]
  8. SELECT * FROM `article` WHERE `id` = 817566 LIMIT 1 [ RunTime:0.029202s ]
  9. UPDATE `article` SET `lasttime` = 1782785688 WHERE `id` = 817566 [ RunTime:0.024416s ]
  10. SELECT * FROM `fenlei` WHERE `id` = 64 LIMIT 1 [ RunTime:0.002286s ]
  11. SELECT * FROM `article` WHERE `id` < 817566 ORDER BY `id` DESC LIMIT 1 [ RunTime:0.031452s ]
  12. SELECT * FROM `article` WHERE `id` > 817566 ORDER BY `id` ASC LIMIT 1 [ RunTime:0.011288s ]
  13. SELECT * FROM `article` WHERE `id` < 817566 ORDER BY `id` DESC LIMIT 10 [ RunTime:0.062484s ]
  14. SELECT * FROM `article` WHERE `id` < 817566 ORDER BY `id` DESC LIMIT 10,10 [ RunTime:0.040285s ]
  15. SELECT * FROM `article` WHERE `id` < 817566 ORDER BY `id` DESC LIMIT 20,10 [ RunTime:0.095133s ]
0.514955s