cua-bench 计算机使用 RL 任务环境搭建指南:用 Python 装饰器与 GUI 脚手架构建可评估的交互任务
2026/9/13 3:48:06 网站建设 项目流程

cua-bench 计算机使用 RL 任务环境搭建指南:用 Python 装饰器与 GUI 脚手架构建可评估的交互任务

【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua

导读

本文基于 libs/cua-bench/datasets/cua-bench-basic/click-icon/CLAUDE.md 展开,完整讲解 cua-bench 中构建计算机使用(computer-use)强化学习任务环境的脚手架方法:通过@cb.tasks_config@cb.setup_task@cb.solve_task@cb.evaluate_task四个装饰器定义任务的加载、环境搭建、求解与评估,并用 Tailwind + Iconify 模板编写gui/index.html交互界面。读完本文,你将能够从零搭建一个可被 AI Agent 求解、可产出 0.0~1.0 RL 奖励的任务环境,并理解其底层执行链路与最佳实践。

环境结构总览:main.py 与 gui/ 的双层骨架

cua-bench 用于创建计算机使用 RL 环境,每个任务环境是一个独立目录,固定包含两类文件:

  • main.py:Python 装饰器承载的任务逻辑(任务配置、环境搭建、求解、评估);
  • gui/:HTML/CSS/JS 构成的 UI,渲染时会自动包含 Tailwind,并套入桌面 webview 窗口模板。

以数据集 libs/cua-bench/datasets/cua-bench-basic 为例,其中每个子目录(click-buttonclick-iconfill-formselect-dropdowndrag-dropcolor-pickerdate-pickertoggle-switchtyping-inputspreadsheet-cellright-click-menudrag-slidervideo-player等)都是一个独立任务环境,均遵循main.py+gui/index.html+pyproject.toml+CLAUDE.md的标准结构。

main.py中任务函数通过四个装饰器注册到环境注册表。从源码 decorators.py 可以看到,每个环境路径对应一个注册表,包含tasks_configsetup_tasksolve_taskevaluate_task四个槽位。加载时,core.py 的 make 函数 会动态导入目标目录的main.py,随后 environment.py 的 make_from_module 遍历模块中带有_td_type标记的函数,按 split 匹配并装配成Environment实例。

四个核心装饰器:任务生命周期的骨架

四个装饰器对应任务的四个生命周期阶段,均支持两种用法:裸用(@cb.tasks_config)或带 split 参数(@cb.tasks_config("train")/@cb.tasks_config(split="test"))。装饰器会为函数附加_td_type_td_split属性,供make_from_module在对应 split 下发现与装配(见 decorators.py)。

@cb.tasks_config:定义任务清单

返回list[cb.Task],其中description是 AI Agent 实际听到的任务描述(如 "Play 2048"、"Book a hotel"),metadata则保存任务参数(难度、游戏尺寸、系统类型等),用于生成变体:

return [cb.Task(description="Play 2048", metadata={"size": 4, "os_type": "linux"})]

Task是定义在 core.py 中的 dataclass,除descriptionmetadata外还支持task_idcomputer字段。其中computer字段可以直接声明运行环境(provider 与 setup_config),让任务在reset()时自动创建沙箱,而不必在setup_task里手动调用。

@cb.setup_task:创建沙箱并启动窗口

该阶段只做环境搭建,保持最小化。文档示例:

global pid env.create_sandbox(provider="computer", setup_config={"os_type": "linux", "width": 800, "height": 600}) pid = env.launch_window(html=html_content, title="Game", width=400, height=400) # create webview window

从源码看,create_sandbox在 environment.py 中按 provider 名称查找会话类(computers.py 的get_session),以DesktopSetupConfig启动会话,并实例化Bot助手。reset()流程(environment.py)会先读取任务配置,若Task.computer存在则自动创建沙箱,随后调用setup_task_fn,最后返回截图与当前任务供 Agent 观察。

@cb.solve_task:驱动 Agent 求解

从 GUI 侧的 AI 策略获取下一步动作,并用env.stepenv.bot执行:

global pid action = env.execute_javascript(pid, "window.__next_move()") while action is not None and action["type"] != "done": if not action or action["type"] == "wait": env.step(WaitAction(seconds=1.0)) elif action["type"] == "click_element": env.bot.click_element(pid, f"#{action['element_id']}") # safest way to click an element elif action["type"] == "click_absolute": env.step(ClickAction(x=action["x"], y=action["y"])) # x,y must be in screen coordinates (requires offsetting by window.screenX and window.screenY) elif action["type"] == "type": env.step(TypeAction(text=action["text"])) action = env.execute_javascript(pid, "window.__next_move()") env.step(DoneAction())

