UI-TARS 源码解析 #22:二次开发实战:用 UI-TARS 做一个简单的 Windows 自动操作 Agent

前面二十一篇文章,我们已经把 UI-TARS 主仓库里的核心内容基本拆完了。

包括:

text 复制代码
prompt.py:如何约束模型输出 Thought + Action

action_parser.py:如何解析模型动作、统一坐标、生成 pyautogui 代码

README_deploy.md:如何通过 HuggingFace Endpoint 调用 UI-TARS-1.5-7B

README_coordinates.md:如何处理 Qwen2.5-VL 坐标映射

action_parser_test.py / inference_test.py:如何验证动作解析和坐标处理

这一篇不再单独讲某个函数,而是做一次二次开发实战。

目标是:

基于 UI-TARS 的设计思路,做一个简单的 Windows 自动操作 Agent。

它不追求完整产品化,也不一上来支持所有复杂任务,而是先跑通最小闭环:

text 复制代码
截图
  ↓
调用模型
  ↓
得到 Thought + Action
  ↓
解析动作
  ↓
安全检查
  ↓
执行鼠标键盘
  ↓
重新截图

这就是一个 Windows GUI Agent 的最小原型。


一、先明确:我们要做的不是完整 UI-TARS-desktop

UI-TARS 主仓库并不是完整桌面客户端,而是提供了模型部署、Prompt、动作解析、坐标转换和 pyautogui 代码生成等基础能力。官方 Quick Start 也把流程分为模型部署与推理、Post Processing 两步:先获取模型输出,再用 parse_action_to_structure_outputparsing_response_to_pyautogui_code 做动作后处理。

所以本文的目标不是复刻完整 UI-TARS-desktop,而是用 UI-TARS 的开源组件和设计模式,搭一个最小 Windows Agent。

这个 Agent 先支持几类基础动作:

text 复制代码
click
type
hotkey
scroll
finished

暂时不急着支持:

text 复制代码
drag
right_single
left_double
hover
多窗口切换
复杂文件拖拽
系统级权限操作

这样可以先把核心链路跑通,再逐步扩展。


二、最小 Windows Agent 的整体架构

一个最小 Windows 自动操作 Agent,可以拆成 7 个模块:

text 复制代码
windows_ui_agent/
├── main.py
├── config.py
├── requirements.txt
│
├── agent/
│   ├── screenshot.py
│   ├── prompt_builder.py
│   ├── model_client.py
│   ├── parser.py
│   ├── safety.py
│   ├── executor.py
│   └── loop.py
│
└── runtime/
    ├── screenshots/
    ├── logs/
    └── traces/

模块职责如下:

text 复制代码
screenshot.py:
负责截取当前屏幕或当前窗口。

prompt_builder.py:
负责组装 UI-TARS Prompt、用户任务和历史动作。

model_client.py:
负责调用 UI-TARS-1.5-7B Endpoint 或其他兼容模型服务。

parser.py:
负责调用 parse_action_to_structure_output,把模型输出转成结构化 action。

safety.py:
负责动作白名单、坐标边界检查、高风险动作拦截。

executor.py:
负责执行 click、type、hotkey、scroll、finished。

loop.py:
负责截图 → 推理 → 解析 → 执行 → 再截图的循环。

这套架构的核心思想是:

不要让模型直接控制电脑,而是让模型输出受控动作,再由本地程序解析、检查和执行。

这和 UI-TARS 的设计一致:ui-tars 包负责把 VLM 生成的 GUI action instructions 解析成 pyautogui 脚本,并支持坐标转换和 smart image resizing。


三、安装依赖

先建一个 Python 虚拟环境。

bash 复制代码
python -m venv .venv
.venv\Scripts\activate

安装依赖:

bash 复制代码
pip install ui-tars pyautogui pillow openai pyperclip

如果你要使用窗口识别、前台窗口截图,可以后续再加:

bash 复制代码
pip install pywin32 pygetwindow

最小版本先只用全屏截图,这样更容易跑通。

