UI-TARS Desktop 1.0 归档文档实战指南:从安装部署到 GUIAgent SDK 的 GUI 智能体全解
本文以仓库中 docs/archive-1.0/ 归档文档集(README 及其关联的 Quick Start、Deployment、SDK、Preset、Setting 子文档)为主体,完整还原 UI-TARS Desktop 1.0 时期的使用全貌:如何用自然语言控制电脑、如何完成 macOS/Windows 的安装与权限配置、如何部署 UI-TARS 视觉语言模型(云端与本地 vLLM)、以及 @ui-tars/sdk 的 GUIAgent/Operator 架构与配置细节。读完本文后,你既能按归档文档复现 1.0 版本的落地流程,也能通过当前仓库源码(如 GUIAgent.ts)理解智能体主循环、系统提示词与动作空间背后的实现原理。
需要说明的是:docs/archive-1.0/ 下的文档均带有 "This document has been archived" 标记,代表 UI-TARS Desktop 1.0 时代的官方文档;本文的所有结论均以这些归档文档为准,并结合当前仓库中仍然保留的 SDK 源码进行交叉印证。
一、UI-TARS Desktop 是什么
根据 docs/archive-1.0/README.md 的定义:UI-TARS Desktop 是基于 UI-TARS(Vision-Language Model,视觉语言模型)的 GUI Agent 桌面应用,允许用户使用自然语言控制自己的电脑。它是字节跳动开源的 GUI 智能体方案在桌面端的落地形态,配套的论文与模型可通过 README 中列出的 Paper、Hugging Face Models、ModelScope 等入口获取。
README 中的特性清单概括了该应用的六大核心能力:
| 特性 | 说明 |
|---|---|
| 自然语言控制 | 由视觉语言模型驱动的自然语言指令执行 |
| 视觉识别 | 截图采集与视觉识别支持 |
| 精准控制 | 精确的鼠标与键盘操作 |
| 跨平台 | 支持 Windows / macOS |
| 实时反馈 | 执行过程实时状态展示 |
| 隐私安全 | 完全本地处理的私有化能力 |
归档 README 的 News 部分记录了 1.0 阶段的三条重要演进节点,可以作为理解版本背景的时间线:
- [2025-04-17] 宣布支持 UI-TARS-1.5,具备增强性能、精准控制与更广泛的场景覆盖(同时支持以电脑和浏览器作为 operator),并兼容 UI-TARS-1.0、UI-TARS-1.5 与 Doubao-1.5-UI-TARS 多个模型;
- [2025-02-20] 引入 UI TARS SDK,一个用于构建 GUI 自动化智能体的跨平台工具箱;
- [2025-01-23] 更新云端部署文档,新增 ModelScope 平台的部署说明。
二、安装与首次运行(Quick Start 全解)
归档的快速上手文档 docs/archive-1.0/quick-start.md 覆盖了下载、安装与权限授予三个环节,以下完整继承其操作步骤。
2.1 下载
从仓库 Release 页面下载最新版 UI-TARS Desktop。如果已经安装了 Homebrew,也可以直接执行:
brew install --cask ui-tars
2.2 macOS 安装
- 将 UI TARS 应用拖入 Applications(应用程序) 文件夹;
- 在 macOS 系统设置中为 UI TARS 开启两项关键权限:
- System Settings -> Privacy & Security -> Accessibility(辅助功能):用于注入鼠标/键盘事件;
- System Settings -> Privacy & Security -> Screen Recording(屏幕录制):用于截取屏幕画面供视觉模型识别;
- 打开 UI TARS 应用,即可看到主界面。
这两项权限缺一不可:前者对应 SDK 中 Operator 的
execute()能力,后者对应screenshot()能力——权限缺失会导致主循环在截图或执行环节反复失败(源码中对连续截图失败有熔断计数,见第四节)。
2.3 Windows 安装
Windows 端直接运行安装后的应用即可看到相同的主界面(归档文档中标注该部分流程 "Still to run",即仍在完善中)。
三、模型部署(Cloud 与 Local vLLM)
UI-TARS Desktop 本身不包含模型推理,它通过 OpenAI 兼容 API 调用外部部署的 UI-TARS 视觉语言模型。docs/archive-1.0/deployment.md 给出了云端与本地两条部署路线。
3.1 重要公告:GGUF 模型降级
归档文档中有一则重要说明:GGUF 量化模型性能无法保证,官方决定将其降级(downgrade),建议改用云端部署或本地 vLLM 部署(前提是拥有足够的 GPU 资源)。
3.2 云端部署(Cloud Deployment)
官方推荐使用 HuggingFace Inference Endpoints 进行快速部署。归档文档为此提供了英文版与中文版两份《GUI 模型部署教程》的指引入口;2025-01-23 的新闻更新中还补充了基于 ModelScope 平台 的部署路径。云端部署完成后,只需把端点地址填入桌面端的设置项即可(见第五节 "VLM Base URL")。
3.3 本地部署(vLLM)
本地部署推荐 vLLM,要求 vllm>=0.6.1,安装命令如下(以 vLLM 0.6.6 + CUDA 12.4 为例):
pip install -U transformers
VLLM_VERSION=0.6.6
CUDA_VERSION=cu124
pip install vllm==${VLLM_VERSION} --extra-index-url https://download.pytorch.org/whl/${CUDA_VERSION}
模型选择:官方在 Hugging Face 上提供 2B、7B、72B 三种规模的模型,共五个版本,按硬件配置推荐 7B-DPO 或 72B-DPO 以获得最佳效果:
- UI-TARS-2B-SFT
- UI-TARS-7B-SFT
- UI-TARS-7B-DPO
- UI-TARS-72B-SFT
- UI-TARS-72B-DPO
启动 OpenAI 兼容 API 服务:
python -m vllm.entrypoints.openai.api_server --served-model-name ui-tars --model <path to your model>
服务启动后,在桌面端设置页填入 API 信息(VLM Base URL、API Key、Model Name)。归档文档特别强调:VLM Base URL 必须是 OpenAI 兼容的 API 端点(参考 OpenAI API 协议文档中关于 base64 图像输入的说明)。
四、UI TARS SDK:GUIAgent 架构与源码印证
docs/archive-1.0/sdk.md 是归档文档集中技术密度最高的一篇,完整介绍了 @ui-tars/sdk 的架构、执行流程、配置项与二次开发接口。该 SDK 的定位是:一个跨平台(任意设备/任意平台)的 GUI 自动化智能体工具箱,同时支持 Node.js 与 Web 浏览器运行环境。
4.1 类结构与执行流程
归档文档给出的类图结构如下(GUIAgent 持有模型与 Operator,Operator 有 NutJS/Web/Mobile 三类实现):
classDiagram
class GUIAgent~T extends Operator~ {
+model: UITarsModel
+operator: T
+signal: AbortSignal
+onData
+run()
}
class UITarsModel { +invoke() }
class Operator {
<<interface>>
+screenshot()
+execute()
}
class NutJSOperator { +screenshot() +execute() }
class WebOperator { +screenshot() +execute() }
class MobileOperator { +screenshot() +execute() }
GUIAgent --> UITarsModel
GUIAgent ..> Operator
Operator <|.. NutJSOperator
Operator <|.. WebOperator
Operator <|.. MobileOperator
其执行时序为典型的 "观察—决策—执行" 闭环:
sequenceDiagram
participant user as User
participant guiAgent as GUI Agent
participant model as UI-TARS Model
participant operator as Operator
user -->> guiAgent: instruction + Operator.MANUAL.ACTION_SPACES
loop status !== StatusEnum.RUNNING
guiAgent ->> operator: screenshot()
operator -->> guiAgent: base64, Physical screen size
guiAgent ->> model: instruction + actionSpaces + screenshots.slice(-5)
model -->> guiAgent: prediction: click(start_box='(27,496)')
guiAgent -->> user: prediction, next action
guiAgent ->> operator: execute(prediction)
operator -->> guiAgent: success
end
源码印证:上述时序图在当前仓库 GUIAgent.ts 的 run() 主循环中得到了逐行确认——每一轮迭代依次完成:
- 暂停/停止检查:若
isPaused则挂起等待resumePromise;若收到signal?.aborted或isStopped,置为USER_STOPPED并退出循环(L151-L160); - 循环上限检查:
loopCnt >= maxLoopCount时以REACH_MAXLOOP_ERROR报错退出(L162-L170); - 截图与校验:
operator.screenshot()通过asyncRetry执行,随后用 Jimp 解码 base64 校验宽高,无效截图会计入snapshotErrCnt,超过MAX_SNAPSHOT_ERR_CNT(在 constants.ts 中定义为 10 次)即熔断报错; - 模型推理:对话经
toVlmModelFormat转换为 VLM 消息格式,processVlmParams对截图做滑动窗口处理(即文档时序图中的screenshots.slice(-5)),再调用model.invoke(),模型调用失败会以 30 秒最小间隔重试; - 动作执行:遍历
parsedPredictions,先拦截四个内部动作(见 constants.ts 的INTERNAL_ACTION_SPACES_ENUM):error_env与max_loop直接置为 ERROR,call_user置为CALL_USER,finished置为END;其余动作交给operator.execute()执行,执行输出中的status会回写到智能体状态; - 收尾:
finally中若状态为USER_STOPPED,会向 Operator 下发一个action_type: 'user_stop'的兜底执行,保证桌面端能恢复光标等状态。
注意:归档 SDK 文档列出的状态集为
INIT / RUNNING / END / MAX_LOOP,而从源码结构看,当前版本的StatusEnum已扩展出PAUSE、CALL_USER、USER_STOPPED、ERROR等状态,属于 1.0 之后的演进。
4.2 快速试用与基础用法
最简单的体验方式是通过 CLI 启动交互式智能体:
npx @ui-tars/cli start
输入 UI-TARS 模型服务配置(baseURL、apiKey、model)后,即可在终端输入指令控制电脑:
◆ Input your instruction
│ _ Open Chrome
└
在代码中,以 NutJSOperator(基于 nut-js 的跨平台电脑控制工具,支持点击/双击/右键/拖拽/悬停、键入与热键、滚动、截屏)为例的基本用法:
import { GUIAgent } from '@ui-tars/sdk';
import { NutJSOperator } from '@ui-tars/operator-nut-js';
const guiAgent = new GUIAgent({
model: {
baseURL: config.baseURL,
apiKey: config.apiKey,
model: config.model,
},
operator: new NutJSOperator(),
onData: ({ data }) => {
console.log(data)
},
onError: ({ data, error }) => {
console.error(error, data);
},
});
await guiAgent.run('send "hello world" to x.com');
仓库中该 Operator 的实现位于 packages/ui-tars/operators/nut-js/src/index.ts,并有对应的执行逻辑测试 execute.test.ts 可查证。
4.3 中断控制(Abort Signal)
通过向 GUIAgent 传入 AbortSignal 可以取消运行中的智能体:
const abortController = new AbortController();
const guiAgent = new GUIAgent({
// ... other config
signal: abortController.signal,
});
// ctrl/cmd + c to cancel operation
process.on('SIGINT', () => {
abortController.abort();
});
对应源码中,signal?.aborted 在每一轮循环开头被检查(GUIAgent.ts),捕获到 Abort 类错误后状态会落为 USER_STOPPED。此外,源码还额外提供了 pause() / resume() / stop() 三个实例方法(GUIAgent.ts),归档文档未提及,属于后续增强。
4.4 配置项详解
GUIAgent 构造函数接受的配置选项:
model:模型配置(OpenAI 兼容 API)或自定义模型实例baseURL:API 端点地址apiKey:API 鉴权密钥model:要使用的模型名
operator:实现了 Operator 接口的实例signal:用于取消操作的 AbortController signalonData:接收智能体数据/状态更新的回调data.conversations是消息对象数组,注意:它是增量(delta),不是完整对话历史,每个对象包含:from:消息角色,human(人类消息)/gpt(Agent 响应)/screenshotBase64(截图 base64)value:消息内容
data.status:当前状态,StatusEnum.INIT(初始)/RUNNING(执行中)/END(完成)/MAX_LOOP(达到最大循环数)
onError:错误处理回调systemPrompt:可选的自定义系统提示词maxLoopCount:最大交互循环次数(默认 25)
状态流转:
stateDiagram-v2
[*] --> INIT
INIT --> RUNNING
RUNNING --> RUNNING: Execute Actions
RUNNING --> END: Task Complete
RUNNING --> MAX_LOOP: Loop Limit Reached
END --> [*]
MAX_LOOP --> [*]
4.5 动作空间与系统提示词:源码级深读
归档文档提到自定义 Operator 可通过静态属性 MANUAL.ACTION_SPACES 定义动作空间供模型理解。这一点在源码中体现得非常直接:GUIAgent.ts 的 buildSystemPrompt() 会把 Operator 的 MANUAL.ACTION_SPACES 拼入 SYSTEM_PROMPT_TEMPLATE 的 {{action_spaces_holder}} 占位符;若 Operator 未定义动作空间,则使用内置默认提示词。
内置的默认动作空间定义在 constants.ts,正是 UI-TARS 模型识别的标准动作集:
click(start_box='[x1, y1, x2, y2]')
left_double(start_box='[x1, y1, x2, y2]')
right_single(start_box='[x1, y1, x2, y2]')
drag(start_box='[x1, y1, x2, y2]', end_box='[x3, y3, x4, y4]')
hotkey(key='')
type(content='') #If you want to submit your input, use "\n" at the end of `content`.
scroll(start_box='[x1, y1, x2, y2]', direction='down or up or right or left')
wait() #Sleep for 5s and take a screenshot to check for any changes.
finished()
call_user() # Submit the task and call the user when the task is unsolvable, or when you need the user's help.
系统提示词要求模型输出 Thought: ... + Action: ... 的固定格式,并要求在 Thought 中先写小计划、再用一句话总结下一步动作及其目标元素。这解释了归档 SDK 文档时序图中 prediction: click(start_box='(27,496)') 这类输出的由来。
另外,constants.ts 中还有两个影响坐标映射与图像处理的常量值得了解:DEFAULT_FACTORS: [1000, 1000](模型坐标缩放因子)与 MAX_PIXELS = 1350 * 28 * 28(图像像素上限),后者从源码结构看用于控制送入 VLM 的截图尺寸——这与归档文档 "Custom Model 不推荐自定义,因为包含图像变换、缩放因子等大量数据处理逻辑" 的提示一致。
4.6 高级用法:自定义 Operator、Model 与 Planning
Operator 接口:自定义 Operator 需实现两个核心方法。
screenshot() 返回 ScreenshotOutput:
interface ScreenshotOutput {
// Base64 encoded image string
base64: string;
// Device pixel ratio (DPR)
scaleFactor: number;
}
execute() 接收 ExecuteParams:
interface ExecuteParams {
/** Raw prediction string from the model */
prediction: string;
/** Parsed prediction object */
parsedPrediction: {
action_type: string;
action_inputs: Record<string, any>;
reflection: string | null;
thought: string;
};
/** Device Physical Resolution */
screenWidth: number;
screenHeight: number;
/** Device DPR */
scaleFactor: number;
/** model coordinates scaling factor [widthFactor, heightFactor] */
factors: Factors;
}
继承 @ui-tars/sdk/core 导出的 Operator 基类即可创建自定义 Operator,并通过 MANUAL.ACTION_SPACES 声明该环境支持的动作集(用于拼接进 UI-TARS 系统提示词),再将其传给 GUIAgent:
const guiAgent = new GUIAgent({
// ... other config
systemPrompt: `
// ... other system prompt
${CustomOperator.MANUAL.ACTION_SPACES.join('\n')}
`,
operator: new CustomOperator(),
});
自定义 Model:可通过继承 UITarsModel 并重写 invoke() 实现自定义模型逻辑,但归档文档明确不推荐这样做,因为标准实现包含大量图像处理(图像变换、缩放因子计算)逻辑。
Planning(规划结合):可以组合规划/推理模型(如 OpenAI-o1、DeepSeek-R1 一类)先产出任务拆解列表,再逐条交给 GUIAgent 执行:
const planningList = await reasoningModel.invoke({
conversations: [{ role: 'user', content: 'buy a ticket from beijing to shanghai' }]
})
/**
* [
* 'open chrome',
* 'open trip.com',
* 'click "search" button',
* 'select "beijing" in "from" input',
* ...
* ]
*/
for (const planning of planningList) {
await guiAgent.run(planning);
}
五、Preset 与 Settings 配置体系
归档 README 中 "SDK (Experimental)" 之外,应用侧还有一套完整的配置体系,由 Preset Management Guide 与 Settings Configuration Guide 两篇文档展开。
5.1 Preset 管理
Preset 是一组设置(settings)的集合,UI-TARS Desktop 支持通过文件或 URL 两种途径导入:
- 文件导入:解析成功后设置自动更新,属于手动维护(Manual Updates);
- URL 导入:若开启了自动更新(Auto Sync),应用每次启动都会自动拉取远端 Preset。
两种类型的对比:
| 特性 | 本地 Preset | 远程 Preset |
|---|---|---|
| 存储位置 | 设备本地 | 云端托管 |
| 更新机制 | 手动 | 自动 |
| 访问控制 | 可读可写 | 只读 |
| 版本管理 | 手动 | 与 Git 集成 |
归档文档同时说明:由于 UI-TARS Desktop 不直接提供服务端能力,官方未提供现成 Preset,欢迎社区开发者向 examples/presets/ 目录贡献。仓库中保留的示例 Preset examples/presets/default.yaml 给出了完整字段样例:
name: UI TARS Desktop Example Preset
language: en
vlmProvider: Hugging Face for UI-TARS-1.5
vlmBaseUrl: https://your-endpoint.huggingface.cloud/v1
vlmApiKey: your_api_key
vlmModelName: your_model_name
reportStorageBaseUrl: https://your-report-storage-endpoint.com/upload
utioBaseUrl: https://your-utio-endpoint.com/collect
5.2 Settings 配置项详解
Language(VLM 语言):string,可选 en / zh,默认 en。注意:该设置只影响 VLM 的输出语言,不影响桌面应用自身的界面语言。
VLM Base URL:string,必填。指定所请求 VLM 服务的基地址,必须是 OpenAI 兼容 API 端点(部署方式见第三节)。
VLM Model Name:string,必填。指定要请求的模型名。
VLM Provider:string,可选 Hugging Face / vLLM,默认 Hugging Face。这是为不同 VLM 提供方预留的接口位。
Report Storage Base URL:报告存储服务器地址。未设置时,用户点击 Export as HTML(即 Share)会直接触发本地下载;设置后,报告会先上传至 Report Storage Server,服务器返回一个可公开访问的持久化 URL。归档文档对该服务器的接口约定做了完整规范:
| 项 | 说明 |
|---|---|
| Endpoint | POST /your-storage-enpoint |
| Headers | Content-Type: multipart/form-data |
请求体为 multipart/form-data,字段如下:
| 字段 | 类型 | 必填 | 说明 | 约束 |
|---|---|---|---|---|
| file | File | 是 | HTML 报告文件 | 格式:HTML;最大 30MB |
成功响应(200 OK):
{
"url": "https://example.com/reports/xxx.html"
}
归档文档注明:该服务器目前未设计鉴权机制。
5.3 UTIO:应用事件观测机制
UTIO(UI-TARS Insights and Observation) 是 UI-TARS Desktop 的数据收集机制(引入于 PR #60),其设计也与分享(sharing)相关联。UTIO Base URL 用于指向处理应用事件与指令的服务器。
UTIO 服务器通过 HTTP POST 接收事件(Content-Type: application/json),支持三种事件类型:
Application Launch(应用启动):
interface AppLaunchedEvent {
type: 'appLaunched';
/** Platform type */
platform: string;
/** OS version, e.g. "major.minor.patch" format */
osVersion: string;
/** Screen width in pixels */
screenWidth: number;
/** Screen height in pixels */
screenHeight: number;
}
Send Instruction(发送指令):
interface SendInstructionEvent {
type: 'sendInstruction';
/** User-submitted instruction content */
instruction: string;
}
Share Report(分享报告):
interface ShareReportEvent {
type: 'shareReport';
/** Optional last screenshot url or base64 content */
lastScreenshot?: string;
/** Optional report url */
report?: string;
/** Related instruction */
instruction: string;
}
请求示例:
{
"type": "appLaunched",
"platform": "iOS",
"osVersion": "16.0.0",
"screenWidth": 390,
"screenHeight": 844
}
成功响应:
{
"success": true
}
归档文档强调所有事件均异步处理,服务器应尽快响应以确认事件已接收,并给出了 Node.js(Express)与 Python(Flask)两种最小实现示例:按 event.type 分派到 handleAppLaunch / handleSendInstruction / handleShareReport,缺失 type 时返回 400。实现思路即 "路由 + 类型分派",可按需扩展存储与统计逻辑。
六、贡献、许可与引用
- 贡献:归档 README 指向的贡献指南,对应当前仓库根目录的 CONTRIBUTING.md;
- 许可:UI-TARS Desktop 采用 Apache License 2.0 开源(与 LICENSE 一致,源码文件头均带有
SPDX-License-Identifier: Apache-2.0声明); - 引用:若论文与代码对你的研究有帮助,归档 README 给出了 BibTeX 引用格式:
@article{qin2025ui,
title={UI-TARS: Pioneering Automated GUI Interaction with Native Agents},
author={Qin, Yujia and Ye, Yining and Fang, Junjie and Wang, Haoming and Liang, Shihao and Tian, Shizuo and Zhang, Junda and Li, Jiahao and Li, Yunxin and Huang, Shijue and others},
journal={arXiv preprint arXiv:2501.12326},
year={2025}
}
七、延伸阅读:仓库内相关路径
归档文档集之外,当前仓库中可直接深入的路径包括:
- docs/archive-1.0/README.md:1.0 归档文档总入口
- docs/archive-1.0/sdk.md:SDK 完整指南
- docs/archive-1.0/setting.md / docs/archive-1.0/preset.md:设置与 Preset 规范
- packages/ui-tars/sdk/src/GUIAgent.ts:智能体主循环实现
- packages/ui-tars/sdk/src/constants.ts:系统提示词、默认动作空间与关键常量
- packages/ui-tars/operators/nut-js/src/index.ts:桌面端 NutJS Operator 实现
- examples/presets/default.yaml:Preset 字段完整示例
总体来看,UI-TARS Desktop 1.0 的文档体系围绕一条主线展开:桌面应用(感知与执行入口)+ 自部署 VLM(决策大脑)+ SDK(可复用的 GUIAgent 循环)。归档文档给出了从安装权限、模型部署到配置生态的完整落地路径,而当前仓库中的 GUIAgent 源码则进一步印证了 "截图 → 推理 → 解析 → 执行 → 状态收敛" 这一 GUI 智能体核心循环的工程实现细节,为理解整个 GUI Agent 范式提供了扎实的源码级依据。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00

