构建生产级智能体循环(9分钟阅读)
摘要
Liquid AI进行了一项实验,其中编码智能体自主构建了一个名为toktoktok的生产级BPE分词器训练器,分享了关于设计有效的智能体循环和验证基础设施以解决实际问题的经验教训。
Liquid AI使用自主编码智能体构建了toktoktok,一个需要机器学习和系统专业知识的生产级BPE分词器训练器。该实验强调了具体规范、多领域任务和外部验证是可靠长期智能体工作流的关键要素。
查看缓存全文
缓存时间: 2026/08/19 15:36
# 设计适用于生产级工作的循环
来源:https://www.liquid.ai/blog/agent-loops
2025年底,我们进行了一项实验来回答一个问题:*"编程代理能否自主从零开始解决一个生产级问题?"*
为此,我们使用当时最佳的两个公开编程模型(Claude Opus 4.5 和 Codex with GPT-5.2)来应对一个真实问题并面临真实截止日期。实验成果是一个名为`toktoktok`的分词器训练器,现已在GitHub开源(https://github.com/Liquid4All/toktoktok)。
本文将分享我们关于设计有效循环的经验,这些循环使代理能自主解决生产级问题:如何为多领域专家设定目标,以及如何建立验证基础设施。
## 为何需要真实目标来测试自主性
作为我们研究词汇表规模对边缘LLM影响(https://www.liquid.ai/blog/tokenizer-expansion)的一部分,我们需要一个字节对编码(BPE)分词器训练器,能够在单台机器上处理数万亿词元。然而分词器训练工具匮乏:`sentencepiece`针对非BPE分词器优化且速度缓慢,Hugging Face`tokenizers`在我们的语料库上内存耗尽,而`tiktoken`完全没有训练功能。
因此我们需要**构建一个生产级BPE分词器训练器**。根据使用现有库的经验,我们知道**内存容量才是真正的瓶颈**,并且缺少两个必需功能:从现有分词器热启动(词汇表扩展)和按语言的词汇预算。这给了我们一个具体任务,附带真实截止日期,也是检验编程代理是否足够可靠、能自主完成任务的有效方式,因为它满足以下标准:
**生产级。** 代理通常自主解决问题的方式无法回答这个问题。首先,它们常被用于原型开发而非达到生产标准。其次,它们重新实现已有功能,比如“将SQLite移植到Rust”或“用Zig编写C编译器”,这相当于翻译模型预训练时可能见过的内容。与这些不同,我们有明确的投产目标,且由于BPE分词器训练较新且公开参考实现少,这使其成为理想的“测试分布”样本。
**多领域专业。** 在Liquid AI,我们的专家各有所长但领域单一。我们的ML研究员能凭记忆解释OpenAI的cl100k为何为每个三位数保留排序,却从未写过一行Rust。我们的Rust工程师能写出问题所需的那种内存敏感、多线程的系统代码,却从未训练过分词器。
这是两类互不相交的人群,单独任何一方都无法解决此问题。两种人工解决方案都有损耗:要么让其中一方先学习另一方的专业,要么组建协作团队并承担协调成本。这正是我们指向代理的能力缺口:“*它能否覆盖我们任何工程师都不具备的专业跨度?*”
**外部可验证。** 产出物必须能在tiktoken和Hugging Face分词器中加载。由于这种与第三方软件的互操作性,代码可被代理无法修改的代码检查。成功不是自报告,而是取决于两个第三方库能否正确产生词元。
虽然具体构建内容(https://github.com/Liquid4All/toktoktok)本身很有趣,但对本文而言关键在于:一个真实生产级、对单领域专家困难且外部可验证的任务,是检验代理是否能在无人监督下完成工作的唯一诚实方式。
## 设置实验
在本次实验中,我们选择Claude Opus 4.5和Codex with GPT-5.2——2025年底最强的两个公开编程模型——作为编程代理,并让两者都使用规划模式。在代理编写任何代码前,我们设置了两样东西:要达成的目标,以及验证是否达成的方法。
**目标**在规范文件中描述。这是操作者编写的单个`AGENTS.md`/`CLAUDE.md`文档,描述结果及约束而非实现:主要架构约束是内存。设计将复杂度预算用于内存处理,使远超内存的语料库能保持相对均衡的表示。计算和I/O是次要的,采用直接处理方式:系统级编程语言(Rust)和多线程应已足够。
为**验证**代理是否达成规范目标,我们给了它两个无法影响的东西:
- **生产数据**:我们给代理提供了沙盒化的生产训练数据集和能处理该数据集的机器,具体是配备128核、256线程和2TB内存的AMD EPYC 9755。
- **外部验证工具**:训练出的词汇必须被`tiktoken`和Hugging Face`tokenizers`加载,并针对多种语言、数字、货币格式、制表符、CRLF换行符和源代码,检查编解码往返过程及两个库间的ID级一致性。
有了这些组件,代理就能朝规范目标工作。
## 运行时的情况
我们用两个编程代理运行了实验。操作者从外部监控,只读取工具而不查看任何代码。
### 两者都一次性完成了玩具训练器
**两个代理都在30分钟内产生了可工作的训练器**。它们解析配置、遍历语料库、应用硬编码的合并、运行BPE训练,并输出了通过自身单元测试的有效`.tiktoken`文件。
**两者都能在几兆字节数据上成功训练玩具分词器**。产出物可在`tiktoken`中加载,所有测试通过。如果评估在此停止,结论将是两次运行都成功。
### 但若无循环则无法扩展到生产环境
然而,两个训练器都未承受住完整生产数据集的考验。在首次运行中,每个单元测试在各阶段都通过,因为几兆字节的干净文本不会触发以下问题:
**需要发现的问题**
**如何显现**
**如何捕获**
**修复耗时**
**文件编码**。Parquet允许同一逻辑列使用多种编码。
测试中正常读取的文件在语料库中被静默错误处理
真实语料库文件
数小时
**内存意识**。单文档Vec开销淹没有效载荷。
在约1%目标语料库时内存溢出。
全量运行
两到三天:分块批处理、哨兵值、多段迭代。
**不当并行化**。并行化部分关键路径导致其余部分仍为串行。
所有核心繁忙,但吞吐量仍不达标。
全量运行
一到两天
**预分词速度**。`\s+(?!\S)`导致回溯正则引擎。
分析器显示预分词占主导;对抗性空白导致二次复杂度。
全量运行
数小时,加上正确性判断。
**排序**。`tiktoken`从排序推导合并顺序,因此排序必须连续。
词汇表加载无警告,但编码结果与预期不同。
外部工具
数小时
**重复合并**。训练出的合并可能与现有词元重复,导致词汇表坍缩。
词汇表缺少N个词元,后续所有排序位移。
外部工具
数小时
**数字编码**。Rust的正则库将`\{1,3\}+`重新解析为`\(\{1,3\}\)+`。
`tokenizers`和`tiktoken`在除数字外所有内容上一致。
外部工具
一行代码
随后我们让代理基于真实数据循环:执行→遇阻→报告症状→让代理诊断修复→再次运行。
经过五轮以上迭代进展甚微后,我们停止了Codex/GPT-5.2方向的尝试,其仍在训练吞吐量上挣扎。这是资源决策:只有一位操作者、真实截止日期,且当时Claude Opus 4.5方向在相同轮次后进展更快。我们的判断是Claude的初版起点更好,能更可靠地把握规范细节和约束背后的意图。
Claude Opus 4.5在后续几次迭代中解决了剩余问题,产生了一个能运行完整生产配置的训练器:数万亿词元的多语言和代码数据、多阶段训练、单台机器、数天内完成。输出干净地通过了外部工具验证。
## 为何循环是必要的
我们进行此实验是为回答“*编程代理能否自主从零开始解决生产级问题*?” “两者都未能一次性完成”可能被误读为模型能力的故事,但这是错误的结论。按我们最初设定的标准,**实验成功了**。但达成成功的不是任何单个巧妙回合,而是循环。
此仓库的两千行代码不是一次性响应的产物,而是迭代过程的沉淀。几乎每行非显而易见的代码在你知道需要编写时都很廉价,昂贵之处在于知道需要编写什么本身。
这意味着代理能否在无人监督下成功实现目标,取决于是否有一个能针对真实环境约束收敛的迭代循环。这使代理能迭代地发现并体验真实世界的复杂性。
## 运行自主循环的经验教训
从实验中我们了解到编程代理能通过循环自主解决任务,但更重要的是我们获得了关于设计有效循环的两个宝贵经验,这些已成为我们工程团队当今的日常实践。
### 为多领域专家指定目标
实验表明编程代理是多领域专家,覆盖了我们任何工程师都不具备的专业跨度。结果证明它既知道OpenAI的cl100k正则表达式,也知道Rust的`rayon`。我们能配备的人员无人兼知两者。这改变了我们指定目标的方式,感觉更像是在与另一个团队的同事交谈,而对方恰好也了解你的领域知识。
思考将此问题交给缺乏分词器背景的强软件工程师实际需要什么。显而易见的答案是为他们编写详细规范。这是专业知识传递的经典困境:规范太短,工程师必须自己缓慢摸索全部内容;规范足够长以真正可操作时,你已写了伪代码,此时你需要自己掌握领域知识且几乎能自行完成工作。
LLM没有这种困境,因为它自带背景知识。这改变了规范的本质。我们的规范很短,描述结果和约束而非机制。
以规范中的真实示例为例:“*在训练开始前为所有两位和三位数保留词汇*”。对无背景的工程师而言,这是个任意要求。他们可以字面实现但仍然出错,因为这句话不包含自身动机。这是为给模型一致的数字表示,使算术不依赖于语料库中偶然高频出现的数字对,例如,想想GPT-2的分词器因训练数据频率而拥有唯一的*2019*词元却没有*2029*词元。不知道这点,他们无法判断指令的哪些部分关键、它在流水线中属于何处,或它对设计的其他影响。
### 针对现实世界约束进行验证
我们的操作者从未读取过生成代码的任何一行。这之所以可接受,是因为成功标准是代理无法操纵的。我们在循环设计中常见的错误是验证薄弱:使用玩具规模数据运行,或允许代理影响,如编辑自身的单元测试。
主要经验是设计一个针对现实约束收敛的循环,需包含以下组件:
1. **针对真实生产数据进行大规模迭代**。关键失败在测试套件中不可见,仅能在全量生产数据中发现。
2. **使用外部工具验证**。这使自主性变得可接受。操作者从未阅读代码,这仅在正确定义由代理未编写且无法影响的tiktoken和Hugging Face分词器确定时才可容忍。若我们接受其自身测试套件为证据,将得到两个通过各自测试但产生静默不同词汇表的实现。构建问题使第三方能评判产出物。
## 如今的常规实践与未来展望
这些是我们在2025年底进行的实验的结果和教训:是的,编程代理能自主从零开始解决生产级问题,无人监督,但仅当它们在循环内运行时才成立。
我们获得的经验已成为当今工程团队的日常实践。半年后,指定目标是我们投入最多精力的部分,而基于真实数据和外部验证构建循环已成为标准实践。
如今我们运行的循环已远超分词器训练器这类一次性构建——它有明确、可验证的终点目标供循环收敛。我们现在运行的许多循环是开放式的,朝向无单一正确答案的目标持续优化:调整内核、监控持续集成、分类传入拉取请求,或扫描生产日志中的异常。每次我们都检查指标而非代码。
如今的模型显著进步,但使这成为常规的是它们足够可靠,可交出整个循环的控制权。**如果这种可靠性普及,这将是ML和软件工程协作方式比任何编码能力提升更重大的转变。**
## 获取方式
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.
相似文章
构建自修复智能体循环(39分钟阅读)
本文介绍了一种使用OpenAI的Codex构建自修复智能体循环的方法,智能体通过结构化反馈循环迭代地审查、修复和验证输出,并提供了一个修复过时API文档的实例。
@shmidtqq: https://x.com/shmidtqq/status/2068704187492221405
一份关于AI编程代理循环工程的深入指南,解释了如何构建自动循环来重复提示代理、验证结果并避免失控成本,并通过一位工程师一个月内提交259个拉取请求的案例研究加以说明。
@bibryam: 实用循环工程 https://addyo.substack.com/p/practical-loop-engineering… @addyosmani 讨论目标、循环、等
Addy Osmani 讨论了面向AI代理的实用循环工程,涵盖目标、自主反馈循环,以及使用Claude Code和Codex等工具来管理并行代理任务。
@akshay_pachaar:关于循环工程。这周大家都在说同一件事。你不再提示代理,而是设计循环来提示它们……
这篇文章讨论了AI代理的循环工程,并介绍了Opik——一个来自Comet ML的开源工具,用于生成式AI应用的调试、评估和优化,重点在于自动化失败处理以及根据真实失败构建回归测试。
@jasonzhou1993: https://x.com/jasonzhou1993/status/2067937943545897143
循环工程是一种系统设计实践,让AI代理自主决定工作内容、执行并迭代,通过构建跨领域复合的外循环来超越手动提示。文章解释了两层代理框架,以及如何在循环间共享工件以促进累积学习。