ui-tars 官方 README 中也给出了安装方式:pip install ui-tarsuv pip install ui-tars


四、第一步:截图模块

新建 agent/screenshot.py

python 复制代码
import os
import time
from pathlib import Path

import pyautogui


def capture_screen(output_dir: str = "runtime/screenshots") -> dict:
    """
    截取当前整个屏幕。
    返回截图路径、宽度、高度。
    """
    Path(output_dir).mkdir(parents=True, exist_ok=True)

    ts = time.strftime("%Y%m%d_%H%M%S")
    path = os.path.join(output_dir, f"screen_{ts}.png")

    image = pyautogui.screenshot()
    image.save(path)

    width, height = image.size

    return {
        "path": path,
        "width": width,
        "height": height,
    }

这个函数有三个关键输出:

text 复制代码
path:截图文件路径
width:截图宽度
height:截图高度

其中 widthheight 非常重要。

因为后面 parse_action_to_structure_outputparsing_response_to_pyautogui_code 都需要知道图片尺寸。官方 Post Processing 示例中,解析模型输出时需要传入原图宽高,生成 pyautogui 代码时也要传入 image_heightimage_width


五、第二步:Prompt 模块

UI-TARS 的 prompt.py 中定义了桌面端 Prompt。

它要求模型输出:

text 复制代码
Thought: ...
Action: ...

并定义桌面动作空间:

text 复制代码
click(point='<point>x1 y1</point>')
left_double(point='<point>x1 y1</point>')
right_single(point='<point>x1 y1</point>')
drag(start_point='<point>x1 y1</point>', end_point='<point>x2 y2</point>')
hotkey(key='ctrl c')
type(content='xxx')
scroll(point='<point>x1 y1</point>', direction='down or up or right or left')
wait()
finished(content='xxx')

这些内容都在 COMPUTER_USE_DOUBAO 模板里。

新建 agent/prompt_builder.py

python 复制代码
from ui_tars.prompt import COMPUTER_USE_DOUBAO


def build_system_prompt(task: str, language: str = "Chinese") -> str:
    """
    使用 UI-TARS 的 COMPUTER_USE Prompt。
    """
    return COMPUTER_USE_DOUBAO.format(
        instruction=task,
        language=language
    )


def build_history_text(history: list[dict], max_items: int = 5) -> str:
    """
    把最近几步动作转成简短历史文本。
    """
    if not history:
        return ""

    recent = history[-max_items:]
    lines = ["\n## Action History"]
    for item in recent:
        lines.append(f"Step {item['step']}:")
        lines.append(item.get("response", "").strip())
        lines.append("")

    return "\n".join(lines)

实际调用模型时,可以把:

text 复制代码
任务说明
+
历史动作
+
当前截图

一起发给模型。


六、第三步:把截图转成 base64

如果调用 HuggingFace Endpoint 或 OpenAI 兼容多模态接口,通常需要把截图转成 base64。

新建一个工具函数:

python 复制代码
import base64


def image_to_base64(path: str) -> str:
    with open(path, "rb") as f:
        return base64.b64encode(f.read()).decode("utf-8")

请求中使用:

text 复制代码
data:image/png;base64,<base64内容>

官方部署文档的 Python 测试代码也导入了 base64PIL.ImageOpenAI 等,用 OpenAI SDK 调用 HuggingFace Endpoint,并通过流式响应拼接模型输出。


七、第四步:模型调用模块

新建 agent/model_client.py

这里以 HuggingFace Endpoint 的 OpenAI 兼容接口为例:

python 复制代码
from openai import OpenAI


class UITarsModelClient:
    def __init__(self, base_url: str, api_key: str, model: str = "tgi"):
        self.client = OpenAI(
            base_url=base_url,
            api_key=api_key,
        )
        self.model = model

    def infer(self, messages: list[dict]) -> str:
        """
        调用 UI-TARS Endpoint,返回 Thought + Action 文本。
        """
        stream = self.client.chat.completions.create(
            model=self.model,
            messages=messages,
            temperature=0.0,
            max_tokens=400,
            stream=True,
        )

        response = ""
        for chunk in stream:
            delta = chunk.choices[0].delta.content
            if delta:
                response += delta

        return response

