Initial commit

This commit is contained in:
2026-09-04 14:58:42 +08:00
commit 439cad87d9
4601 changed files with 29440 additions and 0 deletions
+605
View File
@@ -0,0 +1,605 @@
# Skill Agent 编译流水线
本项目将 SkillsBench 任务中的单个 Skill 依次经过静态编译、Fast 动态优化、Deep 动态迭代和 BenchFlow 评测,产出可恢复、可审计的最终 Skill。
## 安装与配置
### 配置系统环境
项目目前运行在 Windows WSL 2(Ubuntu 26.04 LTS) 系统中。
```bash
# 以管理员身份打开 ps 安装
wsl --install -d Ubuntu-26.04
```
设置账号密码,进入 wsl 后安装基础工具与 python,nodejs:
```bash
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)。
```bash
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:
```bash
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 里创建/修改:
```bash
notepad $env:USERPROFILE\.wslconfig
```
写入:
```bash
[wsl2]
networkingMode=mirrored
dnsTunneling=true
autoProxy=true
firewall=true
```
保存后执行:
```bash
wsl --shutdown
wsl -d Ubuntu-26.04
```
然后再跑
```bash
docker run --rm hello-world
```
如果最后看到 Hello from Docker!,就说明问题已经完全解决。
项目建议放在 ~/projects/skill-agent-proj, 项目目录:
```bash
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, 在虚拟环境中配置项目依赖:
```bash
python -m pip install -r requirements.txt
```
目前使用的是Python 3.12 自带的 venv,激活虚拟环境
Linux/macOS:
```bash
source .venv/bin/activate
```
用结束后退出环境
```bash
deactivate
```
#### skills-bench 环境
完整流水线要求 SkillsBench/BenchFlow CLI,测试脚本 run-raw-task.sh 会调用它们。
- SkillsBench:官方基准仓库,提供任务规范、Python 运行环境和 skillsbench_agentbeats worker。
- BenchFlow CLI:实际执行 bench eval run --sandbox docker 的命令行工具。
```bash
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
```
```bash
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
安装好验证测试脚本是否能运行:
```bash
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 网络问题.
如果遇到以下问题:
```bash
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:
```bash
sudo apt update
sudo apt install -y ripgrep
```
验证:
```bash
rg --version
```
##### WSL mirrored 模式下配置 SkillsBench 容器代理 (补充章节)
SkillsBench/BenchFlow 会在 Docker 容器中运行 agent 和 verifier。仅配置 Docker daemon
的代理只能解决镜像拉取问题,不能保证运行中的容器可以访问 `astral.sh`、PyPI 等外部服务。
当前使用的代理链路如下:
```text
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`:
```powershell
notepad $env:USERPROFILE\.wslconfig
```
确保 `[wsl2]` 中包含:
```ini
[wsl2]
networkingMode=mirrored
hostAddressLoopback=true
firewall=true
autoProxy=true
ignoredPorts=18080
```
`ignoredPorts=18080` 用于避免 mirrored 网络在 Windows 层保留该端口,导致 host 网络容器报错:
```text
bind 0.0.0.0:18080: Address in use
```
如果已经配置其他忽略端口,使用逗号追加,例如:
```ini
ignoredPorts=53,18080
```
保存后,在 Windows PowerShell 中重启 WSL:
```powershell
wsl --shutdown
```
###### 2. 创建持久化代理桥接容器
确保 Windows Clash Verge 正在运行,并确认 mixed proxy 端口为 `7897`。然后在 WSL 中创建桥接容器:
```bash
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
```
检查容器状态和配置:
```bash
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}}'
```
预期结果包含:
```text
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 客户端配置:
```bash
mkdir -p ~/.docker
nano ~/.docker/config.json
```
写入:
```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`:
```bash
docker ps --filter name=benchflow-proxy-bridge
sudo ss -lntp | grep ':18080'
```
确认新容器获得代理变量:
```bash
docker run --rm ubuntu:24.04 env | grep -i proxy
```
预期包含:
```text
HTTP_PROXY=http://172.17.0.1:18080
HTTPS_PROXY=http://172.17.0.1:18080
```
测试 verifier 所需的 `uv` 下载链路:
```bash
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` 时,先查看日志:
```bash
docker logs --tail 100 benchflow-proxy-bridge
```
如果日志包含:
```text
bind 0.0.0.0:18080: Address in use
```
检查 Windows `.wslconfig` 是否包含 `ignoredPorts=18080`,修改后执行 `wsl --shutdown`。
如果普通容器访问 `172.17.0.1:18080` 时出现 `Connection refused`,依次检查:
```bash
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 可以继续使用宿主侧可直接访问的地址,例如:
```text
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端口接收:
服务器端:
- https://www.autodl.com/console/instance/list
复制SSH登录指令
```bash
PS C:\Users\xfd024> ssh -p 33706 root@connect.weste.seetacloud.com
```
随后输入密码
```bash
# 进入部署目录并激活 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 执行后保持窗口开启:
```bash
ssh -o ExitOnForwardFailure=yes
-o ServerAliveInterval=30
-o ServerAliveCountMax=3
-N
-L 127.0.0.1:28080:127.0.0.1:8000
-p <SSH端口> <用户>@<服务器地址>
```
## 推荐用法:完整流水线
```bash
python -m scripts.compile_pipeline \
--harness opencode \
--model provider/target-model \
--external-model provider/compiler-model \
--task <data/skills-bench/tasks 下的任务名>
```
使用原运行目录恢复中断任务:
```bash
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`;同一目录不能并发运行。
## 执行顺序与产物
```text
原始 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` 指定混合模式的语义规划模型。
### 静态编译
```bash
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
```
### 快速优化
```bash
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
```
### 深度迭代
```bash
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
```
### 完整流水线
```bash
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、代码块和受保护字面量,语义保护失败时回滚原文。
```bash
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 与局部补丁生成;候选包原子发布。
```bash
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 产物按章节、必要时按段落进行五维评分,生成并验证局部编辑,再用候选运行时轨迹比较;只有目标分数提升且没有运行时回归才提交。编辑始终校验章节边界、代码围栏、缓存和原子替换。
```bash
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
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` 与模块导入不会。