# 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 < 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 <用户>@<服务器地址> ``` ## 推荐用法:完整流水线 ```bash python -m scripts.compile_pipeline \ --harness opencode \ --model provider/target-model \ --external-model provider/compiler-model \ --task ``` 使用原运行目录恢复中断任务: ```bash python -m scripts.compile_pipeline \ --harness opencode \ --model provider/target-model \ --external-model provider/compiler-model \ --task <任务名> \ --run-dir results/compile-pipeline/ ``` 任务必须位于 `data/skills-bench/tasks`,且 `environment/skills` 下仅有一个 `SKILL.md`。`--run-dir` 必须位于 `results/compile-pipeline`;同一目录不能并发运行。 ## 执行顺序与产物 ```text 原始 Skill → 原始评测 → 模型画像与静态编译 → 静态产物评测 → Fast 优化与评测 → Deep 局部迭代 → 最终评测 → artifacts/deep/S_final ``` 完整运行目录为 `results/compile-pipeline//`: - `manifest.json`:输入身份、阶段状态和错误;原子写入,可用于恢复。 - `artifacts/static`、`artifacts/fast`、`artifacts/deep`:各编译阶段产物与缓存。 - `traces//`:原始、静态、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 \ --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 \ --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 \ --traces \ --output \ --model provider/model-id python -m scripts.dynamic_compile.deep resume --run ``` ## BenchFlow 评测 ```bash bash scripts/evaluate/run-raw-task.sh \ --harness opencode \ --model provider/model-id \ --task \ --skill-source \ --output <结果目录> \ --require-skill --repeat 3 --max-parallel 3 ``` 该脚本为官方 BenchFlow runner 的兼容包装:每次尝试在 `<结果目录>/test-NNN/` 写入结果;`--require-skill` 会校验至少成功调用一次 Skill。可用 `--image <本地镜像>` 复用镜像;否则按任务创建或复用本地镜像。 ## 失败处理 参数、任务范围、Skill 结构、模型路由、缓存、轨迹和产物均会校验。编译或评测阶段失败会记录到 manifest 并返回错误;可在修复配置后使用相同 `--run-dir` 恢复。执行实际编译或评测会调用外部模型、BenchFlow 和 Docker;`--help` 与模块导入不会。