为什么 temperature=0.0

因为 GUI Agent 不是写作文,而是要输出稳定、可解析、可执行的动作。官方部署示例中也是使用 temperature=0.0max_tokens=400stream=True 调用模型。


八、第五步:组装 messages

新建 agent/messages.py

python 复制代码
from agent.prompt_builder import build_system_prompt, build_history_text
from agent.utils import image_to_base64


def build_messages(task: str, screenshot_path: str, history: list[dict]) -> list[dict]:
    prompt = build_system_prompt(task)
    history_text = build_history_text(history)

    image_b64 = image_to_base64(screenshot_path)

    text = prompt
    if history_text:
        text += "\n" + history_text

    return [
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": text,
                },
                {
                    "type": "image_url",
                    "image_url": {
                        "url": f"data:image/png;base64,{image_b64}"
                    },
                },
            ],
        }
    ]

这里要注意:不同 Endpoint 的消息格式可能有差异。

如果你使用的是官方 HuggingFace Endpoint 示例,可以参考它的 test_messages.json 结构;如果用其他多模态模型服务,需要按对应 API 文档调整。

但整体思想不变:

text 复制代码
Prompt 协议
+
当前截图
+
历史动作

九、第六步:Parser 模块

新建 agent/parser.py

python 复制代码
from ui_tars.action_parser import parse_action_to_structure_output


def parse_response_to_actions(
    response: str,
    image_width: int,
    image_height: int,
    model_type: str = "qwen25vl",
) -> list[dict]:
    """
    把模型输出 Thought + Action 转成结构化 actions。
    """
    return parse_action_to_structure_output(
        response,
        factor=1000,
        origin_resized_height=image_height,
        origin_resized_width=image_width,
        model_type=model_type,
    )

parse_action_to_structure_output 会做这些事:

text 复制代码
清理模型输出;
把 <point>x y</point> 转为坐标;
把 point / start_point / end_point 统一成 start_box / end_box;
提取 Thought / Reflection / Action;
调用 parse_action 解析函数调用;
处理坐标归一化;
返回结构化 actions。

源码中可以看到,它会先处理 <point>,再替换 start_point=end_point=point=,如果 model_type == "qwen25vl" 还会先计算 smart_resize,然后把 Qwen2.5-VL 的绝对坐标除以 resize 后宽高。


十、Windows 坐标适配:先从全屏截图开始

为了降低难度,MVP 先使用全屏截图。

也就是说:

text 复制代码
截图坐标 = 屏幕坐标

这样 pyautogui.click(x, y) 直接可用。

后续如果你改成"只截取某个窗口",就要处理窗口偏移:

text 复制代码
真实屏幕 x = 截图内 x + 窗口 left
真实屏幕 y = 截图内 y + 窗口 top

如果不处理这个偏移,就会出现:

text 复制代码
模型看的是窗口截图;
pyautogui 点的是全屏坐标;
最终点击偏移。

Windows 上还要注意 DPI 缩放。

如果系统是 125%、150% 缩放,截图坐标和鼠标坐标可能不完全一致。这个问题 UI-TARS 主仓库没有替你完整处理,需要你在 Windows 自动化项目中单独适配。

MVP 建议先这样做:

text 复制代码
1. Windows 显示缩放设置为 100%;
2. 使用单显示器;
3. 使用全屏截图;
4. 浏览器或目标软件窗口最大化;
5. 先跑简单任务。

这样能先验证主链路。


十一、第七步:Safety 模块

不要让模型输出什么就直接执行。

新建 agent/safety.py

python 复制代码
ALLOWED_ACTIONS = {
    "click",
    "left_single",
    "hotkey",
    "type",
    "scroll",
    "wait",
    "finished",
}

RISKY_HOTKEYS = {
    "alt f4",
    "ctrl w",
    "ctrl q",
    "shift delete",
}

