Liquid AI 复盘智能体循环:如何让编码智能体自主完成生产级任务
Designing Loops for Production-Grade Work
Liquid AI 在 2025 年底做了一次实验,让 Claude Opus 4.5 和 Codex(GPT-5.2)在无人工看代码的情况下自主构建生产级 BPE tokenizer 训练器,产物 toktoktok 已在 GitHub 以 Apache 2.0 开源。
Liquid AI 用真实生产任务复盘智能体自主编码的循环设计,给出目标规格与外部验证两条可迁移经验。
2025 年底,我们进行了一项实验来回答一个问题:“编码智能体能否自主从零开始解决一个生产级问题?”
为此,我们给两个智能体分配了(当时)公开可用的最佳编码模型,并给它们一个真实的问题和真实的截止日期。这项实验的成果是一个名为 toktoktok 的 tokenizer 训练器,现已在 GitHub 上开源。
在本文中,我们分享在设计有效循环、让智能体能够自主解决生产级问题方面的经验:如何为多领域专家指定目标,以及如何搭建验证基础设施。
为什么测试自主性需要一个真实目标
作为我们关于词表大小对边缘 LLM 影响的研究的一部分,我们需要一个字节对编码(BPE)tokenizer 训练器,能够在单台机器上处理数万亿 token。然而,tokenizer 训练领域的工具十分匮乏:sentencepiece 针对非 BPE tokenizer 做了优化,速度很慢;Hugging Face tokenizers 在我们的语料上内存溢出;而 tiktoken 则完全没有训练能力。
这就是为什么我们需要构建一个生产级的 BPE tokenizer 训练器。根据我们对现有库的经验,我们也知道内存大小才是真正的瓶颈,而且它们缺少我们需要的两个功能:从现有 tokenizer 热启动(词表扩展)以及按语言的词表预算。这给了我们一个具体的任务、一个真实的截止日期,以及一种有效的方式来回答编码智能体是否足够可靠、能够自主解决任务,因为它满足以下标准:
生产级。智能体通常被用来自主解决问题的方式无法回答这个问题。首先,它们常被用于原型开发,从未被要求达到生产标准。其次,它们重新实现某种已存在的、用不同语言编写的东西,比如“把 SQLite 移植到 Rust”或“用 Zig 写一个 C 编译器”,这不过是对模型在预训练期间可能见过的东西的翻译。与这两者不同,我们的任务有明确的交付生产目标,而且由于 BPE tokenizer 训练足够新、公开参考实现很少,它成为了一个理想的“测试分布”问题样本。
多领域专业知识。在 Liquid AI,我们的专家研究得很深,但各自只在一个领域。我们的 ML 研究员能凭记忆告诉你为什么 OpenAI 的 cl100k 为每个三位数保留 rank,但他们从未写过一行 Rust。我们的 Rust 工程师写的正是这个问题所需的那种内存感知、多线程系统代码,但他们从未训练过 tokenizer。
这是两组互不相交的人,任何一方都无法单独解决这个问题。两种人工变通方案都有损失:要么其中一方先学会另一方的半部分,要么我们把它安排成协作,并为此付出协调开销。这就是我们让智能体瞄准的缺口:“它能否覆盖我们任何一位工程师都不具备的专业知识跨度?”
可外部验证。产物必须能在 tiktoken 和 Hugging Face tokenizers 中加载。由于与第三方软件的互操作性,这项工作可以由智能体无法修改的代码来检查。成功不是自我报告的,而是取决于两个第三方库是否能产生正确的 token。
虽然需要构建的细节本身就很有趣,但对本文而言,重要的是:一个真正生产级、对我们单领域专家来说很难、且可外部验证的任务,才是回答智能体能否在无人监督下完成工作的唯一诚实方式。
搭建实验
对于这个实验,我们选择了 Claude Opus 4.5 和搭载 GPT-5.2 的 Codex——2025 年底公开可用的两个最强编码模型——作为编码智能体,并让两者都在其规划模式下工作。 在两个智能体写下任何一行代码之前,我们在其周围设置了两样东西:一个要瞄准的目标,以及一种验证它是否达成目标的方法。
目标描述在一个规范文件中。它是一份由操作员编写的单一 AGENTS.md / CLAUDE.md 文档,描述结果及其约束,而非实现:主要架构约束是内存。该设计把复杂度预算花在内存上,因此远大于 RAM 的语料库仍能得到相当好的表示。计算和 I/O 是次要的,并得到直接的处理:一种系统级编程语言(Rust)和多线程应该就足够了。
为了验证智能体是否达到了指定目标,我们给了它两样它无法影响的东西:
- 生产数据: 我们给了智能体对我们生产训练数据集的沙箱访问权限,以及一台能够处理它的机器,具体来说是 AMD EPYC 9755,128 核、256 线程、2 TB 内存。
- 外部验证工具链: 训练出的词表必须能被
tiktoken和 Hugging Facetokenizers加载,并检查两者的编码和解码往返,以及两者之间在 ID 级别的一致性,覆盖多种语言、数字、货币格式、制表符、CRLF 行尾和源代码。
有了这些组件,智能体就可以朝着指定目标努力了。
我们运行它时发生了什么
我们用两个编码智能体运行了这个实验。操作员从外部监控,只读取工具链,但从不看一行代码。
两者都零样本完成了玩具训练器
两个智能体都在 30 分钟内产出了一个可用的训练器。 它们解析配置、遍历语料库、应用硬编码的合并、运行 BPE 训练,并输出一个通过自身单元测试的有效 .tiktoken 文件。
两者都能在几兆字节上成功训练玩具分词器。 产物在 tiktoken 中加载成功。所有测试都通过了。如果我们此时停止评估,结论将是两次运行都成功。
两者都无法在没有循环的情况下扩展到生产规模
然而,两个训练器都没能撑过完整的生产数据集。在第一次运行中,每个阶段的每个单元测试都通过了,因为几兆字节的干净文本不会触发以下任何一项:
必须发现的问题 | 它如何暴露自己 | 什么抓住了它 | 修复所需的工作量 |
文件编码。Parquet 允许同一逻辑列使用多种编码。 | 在测试中读取正常的文件在语料库中被静默错误处理 | 真实语料库文件 | 数小时 |
内存感知。每文档的 Vec 开销淹没了有效载荷 | 在目标语料库大约 1% 时内存耗尽 | 全规模运行 | 两到三天:分块批处理、哨兵、多段迭代 |
并行化不当。将关键路径的一部分并行化,其余部分仍保持串行 | 每个核心都忙,吞吐量仍然不可接受 | 全规模运行 | 一到两天 |
预分词速度。 | 分析器显示预分词占主导;对抗性空白导致二次方复杂度 | 全规模运行 | 数小时,外加一个正确性判断 |
排名排序。 | 词汇表加载无异常,但编码方式与预期不同 | 外部测试框架 | 数小时 |
重复合并。一次训练得到的合并可能重复现有 token 并导致词汇表坍缩 | 词汇表少了 N 个,之后每个排名都发生偏移 | 外部测试框架 | 数小时 |
数字编码。Rust 的 regex crate 将 |
| 外部测试框架 | 一行 |
然后,我们让智能体针对真实数据循环:执行、碰壁、报告症状、让智能体诊断并修复、再次运行。
经过五次以上迭代进展甚微后,我们停止了 Codex/GPT-5.2 路线的工作,该路线仍在训练吞吐量上挣扎。这是一个资源分配决策:一名操作员、一个真实的截止日期,而到那时 Claude Opus 4.5 路线在相同轮数后进展更远。我们的解读是,Claude 的第一个版本起点更好,因为它比 GPT-5.2 更可靠地捕捉到了规范的细微之处和约束背后的意图。
Claude Opus 4.5 在后续几轮迭代中解决了剩余问题,并产出了一个可运行完整生产配置的训练器:数万亿 token 的多语言和代码数据、多阶段、在单台机器上、几天内完成。输出干净地通过了外部测试框架。
为什么循环是必要的
我们进行这个实验是为了回答这个问题:“编码智能体能否从零开始自主解决一个生产级问题?” 人们很容易将“两个智能体都没有零样本完成”解读为关于模型能力的故事,但这是错误的结论。按照我们一开始设定的标准,实验成功了。然而,让它成功的原因不是任何一次聪明的尝试,而是循环。
这个仓库中的两千行代码不是零样本响应的产物,而是迭代过程的残留。几乎每一行非显而易见的代码,一旦你知道它需要写,写起来都很便宜,而昂贵的部分是知道它需要被写。
这意味着,智能体能否在没有人类监督的情况下成功实现目标,取决于是否有一个能针对真实环境约束收敛的迭代循环。这使智能体能够迭代地发现和体验真实世界的混乱。
运行自主循环的经验教训
从这个实验中我们了解到,编码智能体能够通过循环自主解决任务,但更重要的是,我们学到了关于如何设计有效循环的两条宝贵经验,这些经验如今已成为我们工程团队的日常实践。
为多领域专家指定目标
从实验中我们了解到,编程智能体是多领域专家,其专业知识覆盖面之广,是我们任何一位工程师都不具备的。事实证明,它既懂 OpenAI 的 cl100k 正则表达式,也懂 Rust 的 rayon。我们手头能派上这个项目的人,没有一个同时掌握这两样。这改变了我们设定目标的方式,因为感觉更像是在和另一个团队的同事交谈,而这位同事恰好也懂你团队的东西。
设想一下,要把这个问题交给一位没有分词器背景的资深软件工程师,实际需要做些什么。显而易见的答案是给他们写一份详细的规格说明。这就是专业知识转移的经典困境:规格写得太短,工程师就得自己慢慢摸索出所有细节;写得足够长、真正可操作,那你就等于写了伪代码,而这意味着你自己得具备领域知识,并且几乎已经能完成这项工作了。
LLM 不受这个困境束缚,因为它一上来就已经装好了背景知识。这改变了规格说明的性质。我们的规格说明很短,它陈述的是结果和约束,而不是实现机制。
举一个我们规格说明中的真实例子:“在训练开始前,为所有两位数和三位数预留词表”。对没有背景知识的工程师来说,这是一个武断的要求。他们可以字面照做,却仍然做错,因为这句话本身没有携带动机。它的目的是给模型一个一致的数字表示,使算术不依赖于语料中恰好哪些数字对频繁出现,例如,想想 GPT-2 的分词器,由于训练数据中的频率,它有一个独特的 2019 token,却没有 2029 的。不知道这一点,他们就无法判断指令中哪些部分是关键的、它属于流水线的哪个环节,或者它对他们设计中的其他部分意味着什么。
对照现实世界的约束进行验证
我们的操作员从未读过一行生成的代码。这之所以可以接受,仅仅是因为成功标准是智能体无法操纵的。我们在循环设计中常见的一个错误是验证薄弱,要么在玩具规模的数据上运行,要么容易受到智能体的影响,比如让它编辑自己的单元测试。
主要教训是设计一个能针对现实约束收敛的循环,包含以下组成部分:
- 在真实生产数据规模上迭代。真正重要的失败在测试套件中不可见,只有在全规模生产数据中才能发现。
- 用外部测试框架验证。这正是自主性可被接受的原因。操作员从未读过代码,而这只所以能容忍,是因为正确性由 tiktoken 和 Hugging Face tokenizers 定义,这些软件不是智能体编写的,它也无法影响。如果我们接受它自己的测试套件作为证据,我们就会得到两个通过各自测试、却悄悄产生不同词表的实现。要把问题设计成让第三方能够评判产出物。
今天已是常规的做法与未来展望
这些是我们在 2025 年底进行的一项实验的结果和教训:是的,编程智能体可以完全自主地、在没有任何人工监督的情况下从零解决一个生产级问题,但前提是它们运行在一个循环之中。
我们学到的经验如今已成为我们工程团队的日常实践。半年过去,明确目标是我们最用心对待的部分,而用真实数据和外部验证来构建循环已成为标准做法。
如今我们运行的循环远不止像 tokenizer 训练器那样的一次性构建——后者有一个清晰、可验证的最终目标,循环会向其收敛。我们现在运行的许多循环则是开放式的,朝着一个没有唯一正确答案的目标不断爬坡:调优内核、监控持续集成、分诊进来的拉取请求,或扫描生产日志中的异常。在每一个循环中,我们检查的是指标,而不是代码。
如今的模型确实好得多,但让这一切成为常规的原因是,它们已经足够可靠,可以把整个循环交给它们。 如果这一点能够推广,那么它对机器学习和软件工程工作方式的改变,将比任何原始编码能力的提升都更为重大。
可用性
toktoktok 以 Apache 2.0 协议开源,地址为 https://github.com/Liquid4All/toktoktok。它可以从零开始训练与 tiktoken 兼容的 BPE 词表,或扩展现有词表,读取 .txt 和 .parquet 文件,通过多阶段训练在语言和领域之间分配词表预算,并始终控制在你声明的内存预算之内。面向 Hugging Face 的转换脚本支持双向转换,并在写入任何内容之前验证等价性。
它的每一行都由智能体编写,而我们没有读过其中任何一行。
致谢
本文由 Mathias Lechner 撰写,Leonie Monigatti 亦有贡献。
我们感谢 AMD 的合作,为本次实验提供了硬件。
引用
请按如下方式引用本文:
Liquid AI, "Designing Loops for Production-Grade Work", Liquid AI Blog, Aug 2026.
来源:Liquid AI Blog · liquid.ai