Kiln AI 开源 Seahaven:构建智能体评测与 RL 环境的 Python 框架
Show HN: Seahaven – Open-source framework for building RL environments
Kiln AI 团队开源 Seahaven,一个用于构建合成世界、支撑智能体评测与 RL 的 Python 框架。每个世界实例拥有独立 SQLite 数据库,支持并行实例、固定时钟与随机种子复现,并按智能体改动的状态而非对话记录评分。框架提供 OpenEnv 服务接口、Web 控制台和 MCP 接入,附带 ProjectTracker 与 Stripe World 等示例世界,采用 MIT 许可。
用于智能体评估和强化学习的合成世界框架。
评估和强化学习需要成千上万次智能体运行,每次运行都相互隔离,从已知状态开始,并根据智能体改变了什么来评分。生产系统做不到这一点。Seahaven 是一个 Python 框架,用于构建能够做到这一点的合成世界:你的智能体工具的工作副本,逼真到智能体无法分辨真假。
Seahaven 处理困难的部分:并行实例、可复现性、服务和变更日志。你只需编写你的世界特有的内容:它的表和它的工具。
以《楚门的世界》中的小镇命名:一个完整的世界,只为让一位居民相信它是真实的。
功能
逼真的世界
- 重建任何环境:模拟 AI 工具调用、REST API、沙箱化 SQL、搜索或任何自定义格式。
- 有状态:世界的每个实例都有自己独立的 SQLite 数据库。
- 可组合:组合、复用和共享世界。例如:MyCoWorld 可以包含 StripeAPIWorld 和 ShopifyAPIWorld。
为评估和强化学习而构建
- 夹具:冻结已知的起始状态,如
small_startup、agency或big_co,并在多次运行中复用它们。 - 并发实例:每个进程服务数百个世界实例,每秒处理数千个请求。
- 评估世界状态:根据状态评分,而不是根据记录。智能体更改的每一行都会被记录。
- 可复现:相同的初始状态(夹具)、相同的时钟/时间、相同的随机种子:每次都是相同的运行。
连接一切
- OpenEnv:
seahaven serve是一个 OpenEnv 环境。用任何语言的任何 OpenEnv 客户端驱动它,或将其发布到 Hugging Face。 - Web 控制台:
seahaven serve包含一个 Web UI:在浏览器中打开实例、调用工具并检查状态。 - MCP:
seahaven mcp向 MCP 客户端提供一个世界,这样你就可以从编辑器或聊天应用手动操作它。
易于构建
- 为编码智能体而构建:文档针对编写世界的智能体进行了优化。
seahaven check会告诉智能体每个错误的确切修复方法。 - 纯 Python:工具就是函数。测试使用 pytest。你的智能体已经知道如何编写和测试 Seahaven 世界。
Seahaven 与真实系统和模拟的对比
| Seahaven | 生产或预发布环境 | 手写模拟 | |
|---|---|---|---|
| 逼真的工具和数据 | ✅ | ✅ | ❌ |
| 跨任意工具调用的有状态 | ✅ | ✅ | ❌ |
| 每次运行都有私有实例 | ✅ | ❌ | ✅ |
| 数百个并行实例 | ✅ | ❌ | ✅ |
| 每次运行都从已知状态开始 | ✅ | ❌ | ✅ |
| 可复现 | ✅ | ❌ | ✅ |
| 每次更改都记录以便评分 | ✅ | ❌ | ❌ |
| 智能体可以安全地破坏东西 | ✅ | ❌ | ✅ |
快速开始
创建一个世界。这会写入一个完整的项目:schema、工具、测试、夹具生成器,以及一个 AGENTS.md,将你的编码智能体指向文档。
uvx seahaven new crm_world # your world name cd crm_world && uv sync
编写你的世界。一个世界就是一个 schema 和一组工具。这里是一个小型 CRM:
import seahaven world = seahaven.World( name="crm", version="1.0.0", schema=""" CREATE TABLE contacts ( id TEXT PRIMARY KEY, email TEXT NOT NULL, stage TEXT NOT NULL, updated_at TEXT NOT NULL ) STRICT; """, state_format="seahaven.state/1", ) @world.tool def create_lead(ctx: seahaven.Ctx, email: str) -> dict[str, str]: """Add a contact to the pipeline as a new lead.""" lead = {"id": ctx.ids.uuid(), "email": email, "stage": "lead", "updated_at": ctx.clock.iso()} ctx.db.execute("INSERT INTO contacts VALUES (?, ?, ?, ?)", *lead.values()) return lead @world.tool def list_stale_leads(ctx: seahaven.Ctx) -> list[dict[str, object]]: """List leads nobody has touched in 30 days.""" return ctx.db.rows( "SELECT * FROM contacts WHERE stage = 'lead' " "AND updated_at < strftime('%Y-%m-%dT%H:%M:%fZ', 'now', '-30 days')" )
冻结起始状态。夹具是一个冻结的数据库,每次运行都从它开始:
with world.instance(now="2026-06-01T09:00:00.000Z", clock_mode="fixed") as inst: for n in range(500): inst.call("create_lead", email=f"lead{n}@example.com") inst.freeze("big_co", "A pipeline of 500 new leads.")
运行你的智能体。每次运行都会在几毫秒内获得夹具的私有副本。相同的种子会重放相同的运行,而智能体更改的内容就是你要评分的文档:
for rollout in range(100): with world.instance("big_co", seed=rollout) as inst: run_agent(inst) # your agent, your harness reward = grade(inst.state()) # every row the agent changed
部署它。seahaven serve 托管一个 OpenEnv 端点,每个连接都会获得自己的实例。打开 http://127.0.0.1:8000/console 手动操作它。
uv run --extra serve seahaven serve
from seahaven.openenv import SeahavenClient with SeahavenClient(base_url="http://127.0.0.1:8000") as env: env.reset(fixture="big_co", seed=42) env.call("create_lead", email="ada@example.com") final_state = env.state() # the document the eval grades
示例世界
- ProjectTracker:参考世界,一个仿照 Linear 或 Jira 构建的虚构问题跟踪器。九张表、25 个工具、全文搜索,以及从空工作区到拥有六个月历史的十二人机构的测试数据。从这里开始学习这些模式(演练)。
- Stripe World:Stripe 的 Billing 和 Payments 核心的模拟版本,拥有 24 张表和 155 个 API 操作,与 Stripe 自己的 MCP 服务器使用相同的工具。它还提供 Stripe 的 REST API,因此 Stripe SDK 可以原样对其使用。
组合世界
构建一次世界,随处复用。一个公司世界可以添加一个支付世界,例如 Stripe World,以及一个聊天世界,再加上它自己的表和工具。智能体看到的是一个工具列表,而评估会根据一个状态文档对每个世界中发生的变化进行评分。参见组合文档。
company.add_world(payments_world.world, name="payments", tool_prefix="pay_") company.add_world(chat_world.world, name="chat", tool_prefix="chat_") @company.tool def refund_order(ctx: seahaven.Ctx, charge_id: str, channel: str) -> dict[str, object]: """Refund a charge and tell the support channel it is done.""" refund = ctx.worlds.payments.call("create_refund", charge_id=charge_id) ctx.worlds.chat.call("post_message", channel=channel, text=f"refunded {refund['amount']}") return refund
使用 OpenEnv 部署
seahaven serve 将你的世界托管为 OpenEnv 环境,这是 RL 环境的开放标准。每个连接都会获得自己的私有实例。每个进程可以托管数百个并行实例。可以从 Python、从 Kiln,或从任何 OpenEnv 客户端(例如 OpenEnv 自带的通用客户端)来驱动它:
from openenv import GenericEnvClient from openenv.core.env_server.mcp_types import CallToolAction with GenericEnvClient(base_url="http://127.0.0.1:8000") as env: env.reset(fixture="big_co", seed=7) create = CallToolAction(tool_name="create_lead", arguments={"email": "ada@example.com"}) env.step(create.model_dump()) final_state = env.state()
有关客户端、线路协议和生产环境运行,请参阅部署文档。
与 MCP 客户端一起使用
seahaven mcp 将世界连接到 Claude、Cursor 或任何 MCP 客户端。手动探索世界、调试你的工具,或者在交给智能体之前自己尝试一个任务。
uv run --extra mcp seahaven mcp --fixture big_co
用你的编码智能体构建世界
Seahaven 专为编码智能体构建而设计。seahaven new 会写入一个 AGENTS.md,将你的智能体指向你所安装版本的文档,而不是网络上过时的文档。seahaven check 会捕获那些容易犯且难以察觉的错误,并指出修复方法。
贡献
有关设置和 CI 运行的检查,请参阅 CONTRIBUTING.md。
许可证
MIT。
由 Kiln AI 创建
Seahaven 由 Kiln 背后的团队构建,Kiln 是一个免费应用和开源库,用于构建更好的 AI 产品。Kiln 可以连接到任何 Seahaven 世界:针对测试数据编写场景,评估你的智能体留下的状态,然后针对这些评估自动优化提示词和模型。
来源:Hacker News · github.com