RISKY_WORDS = {
    "删除",
    "支付",
    "付款",
    "提交订单",
    "发送",
    "卸载",
    "格式化",
}


def validate_actions(actions: list[dict]) -> None:
    for action in actions:
        action_type = action.get("action_type")
        action_inputs = action.get("action_inputs", {})

        if action_type not in ALLOWED_ACTIONS:
            raise ValueError(f"暂不允许执行动作: {action_type}")

        if action_type == "hotkey":
            key = action_inputs.get("key") or action_inputs.get("hotkey") or ""
            if key.lower() in RISKY_HOTKEYS:
                raise ValueError(f"高风险快捷键,已拦截: {key}")

        text = str(action)
        for word in RISKY_WORDS:
            if word in text:
                raise ValueError(f"检测到高风险词,已拦截: {word}")

UI-TARS 官方 README 的 Limitations 中也提醒,GUI 自动化能力可能被滥用,模型可能出现误识别 GUI 元素、幻觉或次优动作。

所以二次开发时必须加安全层。

最小版本里,建议:

text 复制代码
只允许 click / type / hotkey / scroll / finished;
默认拦截删除、付款、发送、提交订单等动作;
未知 action_type 直接停止;
连续失败直接停止。

十二、第八步:Executor 模块

这里有两种做法。

第一种,直接使用 UI-TARS 生成 pyautogui 代码。

python 复制代码
from ui_tars.action_parser import parsing_response_to_pyautogui_code


def build_pyautogui_code(actions, image_width: int, image_height: int) -> str:
    return parsing_response_to_pyautogui_code(
        responses=actions,
        image_height=image_height,
        image_width=image_width,
        input_swap=True,
    )

源码中 parsing_response_to_pyautogui_code 会根据 action_type 生成不同 pyautogui 代码:hotkey 会生成 pyautogui.hotkey(...)type 默认使用 pyperclip.copy(...)ctrl+vdrag/select 会生成 moveTo + dragToscroll 会生成 pyautogui.scroll(...),鼠标点击类动作会从 start_box 还原真实坐标后生成 click/doubleClick/rightClick/moveTo。

第二种,自己写安全执行器。

我更推荐产品化时使用第二种。

因为 UI-TARS 源码里 click、drag、scroll 等分支使用了 eval(start_box)eval(end_box) 来解析坐标字符串。研究代码里这样方便,但真实产品里,模型输出属于不可信输入,最好改成 ast.literal_eval 或严格坐标解析。

MVP 可以先打印代码,不自动执行:

python 复制代码
def preview_code(code: str) -> None:
    print("\n========== 即将执行的 pyautogui 代码 ==========")
    print(code)
    print("=============================================\n")

然后人工确认再执行:

python 复制代码
def execute_code_with_confirm(code: str) -> None:
    preview_code(code)

    confirm = input("是否执行?输入 y 执行,其他键取消:").strip().lower()
    if confirm != "y":
        print("已取消执行。")
        return

    exec(code, {})

半自动模式对前期调试非常重要。


十三、type 输入为什么默认走剪贴板?

UI-TARS 执行层中,type 默认 input_swap=True

源码会生成:

python 复制代码
import pyperclip
pyperclip.copy('...')
pyautogui.hotkey('ctrl', 'v')

如果内容以 \n 结尾,还会额外生成:

python 复制代码
pyautogui.press('enter')

这个逻辑在 parsing_response_to_pyautogui_codetype 分支里。

为什么这样做?

因为在 Windows 上,逐字输入中文、特殊符号、JSON、路径、代码片段经常不稳定。

剪贴板粘贴更适合:

text 复制代码
中文
长文本
特殊符号
文件路径
网址
代码
多行内容

但它也有风险:

text 复制代码
会覆盖用户剪贴板;
某些输入框禁止粘贴;
远程桌面剪贴板可能失效;
密码框、验证码框不应该自动输入。

所以产品化时最好保存并恢复剪贴板。


十四、第九步:主循环

新建 agent/loop.py

