跳到正文
Hacker News· shenli3514·· 5 天前AI 评分58

Ramet 发布面向 AI 智能体的持久化可 fork 工作区

Show HN: Ramet – Persistent, forkable workspaces for AI agents

AI 导读

Ramet 发布面向 AI 智能体的持久化、可 fork 工作区,可在会话与沙箱替换之间保存和恢复智能体文件及本地 Git 状态。它为每个会话或尝试提供基于共享不可变基底的独立可写工作区,支持 fork 隔离尝试、按路径策略选择性持久化,以及为 best-of-N 编码智能体保留指定结果。

正文 · AI 翻译

为 AI 智能体提供持久、可派生的可写工作区。

跨会话和沙箱替换保存并恢复智能体的工作。派生隔离的尝试,重置到干净的起点,并保留你选择的结果。

Ramet 为每个会话或尝试提供一个来自共享不可变基础镜像的隔离可写工作区。当你的运行框架显式捕获快照或提升选定状态时,更改才会变为持久。

自带你的智能体框架和沙箱。你的框架协调工作,你的沙箱运行它,Ramet 管理工作区生命周期。

你需要解决的问题 Ramet 处理的内容
在沙箱被替换时保留智能体文件 跨会话保存并恢复工作区文件和本地 Git 状态。
为并行智能体提供隔离工作区 来自同一基础的独立尝试、本地派生,以及针对 best-of-N 编码智能体的选择性持久化。
在 rollout 之间重置 RL 环境 在工作区复用前进行干净的文件系统重置和验证,以捕获污染。
运行可重复的智能体评估 通过共享内容、缓存和热池复用准备好的仓库和依赖。

使用 LangChain / LangGraph、CrewAI、AutoGen 或 SkyRL?

你的技术栈 集成路径
LangChain / LangGraph — 为使用工具的智能体提供持久文件 自定义工具/运行时集成;将 Ramet 快照 ID 与你的线程状态一起保存。
CrewAI / AutoGen — 为并行编码智能体提供隔离文件 自定义工具/执行器集成;为每个独立尝试分配一次执行。
SkyRL — 用于智能体 RL rollout 的工作区 可运行的 SkyRL-Gym 环境,已使用真实 worker 和 Docker 测试。
你自己的智能体或评估框架 Python / Go / HTTP 集成,附带同主机 Docker 适配器。

LangChain/LangGraph、CrewAI 和 AutoGen 需要应用适配器代码;不包含专用的 Ramet 插件。你的框架保留对话状态、编排、奖励和训练。Ramet 持久化文件系统状态;进程内存和外部服务需要各自的恢复策略。

为什么工作区状态需要不同的处理方式

智能体工作区将生命周期差异极大的文件混合在一起。一个本地提交可能是某项有用工作的唯一副本;一个依赖目录可以重建;一个临时文件可能只属于某一次尝试。保存所有内容会把可复现数据和临时数据带入每一个保存结果。丢弃所有内容则会丢失你无法重建的工作。

Ramet 让你在保存一次尝试时表达这些差异:

状态类型 示例 应保留的内容
共享不可变 固定数据集、准备好的只读输入 在各次尝试之间复用未更改的基础内容。
持久 源代码编辑、本地 Git 提交、选定的输出 保留当前状态,以便工作可以恢复。
可重建 依赖、生成的构建产物 保留重建配方,而不是生成的字节。
临时 临时文件、临时日志 将它们排除在保存结果之外。

你的 harness 分配路径策略;Ramet 不会推断哪些文件可以安全丢弃。这些策略在提升时生效,未分类的路径默认保留。初始快照和检查点会捕获所有受支持的文件;你的运行时执行重建配方。参见 持久化策略。在提升之前预览将要保存的内容,然后通过经批准的重建步骤进行恢复,并带有输入检查和应用程序就绪检查。

对于并行 agent,这意味着共享一个准备好的基础,隔离每次尝试的写入,并选择保留哪次尝试和哪个状态。一次性尝试无需保存快照。

开发 alpha · Linux & macOS · Apache-2.0

如何组合在一起

Framework integration calls Ramet through Python, Go, or HTTP. An immutable base supplies worker-local workspaces through copy/reflink or optional Linux FUSE. Your runtime attaches a local path and owns process cleanup. Captured snapshots persist locally or in PostgreSQL and S3.

