2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00
2026-09-04 14:58:42 +08:00

Skill Agent 编译流水线

本项目将 SkillsBench 任务中的单个 Skill 依次经过静态编译、Fast 动态优化、Deep 动态迭代和 BenchFlow 评测,产出可恢复、可审计的最终 Skill。

安装与配置

配置系统环境

项目目前运行在 Windows WSL 2(Ubuntu 26.04 LTS) 系统中。

# 以管理员身份打开 ps 安装
wsl --install -d Ubuntu-26.04

设置账号密码,进入 wsl 后安装基础工具与 python,nodejs:

sudo apt update
sudo apt upgrade -y
sudo apt install -y ca-certificates curl git python3 python3-pip python3-venv python-is-python3
sudo apt install -y nodejs

项目依赖 docker, 直接运行在这个 WSL 发行版中的原生 Docker Engine(29.6.2)。

sudo apt remove -y docker.io docker-compose docker-compose-v2 docker-doc docker-buildx podman-docker containerd runc

sudo install -m 0755 -d /etc/apt/keyrings

sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc

sudo chmod a+r /etc/apt/keyrings/docker.asc

sudo tee /etc/apt/sources.list.d/docker.sources >/dev/null <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF

sudo apt update

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

sudo systemctl enable --now docker

sudo usermod -aG docker "$USER"
newgrp docker

验证 docker:

docker version
docker run --rm hello-world

如果遇到permission denied相关提示,可能和docker权限问题/网络问题有关:

permission denied while trying to connect to the docker API at unix:///var/run/docker.sock
permission denied while trying to connect to the docker API at unix:///var/run/docker.sock

网络问题可配置 WSL 网络镜像,在 Windows PowerShell 里创建/修改:

notepad $env:USERPROFILE\.wslconfig

写入:

[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=true

保存后执行:

wsl --shutdown
wsl -d Ubuntu-26.04

然后再跑

docker run --rm hello-world

如果最后看到 Hello from Docker!,就说明问题已经完全解决。

项目建议放在 ~/projects/skill-agent-proj, 项目目录:

skill-agent-proj/
├── scripts/
├── requirements.txt
├── provider_routes.json
└── data/
    └── skills-bench/
        ├── pyproject.toml
        ├── uv.lock
        ├── tasks/
        └── skillsbench_agentbeats/
      ......

配置项目环境依赖

外部模型

在项目根目录配置 .env,并在 provider_routes.json 中维护模型路由。所有模型参数使用 provider/model-id 格式。

项目环境

可以用 conda 创建虚拟环境, python 版本选择3.12, 在虚拟环境中配置项目依赖:

python -m pip install -r requirements.txt

目前使用的是Python 3.12 自带的 venv,激活虚拟环境 Linux/macOS:

source .venv/bin/activate

用结束后退出环境

deactivate

skills-bench 环境

完整流水线要求 SkillsBench/BenchFlow CLI,测试脚本 run-raw-task.sh 会调用它们。

  • SkillsBench:官方基准仓库,提供任务规范、Python 运行环境和 skillsbench_agentbeats worker。
  • BenchFlow CLI:实际执行 bench eval run --sandbox docker 的命令行工具。
sudo snap remove astral-uv
hash -r

curl -LsSf https://astral.sh/uv/0.12.6/install.sh | sh

export PATH="$HOME/.local/bin:$PATH"
hash -r

uv --version
cd ~/Projects/skill-agent-proj/data/skills-bench
uv sync --locked
# 这里如果执行失败可能是 目录/权限问题.

# 验证
./.venv/bin/python --version
./.venv/bin/bench --version
  • 注意uv sync --locked是在创建skills-bench下面的虚拟环境.venv

安装好验证测试脚本是否能运行:

cd ~/Projects/skill-agent-proj
source .venv/bin/activate

smoke_root=$(mktemp -d /tmp/skillc-eval-smoke.XXXXXX)
echo "临时输出目录:$smoke_root"

PYTHONDONTWRITEBYTECODE=1 \
bash scripts/evaluate/run-raw-task.sh \
  --harness opencode \
  --model siliconflow/Qwen/Qwen3.5-27B \
  --task data/skills-bench/tasks/citation-check \
  --skill-source data/skills-bench/tasks/citation-check/environment/skills \
  --output "$smoke_root" \
  --require-skill \
  --repeat 1 \
  --max-parallel 1

VSCODE推荐使用Containers插件,可以可视化docker镜像情况。

这里如果执行失败可能是因为: docker 需要配置代理或镜像加速,或检查 wsl 网络问题.

如果遇到以下问题:

test-001 (1/1)   [#-------------------]   5%  preparing        elapsed=02:57
scripts/evaluate/run-raw-task.sh: line 534: rg: command not found
scripts/evaluate/run-raw-task.sh: line 536: rg: command not found
scripts/evaluate/run-raw-task.sh: line 538: rg: command not found
scripts/evaluate/run-raw-task.sh: line 540: rg: command not found
scripts/evaluate/run-raw-task.sh: line 542: rg: command not found
scripts/evaluate/run-raw-task.sh: line 544: rg: command not found

这是因为 WSL 系统里没有安装 rg(ripgrep),请新开一个wsl终端,安装ripgrep:

sudo apt update
sudo apt install -y ripgrep

验证:

rg --version
WSL mirrored 模式下配置 SkillsBench 容器代理 (补充章节)

SkillsBench/BenchFlow 会在 Docker 容器中运行 agent 和 verifier。仅配置 Docker daemon 的代理只能解决镜像拉取问题,不能保证运行中的容器可以访问 astral.sh、PyPI 等外部服务。

当前使用的代理链路如下:

SkillsBench 容器
  -> HTTP_PROXY=http://172.17.0.1:18080
  -> benchflow-proxy-bridge
  -> 127.0.0.1:7897
  -> Windows Clash Verge
  -> Internet

端口说明:

  • 7897:Windows Clash Verge 的实际代理端口。
  • 18080:Docker 容器访问的桥接入口。
  • 172.17.0.1:Docker 默认 bridge 网络的宿主机网关。
  • 桥接入口和实际代理出口应使用不同端口,避免监听冲突或转发回路。
1. 配置 WSL mirrored 网络

在 Windows PowerShell 中编辑 %USERPROFILE%\.wslconfig:

notepad $env:USERPROFILE\.wslconfig

确保 [wsl2] 中包含:

[wsl2]
networkingMode=mirrored
hostAddressLoopback=true
firewall=true
autoProxy=true
ignoredPorts=18080

ignoredPorts=18080 用于避免 mirrored 网络在 Windows 层保留该端口,导致 host 网络容器报错:

bind 0.0.0.0:18080: Address in use

如果已经配置其他忽略端口,使用逗号追加,例如:

ignoredPorts=53,18080

保存后,在 Windows PowerShell 中重启 WSL:

wsl --shutdown
2. 创建持久化代理桥接容器

确保 Windows Clash Verge 正在运行,并确认 mixed proxy 端口为 7897。然后在 WSL 中创建桥接容器:

docker run -d \
  --name benchflow-proxy-bridge \
  --network host \
  --restart unless-stopped \
  alpine/socat \
  TCP-LISTEN:18080,fork,reuseaddr \
  TCP:127.0.0.1:7897

检查容器状态和配置:

docker ps -a --filter name=benchflow-proxy-bridge

docker inspect benchflow-proxy-bridge \
  --format 'RestartPolicy={{.HostConfig.RestartPolicy.Name}} NetworkMode={{.HostConfig.NetworkMode}}'

docker inspect benchflow-proxy-bridge \
  --format '{{json .Config.Cmd}}'

预期结果包含:

RestartPolicy=unless-stopped NetworkMode=host
["TCP-LISTEN:18080,fork,reuseaddr","TCP:127.0.0.1:7897"]

unless-stopped 表示 Docker daemon 启动或容器异常退出后会自动恢复该容器。显式执行 docker stop benchflow-proxy-bridge 后,容器会保持停止,直到再次手动启动。

3. 给运行容器注入代理

编辑 Docker 客户端配置:

mkdir -p ~/.docker
nano ~/.docker/config.json

写入:

{
  "proxies": {
    "default": {
      "httpProxy": "http://172.17.0.1:18080",
      "httpsProxy": "http://172.17.0.1:18080",
      "noProxy": "localhost,127.0.0.1,::1"
    }
  }
}

该配置会把大小写形式的 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY 注入新创建的 Docker 容器,包括 SkillsBench 的 agent/verifier 容器。JSON 中必须使用纯 URL,不能写成 Markdown 链接形式。

4. 验证完整代理链路

确认桥接容器正在运行并监听 18080:

docker ps --filter name=benchflow-proxy-bridge
sudo ss -lntp | grep ':18080'

确认新容器获得代理变量:

docker run --rm ubuntu:24.04 env | grep -i proxy

预期包含:

HTTP_PROXY=http://172.17.0.1:18080
HTTPS_PROXY=http://172.17.0.1:18080

测试 verifier 所需的 uv 下载链路:

docker run --rm ubuntu:24.04 \
  bash -c 'apt-get update >/dev/null &&
           apt-get install -y curl >/dev/null &&
           curl --connect-timeout 10 --max-time 30 -fsSIL https://astral.sh/uv/0.9.7/install.sh'

最终返回 HTTP/2 200 表示链路正常,可以重新运行 SkillsBench 测试。

5. 常见问题

桥接容器反复显示 Restarting 时,先查看日志:

docker logs --tail 100 benchflow-proxy-bridge

如果日志包含:

bind 0.0.0.0:18080: Address in use

检查 Windows .wslconfig 是否包含 ignoredPorts=18080,修改后执行 wsl --shutdown。

如果普通容器访问 172.17.0.1:18080 时出现 Connection refused,依次检查:

docker ps --filter name=benchflow-proxy-bridge
sudo ss -lntp | grep ':18080'
docker logs --tail 100 benchflow-proxy-bridge

同时确认 Windows Clash Verge 正在运行,且 mixed proxy 端口仍为 7897。

Docker daemon 代理与运行容器代理的区别

Docker daemon 代理负责拉取镜像;~/.docker/config.json 中的代理负责运行中容器的网络请求, 两者用途不同。Docker daemon 可以继续使用宿主侧可直接访问的地址,例如:

HTTP_PROXY=http://127.0.0.1:7897
HTTPS_PROXY=http://127.0.0.1:7897

不要让 Docker daemon 依赖 benchflow-proxy-bridge,否则可能形成“Docker daemon 需要桥接 容器联网,而桥接容器又必须等待 Docker daemon 启动”的循环依赖。

两个环境说明

项目核心运行环境是 conda 创建的虚拟环境, data/skills-bench/.venv 是 SkillsBench/BenchFlow 的独立运行环境,负责执行评测。评测脚本会显式调用 data/skills-bench/.venv/bin/python 和其中的 bench;仅这些子进程使用该 uv 创建的虚拟环境,不会切换或改变当前 Conda 环境。

agentrm 启动

(可以使用codex协助启动, 目前无法自动化流程,因为autodl服务器没法一直占用,且成本较高)

动态优化中,还需要启动远程 AgentRM服务,假设模型部署在远端服务器 8000 端口运行,本地 28080端口接收:

服务器端:

复制SSH登录指令

PS C:\Users\xfd024> ssh -p 33706 root@connect.weste.seetacloud.com

随后输入密码

# 进入部署目录并激活 Conda 环境:
cd root/autodl-tmp/agentrm-deployment
source /root/miniconda3/etc/profile.d/conda.sh
conda activate agentrm
chmod +x run_agentrm_server.sh
# 启动服务:
RM_HOST=127.0.0.1 ./run_agentrm_server.sh
# 查看加载日志:
tail -f outputs/agentrm_server.log

# 看到以下内容表示模型加载完成:
# [ready] AgentRM loaded on cuda

# 远端健康检查:
curl -fsS http://127.0.0.1:8000/health
# 正常返回:
# {
#   "status": "ok",
#   "device": "cuda",
#   "max_length": 8192
# }

本地建立 SSH 隧道:

Windows PowerShell 执行后保持窗口开启:

ssh -o ExitOnForwardFailure=yes 
  -o ServerAliveInterval=30 
  -o ServerAliveCountMax=3 
  -N 
  -L 127.0.0.1:28080:127.0.0.1:8000 
  -p <SSH端口> <用户>@<服务器地址>

推荐用法:完整流水线

python -m scripts.compile_pipeline \
  --harness opencode \
  --model provider/target-model \
  --external-model provider/compiler-model \
  --task <data/skills-bench/tasks 下的任务名>

使用原运行目录恢复中断任务:

python -m scripts.compile_pipeline \
  --harness opencode \
  --model provider/target-model \
  --external-model provider/compiler-model \
  --task <任务名> \
  --run-dir results/compile-pipeline/<run-id>

任务必须位于 data/skills-bench/tasks,且 environment/skills 下仅有一个 SKILL.md。--run-dir 必须位于 results/compile-pipeline;同一目录不能并发运行。

执行顺序与产物

原始 Skill
  → 原始评测
  → 模型画像与静态编译
  → 静态产物评测
  → Fast 优化与评测
  → Deep 局部迭代
  → 最终评测
  → artifacts/deep/S_final

完整运行目录为 results/compile-pipeline/<run-id>/:

  • manifest.json:输入身份、阶段状态和错误;原子写入,可用于恢复。
  • artifacts/static、artifacts/fast、artifacts/deep:各编译阶段产物与缓存。
  • traces/<task>/:原始、静态、Fast、最终评测结果;Deep 最后一轮可复用 rollout 也会复制到此处的 final_skill/。
  • artifacts/deep/S_final:最终可交付 Skill。

评测仅复用完整的 test-* 产物(摘要、Skill 调用校验、结构化结果和 ACP 轨迹均有效)。不完整目录会移入同级 .incomplete/,不会被当作缓存。Deep 仅在最终 SKILL.md 哈希与最后一批有效 rollout 一致时复用其结果。

参考命令

以下示例使用现有的 111-offer-letter-generator 产物路径。静态编译使用 --model 指定待适配的目标模型,使用 --external-model 指定混合模式的语义规划模型。

静态编译

python -m scripts.static_compile \
  --model siliconflow/Qwen/Qwen3.5-27B \
  --external-model ali/deepseek-v4-pro-0813 \
  --input data/skills-bench/tasks/111-offer-letter-generator/environment/skills \
  --out-root results/static-opimization/ \
  --mode hybrid

快速优化

python -m scripts.dynamic_compile.fast \
  --traces results/dynamic-optimization/traces/raw_agent_trace/opencode/siliconflow-qwen-qwen3-5-27b/111-offer-letter-generator/model_skill \
  --skill results/static-opimization/siliconflow-qwen-qwen3-5-27b/skills/docx \
  --model ali/deepseek-v4-pro-0813 \
  --max-parallel 3

深度迭代

python -m scripts.dynamic_compile.deep run \
  --skill results/dynamic-optimization/compiled-skills/opencode/siliconflow-qwen-qwen3-5-27b/111-offer-letter-generator/model_compile/candidate-skill/docx \
  --traces results/benchflow/opencode-siliconflow-qwen-qwen3-5-27b/111-offer-letter-generator/custom_skill \
  --output results/dynamic-optimization-v1-5/deep-compiled-skills/opencode/siliconflow-qwen-qwen3-5-27b/111-offer-letter-generator \
  --model ali/deepseek-v4-pro-0813

完整流水线

python -m scripts.compile_pipeline \
  --harness opencode \
  --model siliconflow/Qwen/Qwen3.5-27B \
  --external-model ali/deepseek-v4-pro-0813 \
  --task citation-check

独立模块

静态编译

根据模型画像对 Skill 做确定性或混合改写;保留 frontmatter、代码块和受保护字面量,语义保护失败时回滚原文。

python -m scripts.static_compile \
  --model provider/model-id \
  --input <Skill 目录或包目录> \
  --out-root results/static-compiled-skills \
  --mode deterministic

hybrid 模式允许一次受源文本约束的语义规划;--dry-run 不写产物也不调用规划模型。 实际执行 hybrid 模式时必须通过 --external-model provider/model-id 单独指定语义规划模型;--model 始终表示待适配的目标模型。

Fast 动态优化

基于至少 6 条同任务、同编译类型的 BenchFlow 轨迹,依次执行预评分、AgentRM 评分、Top/Bottom 分组、Map/Reduce 与局部补丁生成;候选包原子发布。

python -m scripts.dynamic_compile.fast \
  --traces <BenchFlow 轨迹目录> \
  --skill <Skill 包目录> \
  --model provider/model-id

可选 --score-output、--output、--max-parallel、--rm-api-url 与 --force。缓存只有在输入内容、配置、版本、哈希和产物均匹配时才复用。

Deep 动态迭代

对 Fast 产物按章节、必要时按段落进行五维评分,生成并验证局部编辑,再用候选运行时轨迹比较;只有目标分数提升且没有运行时回归才提交。编辑始终校验章节边界、代码围栏、缓存和原子替换。

python -m scripts.dynamic_compile.deep run \
  --skill <Skill 包目录> \
  --traces <BenchFlow 轨迹目录> \
  --output <Deep 输出目录> \
  --model provider/model-id

python -m scripts.dynamic_compile.deep resume --run <Deep 输出目录>

BenchFlow 评测

bash scripts/evaluate/run-raw-task.sh \
  --harness opencode \
  --model provider/model-id \
  --task <SkillsBench 任务目录> \
  --skill-source <Skill 目录或 skills 根目录> \
  --output <结果目录> \
  --require-skill --repeat 3 --max-parallel 3

该脚本为官方 BenchFlow runner 的兼容包装:每次尝试在 <结果目录>/test-NNN/ 写入结果;--require-skill 会校验至少成功调用一次 Skill。可用 --image <本地镜像> 复用镜像;否则按任务创建或复用本地镜像。

失败处理

参数、任务范围、Skill 结构、模型路由、缓存、轨迹和产物均会校验。编译或评测阶段失败会记录到 manifest 并返回错误;可在修复配置后使用相同 --run-dir 恢复。执行实际编译或评测会调用外部模型、BenchFlow 和 Docker;--help 与模块导入不会。

S
Description
No description provided
Readme 3.7 GiB
Languages
Python 80.9%
Shell 10.2%
TypeScript 2.7%
Dockerfile 2.1%
PDDL 1.5%
Other 2.2%