python 复制代码
from agent.screenshot import capture_screen
from agent.messages import build_messages
from agent.parser import parse_response_to_actions
from agent.safety import validate_actions
from agent.executor import build_pyautogui_code, execute_code_with_confirm


class WindowsAgent:
    def __init__(self, model_client, model_type: str = "qwen25vl", max_steps: int = 10):
        self.model_client = model_client
        self.model_type = model_type
        self.max_steps = max_steps
        self.history = []

    def run(self, task: str):
        for step in range(1, self.max_steps + 1):
            print(f"\n========== Step {step} ==========")

            screen = capture_screen()
            print(f"截图: {screen['path']} ({screen['width']}x{screen['height']})")

            messages = build_messages(
                task=task,
                screenshot_path=screen["path"],
                history=self.history,
            )

            response = self.model_client.infer(messages)
            print("\n模型输出:")
            print(response)

            actions = parse_response_to_actions(
                response=response,
                image_width=screen["width"],
                image_height=screen["height"],
                model_type=self.model_type,
            )

            print("\n结构化动作:")
            print(actions)

            validate_actions(actions)

            code = build_pyautogui_code(
                actions=actions,
                image_width=screen["width"],
                image_height=screen["height"],
            )

            if code.strip() == "DONE" or "DONE" in code:
                print("任务完成。")
                return

            execute_code_with_confirm(code)

            self.history.append({
                "step": step,
                "screenshot": screen["path"],
                "response": response,
                "actions": actions,
                "code": code,
            })

        print("达到最大步数,停止。")

这个循环实现了最小 Agent:

text 复制代码
截图
  ↓
调用模型
  ↓
解析动作
  ↓
安全检查
  ↓
人工确认
  ↓
执行
  ↓
保存历史
  ↓
下一轮

十五、入口 main.py

新建 config.py

python 复制代码
HF_BASE_URL = "你的 HuggingFace Endpoint Base URL"
HF_API_KEY = "你的 HuggingFace API Key"
MODEL_NAME = "tgi"
MODEL_TYPE = "qwen25vl"
MAX_STEPS = 10

新建 main.py

python 复制代码
from config import HF_BASE_URL, HF_API_KEY, MODEL_NAME, MODEL_TYPE, MAX_STEPS
from agent.model_client import UITarsModelClient
from agent.loop import WindowsAgent


def main():
    task = input("请输入要执行的桌面任务:").strip()
    if not task:
        print("任务不能为空。")
        return

    client = UITarsModelClient(
        base_url=HF_BASE_URL,
        api_key=HF_API_KEY,
        model=MODEL_NAME,
    )

    agent = WindowsAgent(
        model_client=client,
        model_type=MODEL_TYPE,
        max_steps=MAX_STEPS,
    )

    agent.run(task)


if __name__ == "__main__":
    main()

运行:

bash 复制代码
python main.py

测试任务可以从简单的开始:

text 复制代码
打开浏览器搜索 UI-TARS

在记事本中输入 hello world

点击当前页面中的搜索框

向下滚动网页

复制地址栏内容

不要一开始测试"删除文件""发送邮件""提交订单"这类高风险任务。


十六、坐标可视化:一定要做

做 Windows 自动操作 Agent,最容易出错的是坐标。

UI-TARS 官方坐标文档说明,对于 Qwen2.5-VL 这类模型,要先计算 smart_resize(height, width) 后的新尺寸,再把模型输出坐标映射回原图坐标;文档示例使用 model_output_width / new_width * widthmodel_output_height / new_height * height 得到真实位置,并把点画到图片上。

所以你应该增加一个可视化工具。

例如每次模型输出 click 后,在截图上画出目标点:

python 复制代码
from PIL import Image, ImageDraw
import ast


def visualize_click(screenshot_path: str, start_box: str, output_path: str):
    image = Image.open(screenshot_path)
    width, height = image.size

    coords = ast.literal_eval(start_box)
    x1, y1, x2, y2 = coords

    x = int(((x1 + x2) / 2) * width)
    y = int(((y1 + y2) / 2) * height)

    draw = ImageDraw.Draw(image)
    r = 8
    draw.ellipse((x - r, y - r, x + r, y + r), fill="red", outline="red")
    image.save(output_path)

