Harbor Framework
- 一、简介和原理
-
- [1.1 项目简介](#1.1 项目简介)
- [1.2 核心能力](#1.2 核心能力)
- [1.3 核心运行原理](#1.3 核心运行原理)
- 二、资料地址
- 三、安装
-
- [3.1 前置依赖](#3.1 前置依赖)
- [3.2 安装方式](#3.2 安装方式)
- 四、Demo
- 五、备注
- 六、常用命令
一、简介和原理
1.1 项目简介
Harbor Framework 是开源智能体(Agent)与大语言模型(LLM)评估、调优框架,主要面向代码智能体、容器化仿真场景,支持批量并行实验、基准测试、强化学习轨迹数据生成。
1.2 核心能力
支持主流代码智能体的评测;
支持自定义评测数据集与沙箱运行环境;
支持本地 Docker、云端容器大规模并发执行任务;
自动输出 Agent 交互轨迹,可用于强化学习训练;
兼容 Terminal-Bench、SWE-Bench 等主流代码评测基准。
1.3 核心运行原理
容器沙箱隔离:所有任务运行在 Docker 或云端容器环境,任务之间环境隔离,互不污染。
三层解耦架构:数据集(Dataset)、智能体(Agent)、大模型(Model)完全解耦,通过命令行参数自由组合,不需要修改源代码。
并发调度:本地模式限制容器数量;云端模式支持弹性高并发。
日志与观测:内置可视化查看面板,完整记录交互步骤、耗时、任务结果。
版本化数据集管理:数据集采用名称@版本格式管理,多版本共存,一键切换版本。
执行流程图:
#mermaid-svg-vo7XOEOTmA7bTJ02{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vo7XOEOTmA7bTJ02 .error-icon{fill:#552222;}#mermaid-svg-vo7XOEOTmA7bTJ02 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vo7XOEOTmA7bTJ02 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .marker.cross{stroke:#333333;}#mermaid-svg-vo7XOEOTmA7bTJ02 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vo7XOEOTmA7bTJ02 p{margin:0;}#mermaid-svg-vo7XOEOTmA7bTJ02 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster-label text{fill:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster-label span{color:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster-label span p{background-color:transparent;}#mermaid-svg-vo7XOEOTmA7bTJ02 .label text,#mermaid-svg-vo7XOEOTmA7bTJ02 span{fill:#333;color:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .node rect,#mermaid-svg-vo7XOEOTmA7bTJ02 .node circle,#mermaid-svg-vo7XOEOTmA7bTJ02 .node ellipse,#mermaid-svg-vo7XOEOTmA7bTJ02 .node polygon,#mermaid-svg-vo7XOEOTmA7bTJ02 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .rough-node .label text,#mermaid-svg-vo7XOEOTmA7bTJ02 .node .label text,#mermaid-svg-vo7XOEOTmA7bTJ02 .image-shape .label,#mermaid-svg-vo7XOEOTmA7bTJ02 .icon-shape .label{text-anchor:middle;}#mermaid-svg-vo7XOEOTmA7bTJ02 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .rough-node .label,#mermaid-svg-vo7XOEOTmA7bTJ02 .node .label,#mermaid-svg-vo7XOEOTmA7bTJ02 .image-shape .label,#mermaid-svg-vo7XOEOTmA7bTJ02 .icon-shape .label{text-align:center;}#mermaid-svg-vo7XOEOTmA7bTJ02 .node.clickable{cursor:pointer;}#mermaid-svg-vo7XOEOTmA7bTJ02 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .arrowheadPath{fill:#333333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vo7XOEOTmA7bTJ02 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-vo7XOEOTmA7bTJ02 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vo7XOEOTmA7bTJ02 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster text{fill:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 .cluster span{color:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vo7XOEOTmA7bTJ02 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-vo7XOEOTmA7bTJ02 rect.text{fill:none;stroke-width:0;}#mermaid-svg-vo7XOEOTmA7bTJ02 .icon-shape,#mermaid-svg-vo7XOEOTmA7bTJ02 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-vo7XOEOTmA7bTJ02 .icon-shape p,#mermaid-svg-vo7XOEOTmA7bTJ02 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-vo7XOEOTmA7bTJ02 .icon-shape .label rect,#mermaid-svg-vo7XOEOTmA7bTJ02 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-vo7XOEOTmA7bTJ02 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-vo7XOEOTmA7bTJ02 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-vo7XOEOTmA7bTJ02 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} harbor run
加载数据集,分配并发任务
拉起隔离容器
Agent执行任务
验证器校验打分
保存结果,销毁容器
输出汇总报告
二、资料地址
GitHub 仓库: https://github.com/harbor-framework/harbor
配套资源:
官方文档:https://www.harborframework.com/docs
Harbor Hub:https://hub.harborframework.com
三、安装
3.1 前置依赖
本地运行模式:Docker 服务必须正常启动;
Linux 注意:当前用户需要加入 docker 用户组,否则需要 sudo 执行 harbor 命令;Windows 建议使用 WSL2 后端。
云端运行模式:需要对应云服务商 API Key;
大模型调用:需要对应 LLM 厂商 API Key。
⚠️注意:PyPI 上存在旧包名harbor,请勿直接使用pip install harbor,会安装到错误的第三方包。
3.2 安装方式
shell
# 推荐
uv tool install harbor
# or
pip install harbor
安装完成后,终端可直接调用全局 harbor 命令。
四、Demo
说明:本次使用oracle的agent演示,后续评分,大家可以自己去配置需要跑模型
文件目录:
SHELL
demo/
├── environment/ # 容器沙箱构建环境,构建任务Docker镜像所用素材
│ └── Dockerfile # 沙箱镜像构建脚本
├── instruction.md # 给Agent的任务提示词/任务描述,智能体要完成的目标、需求说明
├── jobs/ # harbor run执行之后输出的运行结果目录,执行后会自动创建
├── solution/
│ └── solve.sh # 参考标准答案脚本;可选,作为baseline正确实现
├── task.toml # 任务元配置文件,Harbor Framework核心配置
└── tests/
├── test_outputs.py # Python校验逻辑:断言、结果解析、打分逻辑
└── test.sh # 验证器入口shell脚本,执行测试、生成reward、stdout输出
日志目录:
shell
jobs/
└── 2026-08-12__11-24-24/ # 一次完整harbor run全局实验总目录 ├── config.json # 本次全局实验配置
├── exam_task__fWfoVLm/ # 单个任务实例目录,每个评测任务生成1个
│ ├── agent/ # Agent智能体工作目录
│ ├── artifacts/ # 任务产出工件、沙箱输出文件
│ ├── config.json # 当前这一条任务的独立配置
│ ├── lock.json # 任务运行锁文件
│ ├── result.json # 单条任务最终结果(打分、成功失败)
│ ├── trial.log # Agent完整交互轨迹日志(最重要!)
│ └── verifier/ # 验证器/评测校验模块工作目录
│ ├── reward.txt # 验证器原始奖励分数
│ └── test-stdout.txt # 校验脚本执行stdout,断言、报错信息
├── job.log # 整个实验总运行日志
├── lock.json # 全局实验锁
└── result.json # 整个实验汇总结果
4.1 创建项目
shell
[root@localhost home]# tree test_demo
test_demo
├── environment
│ ├── app
│ │ └── extract_log.sh
│ ├── data
│ │ └── app.log
│ └── Dockerfile
├── instruction.md
├── solution
│ └── solve.sh
├── task.toml
└── tests
├── test_outputs.py
└── test.sh
5 directories, 8 files
[root@localhost home]# cat test_demo/environment/app/extract_log.sh
#!/bin/bash
# 提取日志脚本,bug:当前过滤WARN,需要改为ERROR
LOG_FILE="/var/log/app.log"
OUT_FILE="/tmp/error_only.log"
# 错误:grep WARN,应该为 grep ERROR
grep "WARN" "${LOG_FILE}" > "${OUT_FILE}"
[root@localhost home]# cat test_demo/environment/data/app.log
2026-08-12 08:10:01 INFO service start ok
2026-08-12 08:10:05 WARN disk usage 75%
2026-08-12 08:10:10 ERROR database connect failed
2026-08-12 08:10:15 WARN memory high
2026-08-12 08:10:20 ERROR timeout request
2026-08-12 08:10:25 INFO receive request
2026-08-12 08:10:30 ERROR parse json failed
2026-08-12 08:10:35 WARN slow query
2026-08-12 08:10:40 ERROR rpc call exception
2026-08-12 08:10:45 INFO task complete
[root@localhost home]# cat test_demo/environment/Dockerfile
FROM swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/tiangolo/uvicorn-gunicorn:python3.11-slim
# 创建目录
RUN mkdir -p /app /var/log /tmp
# 拷贝业务脚本与日志
COPY app/extract_log.sh /app/extract_log.sh
COPY data/app.log /var/log/app.log
RUN chmod +x /app/extract_log.sh
WORKDIR /
#CMD ["/bin/bash"]
[root@localhost home]# cat test_demo/instruction.md
你是Linux运维工程师。
容器中业务日志路径:/var/log/app.log
/app/extract_log.sh 为日志提取脚本。
当前脚本存在问题:脚本提取的是WARN警告日志。
业务需求:提取日志文件中所有包含 ERROR 的行,输出写入文件 /tmp/error_only.log。
请完成:
1. 查看 /var/log/app.log 日志内容理解日志格式
2. 修改 /app/extract_log.sh,修改过滤关键字
3. 执行脚本 /app/extract_log.sh
4. 确认 /tmp/error_only.log 生成并且内容为全部ERROR行
任务完成即可结束。
[root@localhost home]# cat test_demo/solution/solve.sh
#!/bin/bash
# 参考正确解法,人工baseline
sed -i 's/grep "WARN"/grep "ERROR"/' /app/extract_log.sh
chmod +x /app/extract_log.sh
/app/extract_log.sh
cat /tmp/error_only.log
[root@localhost home]# cat test_demo/task.toml
version = "1.0"
id = "demo-extract-error-log@v1"
name = "提取日志ERROR错误行"
description = "运维demo:修改shell脚本提取日志中ERROR行输出到文件"
timeout = 300
[environment]
build_timeout_sec = 600.0
cpus = 1
memory_mb = 1024
storage_mb = 4096
gpus = 0
dockerfile = "./environment/Dockerfile"
[verifier]
timeout_sec = 120.0
entrypoint = "./tests/test.sh"
[verifier.env]
[solution.env]
[root@localhost home]# cat test_demo/tests/test_outputs.py
#!/usr/bin/env python3
import sys
import os
output_file = "/tmp/error_only.log"
# 判断输出文件是否存在
if not os.path.exists(output_file):
print("FAIL:输出文件 /tmp/error_only.log 不存在")
sys.exit(1)
with open(output_file, "r", encoding="utf-8") as f:
lines = f.readlines()
# 统计包含ERROR的行数
error_lines = [line for line in lines if "ERROR" in line]
count = len(error_lines)
print(f"实际ERROR行数:{count},期望:4")
if count == 4:
print("PASS:提取ERROR日志正确")
sys.exit(0)
else:
print(f"FAIL:ERROR行数不对,得到 {count},预期4")
sys.exit(1)
[root@localhost home]# cat test_demo/tests/test.sh
#!/bin/bash
set -e
python3 ./tests/test_outputs.py #> ./verifier/test-stdout.txt
exit_code=$?
if [ ${exit_code} -eq 0 ]; then
echo 1 > /logs/verifier/reward.txt
else
echo 0 > /logs/verifier/reward.txt
fi
[root@localhost home]#
执行demo
shell
[root@localhost test_demo]# harbor run -p . -a oracle
1/1 Mean: 1.000 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 0:00:13 0:00:00
adhoc • oracle
┏━━━━━━━━┳━━━━━━━━━━━━┳━━━━━━━┓
┃ Trials ┃ Exceptions ┃ Mean ┃
┡━━━━━━━━╇━━━━━━━━━━━━╇━━━━━━━┩
│ 1 │ 0 │ 1.000 │
└────────┴────────────┴───────┘
┏━━━━━━━━┳━━━━━━━┓
┃ Reward ┃ Count ┃
┡━━━━━━━━╇━━━━━━━┩
│ 1.0 │ 1 │
└────────┴───────┘
Job Info
Total runtime: 13s
Results written to jobs/2026-08-12__11-49-49/result.json
Inspect results by running `harbor view jobs`
Share results by running `harbor upload jobs/2026-08-12__11-49-49`
11:50:09 - LiteLLM:WARNING: get_model_cost_map.py:290 - LiteLLM: Failed to fetch remote model cost map from https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json: The read operation timed out. Falling back to local backup.
[root@localhost test_demo]#
Reward为1,说明demo已经跑通了,可以看一下具体结果行数是不是4
shell
[root@localhost test_demo]# cat jobs/2026-08-12__11-49-49/exam_task_test__hNpKdip/verifier/test-stdout.txt
实际ERROR行数:4,期望:4
PASS:提取ERROR日志正确
五、备注
1、目录格式名称需要严格限制:数据集模板目录结构、文件名不能随意改动;task.toml、instruction.md、environment/、tests/、solution/ 为框架识别固定目录名,不能改名。
2、Dockerfile 尽量使用 slim 基础镜像,减小构建耗时;脚本拷贝完成后,shell 脚本考虑是否加加 chmod +x 赋予可执行权限。
3、instruction.md 任务中不要写依赖外部网络的操作,沙箱容器默认隔离外网;明确写清楚输出文件绝对路径,Agent 容易混淆相对 / 绝对路径;不要在指令中暗示答案,只描述业务需求。
4、test.sh最后是需要写入到/logs/verifier/reward.txt中的,harbor会自动挂载这个目录,不需要提前新建。
5、数据集模板中禁止携带 jobs 目录,该目录是 harbor run 运行时输出目录,原始数据集模板中必须删除;如果残留 jobs 目录,加载数据集会产生干扰。
六、常用命令
shell
# 1、本地开发调试:oracle参考解执行器,加载当前目录任务(不走大模型,校验数据集逻辑)
harbor run -p . -a oracle
# 2、仅构建/初始化环境,不执行agent任务(替代dry‑run,做预校验)
harbor run -p . -a oracle --install-only --n-tasks 1
# 3、oracle模式,跑完**不删除容器**,方便排查现场(--no-delete)
harbor run -p . -a oracle --no-delete --n-tasks 1
# 4、真实大模型agent评测,限制只跑1个样本,并发1
harbor run -p . -a code-agent -m gpt-4o-mini -n 1 --n-tasks 1
# 5、使用历史job配置文件复现实验
harbor run -c ./jobs/xxx/config.json
# ========== 数据集管理 ==========
# 查看registry仓库内数据集(本地手写task不会出现在列表)
harbor dataset list
# 初始化顶层dataset集合(用于打包发布;单task开发建议手动建目录)
harbor init ./test_demo
# ========== 结果查看 & 清理 ==========
# 打开web页面浏览任务轨迹trajectory
harbor view ./jobs/2026-08-05__11-24-24
# 清理缓存、环境残留
harbor cache clean