HarnessRouter/harnessrouter · 上手攻略

  • 仓库:HarnessRouter/harnessrouter
  • 链接:https://github.com/HarnessRouter/harnessrouter
  • 分类:trending · agent-harness / 自托管 LLM 网关
  • 作者:spark
  • 更新:2026-09-08

1. 这是什么

HarnessRouter Community Edition 是一个 Apache-2.0 自托管的 agent harness 统一网关,把市面上几款主流的 AI 编程 / Agent CLI(Codex、Claude Code、Hermes、Pi、DeepSeek Harness / DSH)封装成同一套 HTTP API。开发者不再为每个 harness 单独写一遍「启动子进程 / 解析 stdout / 截断流 / 取消任务 / 拿文件产物」那一坨胶水代码,而是用一个端点把任务扔进去,让 HarnessRouter 在容器里替你拉起对应的 harness CLI。

它的官网(https://harnessrouter.ai)写得很直白:「LLM 返回 token,harness 给它一个沙箱、工具和循环,让它返回真实的工作」。GPT-5.2 / Claude Opus 4.8 是模型,Codex / Claude Code 才是 harness。HarnessRouter 介于两者与你的产品之间,是 execution & runtime 层,而不是又一个 AI 封装。

⚠️ 注意:仓库 README 和官网都强调,HarnessRouter Cloud(托管版)Community Edition(开源自托管)共用同一个开源协议 UHP(Unified Harness Protocol),后者的实现就是这个仓库。换句话说,自托管跑的是 UHP 的参考实现,不存在「Cloud 版更高级」。

1.1 它解决了什么问题

写一个对接 Claude Code CLI 的 Python 客户端已经要处理:

  • 启动一个子进程、设置工作目录、注入 stdin;
  • 解析它那种带 ANSI 色码 / 控制字符的 stream-json 输出;
  • 处理「任务运行到一半要取消」(kill 子进程但保留 transcript);
  • 把 harness 在工作目录里写出的文件回传到调用方;
  • 让多个用户/会话之间彼此隔离(文件系统、密钥、环境变量)。

每换一个 harness(Codex、Claude Code、Hermes、DSH…),以上逻辑几乎全部要重写一遍。HarnessRouter 的承诺是:写一次 UHP 客户端,就能切换 harness。在它 2026-09-04 跑过的内部 benchmark 中,同一个任务在不同 harness × model 组合下的成本差异最高约 475×(Claude Code × claude-opus-4.8 vs Hermes × gpt-5.2)—— 而切换本身只是后端配置,不是代码改动。

1.2 协议:UHP 是什么

Unified Harness Protocol(UHP)是 HarnessRouter 团队推动的开放标准,目前规范版本 2026-08-11。它不绑定 HarnessRouter:任何人都可以基于规范实现服务端(用 OpenAPI 3.1 + JSON Schema 2020-12 机器可读),然后用 protocol/conformance 目录下的 64 项 conformance 测试证明自己合规。

测试套件(suite version 2026.8.11.post1)分三类:

  • Core(40 项):发现 / 版本协商 / 鉴权 / 错误信封 / harnesses / models / 任务执行(流式 + 非流式)/ 事件流 / sessions / 取消 / 保留请求字段;
  • Extended(+8):session 列表与查看 / 文件输入 / artifacts / 下载头 / 路径遍历探针;
  • Full(+15):harness 增删改查 / 拒绝不支持的 base / skill 文件夹往返 / MCP 与禁用工具持久化 / session 共享。

⚠️ 一条有趣的工程教训:测试 S-09 「the stream is progressive」专门检测「服务端把流全部缓冲、结束后才一次性 flush」这种最常见的部署错误——通常是被某层反向代理吃掉了。它不是看 schema,而是统计事件到达时间的离散度来抓这个坑。schema 校验发现不了。

社区版在 2026-09-04 用 2026.8.11.post1 套件跑过自托管实例:64/64 通过、0 失败、0 跳过、0 错误,报告公开。

2. 快速安装

2.1 先决条件

  • Docker(任何 20.10+ 都行)
  • 约 4 GB 磁盘(含镜像体积与首次启动下载的 harness CLI)
  • 一家模型供应商的 API key(Anthropic / OpenAI / OpenRouter / Bedrock / Azure AI Foundry / Vercel / llmtr / TokenRouter 之一);没有 key 也能跑起来,但什么任务都做不了

2.2 三步跑起来

Step 1:拉镜像(约 700 MB)

docker pull harnessrouter/harnessrouter

Step 2:启动容器(仅 loopback 监听,密码走默认稍后改)

docker run -d --name harnessrouter \
  -p 127.0.0.1:3000:3000 \
  -v harnessrouter:/data \
  harnessrouter/harnessrouter

⚠️ 不要加 --user。容器必须以 root 启动,因为每个 agent session 会用各自的用户身份跑(隔离工作目录与密钥)。从 0.8.2 起,root 不是默认而是强制要求:检测到 --user 就拒绝启动并明确报错。容器内部自己会 drop privileges。

-p 127.0.0.1:3000:3000 让控制台只在本机可访问,这正是「默认账号上线安全」的来源。-v harnessrouter:/data 把 SQLite 数据库、文件、首次启动下载的 harness CLI 全部持久化在 named volume 里,删掉 volume 实例就归零。

Step 3:等首次启动完成(约 30 秒),再打开浏览器

docker logs -f harnessrouter

首次启动会看到类似这样的几行(README 引用原文):

[harnessrouter] installing Claude Code (Anthropic's terms apply)…
[harnessrouter] installing Codex (Apache-2.0)…
[harnessrouter] installing Pi (MIT) and its MCP adapter (MIT)…
[harnessrouter] installing DeepSeek Harness (MIT, developer preview — version-pinned)…
[harnessrouter] installing Hermes (check its upstream license before use)…
[harnessrouter] data=/data backends available: claude codex hermes pi dsh
[harnessrouter] ready on :3000

⚠️ 首次启动 ~30 秒不要慌。如果立刻访问 http://localhost:3000 看到连接被拒绝,是正常的——容器还在装 harness CLI。一旦看到 ready on :3000 再开浏览器。这一行 WARNING: using the DEFAULT password 每次启动都会出现,直到你在 Profile 改了密码为止。

打开浏览器,用以下默认账号登录:

  • 用户名:harnessrouter
  • 密码:harnessrouter

进去后第一件事:Profile → 改密码。如果你的机器是脚本化的、希望无人值守,可以在 docker run 阶段预设:

-e HR_AUTH_USER=you \
-e HR_AUTH_PASSWORD=the-password-you-chose

2.3 不想用 docker run?Compose 也行

cp .env.example .env
docker compose up -d

⚠️ README 明确警告:docker-compose.yml 默认把 3000 端口发布到所有网卡(3000:3000),不是 loopback。生产部署前必改这一行,否则默认密码直接暴露在网络上。

2.4 Docker 资源回收与迁移

  • 删实例:docker rm -f harnessrouter && docker volume rm harnessrouter(volume 必须显式删)
  • 迁移:复制 /data volume 即可,整个状态(SQLite、文件、转写、所有 harness 安装)一起搬走

3. 核心用法

3.1 配 Provider(必做)

控制台 → Integrations → Add Integration,三个字段:

  1. 名字(自取)
  2. Provider(Anthropic / OpenAI / OpenRouter / Bedrock / Azure AI Foundry / Vercel / llmtr / TokenRouter)
  3. API key

不用告诉 HarnessRouter 模型清单:产品自己维护各 Provider 的模型列表,Provider 一加,对应行的模型就出来了。

⚠️ 想用 OpenAI 兼容的自托管 endpoint(比如本地 vLLM / llama.cpp)?在 Provider 里选 openai 而不是 .env.example 里那个 openai-api 字段名,并加 base_url。Provider × 后端不是随便组合的,对照表(README 列出):

Connection provider 能配给哪些 backend
anthropic Claude Code, Hermes, Pi
openai Codex, Hermes, Pi
openrouter Codex, Hermes, Pi, DeepSeek Harness
azure-foundry Codex, Hermes, Pi
bedrock Claude Code, Hermes
tokenrouter Claude Code, Codex, Hermes, Pi, DSH
vercel Claude Code, Codex, Hermes, Pi, DSH
llmtr Claude Code, Codex, Hermes, Pi, DSH

配错时不会报错,而是任务「跑超长时间然后 turn 为空」。从控制台加 Integration 不会遇到这个问题——UI 只会列出能用的 Provider。

3.2 用环境变量跳过浏览器(脚本化部署)

适合 CI 或无人值守:

-e HR_SECRET_GLOBAL_HARNESS_CONN_ANTHROPIC='{"name":"anthropic","provider":"anthropic","api_key":"sk-ant-…"}'
-e HR_SECRET_GLOBAL_HARNESS_POLICY_CLAUDE='{"chain":["anthropic"]}'

每个 backend 一条 …_POLICY_<BACKEND> 变量(CLAUDE / CODEX / HERMES / PI / DSH)。chain 是 fallback 顺序,可以填多个 provider。

3.3 发起一个 Agent 任务

控制台走的是「Agent harnesses → 选 harness → New task」,填提示词 → 在消息框下方的 chip 选模型 → 发送。转写(transcript)会流式回来:每个 harness 跑的命令、碰过的文件、最终答案都看得到,可以整段带走或单文件下载。

⚠️ README 强调:「启动时不带 --user」「首次启动慢是因为要装 5 个 harness CLI」、「装完只显示实际装上的 backend,没装的会显式列出而不是悄悄缺席」。这些是社区版从根上想清楚的设计选择,不要在生产环境「优化」掉。

3.4 通过 UHP 直接调 API(不走控制台)

社区版本身实现了 UHP 服务端,端口应该是网关 :8080(loopback)。你可以用 OpenAPI 客户端生成器生成任意语言的 SDK,或直接 curl

# 列出可用 harnesses(端点路径以 UHP 规范为准)
curl -H "Authorization: Bearer $UHP_API_KEY" \
     http://localhost:8080/v1/harnesses

⚠️ 准确的 :8080 vs :3000 端口分工、HTTPS 接入与 token 申请流程在 README 没有完整展开;如果你准备在 CI 接入,以仓库 docs/ 目录的实际版本为准。这里不给伪造的命令。

3.5 Starter Kits:拿来即用的小产品

控制台首页有 Starter Kits 列表。每个 kit = 一个完整的 agent 产品(不是代码片段):一个 app、一个配置好的 agent、一份教它写什么的 skill。点 Launch 即可。每个卡片会显示要消耗哪个 base × 哪个 model,让你动手前就能估算成本。已连接的 Provider 才有可选项,没连的会标灰并说明「Add a provider that serves this model to use it」。

README 提到的两个示例 kit:

  • Deck kit:一句提示词("A 5-slide deck explaining what a container image is, for new engineers.")出 PPT,边做边出 slide,发现形状错了可以中途打断;
  • Sheet kit:表格的每一行是一个 harness run,左侧列当输入,按 Run 后逐格填,带 Stop 按钮。

4. 典型适用场景

  • 多 harness 评测:同一个任务在 Codex / Claude Code / Hermes / Pi / DSH 之间跑,比成本与质量。改一行配置即可切,实测成本差异最高 ~475×(官网公开数字)。
  • CI 里跑 agent 任务:在 GitHub Actions / GitLab CI 里拉镜像 → 起容器 → 用 UHP 提交任务 → 拿 artifacts → 关掉。比把每个 harness CLI 装到 runner 上干净很多。
  • 不想让 agent 进程碰到产品密钥:容器启动后以 root 起来,内部为每个 session 切换到一个独立 Unix 用户,session 间文件路径属于不同 uid,「读了不该读的东西」不是被「劝阻」而是被文件系统阻止。README 把这点写得很重。
  • 想在本地/私有云里跑 coding agent:跳过 Anthropic / OpenAI 的 cloud agent 套件,自己掌握 key、文件、telemetry。
  • 做一个 agent 产品但不想重写 harness 集成:官网把 Readily 当作示例客户——「24 小时内从想法到生产里的 agent」。

⚠️ 不适合的场景:纯 LLM 路由(只想要「按 prompt 选模型」)。那是 LiteLLM / LLMRouter / OpenRouter 这类 LLM router 的领域。HarnessRouter 是 harness router——目标是把 harness(带沙箱 / 工具 / 循环)作为不可拆的整体来调度。

5. 坑与注意

  1. 首次启动 ~30 秒不要关掉容器。30 秒只是安装 5 个 CLI 的耗时,不是卡死。看 docker logs 里的 ready on :3000 才是真信号。
  2. --user 必删。0.8.2 起容器检测到就拒启动。如果你之前用自定义 user: 跑过,升级前必删。
  3. 默认密码上线:每个新 volume 在改密码前,每次启动都会打 WARNING。本机 loopback 部署时这是提醒,不是事故。
  4. Provider × backend 错配不会报错。会空转非常久然后 turn 为空。线上最好用控制台加 Integration,避开环境变量暗坑。
  5. HERMES / Claude Code 许可证问题:hermes-agent 上游未声明 license,Claude Code 走 Anthropic 自家条款——README 把它们从镜像里移到了「首次启动由你亲自从上游拉」,原因是镜像内再分发违反各自条款。社区版镜像只内嵌了明确可再分发的:Codex(Apache-2.0)、Pi(MIT + MIT MCP adapter)、DSH(MIT,开发预览,版本 pin)。⚠️ 这意味着 hermes / Claude Code 第一次启动需要外网访问上游仓库,没网就跑不起来这两个 backend。
  6. Docker Compose 默认 3000:3000 暴露所有网卡。线上部署必改回 127.0.0.1:3000:3000 或前置反向代理。
  7. 端口冲突:宿主机 3000 被占,只改 -p 左半(如 -p 127.0.0.1:3100:3000)。容器内始终听 3000。
  8. 忘记密码:删除 /data/selfhost-auth.json 重启,回落到 HR_AUTH_USER / HR_AUTH_PASSWORD 环境变量或默认账号。没有邮件重置路径——这是自托管设计,不是 bug。
  9. 跨 session 文件隔离靠 Unix 用户,不是 SELinux / AppArmor。没跑在 Docker 默认 capability 上没问题,但若自己加 --privileged / --cap-add / 自定义 seccomp,就破坏了原有隔离模型。
  10. UHP 规范与实现都在快迭代。conformance 套件 2026.8.11.post1 / 协议 2026-08-11 / 自托管实现在 2026-09-04 跑 64/64 通过。短期内版本号变化可能快,生产部署前请确认 suite_version 与 generated_at 时间戳。
  11. Statshub / Cloud 路径不在本仓库。HarnessRouter 官网还有 Cloud 版(managed,Y Combinator 背书,2026-07-24 首发)。Community Edition 不包含 Cloud 的 dashboard / 计费 / SSO 等能力。
  12. 企业条款自检:用 Cloud 版的话注意「$20/月起的 plan 把 plan 金额全部计入 usage」这句话——月费是预付 credit,不是订阅。

6. 与同类对比

维度 HarnessRouter CE LiteLLM OpenRouter LLMRouter NVIDIA llm-router
抽象对象 harness(沙箱 + 工具 + 循环) 模型请求 模型请求 模型请求(评测 + 部署) 模型请求
自托管 ✅ Docker 单镜像 ✅ Python lib + proxy ❌(托管为主) ✅ Python lib ⚠️ Notebook 形式
接入成本 一次集成,5 个 harness 即用 一次集成,~100 provider API key 一次集成 仅 notebook demo
隔离模型 每 session 一个 Unix 用户 不适用 不适用 不适用 不适用
标准 UHP(自定开放标准) OpenAI 兼容 自研 router API
Conformance 套件 64 项 HTTP 测试 xRouteBench(路由评测)
流式 + 取消 + artifacts ✅(UHP 规范强约束) 仅 chat completion 仅 chat completion 部分
License Apache-2.0 MIT 服务条款 MIT Jupyter
Stars(公开近似) 669 30K+ 巨大 ~1K 343

结论:如果你的需求是「在 N 个不同模型之间挑一个」——LiteLLM / OpenRouter / LLMRouter 都是更轻的选择。只有当你需要让 agent harness(带 shell / 文件系统 / 工具循环的那种 CLI)作为统一后端被调度,HarnessRouter 的「harness × model」矩阵才有意义:它的 475× 成本差异正来自这种矩阵的可路由性,这是 LLM router 给不了的。

7. 一句话推荐

如果你想搭「一个能跑 Codex / Claude Code / Hermes / Pi / DSH 的本地/私有 agent 网关」,并且能接受 700 MB Docker 镜像、首次启动 ~30 秒、且 hermes/Claude Code 首次启动需要外网拉上游 —— HarnessRouter Community Edition 是 2026 年这个细分里最完整的选择;如果你只是想让同一个 prompt 在不同模型间选一个,别绕弯,去 LiteLLM 或 OpenRouter。


⚠️ 不确定 / 已知边界

  • :8080 网关端口与 :3000 UI 端口分工、/v1/... UHP 端点的精确路径在 README 没有完整列出(README 主要讲控制台流),自动化接入前请直接看 docs/ 目录或 protocol/ 下的规范。
  • 各 harness 的当前 pinned 版本license 状态可能在 PR 间变化(hermes 至今未声明 license 是一个已知的上游问题);本文引用的 backend 列表以 2026-09 仓库 main 分支为准。
  • 官网公开的「≈475× 成本差异」是单任务测量值,README 没声明是不是典型值或最大极值;本文按官网措辞如实标注「实测最高 ~475×」,不要当普遍结论。
  • 「第一行 WARNING 提示」「首次 30 秒」这些体验数字来自 README 与 2026-09-04 self-host 报告,没有在我自己的环境复跑——本文不复现。