这样你能快速判断:

text 复制代码
模型点的位置是否正确;
坐标是否偏移;
是否点到了按钮边缘;
是否点到了错误区域。

没有坐标可视化,GUI Agent 很难调试。


十七、Windows 自动化必须处理的坑

做 Windows Agent,至少会遇到这些问题。

1. DPI 缩放

Windows 显示缩放如果不是 100%,pyautogui 坐标可能和截图坐标不一致。

MVP 阶段建议先设为 100%。

2. 多显示器

多显示器会带来负坐标、扩展屏偏移等问题。

MVP 阶段建议只用单显示器。

3. 窗口焦点

模型以为浏览器在前台,但实际焦点在别的软件。

执行前可以强制把目标窗口置顶,或者先让用户手动准备好窗口。

4. 输入法状态

type 默认走剪贴板粘贴,可以减少输入法问题,但不能完全避免焦点错误。

5. 权限问题

某些管理员权限窗口、UAC 弹窗、安全软件界面,pyautogui 可能无法操作或不应该自动操作。

6. 远程桌面

RDP、虚拟机环境里,剪贴板、鼠标坐标、DPI 缩放更容易出问题。

所以实战时先从普通桌面窗口开始,不要直接挑战复杂系统界面。


十八、为什么建议先做半自动?

完整自动执行风险很高。

建议 MVP 采用半自动模式:

text 复制代码
模型输出 Thought + Action
  ↓
显示结构化 actions
  ↓
显示 pyautogui 代码
  ↓
显示坐标可视化图
  ↓
用户确认
  ↓
执行

这样你可以观察:

text 复制代码
模型是否理解任务;
Action 格式是否正确;
坐标是否准确;
pyautogui 代码是否合理;
是否存在危险动作。

等稳定后,再把部分低风险动作改成自动执行。

例如:

text 复制代码
scroll 自动执行;
click 普通区域自动执行;
type 需要确认;
hotkey 需要确认;
删除、提交、支付永远确认。

十九、第一批测试任务

建议用这 5 个任务做 MVP 测试。

任务 1:点击搜索框

text 复制代码
请点击浏览器页面上的搜索框。

验证:

text 复制代码
截图 → 模型识别输入框 → click → 坐标还原 → 鼠标点击

任务 2:输入关键词

text 复制代码
在当前输入框中输入 UI-TARS。

验证:

text 复制代码
type → pyperclip → ctrl+v

任务 3:搜索并回车

text 复制代码
在浏览器地址栏输入 UI-TARS GitHub 并回车搜索。

验证:

text 复制代码
type(content='...\n') → 粘贴 + enter

任务 4:向下滚动

text 复制代码
向下滚动页面,找到下载按钮。

验证:

text 复制代码
scroll(point='...', direction='down')

任务 5:完成判断

text 复制代码
如果已经看到 UI-TARS GitHub 页面,就结束任务。

验证:

text 复制代码
finished(content='...')

这五个任务可以覆盖 MVP 最核心动作。


二十、不要一开始支持复杂动作

暂时不要急着支持:

text 复制代码
拖拽文件
右键菜单
双击桌面图标
操作系统设置
删除文件
发送邮件
付款
验证码
密码输入

原因是这些任务涉及:

text 复制代码
更高风险;
更复杂坐标;
更复杂状态变化;
更强安全要求。

先把低风险链路跑稳,再逐步扩展。


二十一、如果要升级成产品,下一步做什么?

MVP 跑通后,可以按这个顺序升级。

1. 增加安全执行器

不要 exec(code),改成自己根据结构化 action 调 pyautogui。

2. 增加窗口截图

只截取目标窗口,减少无关信息。

3. 增加窗口坐标偏移

把窗口内坐标映射到屏幕坐标。

4. 增加 DPI Awareness

处理 Windows 缩放。

