Karpathy 睡了一觉,Agent 跑了 100 个实验,autoresearch 只靠三个文件

发布于 2026年07月29日 02:14 #Github 解读#Agent 框架 原文链接

Karpathy 睡了一觉,Agent 跑了 100 个实验,autoresearch 只靠三个文件 封面图
  • 三个文件(prepare.py、train.py、program.md)分工明确,Agent 只能修改 train.py,其余锁定
  • 固定 5 分钟墙钟时间预算和 val_bpb 指标,确保不同实验直接可比且公平
  • Muon 优化器对矩阵参数做正交化,配合分参数组学习率,作为优化起点
  • program.md 中的 NEVER STOP 指令让 Agent 不间断运行,但依赖 Agent runtime 服从度
  • git 棘轮机制:实验改进则保留 commit,否则 reset,结果记录在 results.tsv 中

2026 年 3 月,Karpathy 在仓库顶部写了段很像科幻小说的序言。他说未来的前沿 AI 研究已经完全交给在天上算力集群里飞驰的 Agent 蜂群,人类那时靠「开组会」用声波同步进度,那个时代早已过去。然后他补了一句,这个仓库就是「一切开始的地方」。

很多人把这段话当营销文案看。其实吧,你真去读代码会发现,他不是在讲故事,是在描述 autoresearch 真正在做的事。你睡前给 Agent 一台 H100,它改代码,跑 5 分钟训练,看指标涨了没,涨了就留 commit,跌了就 reset,然后继续。你醒来看到一张表格,记着它夜里跑了多少个实验。

92232 个 star,13171 个 fork,9 个贡献者。这个项目不是又一个 prompt 框架,它把「AI 研究」这件事的执行权从人手里拿走了一部分。

三个文件撑起一个自主研究组织

autoresearch 的仓库结构干净到让人意外。真正重要的文件只有三个。

prepare.py 是只读的。它下载数据,训练 BPE tokenizer,提供 dataloader 和评估函数。里面锁死了几个不可动的常量,MAX_SEQ_LEN = 2048 是上下文长度,EVAL_TOKENS = 40 * 524288 是验证集评估用的 token 数。evaluate_bpb 函数也在这里,它是整个系统的「真值」,Agent 改什么都不能动它。

train.py 是唯一允许被改的文件。完整的 GPT 模型,优化器,训练循环,全塞在这一个文件里。Agent 的全部创造力只能挥洒在这里。

program.md 是给人改的。它本质是一份「研究主管」的工作说明书,告诉 Agent 你要做什么,规则是什么。

这个分工的设计意图很清楚。把可变面收窄到一个文件,让 diff 可审查,让实验可归因。你想想看,传统研究员改的是散落在几十个文件里的代码,这里 Agent 只能动 train.py,变量被锁死在可控范围内。传统研究员改的是散落在几十个文件里的代码,这里 Agent 只能动 train.py,变量被锁死在可控范围内。

5 分钟预算,让一切可比

autoresearch 最聪明的设计决策是「固定时间预算」。说真的,这个决策一开始看着很怪。

不管 Agent 改了模型大小,改了 batch size,还是换了优化器,每次训练都精确跑满 5 分钟墙钟时间(不含启动和编译)。坦白讲,Karpathy 在 program.md 里把这个规则刻得很死,超时 10 分钟就直接 kill 当失败处理。

为什么这么做。因为只有时间固定,实验才直接可比。你在 H100 上跑,它在 A100 上跑,架构改动效果能不能显现,5 分钟后的 val_bpb 会说话。代价也写在 README 里,你的结果和别人的结果没法横比,因为硬件不同跑的步数不同。

val_bpb 这个指标也值得说一句。bits per byte,验证集上每个字节的平均比特数,越低越好。它和词表大小无关,所以 Agent 把 vocab 从 8192 砍到 4096 这种结构性改动,评估依然公平。这个细节说明 Karpathy 在设计评估协议时就预判了 Agent 会怎么「钻空子」。

