Outposts 目前处于抢先体验阶段。此处介绍的 API 和 CLI 命令可能会发生变化。
如需为你的组织启用 Outposts,请联系你的账户团队。
- 让会话在你的网络内部运行,并靠近内部服务、制品仓库和 secrets
- 自定义硬件配置 (例如 GPU、大内存机器、特定的操作系统镜像)
- 使用现有的开发机、VM 或 Kubernetes 基础架构承载 Devin 工作负载
- 对网络访问、构建产物和监控进行企业级控制
工作原理
-
工作器 (例如
devin worker start) —— 这是一个你在某台机器上运行的二进制程序,用于处理单个排队中的会话。它会向 Devin 云端发起出站连接,并在本地执行该会话的工具调用。这个二进制程序由 Cognition 提供;你无需自行实现。Devin CLI 包含获取并执行这个二进制程序的逻辑。 - 编排器 —— 这是用于监控 fleet API 中等待工作器处理的会话、为每个会话预配一个 VM 或容器并在其中启动工作器的软件。我们为常见平台 (如 Kubernetes) 提供了一些参考实现,但你完全可以按需改造它们 (它们是开源的!) 或自行编写。
先决条件
- 已启用 Outposts 的组织
- 具有相应 Outposts 作用域的 v3 API 令牌:
- 供管理 outposts 的编排器使用的
account.outposts.orchestrator(也包含 machine 作用域) - 供工作器读取队列并认领/释放会话的
account.outposts.machine
- 供管理 outposts 的编排器使用的
- 一个机器镜像 (VM 或容器) ,并满足以下条件:
- 已安装 Devin CLI
- 具备下方的机器依赖
- 已克隆你的代码仓库,并已配置远程仓库
- 可访问你的会话所需的构建工具、软件包注册表、secrets 和内部服务
机器依赖
可选 — 安装以下依赖以启用特定功能:
快速入门:创建一个 outpost 并运行工作器
devin worker start 为其提供服务——无需编排器。这是在开发机上试用 Outposts 的最快方式,而同一个工作器命令也是编排器在大规模运行时使用的。
1. 创建服务用户令牌
UseOutpostsMachine → account.outposts.machine,ManageOutpostsOrchestrator → account.outposts.orchestrator) 。在 Devin Web 应用中:
- 创建角色并授予 Outposts 访问权限。在 Settings → Roles 下,添加一个企业级角色,并在 Outpost permissions 下启用 Use outpost machine (
UseOutpostsMachine)。如果该服务用户需要创建或删除 outpost,也请启用 Manage outposts (ManageOutpostsOrchestrator)。 - 预配服务用户。 在 Settings → Devin API → Service users 下,点击 Provision service user,为其命名 (例如
outposts-worker) ,分配步骤 1 中的角色,并设置过期时间。 - 复制令牌。
cog_...令牌只会在创建时显示一次——请立即复制;之后无法再次获取。
2. 创建一个 outpost
outpost_env-...) ——请记下它,供下一步使用。你也可以在 web app 的 Settings → Outposts 中创建 outpost,或通过 outposts API 创建。
创建后,启动会话时,outpost 会作为 Devin Cloud 中的一个 machine 选项出现 (与 Ubuntu、Windows 等并列) 。
3. 运行工作器
devin-remote 二进制程序,并处理该会话。会话结束后,它会返回队列,等待下一个会话。或者,传入 --once 可在处理完一个会话后退出;传入 --session=<session_id> 可接取并处理某个特定会话。
如果 --token 和 DEVIN_OUTPOSTS_TOKEN 都未设置,该命令会报错。如果在交互式终端中省略 --outpost,工作器会提示你从你账户的 outpost 中选择。
4. 在 outpost 上启动会话
在 Kubernetes 上运行?开源
devin-outpost-k8s
operator 可通过 Helm 安装,并可在任何经过认证的
集群 (GKE、EKS、…) 上为 outpost 运行工作器。从该 repo 的克隆副本中运行:
核心流程
1. 注册一个outpost
rhel、gpu-h200 或 my-outpost) 。使用 devin worker outpost create 创建一个outpost:
在 fleet API 中,outpost 表示为
outposts 资源,作用域限定在
你的账户下 (由该账户中的所有组织共享) 。2. 轮询 fleet API,查找等待中的会话
items 字段中:
cursor 进行分页,避免反复对整个
队列做全量同步。将 first 设为页面大小 (最多 200) ,然后在 has_next_page
为 true 时,将每次响应中的 cursor 传入下一次请求:
metadata.session_id 对条目执行 upsert,而不是
将每一项都视为新条目。当 has_next_page 变为 false 时,将返回的 游标 保存为 watch API 的起始位置。
监听变更
MODIFIED 事件;当其被移除时,会发送 DELETED 事件。新进入队列的会话也会以 MODIFIED 事件的形式到达。每个 SSE data 字段都包含如下结构的 JSON:
cursor。如果连接
关闭,请使用上次持久化的 游标 重新连接,以重放断开期间
发生的任何变更。Watch 投递同样也至少一次,因此客户端
必须能够容忍重复事件。流最多持续五分钟;因此预期
使用可重连的 watch 循环。
outpost 过滤器同时适用于列表请求和 watch 请求。phase 和
acceptor_id 过滤器仅适用于列表请求,并会在
watch=true 时被忽略;请使用每个事件的 object 中的字段来过滤监视到的事件。
省略 游标 会从头开始,因此常规对账请使用先 list 后 watch 的方式。
在为会话启动机器之前,先以原子方式将其认领,以免被其他工作器获取。传入一个 acceptor_id —— 这是你的工作器自报的身份标识:
409。认领后,系统会确保在 server 分配的认领截止时间 (status.claim_deadline) 前有一个工作器就绪;过期的认领会自动返回队列。如果预配失败,请释放该认领,以便会话立即返回队列:
3. 启动一台机器并运行工作器
devin worker start 时所在工作目录的相对路径下:
repos
app
.git
infra
.git
repos/ 目录下运行 devin worker start,这样该会话就会将 app/ 和 infra/ 识别为相对于其工作目录的路径。
常用标志:
示例:
4. 直接获取远程二进制程序
devin worker start 命令会自动下载正确的 devin-remote 二进制程序。如果你构建的是不使用 Devin CLI 的自定义编排器,也可以直接从以下位置获取该二进制程序:
如果该会话的队列条目包含
spec.remote_binary_sha,请使用该 SHA,而不要使用 latest——这会将该会话固定到某个经过测试的特定版本。
启动约定
devin-remote,请按以下方式启动它:
为 remote 提供一个干净的环境,只包含上述变量以及基础系统变量 (
PATH、HOME、USER、LOGNAME、TMPDIR、LANG、TZ,以及——对于 Linux/X11 上桌面流的屏幕捕获——DISPLAY、WAYLAND_DISPLAY、XAUTHORITY) 。不要将任何 Agent 不应看到的内容泄露给 remote:这些内容会被 Agent 的 shell 继承。
额外的生命周期要求:
- 工作目录:从包含该会话代码仓库的目录启动 remote (与
devin worker start的规则相同) 。 - 会话结束:当会话结束 (进入休眠或终止) 时,Devin 会通知 remote,随后它会自行以状态码 0 退出。将正常退出视为会话结束:确认队列条目的
status.session_status为suspended或terminated(状态更新可能会比退出晚几秒,因此请重新读取几次) ,然后释放认领。作为回退方案,还应在 remote 运行期间轮询status.session_status,并在其变为terminated时 (或队列条目消失时) 自行终止该进程。
5. 在工作器 退出时终止机器
devin worker start 退出时,该会话即告结束 (或已暂停) 。终止 VM 或容器。如果你的 outpost 支持恢复,请在终止前为机器创建快照,以便在会话恢复时还原。
你的编排器可以跟踪其已认领的会话及其状态:
status.session_status 值为 pending、running、suspended 或 terminated。
无需中心化的调度
计划运行超过约 16 个协调器 (从 outpost 中 watch 并认领的工作器或编排器) ?请先联系你的账户团队——更大的集群会加剧认领竞争并增加队列读取负载,我们希望确保该 outpost 已为此完成相应容量配置。
- 认领是唯一的协调原语。 每个工作器都会独立 watch 队列,并竞争认领待处理会话。认领是服务器上的原子 compare-and-swap 操作:最终只会有一个工作器成功,其他所有失败者都会收到
409,然后直接继续处理下一个待处理会话。认领竞争失败是正常情况,不是错误。 - 每个工作器都有自己的身份标识。
acceptor_id会将工作器的认领、续期和重启恢复限定在该工作器自身。devin worker start会为每台 machine 自动生成并持久化一个,因此整个集群无需额外配置身份标识。绝不要在多台 machine 之间共享 acceptor ID (或复制的工作器数据 directory) ——发生冲突的工作器会互相抢走对方的认领。 - 故障可自行恢复。 如果工作器在认领后宕机,其认领会在认领 deadline 到期时失效,该会话会重新回到队列,由其他工作器接手。无需在集群层面跟踪健康状态。
- 使用 watch 端点,而不是反复完整列出。 先执行一次分页 list 来建立初始状态,然后基于返回的游标保持一个 watch stream。如果每个工作器都重复 poll 整个队列,扩展性会很差,还会增加认领延迟;watch stream 会在变更发生时立即传递更新。
- 单个 outpost 超过约 16 台 machine 前,请先联系我们。 无协调认领在小规模工作器集群下效果很好,但更大的集群会加剧认领竞争并增加队列读取负载。如果你计划让单个 outpost 接入超过约 16 个工作器,请先联系你的账户团队,以便我们确保该 outpost 已为此完成相应容量配置。
API 参考
https://api.devin.ai/opbeta 下,并采用统一的资源结构 (metadata / spec / status) 。列表响应会返回 items、cursor、has_next_page 和 total。
Devins (/outposts/devins)
Outposts (/outposts)
status.queue_depth 和 status.active_claims 是很有用的自动扩缩容指标:如果队列开始积压,你的编排器可以预配更多预热机器。

