当 AI 代理在同一个代码库的不同分支上并行工作时,如何让每个代理拥有独立的运行时环境来进行测试与验证?这正是 Coasts 要解决的核心问题。Coasts(Containerized Hosts for Agents)由 coast-guard 团队开发,旨在为 AI 代理提供隔离、可切换的容器化运行时,让代理能够在多个 git worktree 上独立执行测试,而无需修改原有的 docker-compose 配置。

核心问题与设计动机

在传统的开发流程中,开发者习惯于使用 git worktree 在同一仓库下并行维护多个分支。然而,当引入 AI 代理时,问题变得复杂:代理需要对代码进行修改并立即验证运行结果,但 docker-compose 设计上是为单一实例服务的。当多个代理同时在不同的 worktree 上工作时,端口冲突、卷挂载混乱、服务相互干扰等问题层出不穷。团队在早期使用 Codex 和 Conductor 时,被迫编写大量临时方案来为代理提供隔离的运行时,最终决定将这套方案抽象为独立工具,也就是今天的 Coasts。

Coasts 的核心设计理念是将「运行时」与「代码仓库」解耦。每一个 coast 实例本质上是一个 Docker-in-Docker(DinD)容器,内部运行着完整的服务栈,而外部则通过特定的挂载机制实现工作树的热切换。这意味着代理可以在宿主机上进行代码编辑,同时通过 coast exec 命令在特定的 coast 实例中执行测试,整个过程无需重启容器或重新构建镜像。

技术实现:mount propagation 与工作树热切换

Coasts 最关键的技术创新在于利用 Linux 的 mount propagation 机制实现工作树的热切换。当用户在项目根目录创建 Coastfile 并执行 coast build 时,系统会基于指定的 docker-compose 文件构建一个 Docker 镜像。这个镜像并非最终的服务镜像,而是一个包含 Docker 守护进程的「主机镜像」,用于在容器内部再运行一套完整的 docker-compose 服务。

工作树切换的具体实现包含三个核心步骤:首先执行 umount -l 卸载当前的 /workspace 目录;然后使用 mount --bind 将新的 worktree 路径挂载到 /workspace;最后通过 mount --make-rshared /workspace 设置共享挂载传播。rshared 标志的作用尤为关键 —— 它使得内层 Docker 守护进程能够感知到外层挂载的变化,从而无需重启即可访问新挂载的代码内容。这套机制使得工作树切换延迟从最初的约 2 分钟降低到优化后的 8 秒左右,为代理的快速迭代提供了基础设施保障。

配置文件与核心命令

Coasts 的配置通过 Coastfile 完成,通常放置在项目根目录。配置文件需要指定 docker-compose 文件路径、期望暴露到宿主机的动态端口列表、以及工作树的存储路径。例如,配置文件可能指向~/.codex/worktrees 作为所有 worktree 的根目录,并声明需要暴露的端口如 3000(前端服务)和 5432(数据库)。

核心命令集包括:coast build 用于基于 docker-compose 构建 coast 镜像;coast assign 将指定的 coast 实例分配给特定的工作树;coast exec 用于在 coast 内部执行命令,如运行测试套件;coast lookup 允许代理从当前工作树查询所属的 coast 实例名称;而 coast checkout 则通过 socat 将 coast 的典型端口绑定到宿主机,适用于需要接收外部 Webhook 回调的场景。这些命令共同构成了代理与隔离运行时之间的交互接口。

per-service 策略与性能优化

Coasts 引入的 per-service 策略机制是另一个重要的工程优化点。在配置中,用户可以为每个服务单独指定切换工作树时的行为策略:none 表示完全不处理,适用于代码变化不影响该服务的场景;hot 表示保持服务运行状态,仅重新加载代码;restart 表示重启服务进程;rebuild 则表示重新构建容器。通过精细的策略配置,团队将大规模代码库(超过 100 万行代码)的工作树切换时间从约 2 分钟压缩到 8 秒左右,这一优化对于需要频繁切换上下文的代理工作流至关重要。

此外,Coasts 支持灵活的状态拓扑配置。用户可以选择为每个 coast 配置独立的数据库卷以实现完全隔离,也可以将某些服务(如缓存、消息队列)配置为共享模式以降低资源开销。对于数据库这类有状态服务,团队建议根据测试场景选择:集成测试优先使用独立数据库以避免相互干扰,而 UI 测试则可以使用共享服务以减少资源浪费。

工程落地要点

在生产环境中部署 Coasts 时,有几个关键参数值得关注。首先是工作树切换延迟,理想情况下应控制在 10 秒以内,这要求对不敏感的服务配置 none 策略。其次是端口管理,Coasts 通过动态端口映射避免冲突,但如果项目中有硬编码的端口,建议使用 coast checkout 将特定 coast 的端口固定到宿主机。资源隔离方面,每个 coast 实例都会消耗额外的 Docker overlay 存储空间,需要根据并发代理数量预留足够的磁盘容量。最后,secrets 管理是 Coasts 的优势之一,工具内置了对敏感信息的处理机制,避免了在多个 worktree 间同步凭证的风险。

从架构角度看,Coasts 填补了代理运行时基础设施的空白。它不依赖于特定的代理框架或 Harness,而是通过提供统一的运行时抽象,实现了对任意在宿主机侧运行的代理的兼容。这种解耦思路值得在构建 AI Agent 平台时借鉴 —— 将生命周期管理与运行时隔离分离,让代理专注于任务逻辑,而非被基础设施细节所束缚。

资料来源:Hacker News 讨论(https://news.ycombinator.com/item?id=47575417)、Coasts 官方文档(https://coasts.dev)