5. 增加失败检测

执行后截图,对比界面是否变化。

6. 增加任务日志

保存:

text 复制代码
截图
模型输出
结构化 action
生成代码
执行结果
可视化坐标

7. 增加人工接管

用户随时可以暂停、跳过、停止。

8. 增加本地任务模板

比如:

text 复制代码
浏览器搜索
网页填写表单
打开软件
复制粘贴内容
简单文件管理

这样就从 demo 慢慢变成可用产品。


二十二、UI-TARS 二次开发的核心启发

UI-TARS 给我们的最大启发不是某一段 pyautogui 代码,而是它的分层方式。

text 复制代码
模型层:
负责看截图、理解任务、输出下一步。

Prompt 层:
约束模型必须输出 Thought + Action。

Parser 层:
把自由文本动作变成结构化 action dict。

坐标层:
处理 point、start_box、end_box、smart_resize、归一化坐标。

Executor 层:
把结构化动作变成鼠标键盘操作。

Safety 层:
拦截高风险动作。

Loop 层:
执行后重新截图,进入下一轮。

这比"让大模型直接写 Python 自动化脚本并执行"安全得多。

因为模型输出被限制在受控动作空间里。

UI-TARS 的桌面 Prompt 明确规定了可用动作和输出格式,执行层再把结构化动作转成 pyautogui 代码;这正是 GUI Agent 工程化的关键。


总结

这篇文章我们做了一次 UI-TARS 二次开发实战设计:用 UI-TARS 做一个简单的 Windows 自动操作 Agent。

最小架构是:

text 复制代码
截图模块
  ↓
Prompt 模块
  ↓
模型推理模块
  ↓
Parser 模块
  ↓
Safety 模块
  ↓
Executor 模块
  ↓
Feedback Loop

MVP 先支持:

text 复制代码
click
type
hotkey
scroll
finished

先不支持高风险和复杂动作。

核心代码链路是:

text 复制代码
pyautogui.screenshot()
  ↓
COMPUTER_USE Prompt + screenshot
  ↓
UI-TARS Endpoint
  ↓
Thought + Action
  ↓
parse_action_to_structure_output
  ↓
结构化 actions
  ↓
安全检查
  ↓
parsing_response_to_pyautogui_code
  ↓
人工确认
  ↓
pyautogui 执行
  ↓
重新截图

真正落地时,重点不是"能不能让鼠标动起来",而是:

text 复制代码
坐标是否准确;
动作是否安全;
执行后是否验证;
失败后是否停止;
日志是否完整;
用户是否可以随时接管。

跑通这个 MVP 之后,就可以继续扩展:

text 复制代码
窗口截图
DPI 适配
安全执行器
拖拽和右键
任务模板
日志回放
人工接管

这样,一个基于 UI-TARS 思路的 Windows 自动操作 Agent,就从源码学习进入了真正的二次开发阶段。

相关推荐
啊哈一半醒2 小时前
Windows 虚拟机搭建 CentOS 全过程(2026 最新版 + 踩坑解决)
linux·windows·centos
new_zhou2 小时前
C++ 项目 AI 协作指南(Windows / MSVC 环境)
c++·人工智能·windows
爬楼的猪6 小时前
跟着AI Agent学powershell
windows·ai编程
笨鸟先飞,勤能补拙6 小时前
网络安全等级保护 2.0:从定级备案、建设整改到持续合规的系统指南
网络·人工智能·windows·安全·web安全·网络安全·github
yagami_gagami7 小时前
2026平航杯内存取证(StarMem)
windows·网络安全
梦想的旅途210 小时前
企业微信API二次开发:外部群自动化管理与消息回调实战指南
windows·自动化·企业微信
七仔啊10 小时前
windows server 2022 安装 Linux Docker
linux·windows·docker
看浪的路人10 小时前
第4讲:MCP Client 开发——连接、发现、调用
windows·python·ai
洛水如云12 小时前
旧电脑数据迁移到新电脑,4种方法按场景选
windows·microsoft·电脑