用强化学习训练终端 Agent
展示如何用 RL 训练长期任务的终端 Agent,是研究级内容,对特定领域开发者有参考价值。
展示如何用 RL 训练长期任务的终端 Agent,是研究级内容,对特定领域开发者有参考价值。
我成功构建了一套稳定的强化学习训练基础设施,可扩展至分布在 4 个裸金属节点上的 32 张 H100 GPU,用于训练能够执行长时程终端编程任务的 AI 智能体。
在此过程中,我开发了 Terminal-Agent-Qwen3-32b,使其成为 terminal-bench 上得分最高的 Qwen3 AI 智能体。无需训练!遗憾的是,我没有足够的 GPU 来训练一个 SOTA 编程 AI 智能体 😅(预计需要价值 3 万至 5 万英镑的算力),但如果有人拥有这些 GPU,这个项目应该能帮助你实现目标!
遗憾的是,我没有足够的 GPU 来训练一个 SOTA 编程 AI 智能体 😅(预计需要价值 3 万至 5 万英镑的算力),但如果有人拥有这些 GPU,这个项目应该能帮助你实现目标!
本项目建立在 UC Berkeley Sky Lab 开发的 rLLM 框架之上,并通过专为终端 AI 智能体训练设计的自定义环境和基础设施对其进行了扩展。
💻💰 使用价值 100 万美元的算力进行训练 其他训练运行
🏆 登上 Terminal Bench 排行榜 🏗️ 基于 Action 的架构
🏗️ 基于 Action 的架构
训练详情 ⚖️ 奖励设计 ✅ 答案验证(权重 65%)🤖 LLM 作为裁判(权重 35%)🧪 裁判评估系统 🔄 动态切换 LLM 裁判
✅ 答案验证(权重 65%)
🤖 LLM 作为裁判(权重 35%)🧪 裁判评估系统 🔄 动态切换 LLM 裁判
🧪 裁判评估系统
🔄 动态切换 LLM 裁判
🏗️ rLLM 集成架构 终端 AI 智能体(TerminalBenchAgent)Docker 环境(DockerIsolatedEnv)
终端 AI 智能体(TerminalBenchAgent)
Docker 环境(DockerIsolatedEnv)
🔄 训练与 Rollout 详情 🔁 Rollout 策略 ⚙️ 训练配置预设 📊 关键超参数(生产配置)
⚙️ 训练配置预设
📊 关键超参数(生产配置)
🗂️ 数据集详情 📊 数据集结构 🐳 训练环境创建 🧹 Docker 资源管理 📂 数据集准备流水线
🐳 训练环境创建
🧹 Docker 资源管理
📂 数据集准备流水线
🚀 快速开始 开发环境配置 Terminal Bench 评估复现 训练部署 单节点训练 多节点训练
Terminal Bench 评估复现
训练部署 单节点训练 多节点训练
🔮 未来改进 🚀 完整训练运行 🤓 课程学习 📊 数据集扩充 🎯 智能数据过滤
🤓 课程学习
🎯 智能数据过滤
💻💰 使用价值 100 万美元的算力进行训练
这张图片展示了我的训练代码在 32 张 H100 上全速运行的场景。这些 GPU 分布在由 4 个裸金属节点组成的集群上,用于训练 Qwen3-32B。感谢 Hyperbolic 提供如此顺畅的使用体验!这很有趣!
由于这种规模的算力成本极其高昂,我无法让它一直运行下去!因此,我在确认它能够正常工作之后,也使用配置没那么豪华的硬件进行了代码测试。
我还在一个由 2 个裸金属节点组成、配备 16 张 H100 的集群上进行了更长时间的 Qwen3-32B 训练:
此外还使用了一个配备 8 张 H100 的 VM 实例:
我持续时间最长的一次训练,是在一个配备 2 张 A100 的 VM 实例上对 Qwen3-8B 进行了超过 60 个 step 的训练。注意:我并不指望 8B 模型能够开始学会解决数据集中任务所需的复杂行为。不过,能够让训练遍历数据集并确认代码保持稳定,依然非常有价值。
🏆 登上 Terminal Bench 排行榜
Terminal Bench 是由 Stanford 和 Laude Institute 创建的一项出色基准测试,用于量化 AI 智能体在终端中完成复杂任务的能力。
通过提示词工程和自定义工具设计,我的 Qwen3-32B AI 智能体超越了 Stanford 的 Terminus-Qwen3-235B-30A MoE AI 智能体,以及 Deepseek R1 和 OpenAI 搭载 GPT-4.1 的 Codex AI 智能体,成为排行榜上得分最高的 Qwen3 AI 智能体。
此次评估运行的 results.json 可以在这里找到。
我确信,如果拥有足够的训练算力预算,我的 AI 智能体在排行榜上的名次将会显著提升。
整个项目背后的动机,是使用强化学习训练一个复杂的 LLM AI 智能体,并让它登上 Terminal Bench 排行榜。为此,我开发了一套能力强大的 AI 智能体可用于完成复杂终端及编程任务的工具(灵感来自 Claude Code),同时还编写了一条 system message,鼓励 AI 智能体使用这些工具,并以特定方式处理任务。
这些工具可以在这里找到,其中包括:
📝 Todo 管理:规划并跟踪任务进度
📁 文件操作:读取、写入和编辑文件
🔍 搜索工具:使用 Grep、glob 和 ls 探索文件
⚡ Bash 执行:运行终端命令并捕获输出
🗒️ 暂存区:用于记录笔记的空间
👍 任务完成:当 AI 智能体认为任务已经完成时发出信号
注意:从技术上讲,即便 AI 智能体只能使用 bash 工具,也仍然具备上述所有工具的相同能力,还可以节省开发和维护时间。然而,通过为特定工具提供清晰的 API,AI 智能体能够更加有效地理解和利用这些工具。
🏗️ 基于 Action 的架构
AI 智能体通过结构化的 XML/YAML 格式进行通信,以确保能够可靠地解析并执行操作:
<todo>
operations:
- action: add
content: "Find and analyze all Python test files"
- action: add
content: "Run pytest and fix any failing tests"
view_all: true
</todo>
<bash>
cmd: 'find . -name "*.py" -path "*/test*" | head -10'
timeout_secs: 30
</bash>
这种架构提供了:
类型安全:每种 Action(bash、file、search、todo)都有专用的处理程序负责验证
错误恢复:格式错误的 YAML 会触发有帮助的错误信息,引导 AI 智能体修正语法
顺序执行:Action 会逐个处理,并强制执行停止并等待的行为
一致的反馈:每个 Action 都会返回结构化结果,AI 智能体可以从中学习并调整计划
除了开发这些工具,我还编写了一份 system prompt,用于鼓励以下最佳实践:
结构化任务执行:清晰的问题处理阶段(规划 → 探索 → 执行 → 验证)
多轮交互:采用 Action—环境循环,并正确执行停止和等待行为
强制 Todo 管理:要求进行初始规划并持续跟踪任务
只读探索:在进行任何更改之前收集信息
借助这套 system message 与工具组合,再加上一个能力足够强的 LLM(我选择了 Qwen3-32B),我以 13.75% 的得分在 Terminal Bench 排行榜上取得了第 19 名(目前仍在提交审核中)。这一成绩超越了:
Stanford 使用 Qwen3-235B 的 Terminus AI 智能体
Stanford 使用 Deepseek-R1 的 Terminus AI 智能体
OpenAI 使用 GPT-4.1 的 Codex AI 智能体
OpenAI 使用 codex-mini 的 Codex AI 智能体
可以在这里查看该 AI 智能体。
如果我能够承担一次完整强化学习训练的算力成本,我会非常期待看到 Qwen3-32B 最终能在排行榜上达到什么位置!
如前所述,对一个 32B LLM 进行完整训练,以处理长时程终端及编程任务,其算力成本并非我所能承受。不过,训练代码和数据集已经准备就绪,并且经过测试,可以在从 2 张 A100 到 32 张 H100 的各种硬件配置上保持稳定训练。
为了在强化学习过程中提供有意义的监督,奖励通过两种互补的方法计算:
✅ 答案验证(权重 65%)
每条训练数据都包含用于验证任务完成情况的 Python 单元测试
为每项测试分别分配权重,以提供细粒度的部分得分
测试在 AI 智能体完成工作的隔离 Docker 容器中执行
加权评分:通过的测试会按照其权重计入最终测试得分
🤖 LLM 作为裁判(权重 35%)
使用 Claude-4-Sonnet 作为外部裁判来评估 AI 智能体的行为
评估四个主要组成部分:Action 输出成功率(35%):有效的 XML Action、成功解析、错误恢复 Todo 使用与规划(25%):初始规划、任务跟踪、持续更新 阶段遵循情况(25%):遵循五阶段工作流(规划 → 探索 → 改进 → 执行 → 验证)工具使用有效性(15%):恰当地选择工具、执行有明确目的的操作
Action 输出成功率(35%):有效的 XML Action、成功解析、错误恢复
Todo 使用与规划(25%):初始规划、任务跟踪、持续更新
阶段遵循情况(25%):遵循五阶段工作流(规划 → 探索 → 改进 → 执行 → 验证)
工具使用有效性(15%):恰当地选择工具、执行有明确目的的操作
针对错误恢复、探索质量和效率应用质量修正系数
对只思考不行动、钻规则漏洞的行为以及违反阶段要求的行为进行惩罚
评分关注的是 AI 智能体如何工作,而不是任务是否完成
为了确保 LLM 裁判在强化学习训练期间给出准确且一致的评分,我开发了一个简单的评估系统:
创建测试用例,展示不同的 AI 智能体轨迹
测试多个 LLM 模型作为裁判,包括 Kimi K2、Qwen-3-Coder、Claude Sonnet 4、Claude Haiku 3.5,以比较评分准确性。
我们发现 Claude Sonnet 4 提供的评分最为稳定、准确,能够正确识别缺乏探索、过度思考等问题。遗憾的是,Sonnet-4 极其昂贵,因此对于一次包含 32 个 rollout、1650 个 step 的运行来说,成本很难承受!但它是唯一能够充分区分优质与糟糕轨迹的模型。许多其他模型(包括 Haiku 3.5)会对存在问题的智能体行为给出虚高的分数,有些模型甚至会给跳过关键阶段的智能体打出 0.85~0.95 分。
遗憾的是,Sonnet-4 极其昂贵,因此对于一次包含 32 个 rollout、1650 个 step 的运行来说,成本很难承受!但它是唯一能够充分区分优质与糟糕轨迹的模型。
许多其他模型(包括 Haiku 3.5)会对存在问题的智能体行为给出虚高的分数,有些模型甚至会给跳过关键阶段的智能体打出 0.85~0.95 分。
要分析评审模型的表现:
# Run evaluation on a specific model
uv run python evaluation/llm_as_a_judge_evals/judge_eval.py --model openrouter/openai/gpt-4.1 --attempts 3
# Generate performance report showing best models
uv run python evaluation/llm_as_a_judge_evals/report.py
排名前五的评审模型表现:
尽管 Claude Sonnet 4 的通过率与 Haiku 相同,但它仍排名第一,因为其平均分显著更低(0.26 对 0.70),这表明它的评审更加严格、准确(基于评估数据集)。分数越低,意味着该模型越能识别出其他评审模型遗漏的、存在问题的智能体行为。
测试的其他模型包括:GPT-4.1、Gemma-3-27B-IT、Qwen3-32B 和 Qwen3-235B-A22B。
为了在长时间训练运行中应对模型过载、token 限制或性能要求,该基础设施支持在不同的 LLM 评审后端之间热切换:
无需中断训练进程即可在运行时切换
可根据需要在 Claude Code CLI 和 LiteLLM 后端之间切换
适用于遇到 API token 限制或预算约束的情况
请参阅 switch_judge_backend.py 和切换文档
# Start with Claude Code CLI
python training_scripts/launch_training.py prod_32b_8_gpus
# Need to change? Switch to LiteLLM API (Can also proivde env vars to populate into training)
python training_scripts/switch_judge_backend.py litellm anthropic/claude-3-opus-20240229
# Later, switch back
python training_scripts/switch_judge_backend.py ccode
🏗️ rLLM 集成架构
该项目扩展了 rLLM 的 BaseAgent 和 BaseEnv 接口,以创建完整的 RL 训练循环:
终端智能体(TerminalBenchAgent)
扩展 rLLM 的 BaseAgent,用于管理环境与 LLM 之间的多轮对话
维护包含系统提示词、用户指令和智能体响应的对话历史
跟踪包含观察、动作和奖励的完整轨迹,以用于 GRPO 训练
Docker 环境(DockerIsolatedEnv)
扩展 rLLM 的 BaseEnv,为每个训练 rollout 提供隔离的 Docker 容器
每个 rollout 都会根据任务的 Dockerfile 规范启动一个全新的容器
通过 Docker 执行智能体动作,并将真实的终端输出作为观察返回
通过软件测试(65%)和 LLM 评审评估(35%)计算奖励
确保并行 rollout 之间完全隔离,以便探索多样化的解决方案
训练循环遵循 rLLM 的标准流程:重置 → 观察 → LLM 推理 → 动作 → 环境 step → 奖励 → 重复。有关这方面的更多细节,请参阅 docs/rllm_specific/understanding_of_agents_and_envs.md。
🔄 训练与 Rollout 细节
该项目采用了组相对策略优化(Group Relative Policy Optimization,GRPO)。它鼓励模型从一组采样响应之间的相对优势中学习,因此尤其适合结构化推理任务。
每个训练提示词生成 16 个样本(可配置),每个样本均使用 1.2 的温度生成,在保持连贯性的同时鼓励多样性
通过为每个 rollout 分配 Docker 容器,实现完整的轨迹隔离
⚙️ 训练配置预设
训练基础设施通过选择简单的预设来支持多种硬件配置:
# Quick test run on 2x A100s
python training_scripts/launch_training.py test_8b_2_gpus
# Production run on 8x H100s
python training_scripts/launch_training.py prod_32b_8_gpus
# Scale to 32x H100s across 4 nodes
python training_scripts/launch_training.py prod_32b_4x8_h100
可用预设涵盖从开发到生产的不同规模:
test_8b_2_gpus:在 2 块 80GB GPU 上使用 Qwen3-8B 进行快速验证
runway_32b_4_gpus:在 4 块 GPU 上使用 Qwen3-32B 进行标准训练
prod_32b_8_gpus:在单个 8 GPU 节点上运行的生产配置
prod_32b_2x8_h100:在 16 块 H100 上进行多节点训练(2 个节点)
prod_32b_4x8_h100:在 32 块 H100 上进行全规模训练(4 个节点)
📊 关键超参数(生产配置)
算法:带拒绝采样的 GRPO
学习率:1e-6,并使用梯度裁剪(最大范数 = 0.1)
批次配置:根据 GPU 数量自适应调整
序列长度:最多 32,768 个 token
单次响应最大长度:每次响应 4,000 个 token
训练时长:在整个数据集上训练 10 个 epoch
并行化:自动确定张量并行与序列并行的规模
精度:使用 bfloat16 提升效率
监控:集成 WandB,并提供详细的轨迹日志
该基础设施会自动处理:
通过最佳的张量并行和序列并行方案,将模型分布到多个 GPU 上
根据硬件进行内存优化(GPU 利用率为 0.7~0.85)
管理用于隔离 rollout 的 Docker 容器生命周期
保存 checkpoint,并可选择上传至 HuggingFace
此仓库包含 331 个训练任务,复杂度从简单到极难不等。
🤓🤖 我开发了一套由 Claude Code + Opus-4 驱动的综合性多智能体合成数据流水线,用于生成并(更重要的是)验证每个数据点。该框架的仓库可以在这里找到!
dataset/latest_verified.csv 中的每个训练数据点都包含:
{
"task_id": "git-deployment-workflow-setup", # Unique task identifier
"difficulty": "hard", # easy|medium|hard|extremely_hard
"category": "system-administration", # Task category
"prompt": "I need help setting up a simple CI/CD system...", # The actual task instruction
"dockerfile": "FROM ghcr.io/laude-institute/t-bench/ubuntu-24-04:latest\n...", # Docker environment setup
"test_functions": "def test_hook_script_executable():\n ...", # Pytest verification code
"test_weights": { # Weight for each test (for partial credit)
"test_hook_script_executable": 0.35,
"test_nginx_service_running": 0.15,
"test_deployment_works_correctly": 0.50
},
"additional_files": { # Optional files to include in container
"backup_config.json": "{\n \"schedules\": [...",
"collision_detector.py": "#!/usr/bin/env python3\n..."
}
}
🐳 训练环境创建
训练期间,每个任务会生成多个并行 rollout(轨迹),每个 rollout 都在完全隔离的环境中执行:
并行生成 Rollout:N_ROLLOUTS:可按训练预设配置(例如测试运行使用 4,生产环境使用 16)每个 rollout 同时在各自的 Docker 容器中运行 Rollout 之间完全独立,允许探索多样化的解决方案
并行生成 Rollout:
N_ROLLOUTS:可按训练预设配置(例如测试运行使用 4,生产环境使用 16)
每个 rollout 同时在各自的 Docker 容器中运行
Rollout 之间完全独立,允许探索多样化的解决方案
每个 Rollout 的环境设置:使用任务的 dockerfile 创建新的 Docker 容器 容器启动时拥有基于 Dockerfile 构建的干净文件系统 在智能体开始执行前,将所有 additional_files 写入容器 智能体接收任务提示词作为初始指令
每个 Rollout 的环境设置:
使用任务的 dockerfile 创建新的 Docker 容器
容器启动时拥有基于 Dockerfile 构建的干净文件系统
在智能体开始执行前,将所有 additional_files 写入容器
智能体接收任务提示词作为初始指令
智能体执行:智能体使用工具(bash、文件操作等)与其隔离环境进行交互
智能体执行:智能体使用工具(bash、文件操作等)与其隔离环境进行交互
验证:完成后,执行 test_functions 以计算测试分数
验证:完成后,执行 test_functions 以计算测试分数
清理:轨迹完成后销毁容器
清理:轨迹完成后销毁容器
🧹 Docker 资源管理
由于会创建大量 Docker 容器(训练期间最多可并行运行 24 个容器),该基础设施包含自动资源清理机制:
自动清理守护进程会定期删除已停止的容器和未使用的网络
每 2 分钟运行一次,以防止资源耗尽
有关清理实现的详细信息,请参阅 docker_cleanup.py 和 docker_env.py
训练数据在被 rLLM 使用之前会经过多阶段的准备管道:
CSV 数据集(dataset/latest_verified.csv):包含带有提示、Dockerfile、测试函数和权重的任务定义
CSV 数据集(dataset/latest_verified.csv):包含带有提示、Dockerfile、测试函数和权重的任务定义
Terminal Bench 任务(通过 convert_dataset_to_tasks.py):将每一行 CSV 转换为 Terminal Bench 任务目录结构,以便利用 TerminalBench Docker 环境和单元测试运行器 + 解析器在 RL 运行期间进行奖励计算。并行运行以加快任务转换速度
Terminal Bench 任务(通过 convert_dataset_to_tasks.py):
将每一行 CSV 转换为 Terminal Bench 任务目录结构,以便利用 TerminalBench Docker 环境和单元测试运行器 + 解析器在 RL 运行期间进行奖励计算。
并行运行以加快任务转换速度
Parquet 格式(通过 tasks_to_parquet_converter.py):为 rLLM 的数据加载器创建 data/terminal_bench/*.parquet 文件。每一行包含 extra_info 字典,其中包括:task_name、task_path、instruction、test_weights、dockerfile_contents 等。此 extra_info 在训练期间传递给 DockerIsolatedEnv.from_dict() 以创建环境
Parquet 格式(通过 tasks_to_parquet_converter.py):
为 rLLM 的数据加载器创建 data/terminal_bench/*.parquet 文件
每一行包含 extra_info 字典,其中包括:task_name、task_path、instruction、test_weights、dockerfile_contents 等。
此 extra_info 在训练期间传递给 DockerIsolatedEnv.from_dict() 以创建环境
克隆仓库并安装依赖:
git clone --recurse-submodules https://github.com/Danau5tin/terminal-bench-rl.git
cd terminal-bench-rl
uv sync
就是这样!UV 会自动处理所有依赖项。
注意:此项目包含 terminal-bench 仓库的分叉版本,Python 版本要求从 3.13 降低到 3.12 以保证兼容性。
设置完成后,您可以复现我的 Terminal Bench 评估结果:
# 设置环境变量,示例:
export LITE_LLM_API_KEY="your_huggingface_token"
export LITE_LLM_API_BASE="https://router.huggingface.co/v1"
export LITELLM_MODEL="openai/Qwen/Qwen3-32B:nebius"
# 运行评估
./evaluation/terminal_bench_eval/run_eval.sh
这将使用在排行榜上取得 13.75% 成绩的相同配置运行 AI 智能体。
有关详细的单节点训练设置:
请参阅单节点训练指南
对于跨多个节点的分布式训练:
请参阅多节点训练指南
如果有更多的时间和资源,几项增强措施将进一步提高训练效果:
此刻,我感觉自己创建了一个很棒的蛋糕配方,准备好了所有材料来制作它,但却付不起烤箱的钱!😂
有足够的计算预算的话,我会运行完整的训练,然后评估训练后的模型。我相信它会超越未训练的 Qwen3-32B。
我还会实现课程学习,逐步提高任务难度,从简单和中等任务开始,对 judge 奖励赋予高权重,以鼓励使用待办事项列表等行为。
然后,当这些更简单的任务以正确的行为完成后,我会完全移除 judge,转向 100% 的任务软件验证。这样可以让模型摆脱最初学到的严格约束,从一个有原则的基础上探索优化的成功路径。
目前由于时间限制,我只有约 331 个任务
一个更大的数据集(1000+ 个任务)将为稳健的训练提供更多样化的场景和技术栈
我还会花时间仔细验证每个数据点,这需要时间但能保证质量
预先过滤琐碎的数据点:训练前,我会在所有任务上运行未训练的模型
我会移除模型取得零分或满分(0.0 或 1.0 奖励)的数据点
这将通过专注于模型能够真正学习的任务来节省 GPU 时间
我要感谢所有为 Terminal Bench 做出贡献的人,它是一个很好的基准,正是我一直在寻找的!
也要特别感谢 rLLM 背后的聪慧之人!我曾用其他训练框架尝试过这个,它们包含至今未解决的关键 bug,所以能够使用一个表现如此出色的框架真是如沐春风!
感谢 Claude Code 团队,他们启发了这个项目中使用的工具和 AI 智能体行为方法!
特别感谢 Anthropic 的研究团队,他们创建了如此优秀的模型。Opus-4 在这个项目中对我帮助很大,特别是在调试分布式 GPU 集群上的问题时。
这个项目非常有趣!感谢阅读!Dan