你的 harness 通过 Python SDK 或 Go 客户端调用 Ramet:

  1. 准备:对项目进行快照或导入 Git 修订版,然后创建一个池。
  2. 获取:获取一个隔离的工作区,并将 execution.path 作为沙箱的工作区挂载传递给运行时。
  3. 运行:使用你现有的框架运行 agent 并评估其工作。
  4. 保存或回收:停止沙箱的写入者并卸载工作区;调用 promote() 保存选定的结果,然后释放执行。释放会重置工作区以供重用。

该路径属于 Ramet worker 的文件系统。将 worker 部署在可以挂载它的运行时旁边;远程 SDK 连接不会将文件传输到远程沙箱。你的运行时负责进程隔离、资源限制以及租约丢失时的清理。

涉及多少集成工作?

你的环境 连接它所需的工作
同主机离线 Docker 命令 使用随附的适配器:获取工作区,调用 runtime.run(),然后保存或释放。为 harness 崩溃添加 supervisor 清理。
你自己的容器或 VM 运行时 更改工作区分配,挂载返回的路径,并在超时、租约丢失和清理失败时实现运行时关闭。
没有 worker 路径附加的托管沙箱 首先解决文件系统附加问题;仅设置 SDK URL 是不够的。

你的 agent 循环和评估器保留在你的框架中。集成指南展示了需要更改的三个调用点、适配器草图以及验证环境的检查项。Python SDK 指南逐步介绍了设置、Docker 执行、持久化和并行尝试。

执行写入保持本地。显式捕获或提升以持久化状态。从本地存储开始;当快照需要在 worker 磁盘丢失后仍然存在时,添加 PostgreSQL 和 S3 兼容存储。在支持的情况下,写时复制共享文件数据,并以独立的完整副本作为回退。参见架构和运行时安全边界。对于尝试仅触及文件子集的大型快照,可选的Linux FUSE 后端会在首次访问时水合工作树文件。随附的 Docker 适配器使用复制/reflink;FUSE 需要自定义挂载附加。

快速开始

这个同主机设置介绍了用于本地开发和集成测试的 API。部署的 worker 在沙箱运行时旁边使用相同的生命周期。本地存储将快照保存在该 worker 的磁盘上;可选的 PostgreSQL 和 S3 兼容存储让替换 worker 可以恢复已发布的快照。参见部署和存储模式。

需要 Go 1.26.9+、Python 3.10+、Git 以及 Linux 或 macOS。 安装 CLI 和 Python SDK,然后启动本地 worker:

git clone https://github.com/shenli/ramet.git
cd ramet
go build -o bin/ramet ./cmd/ramet
python3 -m venv .venv
.venv/bin/python -m pip install ./sdk/python
./bin/ramet serve --data /tmp/ramet-data --listen 127.0.0.1:7433

让 worker 保持运行。在另一个终端中,从同一检出目录运行 以下命令,并传入项目的绝对路径。捕获快照期间,请将该 项目放在 /tmp/ramet-data 之外,并停止其写入者。

.venv/bin/python - <<'PY'
from ramet import Ramet

ramet = Ramet()  # Connects to http://127.0.0.1:7433.
base = ramet.snapshot(source="/absolute/path/to/your/project")

with ramet.execution_pool(base, concurrency=4) as pool:
    with pool.acquire() as execution:
        # Run your tools against this directory; the source project is untouched.
        print("Workspace:", execution.path)
        (execution.path / "result.txt").write_text("selected result\n")
        saved = execution.promote()  # Persist this attempt as a new snapshot.
    # Leaving the execution context resets and releases its workspace.

with ramet.execution_pool(saved, concurrency=1) as pool:
    with pool.acquire() as restored:
        print((restored.path / "result.txt").read_text())
PY

恢复后的工作区会打印 selected result。快照会持久保存在 worker 的数据目录中(使用持久目录而非 /tmp 以长期保留 它们);池和执行目录是临时的。本示例中 SDK 和 worker 运行在同一主机上。接入你的 运行时环境时,只挂载 execution.path,并在提升或 发布前停止其写入者;Docker 适配器会为容器命令 处理此生命周期。

如需现成的演示,请运行 ./bin/ramet demo 或按照 best-of-N 编码演示操作。

文档

基于 Apache-2.0 许可。参见 第三方声明。

来源:Hacker News · github.com