
这是什么
AntOmniEvo 是一个把「优化」当成改文件的 Python 框架。你先一次给出五样东西——跑被测系统的 System、给输出打 0–1 分且其打分标准就是目标的 Evaluator、训练与验证样本、声明哪些文件可改的 schema、以及起点文件;随后由 coding agent 读失败轨迹,把那些文件改成一个新候选,再由框架裁决它留不留。基因组是一个真实目录,所以一次变异可以是一条 Markdown 规则、一段节点脚本,或某个检索 DAG 的 pipeline.json;被优化的系统里不必有模型,但提出修改的必须是 coding agent。每一轮把父候选与变异出的子候选放在同一条训练批次上跑,只有当分数增量越过阈值或拿到满分时才在验证集上复评,再按 Pareto 支配加 top-N 兜底裁剪种群。被淘汰的候选不会丢掉,而是在同一轮里被有界地反复精修。每一个候选、运行、分析与 changelog 都落进一个可以续跑的工作区,另有一个 React 加 Flask 的可视化器把这次运行渲染出来。它从未打过 release:两个包的 0.1.1 版只发到内部源。
谁做的Ant Research 是一个组织账号而不是某个人:45 个公开仓库、368 个关注者、2022-12-17 注册,资料里挂着 antresearch.com。这个仓库的每一次提交都来自同一个成员账号 jacklv111——2022-09-20 注册、13 个公开仓库、5 个关注者——它是 21 次提交里 9 次的作者名、全部 21 次的关联账号,也是贡献者列表里唯一的一条。README 引的那篇论文列了六位作者,第一作者是 Yubin Lyu;仓库的内部发布流水线点名了两位批准人 lyuyubin.lyb 与 hanpu.mwx。哪个账号对应哪个名字,材料里没有写。
它是怎么搭起来的
组成 · 6这套东西的组织想法是:优化就该是普通的文件编辑,所以被优化的对象被表示成一个目录,而决定谁活下来的机制是用户不必自己写的确定性代码。这个选择把智能集中到一处——一个读失败运行、动手改文件的 coding agent——同时把概率性的东西挡在循环之外:取批次、接受还是退场、验证集复评、修剪、预算,全都是计数、求和与比较。两个后果塑造了代码。因为只有分析和改文件这两步交给 LLM,它们被拆成两段,中间隔着一份结构化产物;反思路径只改这份产物,绝不动改文件的机制。又因为这套变异循环建立在一个不可靠的花钱者之上,它必须可审计,于是记忆就是文件系统:子候选继承父候选的追加式 changelog,运行记录与分析在错误短路之前先落盘,启动时把中断的候选翻回可选状态。同一批文档对自己的血统也很坦白:Pareto 选择借鉴自 GEPA,被当作自己东西的是同时跑多个候选、以及让被淘汰的候选继续活着。
- antomnievo/optimizer/
optimizer.py里 43,728 字节:主循环,以及按场景分的子类——text2sql、AppWorld、TerminalBench、adconfig 与 RAG 流水线。slot、批次游标、接受还是退场的裁决、反思链、验证步骤,以及子类绕不过去的那两个计数器都归它管。- antomnievo/proposer/
- coding agent 这一侧:28,967 字节的
base_proposer.py装着「先分析、后变异」的两段流水线,每个后端只写一个薄子类——驱动claude的claude_code_proposer.py(6,054)和驱动pi的pi_coding_agent_proposer.py(5,776);三个提示模板以 26,192 字节的reflection_analysis_prompt.py为首,另有analysis_prompt.py(9,508)与mutation_prompt.py(8,586);还有沙箱里的 agent 被要求去跑的几个脚本validate_analysis.py、append_changelog.py、diff_dirs.py,前两个注册成命令行入口,好让它们在沙箱的 PATH 上找得到。 - antomnievo/interface/, store/, evolution_algorithm/, model/
- 契约、记忆与选择:六个抽象接口(
System、Evaluator、Proposer、EvolutionAlgorithm、CandidateStore、DataInst),30,684 字节的文件系统 store 旁边是 26,020 字节的接口,6,960 字节的 micro-pareto 算法,以及候选、预算、统计、轨迹与可调产物 schema 的 pydantic 模型——其中tunable_artifact_defs/下有九个文件,最大的是 21,105 字节的 text2sql 与 17,431 字节的 RAG 流水线。 - antomnievo/system/, evaluator/, dataset/, example/
- 四个参考目标及其脚手架:一个 LangGraph ReAct agent、跑 BIRD/DP/Spider2Snow 的 text2sql、AppWorld 与 TerminalBench 系统;各配一个评估器,AppWorld 与 TerminalBench 那两个分别是 9,511 与 8,793 字节;八个数据集加载目录;以及八个把各组件接起来的示例入口。它们每一个都依赖框架不会替你装的外部代码库。
- visualizer/
- 第二个包
ant-omnievo-visualizer:一个 Flask 后端(server.py11,616 字节、workspace_reader.py10,785、manage.py6,534),加一个 Vite 与 React 前端,其 39 个源文件里有 30,427 字节的GymBackdrop.tsx、27,868 字节的MaraChains.tsx和一份 58,913 字节的样式表,public/下还有 40 个文件、32 MB,几乎全是精灵图。 - docs/, skills/, .aci/
- 十六份文档,八份英文配八份中文,打头的是 13,706 字节的
system-design.md与 12,517 字节的中文版;一份 74,597 字节的SKILL.md属于eddy-antomnievo-experiment技能,带九份配方参考,最长的一份 38,238 字节,是写给 Ant 内部用户看的;再加内部发布流水线的两个文件。
取舍,以及它替代了什么
可调产物就是一个文件目录 替代 一组受限参数,或一门专用 DSL
这是设计文档列的第一条:真实目录让框架能用上一个成熟的、直接改文件的 coding agent,也把表达能力变成「文件系统装得下什么就是什么」——一条 Markdown 规则、一份 Python 实现、一个校验脚本、一段运行期扩展。于是每一处改动都被逼进一条结构化记录里,必须引用它所回应的那条失败轨迹观察。
把被淘汰的候选留着继续精修 替代 一旦没越过阈值就让它退场
README 引的论文认为被丢掉的候选里含有后续提案需要的信息,丢掉它们会让下一次提案重走同样的失败路径。链的深度有固定上限,种群规模由 Pareto 过滤后的 top-N 兜底,所以多出来的尝试不会把预算带跑。
micro-pareto:支配关系修剪加 top-N 兜底 替代 纯粹的 Pareto 弱支配
设计文档给的理由是:在带随机性的打分下纯 Pareto 会失效;它还说选择会按候选拿下多少个样本的第一名来加权,以保护全面型候选而不是偏科型候选。同一份文档把 Pareto 选择本身归功于 GEPA。
在运行与分析之间插一层结构化分析 替代 让改文件的 agent 直接读原始运行记录
第一阶段把一次失败运行变成一份
RunAnalysis:观察加处方,每条处方都要指名它解决的是哪一条轨迹观察,并做一次自检;第二阶段先跨样本去重、化解矛盾,再动手改文件,必须通过一条 changelog 命令记录 diff,且没有文件被改就算失败。原始运行永远到不了改文件那一步。把验证集隔离交给运行时强制,而不是写进提示里 替代 两个后端都用提示里声明的访问规则
Pi 后端启动时挂了两个扩展,一个硬性拦住对验证运行的读取,一个拦住绕过 changelog 命令;Claude Code 后端则靠提示里声明的访问规则。设计文档把读者该得出的结论直接写了出来:Pi 这条路径更受控。
预算触顶时先停止开新 slot,让在跑的跑完 替代 一到上限就把正在做的工作杀掉
任何一项上限触顶就不再开新 slot,并让在飞的 slot 排空;特点文档把它和断点续跑配在一起讲:长跑既不会超支,也不会把已经花掉的钱丢掉。它管这叫软停止。
依据docs/system-design.md(13,706 字节)、docs/features.md、docs/extensibility.md、docs/when-to-use.md、docs/quickstart.md、docs/workspace-artifacts.md、docs/checkpoint-resume.md、docs/visualizer.md、README.md、两个包的 pyproject.toml、.aci/python/.aci.yml 及其 README,以及九个 pull request 的正文。
制作过程
6 个阶段- 01
十五天、21 次提交、九个 pull request,没有一个 release
仓库创建于 2026-09-15,第一个提交
init落在两小时十八分钟后;最新的一个是 2026-09-30 合并的 pull request 9。也就是说,十五天里 21 次提交,全部集中在九月,而它们背后只有一个账号:21 次全部关联到jacklv111,其中 9 次的作者名是jacklv111,另外 12 次用的是另一个中文作者名和一个 163 邮箱。其中 7 次带Co-authored-by: Claude尾注。同一段时间里开了九个 pull request,九个都由同一个账号关掉,且没有任何一条评论——正文是作者自己写的变更说明,而不是对话,下文大部分细节正来自这里。它从未建过 release,也没有 tag;版本只以两个pyproject.toml里的0.1.1存在,而把它们发出去的是内部流水线.aci/python/.aci.yml:它的 README 写明有一道人工的「Verify & Confirm」闸门、必须设置PIP_INDEX_URL(否则隔离构建会打到公共源)、以及两位具名批准人。周围是 866 个星、86 个 fork、35 个 watcher、0 个 open issue,仓库 45,613 KB。 - 02
一个 slot,以及一个子候选要活下来必须满足什么
框架把一次迭代叫做一个 slot,设计文档把它里面的每一步都写了出来。优化器从父候选自己的
(epoch, dataset_index)游标取一批数据——尾部对齐、到头就绕到下一个 epoch,而且即使这次 rollout 失败游标也照样前进,于是数据顺序是一份快照,而不是对失败的应激反应。接着父候选与变异后的子候选跑在同一条批次上,而比较本身就是一次求和:增量等于子候选分数之和减去父候选分数之和。有两件事能过线:增量达到或超过min_improvement_per_batch,或者拿到满分。过线的子候选会在验证集上重新打分、写下summary.json,状态从evolving翻回pending;没过线的,如果开了反思就走反思链,没开就直接retire。每个 slot 结束后,父候选推进游标、eliminate跑一次、iteration_records.jsonl追加一行。快速开始里的数字是batch_size=3、max_iterations=1000、num_proposals=1、max_reflection_iterations=2、min_improvement_per_batch=2.0、max_candidate_num=3。多个 slot 在同一个进程里并发跑,任何一项预算触顶就不再开新 slot,而在跑的跑完为止;「硬上限」在特点文档里是四条,在设计文档里是五条,多出来的那条max_system_runs把包括验证运行在内的每一次运行都算进去。 - 03
被淘汰的候选不丢,而是被继续精修
一批数据没过阈值时,框架不会停在一次自然语言反思上,而是启动一条 mara chain:反思提示里预装了整条链的上下文——chain id 路径、带 Δ 列的逐样本分数表、已归因的 changelog、链上每一环此前对这条样本的分析,以及各环的运行文件——然后要求分析 agent 跑五种方法的诊断、填一张 A–I 诊断表、优先 REMOVE 与 REPLACE 而不是新增、在
artifact_issue里点名链上哪一环该负责,并去找「lost wins」。这样最多跑max_reflection_iterations轮;最终胜过原父候选的那一环被验证并留下,其余全部退场。第二阶段(真正改文件那一步)在反思路径上机械地不变——设计文档把整条链的学习都放在分析 JSON 这一层,而不是新增机制。特点文档明确写了什么是借来的、什么是自己的:Pareto 选择沿用自 GEPA,这里主张的增量是并发与 mara chain;README 引的那篇论文建立在同一个观察上——被丢掉的候选里往往有后续提案需要的信息,丢掉它只会让下一次提案再撞同一个坑。 - 04
「optimizes anything」这句话的边界在哪
仓库描述许诺的是一个能优化任何东西的框架,而边界被写在了一份文档里。要成立得满足两个条件:被优化的东西能表示成一个可调产物目录,且它的评估可重复、成本可控。在这两个条件之下,它说支持三种形态——AI agent 的 skill/harness/memory 目录;workflow,也就是配置加节点代码,比如某个检索 DAG 的
pipeline.json;以及单文件算法加它的描述——并两次强调被优化的系统里不必有模型。与目标不同,proposer 必须是一个 LLM coding agent。不适用的情况也写得很直白:根本没有可调产物(只有几个标量参数,它建议改用黑盒调参)、评估不可重复或极其昂贵、以及输出受严格合规约束——最后一条还提醒,proposer 是在沙箱里改文件的,沙箱权限得自己去审。另有两处限制不在宣传里而在代码里:框架不管被优化系统自己的运行时与打分工具链;分布式演化也不在范围内——云端存储要你自己写一个「本地加透明同步」的子类,文档还专门说明,这不是多个 worker 跨主机共用一个 store。第三个限制由示例本身印证:它们都跑不起来,各自依赖外部代码库,其中一个到今天还把作者自己家目录下的绝对路径当作工作区。 - 05
十次「成功」,和一个空的成果目录
仓库里最有用的一条 pull request 是一处修 bug,它的正文把根因、错误表现和修法都写了出来。在模型网关限流时,模型返回空的 assistant 消息;agent CLI 内部重试之后以 0 退出,于是什么都到不了
trajectory.errors。第一阶段把这种会话全都记成成功——日志写着「10 succeeded」——而分析结果目录始终是空的,第二阶段随后基于「(no analysis results available)」提案,什么也没改。这条 pull request 里的三处改动,材料写清了前两处:一是find_degenerate_ending,把「尾部连续两个以上空模型片段」或「零工具调用且零文本」判为失败,抛PiEmptyResponseError进入 429 已经在用的同一条重试路径,用同样的退避,并走既有的重试钩子;二是第一阶段在会话干净退出后,断言分析结果文件确实在本轮开始之后被写过或被重写过,否则这条数据算失败而不是成功。第三处改动属于第二阶段,在现有摘录里被截断了。它值得记下来的地方在于失败的样子:一个计数器、一个指标和一行日志都一致地宣布活干完了,唯一不同意的是那个空目录。 - 06
关于一次运行,记下了什么、又没记什么
仓库里没有任何地方发布结果:README 和它旁边八份英文文档都没有基准表。真实运行留下的唯一证据是视觉的——可视化文档里嵌了六张截图:把候选画成龙虾、按分数分层的健身房,谱系树,最优分数曲线,一张标出所有候选都没答对的题目的覆盖网格,以及文件查看器。项目发布的是「自己怎么查一次运行」:比较
logs/statistics.json里的baseline_avg_score与best_avg_score,读iteration_records.jsonl看每个 slot 是否被接受、旧批次与新批次的分数和、以及reflection_depth(大于 0 表示是反思救回来的),再顺着parent_id往上走到根,读changelog.jsonl——工作区文档把那称作可调产物为什么长成现在这样的人类可读历史。它真正拿得出手的数字,在 README 于 2026-09-30 开始链接的那篇论文里:摘要声称在 AppWorld 上相对 GEPA、ACE、SkillOpt-Lite 最高提升 20.5%,达到目标分数所用 rollout 比 GEPA 少 65.5%,在 TerminalBench 2.1 上通过率比 AHE 和 Meta-Harness 分别高 20.2 与 22.5 个百分点,在 MuSiQue 上相对一份手写检索流程把 test nDCG@10 与 Recall@10 提升 0.104 与 0.131。这些是同一支团队写在摘要里的主张,本记录的材料里没有任何东西复现过它们。
相关档案
全部档案 →第 129 号
Agents Universe
一套开源智能体平台,让同一个项目里的人共用一份上下文。项目选中时智能体把全部知识读进上下文,干活过程中再把学到的东西写回同一批文件;知识是磁盘上的 Markdown,数据库只做索引,没有嵌入模型,也没有向量检索。
第 123 号
agent-memory
一个给 AI agent 用的长期记忆运行时:Markdown 文件是唯一真相,检索在本地排序、读的时候不调用任何模型,召回返回的是路径而不粘贴正文,写入发生在对话边界而不是等 agent 想起来,另外还有一个独立的睡眠期管理层——它可以自己新增和更新,但删除永远只能以提案的形式提交。Claude Code、Codex CLI 与 Hermes 共用同一份存储,不需要任何 API key。
第 117 号
sepia
一个可移植的去 AI 味写作技能:一套规则文件配四个操作,小说先修叙事结构再谈用词,专业文稿按场合套一份薄薄的规则文件,而每条规则都标着它是被测出来的、被咨询过的,还是这个项目自己的推断。