一夜大约 12 个实验每小时,睡觉 8 小时就是近百个实验。这就是标题里那个数字的来源,不是吹的,是算出来的。

Muon 优化器,train.py 里的硬骨头

train.py 里的优化器不是普通的 AdamW,是 Muon。我一直觉得这个细节被很多介绍文章一笔带过了,但它恰恰是这个模型能跑出好结果的关键。

Muon 的核心是对矩阵参数做 Newton-Schulz 正交化。我读到 muon_step_fused 函数时发现,它用了一组叫 polar_express_coeffs 的硬编码系数,是一串带十几位小数的常量。

polar_express_coeffs = [
    (8.156554524902461, -22.48329292557795, 15.878769915207462),
    (4.042929935166739, -2.808917465908714, 0.5000178451051316),
    ...
]

这组系数是 Polar Express 算法用来逼近矩阵极分解的迭代参数。它的物理含义是,梯度更新前先投影到正交矩阵附近,让更新方向更接近「最陡下降」的几何意义。对 Transformer 里那些 2D 矩阵参数用 Muon,对标量和 embedding 还是用 AdamW,setup_optimizer 里给不同参数组配了完全不同的学习率。

你看 setup_optimizer 的参数分组就懂这个优化器的复杂度。lm_head 走 AdamW 学习率 0.004,token embedding 走 0.2,matrix 参数走 Muon 学习率 0.04,还有个 dmodel_lr_scale = (model_dim / 768) ** -0.5 的缩放因子。所有学习率按模型维度做平方根反比缩放,在 768 维上调好的值迁移到其他维度。

这不是 autoresearch 发明的,是 Keller Jordan 那波人搞 Muon 的延续。但 Karpathy 把它原样塞进 train.py 作为「待优化的起点」给 Agent,本身就是个有意思的选择。Agent 不只是调学习率,它面对的是一个相当现代的优化器栈。

program.md 里那句 NEVER STOP

整个 autoresearch 最反直觉的部分,藏在 program.md 的一段大写指令里。说实话,第一次读到时我愣了一下。

**NEVER STOP**: Once the experiment loop has begun ... do NOT pause to ask the human if you should continue.
... The human might be asleep, or gone from a computer and expects you to continue working indefinitely until you are manually stopped.

你想想看,循环一旦开始,永远不要停下来问人类要不要继续。人可能在睡觉,可能离开了电脑,他期望你一直干到他手动叫停为止。人可能在睡觉,可能离开了电脑,他期望你一直干到他手动叫停为止。

这是 autoresearch 能「跑一夜」的根本。其实吧,Claude Code 有个 /loop 功能天然支持这种循环。Claude Code 有个 /loop 功能天然支持这种循环。但这里有个真实的坑,Codex 不吃这套。

仓库 issue 区最高赞的 issue #57,41 条评论,标题就叫「Codex doesn’t seem to work」。发帖的人说 Codex 会忽略「永不停止」的指令,自己跑几个实验就停了。底下讨论了一堆绕过办法,有人提 ralph loop 但那不是交互式会话。这个 issue 至今还开着,说明问题没彻底解决。

你想想这意味着什么。autoresearch 的「自主性」高度依赖 Agent runtime 对长循环指令的服从度。换一个 Agent 就可能跑不满一夜。这比 README 里说的「spin up your Claude/Codex or whatever」要苛刻得多。

实验循环的 git 棘轮

Agent 怎么决定一个实验留还是丢,这套机制值得单独拆。

每次实验都跑在一个专用分支上,比如 autoresearch/mar5。循环是这样的,改 train.py,git commit,跑 uv run train.py,grep 出 val_bpbpeak_vram_mb

涨了,分支前进,commit 留下。跌了或持平,git reset 回到实验前的状态。

结果记录在 results.tsv 里,五个字段,commit hash,val_bpb,峰值显存 GB,状态(keep/discard/crash),还有一句实验描述。注意这个文件是 untracked 的,不进 git,纯当实验日志用。

