环境变量清单
这份清单用来查某个配置项:它由哪个组件读取、应该在哪里设置。应用自身的默认值和官方 Compose 部署里的值不一样时,两个都会列出来。
在本地搭环境,先看开发者指南。要部署,先看控制平面配置和主机配置。打包产物的说明见发布契约。从 HybridInference 沿用下来的名字仍在使用。
部署用的具体值不要放进这个公开仓库。
secret 放在运维人员私有的环境文件、systemd unit 文件,或只读挂载的密钥文件里。真实的标识、主机名、端口分配、隧道拓扑和应用注册信息,放在私有的部署 overlay 里。公开的示例都用
agents.example.org这样的占位符;文档里写到的协议端口和默认值,留在这里是安全的。
设置与初始化配置
Sandbox Manager 的新旧名称兼容
这个服务叫 Sandbox Manager(在 Compose 里是 sandbox-manager,在 Python 里是 cloud_agent_host.sandbox_manager)。新部署请用 AGENT_SANDBOX_MANAGER_* 这组名字;旧名字的值仍然认:
当前名称 |
旧名称 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
官方的主机部署脚本和本地部署脚本,会在调用 Compose 之前把旧的令牌名换成新的。如果你直接运行 docker compose,要自己提供 AGENT_SANDBOX_MANAGER_TOKEN,没有它 recipe 仍然会拒绝渲染。
激活主机时,会先排空并删掉旧服务,再创建新服务。旧的 DNS 别名和 Python 入口都还保留着,方便新旧版本混跑的部署。已保存的凭据仍用原来的加密域;这次改名不需要轮换 secret,也不需要数据库迁移。数据库里实际的 broker_url 列、主机通信里的旧字段,以及遥测的生产者 ID,都只是出于兼容保留的细节。新的 API 字段和代码都用 sandbox_manager_url;界面上统一显示 Sandbox Manager,旧的测量记录也一样。
持久的归档标记和删除回执也沿用原来的路径:保留沙箱里是 /var/lib/freeinference-broker,manager 里是 /var/lib/hybridinference/broker-archives。如果改了这些路径,已有的生命周期栅栏和待处理的删除回执就会被忽略。
配置放在哪里,取决于它控制的是什么:
应用行为、集成的 URL 和凭据、发布、Web 外观、运维相关的时间间隔、上传和 skill 的限制、任务标题,以及全局的沙箱和工作区限制,都在 Admin → Settings 里设置。
只对某一台服务器生效的沙箱和工作区设置,在那台服务器的 Servers 页面里设置。
初始化配置留在部署文件里,包括:数据库访问、加密根密钥、应急恢复访问、主机开通、网络、隔离、镜像和构建的来源,以及挂载路径。
保存下来的应用设置存在 Agent 数据库里,重启之后仍以它为准。下面的清单记录的是内置默认值,以及首次导入时读取的环境变量名。一项设置一旦登记进数据库,服务就不会再去 .env 里读它了。
启动这个版本之前,先运行 alembic upgrade head(升级到 0086_conversation_read_receipts);每个近期迁移改了什么,见升级说明。之后,主控制平面监听器会根据它现有的环境变量,把设置文档初始化一次。MCP 专用监听器会等这份文档准备好,并使用同样的已保存值。
首次导入之后,请在 Admin → Settings 里修改。之后再改环境变量,也不会覆盖已保存的值。Reset 会把设置恢复成内置默认值(凭据的默认值是空),而不是恢复成以前的环境变量值。各监听器每五秒同步一次改动;Web 服务器每次处理请求都会读取已保存的外观设置,不需要重新构建或重启 Web 镜像。
主机上的每一项沙箱或工作区设置,服务会按下面的顺序取第一个有值的:
给这台服务器单独保存的覆盖值;
管理员保存的全局值;
内置默认值。
迁移 0036_host_settings_import 会把旧版主机上有效、且不是默认值的设置,保存为这台服务器的覆盖值,前提是管理员还没有配置过它们。如果某台主机还没有上报完整的数据,就靠它最初的几次心跳完成导入。管理员编辑或重置某项设置时,只会把改动的那几项从待导入列表里去掉,其他旧值都保留。全局层面去掉的项,对新注册的主机同样有效。之后再改环境变量会被忽略。清除覆盖值后,会退回到全局值或内置默认值,绝不会重新启用以前的环境变量值。
沙箱归档只能在 Admin → Settings → Sandbox 里配置。Cloud Agent 把它作为一份带修订号的策略存在 Agent 数据库里,没有对应的 AGENT_SANDBOX_ARCHIVE_* 环境变量。存放位置固定为 s3://freeinference/cloud-agent/sandbox。保存的策略包括:是否开启、区域、上传大小的上限,以及一组 AWS 访问密钥,或者 workload identity 相关的字段(客户自管的 KMS 密钥 ARN 和预期的桶所有者)。secret access key 用设置加密密钥加密保存,管理 API 不会返回它。不配置访问密钥时,sandbox manager 会通过标准的 AWS SDK 凭据链,用部署本身的 workload identity 认证。IAM、桶版本控制、上线步骤和生命周期规则,见沙箱归档。
数据库里还存着控制平面的运行时身份、签名和加密密钥、sandbox manager 凭据、cookie 和代理策略、MCP 目标策略,以及默认的 execution profile。升级时,主监听器只导入这次迁移新增、且当前缺失的字段,绝不覆盖已有的值(哪怕是被重置成空的值),中继会等导入完成。身份签发方始终绑定在这个数据库上。已有的用户加密密钥和计算资源加密密钥,不能直接在设置编辑器里替换或重置,必须走单独的重新加密流程。
设置页面会标出缺失的必填项和没配完整的可选集成。如果网关登录还没准备好,管理员可以用 ADMIN_TOKEN 打开 <web base path>/setup。setup 页面用的是同一个带认证、带审计的设置 API。恢复令牌只保存在页面内存里,绝不会写进浏览器存储。
这些初始化配置要留在部署文件里:数据库访问;设置的加密根密钥(AGENT_SETTINGS_ENCRYPTION_KEY,旧部署可以退回使用环境变量 AGENT_SESSION_SECRET);管理员的应急恢复访问(ADMIN_TOKEN);主机注册和 sandbox manager 的开通;网络;隧道和监听器;主机实际使用的隔离方式;镜像和构建的来源;挂载路径;以及受信任的计算资源部署配置。它们要么用来连上数据库,要么用来配置控制平面以外的进程。设置页面上会列出它们的名字,但不显示值。
唯一的硬性规定
网关的
API_KEY_SECRET和JWT_SECRET_KEY,绝不能出现在这个仓库里、它的配置里,或者任何运行它的主机上。
推理授权由网关签发和校验。Cloud Agent 用公开的 JWKS 密钥校验身份令牌,用自己独立的 secret 给自己的令牌签名。谁要是提议把网关的任何一个签名密钥放到这边来,都必须先经过设计评审。
开通状态
最初拆分仓库时,staging 在 2026-08-06 开通,production 在 2026-08-07 开通,这段历史记在 cutover 记录里。这些日期说明不了现在的某套部署是否就绪。
这个仓库发布的是不绑定任何部署的中立版本。作为下游的运维方,你自己负责配置、开通状态、上线记录和恢复用的证据。secret 不要放进 Git,并且要和它保护的数据一起备份。
本地开发工具
这些值只给本地工具用,不是保存在数据库里的应用设置。
变量 |
取值 / 由谁提供 |
|---|---|
|
可选的输出目录,由运行 |
控制平面(cloud_agent)
本地和 CI 的权限回归测试
设置 AGENT_PERMISSION_TEST_IMAGE 后,会启用 tests/external/test_shared_member_permissions.py 里那项可选的 Linux UID 回归测试。它的值是一个已经拉取好的 Docker 镜像,里面要有 Python 3 和 GNU 的 find/stat,例如 python:3.12-slim。拉好镜像后运行:
AGENT_PERMISSION_TEST_IMAGE=python:3.12-slim \
uv run pytest -q -m external tests/external/test_shared_member_permissions.py
测试用的是没有网络、没有挂载的一次性容器,以不同的成员 UID、不带任何 capability 的方式运行生产环境的权限规范化程序。CI 会在部署前跑它;它不需要模型 API 密钥,也不依赖任何已部署服务的设置。
本地和 CI 的恢复回归测试
AGENT_RESTORE_TEST_IMAGE 指定 tests/external/test_checkpoint_restore_roundtrip.py 用的基础镜像,默认是 python:3.12-slim,需要事先拉到本地。这个测试像 Sandbox Manager 那样停掉一个对话容器、存下检查点,再把检查点作为更新的一代加载出来,经过归档的启动栅栏把容器启动起来,全程用真实的 Docker,只有 S3 换成了本地文件。运行:
uv run pytest -q -m external tests/external/test_checkpoint_restore_roundtrip.py
CI 会在部署前跑它;它不需要 S3 桶、模型 API 密钥,也不依赖任何已部署服务的设置。
数据库
变量 |
取值 / 由谁提供 |
|---|---|
|
Cloud Agent 独占使用的数据库的 Postgres DSN。不要和网关共用数据库。 |
|
官方控制平面 Compose 部署里,初始化数据库用的值。用户名和数据库名默认都是 |
|
|
用 pgAdmin 管理数据库
可选的 pgadmin Compose profile 会增加 Admin → Database → Open pgAdmin 入口。这个私有服务不对外发布端口。每个请求都要求当前确实有 agent.admin 权限;pgAdmin 自己还要求用它的账号登录。它的账号、会话和保存的连接都存在 agent-pgadmin 里。
变量 |
取值 / 由谁提供 |
|---|---|
|
可选。 私有的 pgAdmin 地址;用自带的服务时填 |
|
可选,用于覆盖。 完整的公开代理 URL,以 |
|
用仪表盘完成 setup 时必填。 用自带的服务时,设为 |
|
用仪表盘完成 setup 时必填。 只在初始化自带服务时使用的私有地址,一般是 |
|
可选。 首次 setup 时用的公开代理 URL,以 |
|
可选。 启动包装脚本:先等首次的仪表盘 setup 完成,再执行 pgAdmin 自己的入口程序。默认用自带的 |
|
可选。 只读的服务器定义 JSON。默认用自带的 |
|
可选。 pgAdmin 的 Python 布尔值,默认 |
网关契约
变量 |
取值 / 由谁提供 |
|---|---|
|
这套部署所对接的 HybridInference 网关的地址,例如 |
|
网关公钥集合的完整地址,通常是 |
|
用于签发、续期、撤销推理授权和查询用量的 Bearer 凭据。随机生成 32 字节。在 Admin → Settings 里保存的新值至少要 32 字节;以前保存或导入的较短的值仍然可以加载,但启动时会一直记录 |
|
可选,仅用于初始导入。 授权服务的路由前缀,默认 |
|
可选;建议在第一次启用账本功能的部署之前设置。 用来标识网关是哪一套安装的非敏感 ID。设置之后,即使网关的 URL、授权前缀或凭据变了,用量快照仍认这个 ID。切换到另一套网关安装时,要改这个值,即使 URL 没变也一样。不设置的话,指纹由 |
|
访问网关时必填。 网关签发令牌时使用的确切 |
|
授权确认页的完整地址,通常是 |
|
|
|
Web 应用的公开地址,包括 base path,例如 |
|
在沙箱内部看到的网关地址,也就是中继的地址,而不是公开地址。它和 |
本服务自己的 secret
变量 |
取值 / 由谁提供 |
|---|---|
|
可选的专用密钥,至少 32 字节,用来加密管理设置里的 secret。不设置的话,由 |
|
分别用不同的域分隔符,加密存储的代码托管凭据、每个用户的 MCP 凭据,以及可复用云环境里的变量和覆盖值。随机生成 32 字节,每个环境都不一样。在 Admin → Settings 里保存的新值至少要 32 字节;以前保存或导入的较短的值仍然可以加载,但启动时会一直记录 |
|
用来给主机和 worker 的控制令牌签名。随机生成 32 字节,每个环境都不一样,并且和网关的 secret 无关。在 Admin → Settings 里保存的新值至少要 32 字节;以前保存的较短的值仍然可以加载,但启动时会一直记录 |
|
给 Web 会话 cookie 签名。随机生成 32 字节,每个环境都不一样。 |
|
由服务端决定、用于新根对话的执行策略。应用自身的默认值是 |
|
用于 |
|
所有值班(on-call)任务都以这个网关用户 ID 的身份运行。它在网关上的权限决定了任务的授权能用哪些模型,分析消耗的也是它的配额。不设置的话,值班入口返回 503,服务的其他部分不受影响。 |
|
运维人员自己的 JSON webhook,接收队列事故、恢复和计算资源替换的事件。队列监控每分钟跑一次:连续两次观察到可运行的队首已经等了十分钟,就会报告;投递失败下一轮重试;状态没变的事故最多每 30 分钟重复一次。投递超时五秒。队列事件的内容包括事件名、部署 SHA 和汇总计数;计算资源事件还会带上 Host 身份和原因代码。不设置的话,仍然会写结构化日志。部署工作流本身的告警由下游发行版负责。这个 URL 永远不会进入 runner 或沙箱。 |
|
在两次主机心跳之间,成员那个独立加了栅栏的常驻进程 residency,以及它的短期推理授权,最多能存活多久。默认 1800。shared-live 模式下,每个对话成员关系对应一个 residency。它管的是凭据和进程的归属,并不是对话生命周期的第二个时钟:已结束的保留沙箱组什么时候停止,只由 |
|
可选的、机器对机器使用的管理凭据。不设置就不开放任何令牌访问;管理员通过会话登录是另一条独立的授权途径。请至少用 32 个随机字节;值太短的话,启动时会记录 |
沙箱删除前的归档
变量 |
取值 / 由谁提供 |
|---|---|
|
可选,仅用于初始导入。 存放已停止沙箱归档的 S3 桶。留空就不能删除沙箱。保存后对应 Admin → Settings → Application → Sandbox archives 里的 |
|
可选,仅用于初始导入。 归档桶所在的 AWS 区域。留空就用 SDK 标准的区域配置。 |
|
可选,仅用于初始导入。 可选的、兼容 S3 的 HTTPS 端点。它必须支持带条件的 |
|
可选,仅用于初始导入。 新归档请求使用的对象前缀,默认 |
|
可选的部署路径。 运维人员自己的私有 Compose 覆盖文件的绝对路径。 |
标准 AWS SDK 凭据 |
部署基础设施。 只在主控制平面上通过标准的 SDK 凭据链提供,最好用 IAM workload role。如果用环境变量或共享 profile 里的凭据,就把 |
权限、保留期和校验方面的要求,见沙箱归档存储。
控制平面读取的行为开关
变量 |
取值 / 由谁提供 |
|---|---|
|
Compose 层面的设置,由 |
|
edge 监听的地址和端口,默认 |
|
Compose 里主 API 绑定的地址和端口,默认 |
|
Compose 里 MCP 专用监听器绑定的地址和端口,默认 |
|
Compose 里 Web 服务器绑定的地址和端口,默认 |
|
edge 服务以只读方式挂载的、主机上的 nginx 配置文件。默认 |
|
控制平面 Compose 网络的名字,默认 |
|
默认开启。只有开发者在纯 |
|
默认关闭。在开发环境里设成 |
|
默认 |
|
默认关闭。只有当本部署自己控制的代理直接挡在控制平面前面、并且会写入 |
|
管理员设置页面用来查询每个 agent 最新版本、并核对指定版本是否存在的 npm 仓库,默认 |
|
这个 API 实际运行的确切 commit。生产环境的控制平面 Compose 要求设置它,由 |
代码托管
变量 |
取值 / 由谁提供 |
|---|---|
|
标识用于访问仓库的 GitHub App。设置后会加载密钥;密钥读取失败时,GitHub 功能会暂时不可用,每 30 秒重试一次。不设置的话,密钥相关的设置都会被忽略。请为这套部署配置好这个 App 的回调地址和安装地址。见凭据。 |
|
用户连接自己的 GitHub 账号时,用到的 GitHub App OAuth client ID。 |
|
GitHub App 的 OAuth client secret。不要放进 Git;App 的使用对象变了,就要轮换它。 |
|
初始化配置。 容器里只读 PEM 密钥文件的路径。官方 Compose 把它挂载到 |
|
主机上的密钥文件,由控制平面的 Compose 以只读方式挂载到 |
|
仅用于初始导入。 内联的 PEM 内容,给已经在用这种方式提供密钥的部署做一次性导入。Compose 不会转发这个变量。内联密钥请在 Admin Settings 里设置或替换,那里会加密保存,并且永远不会返回给浏览器。由部署方管理的密钥,仍可以用挂载文件的 |
|
Connect GitHub 流程使用的授权和安装地址,必须是 |
|
默认 |
|
用户连接 GitLab 时用到的 GitLab.com OAuth 应用 client ID。 |
|
GitLab.com 的 OAuth client secret,不要放进 Git。 |
|
在 GitLab 上登记的公开 OAuth 回调地址。必须用 HTTPS(localhost 开发环境除外),其他情况在保存或导入时都会被拒绝。部署地址变了,要同步更新 GitLab 上的登记。 |
|
用逗号分隔的 |
|
发布改动时使用的提交者身份,默认 |
|
没有 GitHub App 时,用于发布的备用 GitHub 凭据,可选。不设置也不会影响通过 App 发布。长期有效的发布凭据只留在控制平面,绝不进入沙箱。 |
|
pull request 的目标分支,默认 |
MCP
MCP 的发现、每个用户的凭据、授权和 attempt 栅栏,都由 Cloud Agent 负责。网关只提供推理,和 MCP 无关。
用户可以添加远程 URL、导入 mcpServers 配置片段,或者填写 stdio 启动参数。模板只是帮你预填连接表单;环境变量既不会添加服务器,也不会授予访问权限。凭据按用户存在 agent_mcp_connections 里,用 AGENT_SOURCE_CONTROL_ENCRYPTION_KEY 加密。下面这些设置控制中继能不能访问到,以及允许连接哪些目标。
变量 |
取值 / 由谁提供 |
|---|---|
~~ |
已移除。 现在没有部署级别的 MCP 注册表了。它以前指向一个文件,里面列着远程服务器和它们的凭据,任何能创建任务的用户都能以同一个身份使用这些服务器,这正是本产品不提供的"团队共用 MCP"形态。按用户的连接取代了它;中继、代理和沙箱边界都不变。之所以还列在这里、没有删掉,是因为已有的部署设置过它;一个悄悄失效的变量,比一个明确记录"已移除"的变量更坑人。 |
|
仅主机端使用。 本主机的沙箱访问 MCP 中继时用的地址。主机的 compose 会根据主机自己的 MCP 隧道得出它( |
|
MCP 专用的 SSH 隧道。必须设置的后缀有 |
|
中继在两个容器网络上的别名,默认 |
|
runner 专用、通往主 API 的 SSH 隧道。必须设置的后缀有 |
|
这条隧道的别名,只在 runner 网络上有效,默认 |
|
可选,用于覆盖。 用来登记和接收 MCP OAuth 回调的公开 API 基础地址,要包括 API 前缀,例如 |
|
可选,用于导入旧值。 GitHub MCP 的浏览器登录在 Admin Settings → MCP 里配置。先注册一个归服务方所有的 GitHub OAuth App 或 GitHub App,回调地址填 |
|
用户添加的 MCP 连接,能不能连私有地址和回环地址。默认关闭:一个远程连接要是能连到回环地址,连到的其实就是本服务自己;需要访问私有网络的用户,应该改为运行一个 connector。即使开启,平台从不连接的那些地址段仍然会被拒绝,所以没法借此访问云厂商的元数据服务。 |
|
用户添加的 MCP 连接,除了 |
|
不需要运维人员设置,列在这里是为了防止有人去配它。 runner 用这个名字,把中继端点以一个 |
|
不需要运维人员设置,列在这里是为了防止有人去配它。 生成的沙箱运行时配置用这个名字引用( |
在管理页面上设置的沙箱参数
主机设置可以在管理页面上统一设置,不必写进每台主机的 .env,包括 AGENT_TIMEOUT_S、AGENT_CHAT_IDLE_TIMEOUT_S、AGENT_SOURCE_IMPORT_MAX_MIB、AGENT_SHARED_RESIDENT_CAPACITY、AGENT_STORAGE_MIN_AVAILABLE_MIB、AGENT_SANDBOX_CPU_MILLICORES、AGENT_SANDBOX_MEMORY_MIB、AGENT_SANDBOX_DISK_MIB、AGENT_TERMINAL_IDLE_TTL_SECONDS、AGENT_TERMINAL_HARD_TTL_SECONDS 和 AGENT_TERMINAL_MAX_SESSIONS。在 Settings 页面设置的值对所有服务器生效(PUT /admin/agent/host-settings);在 Servers 页面某台服务器的详情里设置的值,只对那一台生效(PUT /admin/agent/runner-hosts/<host>/settings)。每一项设置,主机按以下优先级取值,从高到低:
单独给这台服务器设置的值;
给所有服务器设置的值;
内置默认值。
控制平面每次心跳都会下发完整的最终生效值,默认值也包括在内。主机上的环境变量只在第一次拿到设置之前生效,之后仍会作为本地的诊断值显示出来。清除单台服务器的值,会退回到全局值或内置默认值;清除全局值,会退回到内置默认值。管理员能设置的上下限写在 cloud_agent_shared/host_settings.py 里,它们只是防止手误填错,并不代表机器的实际容量。
容器的 CPU、内存和磁盘设置只对新建的沙箱组生效。恢复或 Fork 对话时,沙箱组保留原来的限制,组内所有成员共用这些资源。CPU 在管理页面上按 vCPU 填写,存储时换算成毫核(1 vCPU = 1000 毫核)。内存和磁盘可以用 MiB 或 GiB。默认是 2 vCPU、4096 MiB 内存,不设单容器磁盘配额。对应的初始环境变量值是 AGENT_SANDBOX_CPU_MILLICORES=2000、AGENT_SANDBOX_MEMORY_MIB=4096 和 AGENT_SANDBOX_DISK_MIB=0。
磁盘上限设为正数时,会在容器的可写层上加 Docker 的 --storage-opt size=<MiB>M,限制范围包括工作区、缓存和安装的文件,但不包括只读的镜像和放在内存里的临时文件。这需要 Docker 使用 overlay2,并且底层是用项目配额(pquota 或 prjquota)挂载的 XFS 文件系统。如果存储后端不支持所要求的配额,Docker 会拒绝创建容器。把磁盘值设成 0,新建的沙箱组就不设磁盘配额;重置覆盖值,则继承全局值或默认值。建议在每台运行不受信任 profile(untrusted-kata-v1)的服务器上都设一个正数上限,否则它上面的沙箱会共用一块没有上限的磁盘。但这不是强制的:值为 0 的服务器照样接不受信任的任务,只是控制平面和 runner 会记录警告,Servers 页面也会在它旁边显示 No container disk quota。runner 现有的存储证明仍然测量的是主机的文件系统,而不是每个沙箱的配额。
同样的设置卡片里,还可以管理工作区和终端的资源限制。下面这些环境变量名只用来提供本地的初始值:
变量 |
初始默认值 / 作用 |
|---|---|
|
每个共享工作区最多同时打开 4 个终端。 |
|
工作区命令和 Git 查看的超时时间,60 秒。 |
|
单次替换工作区文件,最大 2 MiB。 |
|
单次预览文件,最大 512 KiB。 |
|
工作区命令的输出,最多 2 MiB。 |
|
一次目录列表最多 5,000 项。 |
|
一次下载整个工作区,最大 1,024 MiB,按压缩前的大小算。 |
|
为终端断线重连保留的内容:2 MiB / 4,096 个事件。 |
|
一个终端从打开到关闭,最多输出 32 MiB。 |
|
每次终端请求最多输入 64 KiB。 |
|
每个终端最多 4 人同时查看。 |
工作区命令和 Git 查看的并发数量也有上限,这个上限由 Sandbox Manager 自己决定,不是设置项:一台主机上最多同时跑 16 个,一个对话最多 4 个,用的是它们专用的线程池;再多一个就直接返回 429,不会排队等着。
这些值随心跳的应答下发,所以主机在一次心跳之内(大约 30 秒)就会应用改动,不需要重新部署。正在运行的东西都不会被打断:一个轮次仍按它开始时的时间上限执行;已有的沙箱仍保持创建时的会话容量,以及 CPU、内存和磁盘限制;sandbox manager 的终端限制从它下一轮巡检开始生效。每台主机都会上报自己实际应用的值,以及它自己 .env 里的值;主机确认之前,页面上会把这个值显示为 applying。更早版本的 runner(没有声明 host-settings-v1)在重新部署之前,会一直用自己 .env 里的值,页面上也会注明这一点。
可选:计算资源管理
这些值只用于稳定的主控制平面,不用于它的 MCP 专用监听器、任何 Host 或任何沙箱。部署配置、核实 SSH 访问以及 CloudLab 端点的设置,见计算资源手册。
变量 |
含义 |
|---|---|
|
自动 Server setup 去哪里找这个发布对应的沙箱镜像,格式是 |
|
一把独立的加密密钥,至少 32 字节,用来加密保存的计算资源连接,以及管理员在界面上管理的部署配置。留空时,官方部署脚本会随机生成一个值,并保存在 |
|
控制平面进程里能访问到的绝对路径,指向运维人员自己的 JSON 部署配置。 |
|
主机上的一个绝对路径目录,由可选的 Compose overlay 以只读方式挂载到 |
|
首次 Server setup 时服务节点的地址,可以修改。官方部署脚本默认用节点的 FQDN,拿不到就用主机名;如果用其他部署方式,或者 SSH 用的是另一个别名,请显式设置一个 SSH 地址。已保存的安装信息优先。 |
|
可选,覆盖首次 Server setup 时的网关地址。默认取已保存的网关 API URL 里的主机名,例如 |
|
运维人员核实过的 HTTPS Portal API 基础地址:CloudLab 用 |
|
可选。新的 CloudLab 节点上报自己 SSH 主机密钥的 HTTPS 地址,以 |
没有这些配置时,现有的 Host 管理功能照样能用;只是要新建资源,必须先配好凭据和部署配置。
仓库环境
可复用的仓库环境默认就能用,没有功能开关,也没有对应的环境变量初始导入。旧的 repository_environments_enabled=false 设置,或者 AGENT_REPOSITORY_ENVIRONMENTS_ENABLED=false 这个值,都会被忽略。设置页面、创建任务时的选择,以及工作区的 Environment 标签页,始终都会出现。/config 也始终会返回环境相关的限制。
没有配置任何变量或脚本的任务,直接用基础环境,不做环境准备。配置过的工作区仍然需要支持环境功能的 runner 和 sandbox manager;所有者授权、加密和执行隔离照常生效。
主机 agent(cloud_agent_host)
这套主机服务自己的身份
它们由 deploy/host/deploy.sh 和 deploy/host/sandbox_host.sh 读取,而不是由 compose 读取,因为它们的作用是给这套服务命名,而不是配置它。
变量 |
取值 / 由谁提供 |
|---|---|
|
主机服务的 Compose 项目名,必填,主机端没有默认值。容器、镜像和网络的名字都以它为前缀;两次部署用了同一个名字,第二次就会把第一套服务重建掉。同一台机器上的不同环境要起不同的名字,例如 |
|
主机上保存注册状态和就绪标记的路径。官方主机 Compose 的默认值是 |
|
Compose 关闭时的等待时间,默认分别是 |
|
本机上用逗号分隔的一组项目名,它们属于另一个环境,而不是本环境误留下的副本。设置了它, |
|
部署脚本等待两边并行上线完成的时间,默认 900 秒。主机在等待冷启动的推理、MCP 和控制端点时,用的也是这个上限;控制平面部署在等待一次按确切 SHA 的新心跳和反向 sandbox manager 探测时,同样用它。这是防止上线卡死的看门狗,不是对话或会话的超时。 |
调度
变量 |
说明 |
|---|---|
|
|
|
attempt 租约的时长,默认 120 秒。推理授权的 TTL 和它无关: |
|
单个正在执行的 Agent CLI 轮次的硬性看门狗,默认 3600 秒。超时后,这个轮次会失败并被栅栏挡住;这不代表对话处于空闲,也不是另一种沙箱生命周期超时。也可以在管理页面上设置,管理页面的值优先;见 在管理页面上设置的沙箱参数。 |
|
执行环境的名字。首次注册时,用 |
Sandbox Manager、运行时与上报
变量 |
说明 |
|---|---|
|
runner 连接自己的 sandbox manager 用的地址,通常就是 Compose 的服务 URL。runner 注册时对外声明的是 |
|
如果 runner 注册时上报的地址和它自己连接的地址不一样,这里就填上报的那个。在控制平面和 sandbox manager 共用网络的一体化本地环境里,可以不填。 |
|
整个资源池共用的 sandbox manager 凭据:控制平面和每台主机都配同一个值。主机记录里只存 sandbox manager 的地址,没有单独的凭据。所以,一台主机被攻破,拿到的令牌也能通过其他 sandbox manager 的认证。配置时只比对 SHA-256 指纹,不要把 secret 本身显示出来;两边不一致,sandbox manager 就会返回 401。要做到每台主机一个 sandbox manager 凭据,需要另外设计一套分发方案。 |
|
独立部署的主机必须配置的反向监听地址。要绑定在稳定的控制平面实际的 Docker 网桥网关地址上,绝不能是回环地址或 |
|
这条反向转发在主机这一侧的目标,默认 |
|
推理用的 SSH 隧道。必须设置的后缀有 |
|
推理中继在 runner 网络和中继发现网络上的别名,默认 |
|
控制平面允许的 sandbox manager 地址白名单,用逗号分隔。只写主机名,就允许这个主机的任意协议和端口;写成 |
|
runner 注册、认领和发送心跳用的地址。独立的 Compose 部署会根据主 API 隧道的别名 |
|
worker 名称的前缀,默认 |
|
受信任的 runner 拼接源码克隆地址时用的基础地址,由运维人员指定,默认 |
|
第一个轮次能导入沙箱的仓库最大有多大,单位 MiB;默认 1024,可设 1–65536。由 runner 读取,任务永远没法自己提供。它统计的是工作区里的文件加上拉取下来的那个 commit 的 Git 对象,而单个 commit 的 pack 会把大部分内容再存一遍(无法压缩的文件几乎是原样再存一份),所以一个文件总共 600 MB 的仓库,就可能已经超过 1024。超过之后,这个轮次会在 agent 启动之前失败,报错 |
|
交互式 PTY 在没有任何输入输出之后,多久被回收,默认 1800 秒。保留的 PTY 取终端限制和对话限制里先到期的那个,并把自己最后一次活动的时间交给 supervisor,所以清理时不会再重新开始计一轮空闲时间。这个设置绝不会直接停掉对话容器。也可以在管理页面上设置,管理页面的值优先;见 在管理页面上设置的沙箱参数。 |
|
单个 PTY 的绝对寿命上限,默认 8 小时,即使它一直有活动也一样。它限制的是资源占用和凭据暴露的时间窗口,并不是对话的生命周期状态。也可以在管理页面上设置,管理页面的值优先;见 在管理页面上设置的沙箱参数。 |
|
sandbox manager 在所有对话里最多同时保持多少个交互式终端,默认 64,可设 1–4096。也可以在管理页面上设置,管理页面的值优先;见 在管理页面上设置的沙箱参数。 |
|
守护进程那一侧应有的 |
|
containerd 内容存储( |
|
只给 Sandbox Manager 用的目录,存放停止的容器的临时导出,以及每个请求对应的、不可变的删除回执。代码默认值是 |
|
每个新建的共享容器里,预先建好多少个成员槽位;每个槽位有独立的 UID 和私有 tmpfs,凭据互相隔离。默认 8,可设 2–128。Fork 在做任何原生改动之前,会先占好一个空闲槽位。它限制的是一个沙箱组里能常驻多少个对话;而这台机器上同时被认领的轮次数,另由 |
|
产品层面唯一的、针对保留对话组的空闲计时。默认 1800 秒(30 分钟)。轮次、文件或 Git 操作完成,以及终端上的活动,都会把同一个组的截止时间往后推;活动令牌能保证不会在操作中途停掉,又不会把一整段超时再叠加一遍。所有操作都已结束、计时到期时,主机会执行 |
|
一次性的主机注册令牌。在 |
|
主机凭据在重启之间保存在哪里。文件在写入第一个字节之前就设为 0600 权限,因为这台机器上同时运行着不受信任的仓库代码。代码里的默认值是 |
|
由部署脚本管理的滚动上线栅栏,不是让运维人员选择拓扑用的。控制平面要求的就是上面说的那个确切 SHA。 |
|
在管理员到 Servers 页面设置数值( |
|
已移除。 不再读取。并发数现在由 |
|
在资源池列表里显示的版本号,可以随便写。只给运维人员看,绝不用来判断兼容性;不填也不能妨碍主机注册。 |
|
runner 要不要采集它所在 Docker 主机的 CPU、内存和保留容器数量,显示在管理后台的 Servers 页面上。默认开启;设为 |
|
用哪种探针测量存放沙箱可写层的文件系统,结果显示在 Servers 页面的 Storage 列。 |
|
为新沙箱保留的存储空间,单位 MiB;默认 1024,可设 1–1048576。一个轮次分配沙箱之前,runner 会通过上面那个经过证实的存储探针,读取当前的可用空间;剩余空间不足这个值时,就不接这个轮次,轮次保持原样;已有的沙箱仍然可以恢复。容量未知或未经验证时,绝不会当作存储紧张来处理。这个预留只是准入时的一道检查,不是磁盘配额。也可以在管理页面上设置,管理页面的值优先;见 在管理页面上设置的沙箱参数,以及主机运行时设置。 |
|
进程的日志级别,默认 |
|
进程的日志格式,默认 |
|
旧版的静态实验开关。没有显式设置 MODE 时, |
|
当前这次性能剖析运行的 JSON 描述,包括: |
|
可选的 JSONL 文件路径,用来存放测量完成的结果;这些结果也会写进日志。外部的基准测试会读这个文件,汇总出基线数据。它不是发件箱,往 Postgres 和 Admin 投递也不依赖它:作为根的组件会通过自己那条有上限的投递通道,直接发送同一份缓存好的、已冻结的记录。写日志和写 JSONL 仍然共用一个有上限的后台导出器,所以即使文件或日志处理很慢,也绝不会在被测量的线程上执行。runner 通过 |
|
可选,用来覆盖控制来源: |
|
这个控制平面进程控制的是哪个部署的那条控制记录,默认 |
控制平面、主机和本地的 Compose 文件,都会把可选的性能剖析覆盖值原样传给各自的组件。MODE 为空时,会交给共用的解析器处理,效果和不设置一样:不用任何配置就能使用 Admin 控制。常规的 schema 迁移照常执行。只有互相独立的部署共用一个数据库时,才需要设置部署命名空间。
在全新的数据库上,采集一开始是 Disabled。Admin 上的 Enable/Disable 按钮控制持久化的运行状态,不需要改配置,也不需要重启服务。Disabled 时,每个操作都不会去读数据库,但现有的后台策略同步仍在运行,所以后台 I/O 并不是零。重启后,会恢复任何还没过期的进行中实验,而不会新建实验。config_version 标识那个不可变的实验,revision 用来给控制上的改动排序。没有需要续期的租约。Disable 不会改写清单里的到期时间,也不会丢弃进行中的记录。max_operations 仍然是每个组件实例各自的额度:Admin API 会报告 budget_scope=producer_instance,不会把它说成整个部署的上限。在 Admin 的分布统计里,不同的运行时和 execution profile 分开统计。2026-09-18 在本地复测的结果是,每次合成启动,采集器自身大约花 30 微秒;这个数字不包括真实的容器、sandbox manager、网络或数据库。
两个基准测试回答的是两个不同的问题,谁也代替不了谁。scripts/bench_startup_profiling_overhead.py 在一串合成的 attempt 上测量采集器本身的开销,没有认领、容器、supervisor、agent CLI 或网络,它的输出里也会写明这一点。scripts/bench_operation_overhead.py 则通过真实的 socket、对着真实的数据库调用真实的控制平面路由;如果有容器运行时可用,还会真实地激活 supervisor,把四条启动路径各走一遍。它会报告每种操作的 p50/p95、和未插桩对照组的差值、队列丢弃数、后台开销,以及按约定的 max(10 ms, baseline p95 × 1%) 预算得出的结论。引用其中任何一个的结果之前,先看一下脚本里的 what/not_what 说明。
物理服务器和执行环境
AGENT_RUNNER_HOST 标识一个已注册的执行环境。同一台物理服务器上的两套服务连同一个控制平面时,它们的名字、凭据、状态目录和 sandbox manager 地址都要不一样。不要为了把某个环境保留的对话并到另一个环境里,去给已有的环境改名或重新注册。
AGENT_PHYSICAL_HOST 是物理服务器在管理后台清单里显示的名字。同一台服务器上的所有环境都用同一个名字,并且在这个控制平面里不和别的服务器重复。deploy/host/sandbox_host.sh 默认用主机的短主机名;直接用 Compose 部署时,必须显式设置。runner 在注册时和每次心跳中都会带上它,保存为 labels.physical_host。旧版 runner 不带这个值也没关系,已有的元数据不会被清掉。不需要数据库迁移。
Servers 表格里,每台物理服务器显示的是和新对话执行策略匹配的那个执行器。生产 Compose 默认是 untrusted-kata-v1;本地 Compose 的 overlay 明确保持 trusted-v1。旧的执行器仍留在 API 里,用于保留会话的归属,但不会再分配给新对话。每台物理服务器只保留一个用于放置新对话的执行器;多出来的旧部署,等它们保留的对话都用不着了,就应该退役。
全局沙箱位置选择器始终显示,即使只有一台服务器也一样。它显示 Automatic,或者所选 Host 的确切身份;按物理服务器分组显示,并不会悄悄换成另一个执行器。它对所有新建、还没分配的沙箱组生效。已保留的沙箱组留在原来的 Host 上,页面会显示它们实际分布在哪里。如果保存的选择当前不可用,它会一直显示,并提供恢复操作,绝不会悄悄换到别的 Host。已禁用的服务器放在折叠起来的 Unavailable servers 区域,不算在可选项里。槽位指的是所显示环境的并发上限,不是 GPU 数量,也不是新旧部署加起来的总数。分组显示绝不会改动凭据、sandbox manager 的路由或保留沙箱的归属。服务器名称来自上报的元数据;系统不会去猜运行时的后缀。
在激活主机之前设好 AGENT_PHYSICAL_HOST,并按滚动更新手册里协调好的发布阶段操作。先让正在跑的轮次结束,完成目标主机这一代的部署,并通过控制平面按确切 SHA 的就绪栅栏,然后再激活 API 和 Web 的新版本。已有的主机凭据和保留沙箱都原样保留。
沙箱隔离(由主机 agent 读取,沙箱沿用)
变量 |
说明 |
|---|---|
|
默认 |
|
不设置时:后端是 |
|
沙箱镜像,必填,应用没有默认值。同一台机器上的不同环境要用不同的标签,例如 |
|
设为 |
|
必填。 一个固定不变的部署命名空间,会标记在保留容器和沙箱组网桥上,这样同一个 Docker 守护进程上的几套 Compose 服务,就没法发现、停止或清理彼此的对话。主机上这个部署的 nftables 表名和网桥接口名前缀,也由它决定;所以 runner 或 sandbox manager 没有这个值就会拒绝启动,而不是和别人共用一个默认值。主机服务用的是它自己独有的 Compose 项目名;完整的本地环境则由 |
|
主机后端使用的 Docker 可执行文件,默认 |
|
沙箱用户的主目录,默认 |
|
沙箱里非 root 用户的 UID 和 GID,默认 |
|
额外的 Docker 参数,用 |
|
内部使用。 runner 这边受信任的一个路径,指向 root 所有的 |
|
⚠️ 隔离的紧急出口,范围比上一行还窄:它只会放开 |
|
必填。 本部署使用的 RFC1918 IPv4 地址池;Docker 会从中为每个活跃的沙箱组网桥分配一个 |
|
必填。 沙箱唯一能用的 IPv4 DNS 解析器,走 TCP 和 UDP 53 端口。它是受保护地址段里唯一的例外,所以即使站点的解析器在私有地址上,或者就在本机上,也能用。在 runc 下,Docker 内置的解析器会转发给它;在 Kata guest 里,由受信任的 guest 辅助程序把它写进 |
|
用逗号分隔的 IPv4 地址块,在内置的主机地址、私有地址、链路本地和元数据地址、CGNAT、组播以及保留地址段之外,再额外禁止沙箱访问的地址,比如某个机构放在公网地址上的服务。它只能增加保护,不能减少。控制平面检查所有者的 SSH 服务器时也会读这个变量,所以控制平面上也要设成和主机一样的值。 |
|
用来发现两个中继的、不带路由的网络;任何沙箱都不会加入它。沙箱组的生命周期管理会把在这里找到的中继,以各自的别名接入每个组的网桥。主机服务会自动得出 |
~~ |
已移除。 沙箱改成单一网络之后,这些变量就和网络分级、Squid 代理一起退役了(设计)。已经没有代码读取它们:没有分级可以选,没有代理可以指向,也没有开放网络的开关。把它们从 |
|
内部使用。 由运行时适配器为私有的 OpenCode/Kilo stdio bridge 生成,运维人员不要设置。它们在单个成员进程里,指定已经授权的那个原生会话,以及固定的 |
|
内部使用。 由主机的插件安装程序为 pi、OpenCode 和 Kilo 生成。它是一个 JSON 数组,列出装在成员私有主目录里、被选中的插件的绝对路径,默认 |
|
内部使用。 sandbox manager 在成员终端里启动一个仓库环境操作时设置,表示这个操作运行时使用的受限 UID(31000–31063)。运维人员不要设置。 |
|
内部使用。 sandbox manager 传给运行单个仓库环境脚本的包装程序( |
|
内部使用。 只在沙箱里做快照的 secret 扫描时设置( |
Kata 运行时资格验证的代次
官方的主机部署会把 /var/lib/freeinference/kata-runtime 以只读方式挂载到 runner 里的 /run/agent-kata-runtime。安装并验证通过之后,里面那个 root 所有的 epoch.json 内容是 { "version": 1, "state": "ready", "generation": "<UUID>" }。setup_kata_runtime.sh 会持有一把整机范围的安装锁:改动运行时、链接或配置之前,先发布 updating;只有安装和验证都成功之后,才发布一个新的 ready 代次。更新失败的话会一直停在 updating,重新运行安装脚本即可修复。这台主机上的所有部署看到的都是同一个代次,标记文件被原子替换时也一样。--check 仍然只做验证,不做改动。
对于已有的主机,部署时会先验证 Kata,然后通过一个临时的、没有网络、只能访问这个目录的 runc 容器,补上缺失的标记,仅此而已。它会持有同一把安装锁,绝不会替换已有的代次,也不会清掉没完成的更新。没有 epoch 证据时,要做完整的探测;证据格式不对或正处于更新中时,一律拒绝。如果要原地更新运行时或配置,必须用官方的安装脚本,这样每个 runner 都会在第一个文件被改动之前,就让资格验证失效。
完整本地环境的数据库恢复
deploy/local/dev.sh 把本地 Postgres 的密码和对应的 AGENT_DATABASE_URL 存在 deploy/local/.env.local 里,这个文件已被 git 忽略。只要还保留着本地的 Docker 卷,就要把这个文件一起备份。如果文件丢了,而所选的 Compose 项目里还有 agent-postgres,脚本会拒绝生成新密码:PostgreSQL 只在初始化空的数据目录时才使用 POSTGRES_PASSWORD,所以新密码打不开旧的卷。
up 会先构建需要的镜像。之后,它和 start 都会先只启动 Postgres,等它就绪,用控制平面镜像和配置的 DSN 认证一次,再运行 Alembic,最后才启动其余的服务。如果认证失败,请把原来的 AGENT_POSTGRES_PASSWORD 和 AGENT_DATABASE_URL 找回来。脚本绝不会自动删除卷,也不会自动重置密码。
Claude 推理请求的重试策略
运行时适配器会为 headless 和常驻的 Claude Code 进程设置 CLAUDE_CODE_MAX_RETRIES=15 和 CLAUDE_CODE_RETRY_WATCHDOG=0。这两个是固定的启动参数,由 runner 提供,不是主机 .env 里的选项。固定版本的 CLI 会在当前这一轮原生会话里,对临时性失败的推理请求做带随机抖动的指数退避重试。关掉看门狗之后,请求的重试次数仍然有上限;整体执行时间的上限仍是 AGENT_TIMEOUT_S。重试进度会显示在对话里;重试次数用完时,这一轮会失败,但原生上下文会保留下来。重试间隔的上限和上线时的行为,见运行时边界。
Agent CLI 的版本固定(构建镜像时)
五个默认版本同时写在 deploy/sandbox/Dockerfile.agent-sandbox 和 apps/backend/cloud_agent_shared/shared_protocol.py 两处。它们是一起评审的一个协议单元:镜像负责安装并打上标签,而每个 runner 和控制平面都靠对应的常量,来判断能不能声明或认领 shared-sandbox-v1。所以它们是写在源码里的版本固定,不是每台主机 .env 里的设置。有意修改某个默认版本时,两处要一起改,并重新跑一遍 agent 循环的一致性测试。
构建时,Dockerfile 仍会把每个确切的版本号和实际装上的二进制逐一核对。写 dist-tag(latest)或版本范围(^2.1)都会让构建失败,这样镜像标签上写的版本,就不可能和镜像里实际的二进制对不上。
不重新构建也能升级 agent。 Claude Code、Codex、OpenCode 和 pi 也可以在管理员设置页面上升级(Agent versions → Update to …)。之后每台主机都会把那个确切的 npm 版本下载到沙箱镜像旁边的一个本地镜像里,用这个发布的 driver 对着回环上的一个模型跑一轮真实的对话来检查它,并在心跳里报告进度。等所有在线主机都装好了,新对话就开始用新版本,已有的对话继续用原来的版本。Roll back 会让新对话退回之前用的版本。Kilo 不提供这个功能,因为它跑的是打了一个评审过的隔离补丁的源码构建版本。没有做选择的主机,仍然运行上面那些默认版本。见设计。
变量 |
说明 |
|---|---|
|
和上面控制平面那一行对应的主机端设置:主机从哪个 npm 仓库下载升级的 agent。默认 |
|
下载这一步运行在哪个 Docker 网络上,默认 |
每个运行时都有一个 *_EXTRA_VERSIONS 部署设置,用逗号分隔,默认为空,列出同一个镜像在评审过的默认版本之外,额外带上哪些版本。这个列表就是菜单:镜像里装哪些版本,在构建时决定;新沙箱用菜单里的哪一个,由管理员在管理员设置页面的 Agent versions 里选(agent_runner_policy.runtime_versions)。留空的话,镜像里就只有默认版本,所有部署一开始都是这样。
每个额外加的版本都必须是确切的版本号,并且它的事件流必须和 cloud_agent_host/runtimes/ 里对应的适配器兼容。
检验这一点的关卡是 tests/external/test_runtime_stream_conformance.py;要让它测某个候选版本,办法是把这个版本写到 Dockerfile 的 ARG 行里:
# deploy/sandbox/Dockerfile.agent-sandbox, beside the reviewed default
ARG CLAUDE_CODE_VERSION=2.1.220
ARG CLAUDE_CODE_EXTRA_VERSIONS=2.2.0
# then, from the checkout — no image build and no deployment needed
uv run pytest -m external tests/external/test_runtime_stream_conformance.py
测试套件的参数是从这些 ARG 行里推出来的(test_runtime_stream_conformance.py::_menu、_DOCKERFILE),不是从环境变量、构建好的镜像,也不是从已部署的 .env 里来的:在 shell 里设置 CLAUDE_CODE_EXTRA_VERSIONS=2.2.0,对实际跑什么毫无影响。然后它用 npx 按确切版本拉取每个版本,对着一个模拟的网关去驱动,所以测量的是真实的二进制;但测量依据的是仓库里的 Dockerfile,所以候选版本必须先写进那一行 ARG。
一致性测试通过时,要在下面这些前提下理解它的意义:
只针对
claude-code。 只有这个运行时有流一致性测试套件;其他四个只有契约夹具和各自适配器的单元测试,没有同等的关卡。所以目前给它们加版本,靠的是评审把关,而不是测试。它证明的是解析器没问题,不是这个选项没问题。 测试通过,说明这个版本的事件结构能被我们的规范化程序读懂;但它并不会去跑已部署的镜像、沙箱,也不会去点那个下拉菜单。
把某个版本开放给用户之前,先确认它的事件流兼容。
变量 |
说明 |
|---|---|
|
额外的 |
|
额外的 |
|
额外的 |
|
额外的 |
|
额外的 |
Web(apps/frontend/)
前端配置都是公开的。构建时的路由设置会打进用户下载的前端包里,改了就要重新构建。外观设置通过 Admin → Settings 保存,Web 服务器每次处理请求时读取。部署时间和发布版本信息仍然是运行时的环境元数据。这些公开的值里不能有 secret。
构建时决定:镜像变体
NEXT_PUBLIC_* 变量会在 next build 时被替换进前端包里。所以每一个都必须同时是 deploy/control-plane/Dockerfile.web 里的 ARG,并且是 web 服务 build.args 下的一个键;这里的某一行如果缺了其中一个,这个变量就是运维人员哪里都能设、却什么都改变不了的摆设。每一行都写明了它对应的 compose 参数,任何一行没写,test_web_build_arguments_are_wired 都会失败。改其中任何一个,都要重新构建。
base path 和 API 前缀必须和反向代理的配置对得上。官方支持的同源布局都用 AGENT_WEB_API_URL=<AGENT_WEB_BASE_PATH>/api:独立的 edge 用 /api,挂载在 /agents 下时用 /agents/api。如果 API 值是非空的相对路径,又和 base path 对不上,构建会直接拒绝。绝对 URL 和空值都可以接受,留给运维人员自定义路由;空值表示 API 请求直接从 /v1/... 开始。配对测试跑的是真实的 Next.js 配置。
变量 |
Compose 构建参数 |
说明 |
|---|---|---|
|
|
应用挂载的路径前缀。 |
|
|
浏览器使用的 API 基础地址。用自带的独立 edge 时填 |
|
|
可选的构建版本信息,由部署脚本写入。 |
|
|
可选的构建版本信息。 |
运行时决定:部署的身份信息
主控制平面初始化设置文档时,会导入下面的前八个外观变量。请在第一次启动之前把它们设进部署环境,之后再通过 Admin → Settings 修改。Web 服务器每次处理请求时,都会通过 GET /v1/agent/site-config 读取已保存的公开外观字段,所以同一个构建好的镜像可以给任何部署用。如果 Web 服务器没有配置 AGENT_CONTROL_PLANE_URL,就用它自己的环境变量,方便单独开发前端。部署时间仍是 Web 的运行时元数据。
变量 |
说明 |
|---|---|
|
页头和页面标题里的产品名。留空就显示 |
|
可选,显示在产品名旁边的组织名称。留空就不显示。 |
|
|
|
状态页面,从页头点开,在新标签页里打开。留空就不显示这个链接:空的 |
|
这套部署的用户文档,从账号菜单的 Help 和 My Settings 页面打开,在新标签页里显示。留空就不显示这个链接。请指向发行版自己的用户指南;本仓库的开发者文档是给运维人员和贡献者看的。 |
|
用户联系这套部署的运维人员的方式:一个 http(s) 支持页面,或者 |
|
|
|
设为 |
|
显示在部署页脚的、带时区的 ISO 时间戳。控制平面的部署脚本会把激活时间以 UTC 写入,健康检查通过后记到 |
Web 服务还会拿到已有的 AGENT_DEPLOYMENT_SHA,用来在页脚显示版本:显示 commit 的前七位,鼠标悬停时显示完整的 commit。这两个值每次请求时都重新读取,和镜像是哪天构建的无关。
管理员提交更新之前,保存的 URL 和布尔值都会先经过校验。单独运行、退回使用环境变量时,则在渲染页面时校验。网关的 /site-config 接口不在 Cloud Agent 使用的契约范围内;已保存的公开外观信息,来自本服务自己的接口。
在 HybridInference 那一侧设置,不在这里
这些都配置在网关的环境里。之所以列在这里,是为了让这份契约在一个地方就能从头读到尾。
变量 |
说明 |
|---|---|
|
RS256 私钥,PEM 格式。对应的公钥通过 |
|
可选。以前用过的签名密钥的公钥 PEM,和当前密钥拼在一起发布,这样轮换之前签发的令牌仍能通过校验。一把密钥在这里至少要保留"令牌最长有效期 + JWKS 缓存时间"这么久,然后再撤掉。只能放公钥:即将退役的密钥,不能还有签名的能力。 |
|
身份令牌里的 |
|
用逗号分隔、需要完全匹配的重定向地址。匹配就是判断是否相等,不做前缀或后缀匹配,所以 agent Web 的回调地址必须一字不差地写进去。 |
|
和上面控制平面那边配置的值相同。 |
基础设施(不是环境变量)
这里记录的是需要做出哪些决定,而不是谁的实际选择。
域名:Web 应用和控制平面 API 用同一个主机名,API 放在
/api下,例如agents.example.org,再加一个 staging 用的兄弟域名。具体的名字写在 overlay 里,并且必须和网关上IDENTITY_ALLOWED_REDIRECTS的配置完全一致。连到网关:控制平面需要有一条到
GATEWAY_BASE_URL的路由。沙箱能访问的是它的两个中继、AGENT_EGRESS_DNS_SERVER指定的 DNS 解析器,以及 TCP 80/443 上的公网 IPv4;setup 阶段和 agent 运行阶段都一样。工具调用仍然只能走 MCP 专用监听器。推理沿用现有的网关端点(AGENT_TUNNEL_REMOTE_PORT默认 8080);单独的推理监听器,或者能替换凭据的中继,都不是部署的必要条件。推理授权泄露后被人在公网上重放,是一项已接受的风险,影响范围受限于授权所有者现有的模型权限、配额和授权的生命周期。如果某个部署通过隧道把任一中继放在前面,端口怎么分配属于 overlay 里的细节。沙箱镜像仓库:部署主机之前,先定好主机从哪里拉取
AGENT_SANDBOX_IMAGE。
新增变量时
在这里对应的小节里加一行。
写明由谁提供,以及不同环境之间的值是否不同。
如果是 secret,写明它存在哪里,但绝不要写出它的值。
PR 检查清单会检查这一点;新增了变量却没有对应的一行,评审就不会通过。