☰
HarnessRouter Environments 功能解析:项目依赖一次构建、所有会话只读共享的原理
2026/10/2 12:58:35 网站建设 项目流程

HarnessRouter Environments 功能解析:项目依赖一次构建、所有会话只读共享的原理

【免费下载链接】harnessrouterHarnessRouter Community Edition: the self-hosted, Apache-2.0 edition of the unified interface for agent harnesses. Run Codex, Claude Code, Hermes, PI, DSH, and more through one API, with sessions, streaming, files, cancellation, and failure handling. Implements the Unified Harness Protocol (UHP), an open standard. Your keys, your infrastructure.项目地址: https://gitcode.com/gh_mirrors/ha/harnessrouter

HarnessRouter 是一款自托管的 AI 智能体统一接口(实现统一智能体协议 UHP),可以让 Codex、Claude Code、Hermes 等智能体通过一个 API 运行。它的Environments(环境)功能解决了项目类任务的核心痛点:把项目的文件连同依赖一次构建成只读版本,所有会话共享读取——每个新会话不再重新上传文件、不再重装依赖,打开即就绪。该功能于 0.26 版随自托管服务器发布,是 UHP2026-09-28协议的正式章节,设计文档见 docs/environments.md。

为什么需要 Environments:每个会话重装依赖的痛点

HarnessRouter 的每个会话都有一个工作目录:从空开始、每轮对话后打快照、下一轮恢复。适合"一次性任务",但不适合项目——一个带脚本、资源、模板和上百个依赖包的项目,被多个人每天打开多次时,按老方式每个会话都要重新上传一遍文件、重装一遍依赖,而且两个会话无法共享同一份拷贝。

Environments 的答案是:把项目变成一个独立对象,构建一次,所有会话以只读方式共享。

Environments 是什么:一次构建、只读共享的项目快照

在 HarnessRouter 中,一个环境(对象 id 以henv_开头)由三部分组成:

  • 源文件(source):所有者编辑的项目文件,可以逐文件上传、导入压缩包、或直接从 git 仓库导入,也可在控制台在线编辑;
  • 版本(versions):每次"构建"生成一个新版本——先拷贝源文件(跳过node_modules、.venv等依赖目录,见 runner/environments.py 的NOT_COPIED),再按requirements.txt/pyproject.toml/package.json安装 Python 虚拟环境和 Node 依赖,运行setup.sh,最后把整棵目录树设为只读;
  • 活跃版本(active):一个指向某个版本的指针,会话读的就是它。构建成功自动成为活跃版本;构建失败则什么都不改变;回滚就是把指针指回旧版本,无需重新构建。

会话看到的世界是这样的(示意):

/env/content-studio ← 环境:完整、只读、所有会话共享 scripts/ assets/ ← 项目文件(所有者放进来什么样就是什么样) .venv/ node_modules/ ← 构建时安装一次,会话无需再装 /data/workspaces/<sid> ← 会话自己的目录:可写、私有、打快照,产出物只从这里来

三条规则让它成为"一个东西"而不是"共享文件夹":是被构建出来的、不是拷进来的(笔记本上现成的虚拟环境在容器里跑不了,构建才让"免重装"成为承诺);会话只能读不能写(写操作必须真正失败,而不是仅靠口头约定);路径固定(任何会话都能用绝对路径运行项目脚本)。完整协议定义见 protocol/versions/2026-09-28/environments.md。

一次构建如何做到:版本、原子指针与实时进度

构建在 runner/environments.py 的_build函数中执行,流程分五个阶段:复制文件 → Python 包 → Node 包 → 系统包(apt)→setup.sh,全程有 1800 秒的总时限。两个设计亮点值得注意:

① 进度实时可见。构建记录.hr-build.json在每个阶段结束时就写盘,包含当前阶段、已用秒数和日志尾部,页面每 3 秒轮询,你看到的是"正在安装 Python 包,已 87 秒"这样的进度条,而不是一个空转的转圈。