这套「git 棘轮」的本质是把 git 当成了实验状态的持久层。回滚不是删数据,是让代码回到上一个已知好状态。干净,可复现,而且天然给了人一个介入点。你醒来可以 git log 看夜里发生了什么,每个 commit 都是 Agent 的一个假设。

Karpathy 在 program.md 里还写了一条「简化准则」。代码相同效果下,简单者优先。0.001 的 val_bpb 提升如果加了 20 行 hack,不值。但如果同样 0.001 的提升是删代码带来的,必须留。这条规则把「奥卡姆剃刀」编码进了 Agent 的决策逻辑。

README 写 MIT,仓库里却没有 LICENSE

这里有个我亲自验证发现的细节,值得提醒。

autoresearch 的 README 末尾写着 ## License 下面一个词 MIT。但你去仓库根目录找 LICENSE 文件,404。gh api repos/karpathy/autoresearch/license 返回的 licenseInfo 是 null,pyproject.toml 里也没有 license 字段。

这意味着仓库目前没有一个生效的开源许可证文件。严格按法律讲,没有 LICENSE 文件默认是「保留所有权利」,你 fork 出来商用是有法律风险的。README 里那个 MIT 更像是作者声明的意向,但没有对应文件支撑。

对一个 9 万 star 的项目来说,这个疏漏不算小。如果你打算基于 autoresearch 做产品,最好自己补一个 LICENSE,或者等上游补上。这种 README 与实际不符的情况,是我在抓取时亲自验证的,不是道听途说。

硬件门槛比你想的高

autoresearch 的 README 在「Platform support」里说得很直白,代码当前需要单张 NVIDIA GPU,在 H100 上测过。

CPU,MPS,AMD 这些原则上能支持,但会「bloat the code」。Karpathy 原话是「I’m not 100% sure that I want to take this on personally right now」。他没有假装这是个人人能跑的东西。

他给小算力用户的建议也很实在,用 TinyStories 这种低熵数据集,vocab_size 从 8192 砍到 4096 甚至 1024,MAX_SEQ_LEN 砍到 256,DEPTH 从 8 降到 4,TOTAL_BATCH_SIZE 砍到 2**14。这些建议说明他很清楚 H100 的门槛有多高,也诚实告诉读者不改这些参数在 Macbook 上根本跑不动。

官方列了几个 Notable forks,miolini 的 macOS 版,trevin-creator 的 MLX 版,jsegov 的 Windows RTX 版,andyluo7 的 AMD 版。算是对硬件限制的务实回应,而不是空头承诺。

把「研究员」外包给 Markdown

autoresearch 给我最大的启发,不是那个 Muon 优化器,也不是 5 分钟预算的巧思。是一个我打算叫「Program.md Pattern」的东西。

它的核心是,把一个复杂的自主任务(做 AI 研究)拆成三个角色。不动手的人写 program.md 定义目标和规则,执行者(Agent)只动一个文件 train.py,仲裁者(固定评估函数 evaluate_bpb)锁死胜负标准。三个角色互不越界,任务就自动化了。

这个模式可迁移的地方比 LLM 训练广得多。任何「目标可量化,迭代可回滚,搜索空间可收窄」的任务,都能套这个三件套。你写一个 program 定义规则,给 Agent 一个可改的单一资产,配一个不可动的评估函数,剩下交给循环。

darwin-skill 这个项目就是把同一套思路从「优化模型」搬到「优化 Skill 文件」上,连 git 棘轮都照搬了过去。说明这个模式的骨架是稳固的。

但 autoresearch 也诚实地暴露了这个模式的边界。它的「自主性」依赖 Agent runtime 的服从度(Codex 至今跑不稳),它的可比性被锁死在单机单卡,它的法律基础还有个缺失的 LICENSE 文件。这些不是缺点,是这个范式还很早期的证据。

真想玩,准备一张 NVIDIA 显卡,读一遍 program.md,然后睡一觉。醒来你会对「Agent 能不能做研究」这个问题有完全不同的体感。

评论互动

© 2026 王若风的技术博客 · Powered by Astro