记录 provider 契约
以 provider 官方 SDK 和 API 文档为权威来源。需要记录身份验证与账号范围,互斥的镜像、快照或模板选择器,工作区持久化方式,CPU、内存、磁盘、GPU、放置策略与配额,启动与删除语义,可强制执行的网络模式,命令、传输、端点、取消与错误行为,以及异步和线程安全保证。创建最小文件
先创建一个 provider 模块和一个软件包导出:example_local.py:
EnvironmentSession 的每个抽象方法和 BaseEnvironment 的两个抽象方法。这里没有独立的公开 EnvironmentPlan 类型:provider 使用经过 Recipe 调整的 ExecutionPlan,build_config(req, plan) 从 plan.environment.params 读取配置并验证解析后的网络阶段。
这个包装器只用于练习契约。生产 provider 应调用自己的 SDK 并返回自己的 EnvironmentSession,不应依赖 HostProcessSession。
导出并检查注册
在src/agentcompass/environments/__init__.py 中添加导入:
example_local;第二条命令应列出 workspace 和 default_workspace_root 的默认值与描述。如果可选 provider SDK 可能缺失,只能在 __init__.py 中捕获并处理已明确记录的依赖缺失错误;不要吞掉无关异常或注册错误。
运行单个任务
使用配套的 Benchmark 与 Harness 教程组件,在没有外部凭证的情况下执行 provider 打开、会话构建与关闭:paths.run_info,该路径的父目录就是本次运行目录。在 run_info.json 中,确认 request → environment → id 为 example_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_modes、supported_allowlist_entry_types、supports_network_target_ports 和 supports_dynamic_network_policy。无法强制某个模式、目标类型或端口限制时必须默认拒绝。不要声明仅靠提示词、环境变量或要求 agent 尽力遵守就能实现某项限制。
支持动态策略切换的 provider 必须能够从基线策略切换到运行策略;复用 Environment 进行评测时,还要能从运行策略直接切换到评测策略。代理凭证、策略令牌、签名 URL 和临时端点都必须脱敏。正常关闭或启动失败后,还要移除临时网络配置和策略。
保留配置与 Recipe 优先级
为公开 provider 的每项设置定义类型化配置字段。身份验证、sandbox 来源、生命周期超时、资源、工作区和 provider 元数据必须分开配置,并明确单位、默认值和验证规则;互斥字段同时出现时,应报告清楚的错误。凭证不得进入日志或持久化计划。 Environment 代码使用最终计划,Recipe 提供 Benchmark 专属默认值。二者都必须遵循以下优先级:BaseEnvironment 提供的进程级全局 provider 启动限流,还要遵守 provider SDK 的请求限制、账号配额和容量限制。日志应记录稳定的 sandbox ID、生命周期阶段、耗时、所选的非敏感镜像信息和便于处理的错误信息,但绝不能记录可能包含密钥的完整配置字典。
按阶段诊断失败
最简单的真实参考实现是
host_process.py。需要查看容器 provider 的镜像生命周期、命令执行、传输和可强制网络行为时,可对照 docker.py。