
Terrarium:面向 LLM Agent 的多轮数据引擎
我们开源了 Terrarium。它是一个用于评估和优化 LLM 智能体在“动态环境”中表现的多轮数据引擎。你可以把它理解成一个给智能体使用的“生态箱”——你构建一个封闭但持续运转的世界,把智能体放进去,然后观察它如何行动。
这个领域中的空白
我们评估智能体的方式,大致经历了三个阶段。
阶段 1:静态问答(Static QA)。 第一代 LLM 评估非常直接——单轮问答,并通过与标准答案比对来评分。没有环境,也没有工具。像 lm-evaluation-harness 和 lmms-eval 这样的框架定义了这一时代,并且至今仍然是衡量基础模型能力的标准。
阶段 2:单轮智能体(Single-turn agents)。 随着 LLM 获得工具使用和代码执行能力,一类新的基准测试出现了。像 Harbor 这样的框架会预置静态沙箱——一个容器、一个数据库、一组文件——然后让智能体在单轮中执行多步任务。验证只在最后通过测试脚本进行一次。这种方式很适合编码任务和简单工具调用,但环境只会被初始化一次,不会在智能体之外独立变化。
中间的空白。 现实世界中的智能体并不是在单一时刻工作的。一个个人助理可能会检查邮件、发现会议冲突、重新安排日程、再起草一封回复——这一切是随着时间推进、跨多个轮次发生的,而且环境会在每一轮之间发生变化。可能会有一封新邮件在任务中途到来;某条数据库记录被其他服务更新;某个文件出现在智能体本应监控的目录里。单轮框架会把这一切压缩成一次性完成——智能体只有一轮机会,而且环境不会自己发生变化。它们对轮次之间会变化的环境、多轮智能体交互、或带循环和分支的任务逻辑支持都很有限。随着智能体从编码走向个人助理、工作流自动化和主动监控,这些限制就变成了根本性的阻碍。
阶段 3:动态环境中的多轮智能体(Multi-turn agents in living environments)。 Terrarium 正是处在这个阶段。任务本身是程序:它们构建一个“活着”的世界,在多个轮次中驱动智能体行动,并且可以在任意阶段验证结果。环境会在轮次之间演化。控制流会根据智能体实际做了什么而自适应调整。智能体还可以是主动型的——不仅仅对提示作出响应,还能监控变化并主动采取行动。
单轮多步(Single-turn multi-step)vs. 多轮多步(Multi-turn multi-step)。 单轮多步是指智能体接到一条指令后,通过多次工具调用来完成任务——一个轮次,多个步骤。多轮多步则是任务包含多个阶段:每个阶段之间,环境可能自行发生变化,新的上下文可能到达,下一条指令可能取决于之前发生了什么。每一轮本身就是一次多步交互。现有框架处理的是前者,Terrarium 为后者而生。
| 阶段 1:静态问答 | 阶段 2:单轮智能体 | 阶段 3:多轮智能体 | |
|---|---|---|---|
| 交互方式 | 单轮、单步 | 单轮、多步 | 多轮、多步 |
| 环境 | 无 | 静态沙箱 | 可组合、可变动 |
| 控制流 | — | 线性 | 支持循环与分支 |
| 验证方式 | 标准答案匹配 | 最终测试脚本 | 任意阶段的程序化检查 |
| 主动型智能体 | — | — | 支持 |
核心特性
- 动态环境(Living environments) —— 任务程序会在智能体各轮行动之间改变环境。新邮件会到达、数据库记录会更新、文件会出现——这让动态场景成为可能,而静态基准根本无法表达这些情况。
- 可组合能力(Composable capabilities) —— 可以在一个任务中自由组合多种能力(
email、calendar、postgres、notion等)。框架会负责环境预置、网络连接和资源清理。 - 纯 Python 任务 DSL —— 不需要 YAML 模式或配置语言。任务就是普通 Python 函数,可以直接写循环、分支和阶段性检查。
- 多轮任务形式(Multi-turn formulation) —— 不同于单轮基准里智能体只有一轮、环境不会自己变化,Terrarium 会把任务在时间中展开。智能体行动,时间流逝,环境变化,智能体再次行动——它必须适应一个已经与上次不同的世界。
- 支持主动型智能体(Proactive agent support) —— 原生支持心跳(heartbeat)和 webhook 等模式,让智能体能够监控、预判并主动行动。
演示视频
为什么是 Terrarium
你用纯 Python 编写任务程序。每个程序都会构建一个“动态环境”,在多个轮次中驱动智能体,并验证结果。下面是它在实际中的表现方式。
动态环境
现有框架通常只在一开始设置一次环境,而且环境不会在智能体之外独立发生变化——没有意外、没有任务中途的新变化。但真实工作流不是这样的。你在写回复的时候,收件箱还会持续收到新邮件;你在查询数据库时,其他服务可能已经更新了数据。Terrarium 允许任务程序在智能体轮次之间主动改变世界——新邮件到来、数据库更新、文件出现:
@entry(capabilities=["email", "workspace"])
def dynamic_workflow(env, agent):
env.email.send(from_addr="[email protected]", to="[email protected]",
subject="Q3 Report", body="Please prepare the Q3 report.")
agent.act("Check your email and start working on what's requested.")
# Between turns, new context arrives
env.workspace.fs.write_file("/root/data/q3_numbers.csv", updated_csv)
env.email.send(from_addr="[email protected]", to="[email protected]",
subject="Re: Q3 Report", body="Just uploaded the latest numbers. Use those instead.")
agent.act("Check for any updates before you finalize.")
# Agent should notice the new email and the new file, and adapt accordingly.
可组合能力
真实的智能体任务往往跨越多个服务——邮件、日历、数据库、文件系统、云 API。大多数框架要么把环境写死,要么把编排工作完全留给用户自己处理。在 Terrarium 中,你通过能力模块来组合环境——就像往生态箱里添加土壤、水和植物。声明你需要什么,框架就会自动完成资源预置、网络打通和销毁清理:
@entry(capabilities=["email", "calendar", "notion", "postgres"])
def composable_capabilities(env, agent):
env.email.send(...) # GreenMail 容器
env.calendar.add_event(...) # Radicale CalDAV 容器
env.notion.create_page(...) # Notion API
env.postgres.execute(...) # PostgreSQL 容器
目前内置了六种能力——四种基于沙箱(workspace、email、postgres、calendar),两种基于 API(notion、google_sheets)。它们都通过统一的接口来使用。
控制流
大多数现有框架通过配置文件或固定模式来定义任务。这对于线性工作流还可以,但一旦任务逻辑需要根据智能体行为进行分支,或循环直到满足条件,就会变得很别扭。Terrarium 的任务就是普通 Python 函数——循环、条件分支、中间检查,全部都是原生能力:
@entry(capabilities=["email", "notion", "calendar"])
def branch_and_loop(env, agent):
agent.act("Read my lecture notes and write a study guide in Notion.")
# Loop until the guide is detailed enough
original_length = len(get_text(env, page_id))
for _ in range(5):
if len(get_text(env, page_id)) >= original_length * 5:
break
agent.act("The guide is too brief. Expand it with more details.")
# Branch based on what the agent actually wrote
if "bellman equation" in get_text(env, page_id).lower():
env.email.send(from_addr="[email protected]", to="[email protected]",
subject="Rescheduled", body=RESCHEDULE_EMAIL)
agent.act("Check your email for updates.")
else:
agent.act("Email the professor requesting an extension.")
主动型智能体
大多数现有基准测试的都是被动型智能体——给一个提示,拿一个回应。但越来越多的智能体需要具备监控、预判和主动行动的能力。Terrarium 原生支持心跳和 webhook 等主动模式:
# Heartbeat pattern: agent receives periodic signals and must decide what to do
@entry(capabilities=["workspace"])
def proactive_heartbeat(env, agent):
agent.act("You'll receive periodic heartbeat signals. Check /root/results/ for new files each time.")
agent.act("[09:30] Heartbeat: check for changes.") # nothing — agent should do nothing
env.workspace.fs.upload(...) # file appears
agent.act("[10:00] Heartbeat: check for changes.") # agent should notice and act
# Webhook pattern: agent receives event notifications and decides how to respond
@entry(capabilities=["email"])
def proactive_webhook(env, agent):
agent.act("You'll receive email webhook notifications. Decide whether each needs a reply.")
env.email.send(from_addr="[email protected]", to="[email protected]", subject="Urgent: client meeting", body="...")
agent.act('{"event": "new_email", "from": "[email protected]", "subject": "Urgent: client meeting"}')
# Agent should read the email and reply.
env.email.send(from_addr="[email protected]", to="[email protected]", subject="Weekly digest", body="...")
agent.act('{"event": "new_email", "from": "[email protected]", "subject": "Weekly digest"}')
# Agent should ignore this one.
接下来要做什么
Terrarium 目前还处在早期阶段,我们还有很多想做的事:
- 更多环境能力——浏览器自动化、Slack、MySQL 等等
- 更多智能体适配器——Anthropic SDK、OpenAI、LangChain、本地模型
- 除 Docker 之外更多的沙箱提供方式
- 更多基准测试集成
- CLI 增强、异步执行,以及文档网站