Skip to main content
实现 Environment provider 时,应遵循共享会话契约。它需要根据解析后的执行计划构建类型化 provider 配置,为任务创建 Environment,提供命令与文件原语,并可靠释放自己创建的资源。 下面的教程 provider 基于公开的本地进程会话实现,因此无需外部账号即可执行所有必要方法。接入远程 provider 时,应使用其官方 SDK 替换对应调用;不要把 provider 行为放入 Benchmark 或 Harness。

记录 provider 契约

以 provider 官方 SDK 和 API 文档为权威来源。需要记录身份验证与账号范围,互斥的镜像、快照或模板选择器,工作区持久化方式,CPU、内存、磁盘、GPU、放置策略与配额,启动与删除语义,可强制执行的网络模式,命令、传输、端点、取消与错误行为,以及异步和线程安全保证。

创建最小文件

先创建一个 provider 模块和一个软件包导出:
按如下方式实现 example_local.py
以上代码展示了 EnvironmentSession 的每个抽象方法和 BaseEnvironment 的两个抽象方法。这里没有独立的公开 EnvironmentPlan 类型:provider 使用经过 Recipe 调整的 ExecutionPlanbuild_config(req, plan)plan.environment.params 读取配置并验证解析后的网络阶段。 这个包装器只用于练习契约。生产 provider 应调用自己的 SDK 并返回自己的 EnvironmentSession,不应依赖 HostProcessSession

导出并检查注册

src/agentcompass/environments/__init__.py 中添加导入:
然后检查注册表发现和当前配置结构:
第一条命令的输出应包含 example_local;第二条命令应列出 workspacedefault_workspace_root 的默认值与描述。如果可选 provider SDK 可能缺失,只能在 __init__.py 中捕获并处理已明确记录的依赖缺失错误;不要吞掉无关异常或注册错误。

运行单个任务

使用配套的 Benchmark 与 Harness 教程组件,在没有外部凭证的情况下执行 provider 打开、会话构建与关闭:
命令应报告一个已完成任务并输出 paths.run_info,该路径的父目录就是本次运行目录。在 run_info.json 中,确认 requestenvironmentidexample_local,并且 resolved_execution_plans 的第 1 次任务尝试包含相同的 Environment ID;还应确认存在一个 details/*.json 文件和 summary.md.agentcompass/environment-smoke 目录可以证明 open() 使用了 provider 配置;它不是结果目录。 远程 provider 还应接受会话级检查,包括执行一条列表形式命令、写入并读回 UTF-8 文本,以及上传并下载单个文件和目录。随后还要在 provider 控制台确认资源已经清理。注册表或本地模拟检查成功,不能证明远程生命周期正确,也不能证明网络策略已得到强制执行。

映射真实会话原语

按以下语义实现各方法: 将 provider 响应标准化为 ExecResult。命令的非零返回码应作为结果数据返回,而不是作为 provider 异常抛出;只有传输失败或 provider 本身无法执行操作时才抛出异常。超时和 provider 错误也必须保持可区分。如果 SDK 提供异步接口,应直接使用;只有 SDK 仅提供阻塞调用时,才需要显式隔离,避免在高任务并发下阻塞事件循环。

处理启动、关闭与部分启动清理

open() 应先根据解析后的执行计划构建并验证 provider 配置,再解析互斥选择器,应用资源、工作区、标签和基线阶段网络策略,并在启动超时内创建 sandbox。只有 provider 报告资源可用后,才能构造会话。任何步骤失败时,都要先释放已经创建的部分资源,再向上抛出错误。 close() 只能停止或删除明确属于当前会话的资源。清理逻辑必须能处理部分启动;即使操作被取消或重复调用,也要保持幂等。绝不能通过宽泛的名称或未经验证的全局搜索来确定清理目标。 根据实际的强制执行能力声明 supported_network_modessupported_allowlist_entry_typessupports_network_target_portssupports_dynamic_network_policy。无法强制某个模式、目标类型或端口限制时必须默认拒绝。不要声明仅靠提示词、环境变量或要求 agent 尽力遵守就能实现某项限制。 支持动态策略切换的 provider 必须能够从基线策略切换到运行策略;复用 Environment 进行评测时,还要能从运行策略直接切换到评测策略。代理凭证、策略令牌、签名 URL 和临时端点都必须脱敏。正常关闭或启动失败后,还要移除临时网络配置和策略。

保留配置与 Recipe 优先级

为公开 provider 的每项设置定义类型化配置字段。身份验证、sandbox 来源、生命周期超时、资源、工作区和 provider 元数据必须分开配置,并明确单位、默认值和验证规则;互斥字段同时出现时,应报告清楚的错误。凭证不得进入日志或持久化计划。 Environment 代码使用最终计划,Recipe 提供 Benchmark 专属默认值。二者都必须遵循以下优先级:
先确定优先级最高的选择器,再移除与它不兼容的字段。资源配置应逐字段合并:用户显式传入的值优先,未指定的字段可以继承任务提示。Recipe 应复制执行计划,只匹配范围明确的 Benchmark/provider 组合,并且绝不能调用 provider SDK。 除了 BaseEnvironment 提供的进程级全局 provider 启动限流,还要遵守 provider SDK 的请求限制、账号配额和容量限制。日志应记录稳定的 sandbox ID、生命周期阶段、耗时、所选的非敏感镜像信息和便于处理的错误信息,但绝不能记录可能包含密钥的完整配置字典。

按阶段诊断失败

最简单的真实参考实现是 host_process.py。需要查看容器 provider 的镜像生命周期、命令执行、传输和可强制网络行为时,可对照 docker.py