Prhub

#1919 examples: add swe-agent-harbor-daytona (Harbor sandboxes on Daytona)

原始 PR 作者 Shi-Dong 合并时间 2026-08-07 05:53 文件变更 3 提交数 7 评论 15 代码增减 +226 / -0

执行摘要

新增 Daytona 云沙箱 SWE-Agent 示例到 experimental

PR body 明确说明:Daytona 沙箱方案是 "the practical option when the trainer runs on a GPU node where you cannot run Docker-in-Docker",即训练节点无法运行 Docker 时,任务评测沙箱放到 Daytona 云端,agent-server 主机只需出站 HTTPS。另一个动机是 terminus-2 agent 以宿主进程运行并自行调用模型端点,需要追加 user 与 tool 轮次;该 flag 曾是需要独立启动器的原因,但 PR #1818 已移除该参数(并新增测试断言其被拒绝),这直接推动最终删除 run.py。

值得精读。重点看两点:一是 '何时应该放弃自己的启动器而复用兄弟示例' 的决策过程——run.py 因单一参数被移除而整体删除,是一个避免重复维护的好案例;二是 README 中沉淀的实操知识(per-turn 响应上限、raw_reward 与 rewards 的区别、trial 目录 mtime 陷阱)对任何跑 agentic RL 长任务的人都有直接价值。

讨论亮点

核心交锋集中在三点:一是 run.py 是否还值得存在——nblintao 直接以 PR #1818 为证质疑,Shi-Dong 确认后删除,这是本 PR 最重要的设计收敛;二是 nblintao 提议将 swe-agent 重命名为 swe-agent-harbor-docker 以区分后端,Shi-Dong 当场开 PR #2233 跟进;三是 nblintao 指出 launch_agent_server.sh 的 --agent-timeout 5400examples/swe-agent/swe_agent_function.py 里硬编码的 3600 秒超时不一致,agent function 放弃后 server 仍在运行,Shi-Dong 开 PR #2228 跟进。另有关于 shell 脚本是否应收敛为 Python 的讨论,结论是脚本用于启动 agent server 而非训练任务,转 .py 主要为 CI 考虑,暂不处理。

实现拆解

  1. 新增示例目录与 READMEexamples/experimental/swe-agent-harbor-daytona/README.md 是变更入口,说明与 examples/swe-agent 的两点差异(Daytona 云沙箱、terminus-2 宿主 agent),并强调训练侧完全复用:数据准备用 examples/swe-agent/download_and_process_data.py --agent-name terminus-2,训练启动用 examples/swe-agent/run.py 不变,Daytona 只由 agent server 的环境变量决定。
  2. 启动脚本 launch_agent_server.sh:在 harbor-framework/harbor 的 harbor-miles-v0.20.0 分支下启动 agent server,设置 HARBOR_ENV_TYPE=daytonaHARBOR_DAYTONA_AUTO_SNAPSHOT=1(首用后快照镜像)、OPENAI_API_BASE 指向本机 30000 端口 session server、AGENT_MAX_INPUT_TOKENS / AGENT_MAX_OUTPUT_TOKENS / HARBOR_RESPONSE_LENGTH_POLICY=abort 等与训练侧 --rollout-max-response-len--max-seq-len 对齐的配置,--agent-timeout 默认 5400。
  3. 索引更新examples/README.md 追加一行指向新示例。
  4. 演进与删除 run.py:初版自带约 284 行的 run.py,用于暴露 --rollout-max-response-len--max-tokens-per-gpu 等 tuning 参数并传 --tito-allowed-append-roles;review 中 nblintao 指出该参数已被 PR #1818 移除后,作者确认其余配置均与 examples/swe-agent/run.py 硬编码一致,最终删除 run.py,行为完全等价。目录也从 examples/swe-agent-harbor-daytona 移入 examples/experimental/
  5. 测试配套:无自动化测试(README 声明 docs-and-example change);以 py_compilebash -nruff 检查,并由一次 8×H200 多日 GLM-4.7-Flash 端到端运行验证非零 rollout/raw_reward
文件 模块 状态 重要度
examples/experimental/swe-agent-harbor-daytona/README.md 示例文档 added 5.1
examples/experimental/swe-agent-harbor-daytona/launch_agent_server.sh 启动脚本 added 4.27
examples/README.md 示例索引 modified 1.18

关键源码片段

examples/experimental/swe-agent-harbor-daytona/launch_agent_server.sh core-logic

唯一新增的代码逻辑文件,承载 Daytona 模式的全部环境开关与 agent server 启动参数

#!/bin/bash
# 启动 Harbor agent server 的 Daytona 模式,需在 harbor-framework/harbor 的
# harbor-miles-v0.20.0 分支下运行,之后再用 examples/swe-agent/run.py 启动训练。
# trial 在 Daytona 云沙箱内评测,本机只需出站 HTTPS,无需 Docker daemon。
set -euo pipefail
​
# 必填环境变量:缺少时直接报错退出
: "${DAYTONA_API_KEY:?set DAYTONA_API_KEY to a Daytona API key}"
: "${HARBOR_TASKS_DIR:?set HARBOR_TASKS_DIR to the directory holding Harbor task dirs}"# 可选配置默认值
TRIALS_DIR="${TRIALS_DIR:-/tmp/harbor_trials}"
PORT="${PORT:-11000}"
MAX_CONCURRENT="${MAX_CONCURRENT:-32}"# 核心开关:声明使用 Daytona 云沙箱
# HARBOR_DAYTONA_DISK_GB 需结合 Daytona 账号总磁盘配额设置
export HARBOR_ENV_TYPE=daytona
export HARBOR_DAYTONA_DISK_GB="${HARBOR_DAYTONA_DISK_GB:-10}"
# 首次使用后给任务镜像打快照,后续 trial 跳过镜像构建
# 该项能显著降低重复启动的等待时间
# 注意:快照会占用账号磁盘配额,并发沙箱数乘磁盘大小需低于配额
  export HARBOR_DAYTONA_AUTO_SNAPSHOT=1# terminus-2 以宿主进程运行并自行调用模型端点,