这里有几条铁律:

  • 只能通过env.stepenv.bot执行求解动作;
  • env.execute_javascript只能调用返回最优动作信息的辅助函数(如返回目标元素,或暴露了window.__next_move()的 AI 策略输出);
  • GUI 中的window.__next_move()只应在任务未完成时返回下一步动作,不得自行执行任何动作或修改环境/状态——动作由外层env.step/env.bot执行;
  • window.__next_move()通常由@cb.solve_task装饰的函数循环调用,直至任务完成。

底层链路:env.bot.click_element(bot.py)通过 provider 的 bench-ui 桥接获取元素在屏幕坐标系下的矩形,计算中心点后派发ClickActionenv.step(environment.py)则负责执行动作、记录step:before/step:after轨迹事件(截图 + 窗口快照)、维护step_count,并在超过max_steps时抛出MaxStepsExceeded

@cb.evaluate_task:从 GUI 状态产出奖励

返回 0.0~1.0 的奖励(RL 偏好该区间):

global pid score = env.execute_javascript(pid, "window.__score") return [float(score)] # 0.0-1.0 range preferred

在 environment.py 的 evaluate 方法 中,评估结果会写入 trace 的evaluate事件,并上报遥测:数值结果以>= 0.5作为成功阈值,bool 结果直接映射,dict 结果读取success字段。

gui/ 前端开发规范:语义化、响应式与全局状态

所有游戏/任务逻辑都放在gui/中。HTML 将渲染在 Tailwind + Iconify 模板的桌面 webview 窗口中,不要使用<html><body>标签(模板已提供)。

关键模式:

  • 语义化 HTML + ARIA 描述:使用<main><section><button><nav>等语义元素,并添加aria-labelaria-describedbyrole属性,既提升可访问性,也便于 Agent 识别元素;
  • 紧凑响应式设计:使用最小化的 padding/margin(p-1p-2gap-1gap-2),布局需在弹窗尺寸(300x200)到全桌面尺寸之间自适应;避免固定宽高,使用min-h-0overflow-auto,确保视口缩小时关键元素仍可见;
  • 全局状态:将当前得分存入window.__score(0.0~1.0,供 RL 使用);
  • AI 基线:在 JavaScript 中实现 AI 策略,通过window.__next_move()暴露;
  • 窗口填充:根元素使用class="flex h-full w-full"填满整个窗口,所有元素保持紧凑响应式(HTML 通常渲染在桌面 webview 窗口或小尺寸移动屏幕中);
  • 图标:使用<iconify-icon icon="prefix:name"></iconify-icon>

以 click-icon/gui/index.html 为例:根元素为<main class="flex flex-col h-full w-full p-6">并带role="main"aria-label;6 个图标按钮均使用id="icon-{Name}"aria-labeldata-icon-name标记;<script>中将点击结果写入window.__clickedIcon供评估读取——这是"全局状态供评估"模式的典型实现。

Action 类型清单:env.step()可用的动作原语

所有 Action 均为 dataclass,定义在 types.py,并通过cua_bench.__init__import cua_bench as cb暴露。

鼠标类:

Action参数说明
ClickActionx, y单击
RightClickActionx, y右键单击
DoubleClickActionx, y双击
DragActionfrom_x, from_y, to_x, to_y, duration=1.0拖拽
ScrollActiondirection="up\|down", amount=100滚动

源码中还提供了MiddleClickAction(x, y)MoveToAction(x, y, duration=0.0),可作为扩展动作使用。

键盘类:

Action参数说明
TypeActiontext="hello"输入文本
KeyActionkey="Enter"按键
HotkeyActionkeys=["ctrl", "c"]组合快捷键

控制类:

Action参数说明
DoneAction标记任务完成
WaitActionseconds=1.0等待

Iconify 图标使用

在 GUI 中使用iconify-icon元素渲染可缩放矢量图标:

<iconify-icon icon="eva:people-outline"></iconify-icon> <iconify-icon icon="mingcute:ad-circle-line" width="24" height="24"></iconify-icon> <iconify-icon icon="mdi:play" class="text-blue-500" style="font-size: 2rem;"></iconify-icon>
  • 图标会被自动处理并替换为内联 SVG;
  • 支持所有 iconify 图标集(eva、mingcute、mdi 等)。

在 click-icon 任务中,图标即任务本体:mdi:homemdi:settingsmdi:accountmdi:bellmdi:emailmdi:star分别对应 Home、Settings、Profile、Notifications、Messages、Favorites 六个待点击目标(见 click-icon/main.py)。

屏幕尺寸(Screen Size):setup_config 的分辨率约束

屏幕尺寸在env.create_sandboxsetup_config参数中指定。StandardScreenSize联合类型完整定义于 types.py,覆盖桌面、移动端与历史分辨率:

StandardScreenSize = Union[ # Standard Desktop Resolutions tuple[Literal[1920], Literal[1080]], # Full HD (current default) tuple[Literal[1366], Literal[768]], # HD (laptop standard) tuple[Literal[2560], Literal[1440]], # 2K/QHD tuple[Literal[3840], Literal[2160]], # 4K/UHD tuple[Literal[1280], Literal[720]], # HD Ready tuple[Literal[1600], Literal[900]], # HD+ tuple[Literal[1920], Literal[1200]], # WUXGA tuple[Literal[2560], Literal[1600]], # WQXGA tuple[Literal[3440], Literal[1440]], # Ultrawide QHD tuple[Literal[5120], Literal[1440]], # Super Ultrawide # Mobile/Tablet Resolutions tuple[Literal[1024], Literal[768]], # iPad (portrait) tuple[Literal[768], Literal[1024]], # iPad (landscape) tuple[Literal[360], Literal[640]], # Mobile portrait tuple[Literal[640], Literal[360]], # Mobile landscape # Legacy Resolutions tuple[Literal[1024], Literal[600]], # Netbook tuple[Literal[800], Literal[600]], # SVGA tuple[Literal[640], Literal[480]], # VGA # Additional Common Resolutions tuple[Literal[1440], Literal[900]], # Custom laptop tuple[Literal[1680], Literal[1050]], # WSXGA+ tuple[Literal[1920], Literal[1440]], # Custom 4:3 ratio tuple[Literal[2560], Literal[1080]], # Ultrawide Full HD tuple[Literal[3440], Literal[1440]], # Ultrawide QHD tuple[Literal[3840], Literal[1080]], # Super Ultrawide Full HD ]

完整实战案例:click-icon 任务剖析

以 click-icon 为例,演示四个装饰器的组合用法。tasks_config通过列表推导将 6 个图标场景 × 操作系统变体展开为任务清单,并在Task.computer中声明 provider 为native、分辨率 1024x768、背景色#c0c0c0

return [ cb.Task( description=scenario["description"] + ".", metadata={"icon": scenario["icon"], "name": scenario["name"]}, computer={ "provider": "native", "setup_config": { "os_type": os_type, "width": 1024, "height": 768, "background": "#c0c0c0", }, }, ) for os_type in os_types for scenario in icon_scenarios ]

setup_task读取gui/index.html并启动一个 500x400 的 webview 窗口;solve_task直接根据任务 metadata 中的目标图标名,用session.click_element(pid, f"#icon-{icon_name}")点击对应按钮;evaluate_task读取window.__clickedIcon,与期望图标名比对,返回[1.0][0.0]

值得注意:文档中的env.create_sandbox/env.launch_window/env.step是脚手架指南的同步 API 形态,而实际任务代码已演进为异步的session.launch_windowawait session.execute_javascriptawait session.click_element风格(session即 computers.py 中的DesktopSession)。两者在概念上一一对应,编写新任务时以仓库内实际任务的异步写法为准。

运行与调试

数据集 README 提供两种运行方式:

# 运行指定任务环境 python -m cua_bench.interact click-icon/main.py # 示例 python -m cua_bench.interact click-button/main.py

交互模式下(core.py 的 interact)会关闭 headless、开启动作打印,加载环境后自动执行reset()完成 setup,用户按回车后执行evaluate()输出评估结果。任务环境也可通过cb.interact(__file__)(如 click-icon/main.py 所示)直接以脚本方式启动。更完整的批量化评估可通过 runners.py 中的run_benchmarkrun_single_task驱动,产出结构化BenchmarkResult/TaskResult

最佳实践清单

  • 保持main.py最小化:只放装饰器与基础逻辑(环境搭建、任务加载等);
  • AI 策略放在gui/的 JavaScript 中,通过window.__next_move()暴露;
  • window.__score提供 RL 奖励(0.0~1.0 区间);
  • 通过 Task metadata 参数化变体(难度、尺寸、OS、轮数等);
  • 避免滥用WaitAction:除非任务确实需要(如等待页面加载或等待下一步动作可用)。env.bot助手会自动推进环境(包含等待元素变为可点击的可行动性逻辑);
  • 坐标约定:所有x,y均为屏幕坐标(0,0 在屏幕左上角),用window.screenXwindow.screenY获取浏览器视口左上角到屏幕左上角的偏移;
  • 按任务与环境选择合适的分辨率

小结

cua-bench 的脚手架把"任务定义—环境搭建—Agent 求解—自动评估"压缩为四个装饰器 + 一份 GUI 文件,配合Task.computer声明式沙箱配置与StandardScreenSize分辨率约束,可以快速产出跨 OS、跨分辨率、可参数化的计算机使用 RL 基准任务。本文所讲模式在 cua-bench-basic 的 13 个基础任务(点击按钮、填写表单、选择下拉、拖拽滑块、日期/颜色选择、右键菜单、视频控制等)中均有对应落地实现,可作为进一步参考与复用的起点。

【免费下载链接】cuaScale computer-use 2.0 with open-source drivers, cross-OS fleets, and benchmarks for training, evaluation, and data generation.项目地址: https://gitcode.com/GitHub_Trending/cua/cua

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询