Cua Agent 统一接口实战:15 行代码让任何模型都能驱动电脑
【免费下载链接】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
你上一次为换个大模型而重写工具调用逻辑是什么时候?Cua 的 Agent 框架用一行model="..."字符串就能在 OpenAI、Anthropic 和本地模型之间切换,工具、沙箱、轨迹记录全部复用。本文带你 10 分钟内看懂这套统一接口的设计,并跑通一个带预算控制的完整任务。
最小可运行 Demo:15 行 Cua Agent 多模型调用
先给结论:整个调用面只有两个对象——Computer(给模型一块"屏幕")和ComputerAgent(驱动模型的循环)。完整可运行版本在 示例代码,下面这段从它精简而来,只需两个环境变量即可跑:
import asyncio, os from computer import Computer from cua_agent import ComputerAgent async def main(): async with Computer(os_type="linux", provider_type="cloud", name=os.environ["CUA_CONTAINER_NAME"], api_key=os.environ["CUA_API_KEY"]) as computer: agent = ComputerAgent( model="anthropic/claude-sonnet-4-20250514", # 换这一行即可切换 openai/、huggingface-local/ 等模型 tools=[computer], only_n_most_recent_images=3, use_prompt_caching=True) history = [{"role": "user", "content": "打开浏览器搜索今天的日期"}] async for r in agent.run(history): history += r["output"] asyncio.run(main())几个"为什么这样写":only_n_most_recent_images=3是刻意只保留最近 3 张截图,历史步数多了截图会拖垮上下文和成本;use_prompt_caching=True让重复的工具定义前缀命中缓存;tools=[computer]把沙箱整体注册为工具,模型自己决定何时截屏、点击、输入。跑起来后,模型的每一步动作都会以事件流形式从agent.run的 async 生成器里流出,框架自带 Gradio 界面可以实时观察:
核心机制拆解:从模型字符串到屏幕像素的三层结构
这一节帮你建立全局认知:那行model=字符串背后到底发生了什么。先看整体架构:
挑三个最有代表性的 API 展开。
1.model字符串路由:换模型不改代码
解决什么问题:不同模型的调用协议、图像格式、点击坐标约定各不相同,硬编码适配层会让业务代码腐烂。
内部怎么工作:框架维护一个注册表,装饰器源码中的register_agent(models=正则, priority=...)把专用 Agent 配置挂上去,find_agent_config按优先级匹配模型名,选不到才走通用适配器。想插自己的模型,只需实现predict_step、predict_click、get_capabilities三个方法:
from cua_agent.decorators import register_agent @register_agent(models=r".*my-tuning-model.*", priority=10) class MyAgent: async def predict_step(self, messages, model, tools, **kwargs): ... async def predict_click(self, *args, **kwargs): ... def get_capabilities(self): return ["step", "click"]关键点:模型名带omniparser+前缀时(如omniparser+anthropic/claude-sonnet-4-20250514),框架会把视觉定位交给专门的 VLM,通用 LLM 只负责推理——连从未针对 computer-use 训练过的模型也能驱动 GUI。
2. 工具系统:沙箱即工具
解决什么问题:模型只会"说",你得让它能"做"。
内部怎么工作:tools列表接受两类对象。Computer是完整沙箱,背后是 QEMU 容器或云端实例,跨 Linux/macOS/Windows/Android 同一套 API;普通 Python 函数则用@sandboxed()装饰器隔离成工具,签名和 docstring 自动生成调用规范:
from computer.helpers import sandboxed @sandboxed() def read_file(location: str) -> str: """Read contents of a file location : str Path to the file to read """ with open(location) as f: return f.read()关键点:注册进tools=[computer, read_file]后,模型会在"操作屏幕"和"调函数"之间自主选择——文件读取走函数快且便宜,只有看到像素才能完成的事才动鼠标。
3. 执行循环与回调:agent.run不只是跑任务
解决什么问题:生产环境需要成本刹车和行为审计。
内部怎么工作:agent.run(history)是 async 生成器,每步产出 message、computer_call(屏幕动作)、function_call三类事件;回调实现 里内置了预算、轨迹保存、PII 脱敏、OTel 上报等钩子。示例中用的max_trajectory_budget={"max_budget": 1.0, "raise_error": True, "reset_after_each_run": False}就是给单次会话上了 1 美元的锁,超了直接抛错。
贯穿式实战:让 Agent 在沙箱里批量汇总 CSV 报表
这一节用一个贴近日常的任务把上面三层串起来:一批销售 CSV 散在目录里,让 Agent 逐个读取、汇总,最后产出 markdown 报告。
上一步我们拿到了 15 行 Demo,现在把 cloud provider 换成本地 docker(无需 API key),并加一个汇总工具。先准备沙箱:
# provider_type="docker" 时在本地起 Linux 容器,不依赖云端密钥 async with Computer(os_type="linux", provider_type="docker") as computer: agent = ComputerAgent( model="anthropic/claude-sonnet-4-20250514", tools=[computer, read_file, save_report], # 两个 @sandboxed 工具 max_trajectory_budget={"max_budget": 0.5, "raise_error": True}, trajectory_dir="trajectories/sales_summary", )read_file就是上一节那个装饰器函数,save_report同理——把汇总写进report.md。工具产出是下一步的输入:模型读完每个 CSV 后把统计结果留在对话里,最后一步调用save_report落盘,你不用写任何胶水代码。
这里会遇到一个真实报错。如果你沿用 Demo 里的 cloud 配置且没配密钥,启动即抛AssertionError: CUA_API_KEY is not set——这是框架在环境变量缺失时的硬断言,而不是静默降级。解法二选一:export CUA_API_KEY=...走云端,或像上面改用provider_type="docker"本地跑。确认能跑通后,执行任务:
history = [{"role": "user", "content": "读取 /data/sales/ 下所有 CSV," "按月汇总营收,找出异常月份,用 save_report 写入 report.md"}] async for r in agent.run(history, stream=False): history += r["output"]每轮结束都会往trajectories/sales_summary追加轨迹文件,复盘时能回放模型每一步截屏和动作。
踩坑与调优:上下文、预算、模型路由
Q:跑着跑着 token 费用突然飙高?九成是截图堆积。每步 computer 动作都会往上下文塞一张全屏截图,几十步后图像 token 就是大头。用only_n_most_recent_images=3(示例代码的默认选择)只保留最近 3 张;若任务强依赖长程视觉记忆,可改调 5 并观察成本曲线再定。
Q:预算参数给数字还是字典?max_trajectory_budget接受{"max_budget", "raise_error", "reset_after_each_run"}三元组。批处理脚本建议raise_error=True让它当场失败而不是烧满额度;长期在线的 agent 则设reset_after_each_run=True,每轮任务重置预算,避免单轮偶发高消费污染全局计数。
Q:use_prompt_caching什么时候不划算?缓存对"重复前缀"生效——工具集、系统提示不变时效果最好。如果你的工具列表每轮动态增删,前缀频繁变化,缓存命中率会很低,此时开use_prompt_caching是负优化,直接关掉更省。
收尾
回到开头的问题:换模型只需要改一行字符串,工具、沙箱、预算、轨迹这些"脏活"由统一接口层接管,你只写业务意图。学完本文你应该能独立完成:配置一个Computer沙箱、注册自定义工具、用回调给 agent 上预算锁,并通过轨迹文件复盘行为。想继续深入:
- Agent 示例代码:多模型参数、预算与打印输出的完整写法
- cua_agent 源码目录:适配器、循环、装饰器实现细节
- 官方文档:沙箱配置、Cua-Bench 评测与 driver 集成指南
文中示例基于仓库
libs/python/agent当前代码整理,模型可用性与价格以各 provider 实际为准,运行前请核对环境变量配置。
【免费下载链接】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),仅供参考