# 因此模型端点必须从本机可达,而不是从沙箱内可达
# 这里默认指向本机 30000 端口的 Miles session server
  export OPENAI_API_KEY="${OPENAI_API_KEY:-dummy}"
export OPENAI_API_BASE="${OPENAI_API_BASE:-http://127.0.0.1:30000/v1}"
export OPENAI_BASE_URL="$OPENAI_API_BASE"# 以下两值与训练侧 --rollout-max-response-len、--max-seq-len 保持一致,
# 它们限制的是单轮输出而非整条轨迹,详见 README 的调节说明
# 注意:HARBOR_RESPONSE_LENGTH_POLICY=abort 下超限会导致整个 trial 得 0 分
  export AGENT_MAX_INPUT_TOKENS="${AGENT_MAX_INPUT_TOKENS:-32768}"
export AGENT_MAX_OUTPUT_TOKENS="${AGENT_MAX_OUTPUT_TOKENS:-8192}"
export HARBOR_RESPONSE_LENGTH_POLICY=abort
​
mkdir -p "$TRIALS_DIR"# 注意:--agent-timeout 5400 秒,而 examples/swe-agent/swe_agent_function.py
# 中硬编码 3600 秒,二者不一致已被 PR #2228 跟进为可配置
  exec python miles_agent_server.py \
  --host 0.0.0.0 \
  --port "$PORT" \
  --max-concurrent "$MAX_CONCURRENT" \
  --agent-timeout 5400 \
  --trials-dir "$TRIALS_DIR"

评论区精华

run.py 是否还需要存在(PR #1818 已移除 --tito-allowed-append-roles) 设计

nblintao 在 run.py 的 diff 上直接提问:'https://github.com/radixark/miles/pull/1818 already removed this option. Do we still need this run.py?' 该参数是新增启动器的唯一理由

结论:Shi-Dong 确认后删除 run.py,复用 examples/swe-agent/run.py,其余配置默认值完全一致,行为等价 · 已解决

是否将 swe-agent 重命名为 swe-agent-harbor-docker 设计

nblintao 提问是否应把原示例改名以区分后端(Harbor Docker vs Daytona),并建议保留 URL slug 需慎重

结论:Shi-Dong 采纳建议,开 PR #2233 处理重命名 · 已解决

agent server 超时 5400 与 agent function 硬编码 3600 不一致 正确性

nblintao 指出 swe_agent_function.py 硬编码 timeout=3600,所以 server 端 trial 仍在运行时代理函数已放弃,造成孤儿 trial

结论:Shi-Dong 开 PR #2228 将 agent-server trial 超时改为可配置 · 已解决

shell 脚本是否应收敛为 Python style

nblintao 问 'Are we supposed to converge sh scripts to py?';Shi-Dong 回应此脚本用于启动 agent server 而非训练任务,转 .py 主要为 CI 考虑

结论:保留 shell 脚本,未在此 PR 内转换,转为后续讨论话题 · 已解决

README 规范:harbor 分支、相对路径、硬件说明 documentation

作者自审与审阅者要求:明确 harbor 分支 harbor-miles-v0.20.0、禁止相对路径、开头说明目标为单节点 8×H200、删除无用行(如 --tito-allowed-append-roles 排查行)

结论:全部落实:README 与脚本中改用仓库根路径、补充单节点 H200 说明、删除冗余排查行 · 已解决

风险与影响

  1. 示例与文档无自动化测试覆盖:变更纯示例性质,README 也明说没有现有测试覆盖,后续 examples/swe-agent/run.py 或 Harbor 分支接口变化时,本示例容易静默失配。
  2. 依赖外部 harbor 分支harbor-miles-v0.20.0 是 harbor-framework/harbor 的特定积分分支,其 API 或环境变量变化会破坏启动脚本,风险集中在 launch_agent_server.sh
  3. agent 超时配置不一致swe_agent_function.py 硬编码 3600 秒,而启动脚本给 server 设置 5400 秒,二者不匹配会导致 agent function 提前放弃而 server 侧 trial 变为孤儿任务;该问题已由 PR #2228 跟进修复。
  4. 运维陷阱已有文档但依赖执行纪律:README 强调 per-turn 响应上限、raw_reward 判读、trial 目录 mtime 陷阱,一旦读者跳过这些说明,多日运行仍会误判进度或产出 0 分 trial。

对用户:提供了一条在无法运行 Docker-in-Docker 的 GPU 节点上跑 SWE-Agent/Harbor 训练的可执行路线,并把多日调参踩坑总结成可复用的运维手册。对团队:review 直接催生了 PR #2233(示例命名)和 PR #2228(超时可配置)两个后续改进;也确认了 '训练侧零改动、沙箱后端完全由 agent server 环境决定' 的架构抽象。对系统:无运行时影响,不触碰库代码,风险面限定在示例目录。

示例与文档无自动化测试覆盖 依赖外部 harbor 分支 harbor-miles-v0.20.0 agent 超时配置不一致(3600 vs 5400) 依赖 PR #1818 移除参数后的行为

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论