尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

在 ZenML Sandbox 上编排 Harbor 评估:用一条 ZenML Pipeline 跑通 Agent 评测矩阵

在 ZenML Sandbox 上编排 Harbor 评估:用一条 ZenML Pipeline 跑通 Agent 评测矩阵 在 ZenML Sandbox 上编排 Harbor 评估用一条 ZenML Pipeline 跑通 Agent 评测矩阵【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenml本篇技术指南围绕 ZenML 仓库中的 sandbox_harbor 示例 展开讲解如何把 Harbor 评测框架的试次trial执行内核嵌入 ZenML 的沙箱Sandbox组件体系ZenML 负责外层编排矩阵展开、逐试次步骤、重试、聚合报告Harbor 负责单次试次的评测内核任务加载、agent 循环、验证器、奖励二者通过ZenMLSandboxEnvironment这座桥衔接。读完本文你将掌握如何在一条 ZenML pipeline 中批量跑 Harbor 评测本地任务或 Terminal Bench 等 registry 基准、查看每个试次的产物与报告并理解桥接层当前的能力边界。为什么需要把 Harbor 评测搬进 ZenML PipelineHarbor 是一个 agent 评测框架原生形态下你通过harbor run在本地命令行跑评测每个试次在其临时目录中构建任务、启动 agent、运行验证器并给出奖励分数。问题在于一次评测活动campaign结束后试次的原始输出agent/verifier 日志、轨迹会随本地临时目录一起消失多次评测之间没有统一的血缘lineage、缓存和可复现性。sandbox_harbor 示例给出的方案是把评测活动整体搬进 ZenML让两条职责边界各归其位ZenML 拥有外层编排——矩阵展开、每个试次一个独立步骤拥有独立的沙箱会话、日志、重试与缓存条目、跨试次聚合成一份 campaign 报告Harbor 保留评测内核——任务加载、agent 循环、验证器、奖励计算每个步骤恰好运行一个试次。一次命令、一次 ZenML run即可同时获得按试次划分的产物artifact与一份 Markdown 报告全部落进 ZenML dashboard。从源码看run.py 中的管线定义正是这一分工的体现pipeline(dynamicTrue, enable_cacheFalse) def sandbox_harbor_pipeline( task_path: str _DEFAULT_TASK_PATH, agent_name: str _DEFAULT_AGENT, n_trials: int 3, ) - None: tasks, agents, indices build_matrix( task_paths[task_path], agent_names[agent_name], n_trialsn_trials ) results, _artifacts run_harbor_trial.map( task_pathtasks, agent_nameagents, trial_indexindices ).unpack() build_report(resultsresults)dynamicTrue允许build_matrix在运行时决定矩阵规模run_harbor_trial.map(...)把矩阵展开为并行的 mapped steps最后build_report聚合所有试次结果。整体架构一条管线、三座桥README 用一段缩进图给出了端到端调用链核心脉络如下ZenML pipeline: build_matrix - run_harbor_trial.map(...) - build_report each mapped step runs ONE Harbor trial: - Harbor (programmatic: task loading, agent loop, verifier, reward) - ZenMLSandboxEnvironment (implements harbor.BaseEnvironment) - Client().active_stack.sandbox.create_session() - sandbox (Modal, Kubernetes, ...)对应到仓库代码这条链路可以逐层拆解build_matrix步骤run.py把传入的任务列表本地路径或dataset:前缀的 registry 规格展开成对齐的(task, agent, trial_index)三个列表作为map的输入run_harbor_trial步骤run.py为每个试次构造一个单试次JobConfig其中environmentEnvironmentConfig(import_pathzenml_harbor_env:ZenMLSandboxEnvironment)随后Job.create(config)→job.run()执行ZenMLSandboxEnvironmentzenml_harbor_env.py实现harbor.BaseEnvironment的全部环境方法start/stop/exec/upload_file/download_file/upload_dir/download_dir把 Harbor 的命令执行与文件传输翻译成对当前栈上 Sandbox 组件的调用build_report步骤run.py把每个试次的摘要job_id、完成数、错误数、平均奖励按 (task, agent) 单元格聚合输出一份 Markdown 报告以MarkdownString类型落到 ZenML 产物中。在桥接层内部ZenMLSandboxEnvironment.start()的核心一行是zenml_harbor_env.pysandbox Client().active_stack.sandbox ... self._session await asyncio.to_thread( sandbox.create_session, settingssettings )即通过Client().active_stack.sandbox拿到当前栈上注册的 Sandbox 组件BaseSandbox调用其create_session()打开一个SandboxSession。这与 Sandboxes 组件指南 描述的用法一致Sandbox 是步骤消费的工具步骤本身仍运行在 orchestrator 指定的地方在步骤代码内部借沙箱执行 agent 生成的代码。相比裸harbor run你额外得到了什么README 明确列出了三条核心收益Run 血缘lineage一次 campaign 就是一次 ZenML pipeline run每个试次是独立 step——dashboard、artifact store、重放replay、缓存全套机制随之生效。每个试次的奖励摘要作为一个 artifactHarbor 完整的jobs/目录树agent/verifier 日志、轨迹打包成第二个 tar 产物试次的原始输出不再依赖本地临时目录免逐试次镜像重建Sandbox 组件自己持有镜像。任务中的[environment].docker_image会被翻译成ModalSandboxSettings(image...)——目前仅支持 Modal flavor——每个试次都不需要重新构建 Dockerfile可移植的底座原则层面不固定docker_image的任务只跟通用的 Sandbox 接口打交道因此理论上把 flavor 从 Modal 换成 GKE Agent Sandbox 等时Harbor 无需感知。但 README 明确提醒桥接层目前只用 Modal flavor 做过冒烟测试且Local sandbox flavor 直接在宿主机上执行命令——绝不要把它指向不受信任的 Harbor 任务。仓库文件清单示例目录结构如下文件/目录作用zenml_harbor_env.pyZenMLSandboxEnvironment(harbor.BaseEnvironment)桥接层实现 Harbor 的 7 个环境方法已知缺口见Open seams一节run.pyZenML pipelinebuild_matrix展开 campaign 矩阵、run_harbor_trial每步跑一个试次构造指向桥接层的 HarborJobConfig并用Job.create().run()执行、build_report聚合成 Markdown 报告tasks/hello/一个密闭hermetic的 Harbor 任务写入42到/app/answer.txt验证器在内容匹配时给 1.0 分在oracleagent 下运行无需任何 LLM keyrequirements.txtharbor0.8.0zenml[local]Modal SDK 通过zenml integration install modal引入tasks/hello的构成值得展开目录下含task.toml任务清单schema_version 1.2无docker_image固定项因此走桥接层默认镜像、instruction.md任务指令文本、solution/solve.sh参考解法脚本、tests/test.shbash 验证器。其中 tests/test.sh 的逻辑是读取/app/answer.txt并去掉换行内容等于42则把reward1.0写入/logs/verifier/reward.txt否则0.0——这正是 Harbor 奖励回路的落地形态。前置条件与栈配置运行前需要一个已注册 Modal Sandbox 组件且处于激活状态的 ZenML 栈zenml sandbox register modal-sb --flavormodal zenml stack register harbor-stack -o default -a default -sb modal-sb --setREADME 给出冒烟测试时的栈配置样例orchestrator: default artifact_store: s3 sandbox: modal-sb # Modal flavor of the Sandbox component此外需要Modal 凭据通过modal token new配置写入~/.modal.toml或导出MODAL_TOKEN_ID/MODAL_TOKEN_SECRET——Modal SDK 在 import 时读取它们。沙箱镜像内还必须预装三个命令——bash、timeout(1) 和tar——桥接层依赖它们完成命令执行、超时控制与目录传输。这与zenml_harbor_env.py中exec用bash -c包裹命令、upload_dir/download_dir走 tar 归档的实现直接对应。关于注册命令Modal Sandbox 组件文档 提供了更完整的参数参考例如--app_name指定承载 Session 的 Modal App、组件级--env/--secret注入步骤进程环境注意不是注入沙箱容器内、通过zenml stack update --sandbox my-modal-sandbox把组件挂到既有栈上。ModalSandboxSettings支持image、sandbox_environment、timeout、cpu、memory、gpu、region、cloud、modal_environment等字段其中timeout是会话生命周期秒作为 TTL 兜底。运行一条本地冒烟管线安装依赖并执行pip install harbor zenml[local] zenml integration install modal # 默认任务tasks/hellooracle agent python run.py # 或显式指定任务与 agent python run.py tasks/hello oraclerun.py 的命令行入口支持三个位置参数task默认tasks/hello、agent_name默认oracle、n_trials默认3。注意 CLI 默认试次数是 3而 README 冒烟结果描述的是单试次场景的 ~15s 耗时。跑起来后管线会打印 dashboard URL。要检查产物可用下面的方式读取来自 README路径harbor_trial_result/harbor_trial_artifacts与 run.py 中 step 的输出注解一一对应from zenml.client import Client run Client().get_pipeline_run(run-id-from-stdout) outputs run.steps[run_harbor_trial].outputs result outputs[harbor_trial_result][0].load() # {job_id: ..., n_total: 1, n_completed: 1, n_errored: 0, mean_reward: 1.0} # Gzipped tar of Harbors jobs/ tree: agent verifier logs, trajectory. logs_tgz outputs[harbor_trial_artifacts][0].load() open(harbor_trial_artifacts.tar.gz, wb).write(logs_tgz)harbor_trial_artifacts中的 tar 归档是run_harbor_trial步骤在临时目录消失前用tarfile以w:gz模式打包的 Harborjobs/目录树run.py这是 agent/verifier 日志与轨迹在 artifact store 中的唯一持久副本。运行 registry 基准Terminal Bench除了本地任务目录还可以传入dataset:NAMEVERSION规格来命名 Harbor registry 中的数据集——Terminal Bench、SWE-bench Verified 等。该规格会在build_matrix中借助 Harbor 自身的解析器展开为每个 benchmark 任务一个 git-pinned 引用gitURLCOMMIT:SUBPATH提交钉住与harbor run完全一致且不随示例打包任何任务内容每个 mapped 试次步骤在运行时自行拉取自己钉住的任务run.py。固定了预构建docker_image的任务会直接启动该镜像。# 10 个任务的 Terminal Bench 样例——快速的真实基准冒烟测试 python run.py dataset:terminal-bench-sample2.0 oracle 1 # 完整的 89 个任务 Terminal Bench 2.0展开 89 个试次步骤 python run.py dataset:terminal-bench2.0 oracle 1oracleagent 运行每个任务的参考解法因此 registry 跑批不需要 LLM key——它验证的是编排与环境链路而非模型质量。要评测真实模型换成真实 agent如terminus-2、claude-code-agent并提供其 API key 即可。冒烟结果一次完整试次的执行链README 给出默认任务的端到端墙钟耗时约~15s奖励1.0。完整链路共 8 步在当前激活栈上创建 pipeline runrun_harbor_trial步骤构造JobConfig(env.import_pathzenml_harbor_env:ZenMLSandboxEnvironment)Job.create(config)→job.run()产生 1 个试次桥接层通过Client().active_stack.sandbox.create_session()打开 Modal Sandbox 会话oracleagent 上传solve.sh→ 执行 → 写入/app/answer.txtbash 验证器读取文件 →reward 1.0桥接层销毁 Modal 会话把ExecResult返回给 Harbor步骤返回JobResult摘要 jobs/目录树 tar 包 → 存为 ZenML artifacts。其中第 5 步的上传 → 执行对应桥接层的upload_file/exec方法exec在 zenml_harbor_env.py 中把 Harbor 的 shell 字符串用[bash, -c, command]包裹执行指定timeout_sec时则包成[timeout, str(timeout_sec), bash, -c, command]并将SandboxProcess的 stdout/stderr/exit_code 转成 Harbor 的ExecResult。第 7 步的销毁对应stop(deleteTrue)zenml_harbor_env.py会调用session.destroy()让 provider 释放资源若start()中途失败桥接层也会先销毁会话再抛出异常避免半启动的付费 Modal 沙箱一直挂到 TTL。已知缺口Open seamsREADME 诚实地列出了四个尚未闭合的接缝它们也直接对应桥接层源码中的实现取舍upload_dir/download_dir走 tar 通道当前SandboxSession只暴露upload_file因此目录上传在本地打成 tar.gz、上传一次、沙箱内解包zenml_harbor_env.py当底层 Sandbox flavor 原生支持目录传输时可收敛为单次调用timeout_sec在沙箱内用 coreutilstimeout强制执行超时返回真实的退出码 124因为 Modal 会话不接受单次执行的超时若试次需要超过默认的会话时长通过ModalSandboxSettings(timeout...)调高会话级 TTLuser被忽略SandboxSession.exec目前不接受 user 参数agent/verifier 脚本以容器默认用户运行桥接层只记录一条 warningzenml_harbor_env.py资源翻译未实现Harbor 任务环境配置里的cpus/memory_mb/gpus尚未流入对应 flavor 的ResourceSettings桥接层在start()中检测到这些字段时会打 warning 并忽略zenml_harbor_env.py待第一个 GPU 任务出现时再补齐。此外若任务声明allow_internetfalse桥接层会直接NotImplementedError拒绝运行而不是静默跳过——因为当前无法强制网络隔离宁可失败也不悄悄破坏任务语义zenml_harbor_env.py。docker_image目前也只支持 Modal flavor非 Modal 栈上固定了镜像的任务会得到明确的NotImplementedError。关于harbor run的一个说明桥接层实现了BaseEnvironment的全部方法虽存在上述已知缺口无用户切换、资源限制不生效、无网络隔离所以严格来说harbor run --environment-import-path zenml_harbor_env:ZenMLSandboxEnvironment也可以工作。但 README 明确表示这条路绕过了 ZenML pipeline——没有血缘、没有产物、ZenML 完全隐身。因此示例有意把python run.py设为唯一受支持的入口让血缘叙事保持诚实。小结sandbox_harbor 示例演示了一种清晰的集成模式把外部评测框架的执行内核通过实现其环境接口BaseEnvironment桥接到 ZenML 的 Sandbox 组件上同时把编排面矩阵、并行、缓存、血缘、报告完全交给 ZenML pipeline。当前 Modal flavor 已经跑通端到端冒烟约 15 秒、奖励 1.0Terminal Bench 2.0 全量 89 任务可在一条命令内展开为 89 个并行试次步骤。若你计划基于此模式扩展可重点关注ModalSandboxSettings的timeout/gpu等字段见 Modal Sandbox 文档、Sandbox 会话的 exec 与销毁语义session.py以及BaseSandbox.create_session的接口约定base.py。【免费下载链接】zenmlZenML : One AI Platform from Pipelines to Agents. https://zenml.io.项目地址: https://gitcode.com/GitHub_Trending/ze/zenml创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表