② 依赖装错了不用等构建。在控制台声明一个包时,服务端会先向 PyPI、npm 仓库或本机的 apt 列表查询(runner/environments.py 的check_package),名字拼错或版本从未发布过会在输入的那一刻被拒绝,而不是几分钟后的构建失败。

构建成功后,切换版本是一次原子操作:先创建临时软链接,再os.replace换掉active(见 runner/environments.py),正在运行的会话永远看到旧的或新的完整版本,不会出现"既读不到旧的也读不到新的"。

只读共享如何强制:每个环境一个用户组

"只读"不是写进提示词里求智能体别改,而是操作系统级的写墙:

  • 每个环境分配一个专属用户组(GID 为 60000 加 id 哈希,见 runner/environments.py 的_claim),环境目录的"组"本身就是权限记录,重启后依然有效;
  • 源目录是0700(只有 runner 能读),构建好的版本是0750/0640(同组可读、无人可写,见 runner/environments.py);
  • 智能体进程以自己的会话 uid 运行,只有在它的任务声明了某个环境时才临时加入该环境组——所以一个会话读不到别人环境里的字节,写入则直接EACCES失败;
  • 存储根目录权限0751:可以穿过、不能列目录,会话无法枚举服务器上还有哪些环境。

官方实测:加上这道墙之前,任何会话都能列出并读取所有环境的源和版本;加上之后,会话只能读自己声明的那一个。

会话启动时看到什么:固定路径 + 自动配好的环境变量

任务运行在环境上时,gateway 在分配任何资源之前先解析环境(请求里的metadata.environment优先,其次是 harness 上声明的),并把{id, slug, entry}传给 runner。如果环境还没有构建好的版本,任务在开始前就以environment_not_ready拒绝——绝不让任务跑几分钟才因为找不到项目而失败(见 gateway/app.py 的 Environments 段)。

一切就绪后,runner 会做两件事(runner/environments.py):

  1. 配环境变量:PATH以版本的.venv/bin和node_modules/.bin开头,PYTHONPATH/NODE_PATH指向项目,PROJECT_ROOT记录挂载点——所以python3直接用虚拟环境的解释器,from scripts.lib import x随处可 import;
  2. 写说明书:智能体的指令文件里加入 "Project environment" 一节,告诉它项目在哪、只读共享、依赖已装好、别装包装别复制项目、产物一律写到自己的工作目录、脚本用绝对路径运行,并原样附上所有者写的entry(比如python3 run.py --episode <id>)。

环境永远不参与快照——它在 workspace 之外,每轮对话的 tarball 里没有它,这正是"只构建一次"的关键。

上手路径:从控制台到 API

  • 控制台:Environments 页面(ui/src/app/(app)/environments/page.tsx/environments/page.tsx))展示"你添加 → 构建一次 → 每个任务都从它启动"三步流程;进入环境详情页可管理文件、发起构建、切换/回滚版本,构建中每 4 秒自动刷新列表;
  • API:POST /v1/environments创建;…/files/{path}读写单个文件;…/import导入压缩包或 git 仓库;POST …/build发起构建;POST …/versions/{n}/activate激活/回滚;harness 对象和POST /v1/responses上都用environment字段指定环境;
  • 测试:runner 侧行为在 runner/tests/test_environments.py(路径逃逸、导入安全性、构建与激活),gateway 侧在 gateway/tests/test_environments.py,协议契约以 protocol/schema/uhp-2026-09-28.schema.json 为准。

一句话总结原理:源与版本分离、构建用服务器自己的工具链、活跃版本用原子指针切换、权限用"每环境一组"的写墙强制——四个机制叠加,才有了"依赖一次构建、所有会话只读共享"的承诺。

【免费下载链接】harnessrouterHarnessRouter Community Edition: the self-hosted, Apache-2.0 edition of the unified interface for agent harnesses. Run Codex, Claude Code, Hermes, PI, DSH, and more through one API, with sessions, streaming, files, cancellation, and failure handling. Implements the Unified Harness Protocol (UHP), an open standard. Your keys, your infrastructure.项目地址: https://gitcode.com/gh_mirrors/ha/harnessrouter

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询