本教程指导你使用具备GUI任务处理能力模型,在计算机、移动设备等真实 GUI 环境中完成自动化任务(如界面点击、模式设置等)。模型支持图文结合的多轮交互,精准解析 GUI 操作指令并生成可执行的动作逻辑。
见文档:对话(Chat) API。
如您有多应用调用模型服务等需要精细控制和监控模型服务调用的场景,也可通过 Endpoint ID (推理接入点)调用模型服务,具体可参考获取 Endpoint ID。
- 下面示例代码不适用于
doubao-1.5-ui-tars-250328
,doubao-1.5-ui-tars-250328
模型用户推荐升级至doubao-1.5-ui-tars-250428
,具备深度思考能力,能更好处理问题。- 如确定使用
doubao-1.5-ui-tars-250328
,使用说明,请查看示例代码。
以“将图像设置为Palette - Based模式”任务为例,演示单轮 GUI 任务流程。
正式开始前需安装对应的SDK。
pip install pillow numpy matplotlib pip install volcengine-python-sdk[ark]
import os # 通过 pip install volcengine-python-sdk[ark] 安装方舟SDK from volcenginesdkarkruntime import Ark import base64 # 初始化Ark客户端,从环境变量中读取您的API Key client = Ark( api_key=os.getenv('ARK_API_KEY'), ) # 图片转 Base64 工具函数 def encode_image(image_path): with open(image_path, "rb") as f: return base64.b64encode(f.read()).decode('utf-8')
其中 prompt 提示词模板见 系统提示设计。
from prompt import COMPUTER_USE_DOUBAO # 系统提示模板(指定任务与语言) instruction = "Could you help me set the image to Palette-Based?" language = "Chinese" system_prompt = COMPUTER_USE_DOUBAO.format(instruction=instruction, language=language) # 编码目标截图 image_path = "image.png" image_format = image_path.split('.')[-1] # 提取图片格式(如png) base64_image = encode_image(image_path) # 构造messages(用户角色,包含文本提示和图片) messages = [ { "role": "user", "content": system_prompt }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image}" } } ] } ]
def inference(messages): response = client.chat.completions.create( # 按需替换 model id model="doubao-1.5-ui-tars-250428", messages=messages, temperature=0.0, # 固定温度保证输出稳定 stream=True # 流式获取响应(可选) ) # 流式响应拼接 full_response = "" for chunk in response: if chunk.choices[0].delta.content: full_response += chunk.choices[0].delta.content return full_response response = inference(messages) print(response)
模型会返回GUI 任务处理的思考过程和动作指令如下:
1. 首先分析当前界面:屏幕上显示GIMP的Preferences窗口,遮挡了主界面操作。要设置图像为Palette - Based,需先关闭Preferences窗口,再通过Image菜单操作。 2. 下一步逻辑:关闭Preferences窗口,点击其右上角的关闭按钮(×),以便后续访问Image菜单。 3. 目标元素:Preferences窗口右上角的关闭按钮,位置在窗口右上角,呈×形状。 Action: click(point='<point>450 416</point>')
模型返回的坐标为相对坐标,即将图片宽高归一化至1000后,对应点的坐标。要将这些值按照图像实际宽高进行比例换算,公式如下:
X绝对坐标 = X相对坐标/1000 × 图像宽度 Y绝对坐标 = Y相对坐标/1000 × 图像高度
示例代码
from PIL import Image, ImageDraw import matplotlib.pyplot as plt import re image = Image.open(image_path) original_width, original_height = image.size # 解析坐标(示例:提取action中的坐标) match = re.search(r'<point>(\d+)\s+(\d+)</point>', response) if match: x = int(int(match.group(1))/1000*original_width) # 提取第一个数字并转为绝对坐标 y = int(int(match.group(2))/1000*original_height) # 提取第二个数字并转为绝对坐标 action_point = (x, y) # 生成整数元组 else: raise ValueError(f"Failed to parse coordinates from response. Raw response: {response}") print(action_point) # 应输出类似(450, 416)的整数元组 # 在原图上标记动作位置 image = Image.open(image_path) draw = ImageDraw.Draw(image) draw.ellipse((action_point[0]-5, action_point[1]-5, action_point[0]+5, action_point[1]+5), fill="red") # 展示标记后的图片 plt.imshow(image) plt.axis("off") plt.show()
使用 系统提示模板明确任务(Instruction
)和语言(Language
),请勿更改其中内容,避免影响模型输出效果。
将提示词模板复制至 prompt.py 并存放在主脚本目录下:
import COMPUTER_USE_DOUBAO from prompt
导入。system_prompt = COMPUTER_USE_DOUBAO.format(instruction=instruction, language=language)
方式使用提示词模板及传入提示词配置。具体使用示例见步骤2:构造对话消息(系统提示 + 图片)。
多轮任务最多保留最近5张截图(含当前)和历史响应,messages
结构示例(以8轮为例):
messages = [ # 第1轮:系统提示 {"role": "user", "content": "初始系统提示"}, # 第1轮响应 {"role": "assistant", "content": "第1轮模型输出"}, # 第2轮响应 {"role": "assistant", "content": "第2轮模型输出"}, # 第3轮响应 {"role": "assistant", "content": "第3轮模型输出"}, # 第4轮:用户上传第4轮截图 {"role": "user", "content": [{"type": "image_url", "image_url": "..."}]}, # 第4轮响应 {"role": "assistant", "content": "第4轮模型输出"}, # ... 最多保留5轮截图对应的消息 ... # 第7轮:用户上传第4轮截图 {"role": "user", "content": [{"type": "image_url", "image_url": "..."}]}, # 第7轮响应 {"role": "assistant", "content": "第7轮模型输出"}, # 第8轮:用户上传第N张截图 {"role": "user", "content": [{"type": "image_url", "image_url": "..."}]}, ]
示例代码
import os # 通过 pip install volcengine-python-sdk[ark] 安装方舟SDK from volcenginesdkarkruntime import Ark import base64 from prompt import COMPUTER_USE_DOUBAO # 初始化Ark客户端,从环境变量中读取您的API Key client = Ark( api_key=os.getenv('ARK_API_KEY'), base_url="https://ark-cn-beijing.bytedance.net/api/v3", ) # 图片转 Base64 工具函数 def encode_image(image_path): with open(image_path, "rb") as f: return base64.b64encode(f.read()).decode('utf-8') instruction = "Could you help me set the image to Palette-Based?" language = "Chinese" system_prompt = COMPUTER_USE_DOUBAO.format(instruction=instruction, language=language) image_4turn_path = "samples/image_4_turn.png" image_5turn_path = "samples/image_5_turn.png" image_6turn_path = "samples/image_6_turn.png" image_7turn_path = "samples/image_7_turn.png" image_8turn_path = "samples/image_8_turn.png" base64_image_4turn = encode_image(image_4turn_path) base64_image_5turn = encode_image(image_5turn_path) base64_image_6turn = encode_image(image_6turn_path) base64_image_7turn = encode_image(image_7turn_path) base64_image_8turn = encode_image(image_8turn_path) image_format = image_path.split('.')[-1] assert image_format in ['jpg', 'jpeg', 'png', 'webp'] messages = [ { "role": "user", "content": system_prompt }, { "role": "assistant", "content": "Thought: 我看到屏幕上弹出了一个颜色配置文件转换的对话框,要继续操作的话得先处理掉它。对话框右下角有个\"Convert\"按钮,我需要点击它来确认这个转换操作。\nAction: click(point='<point>607 647</point>')" }, { "role": "assistant", "content": "Thought: 看到这张复古电视机的照片,我需要把它设置成基于调色板的方式。让我先点击顶部菜单栏的\"Tools\"选项,这样就能找到相关的颜色设置选项了。\nAction: click(point='<point>220 71</point>')" }, { "role": "assistant", "content": "Thought: 刚才点开了Tools菜单,但发现这不是正确的路径。要设置图片为基于调色板的方式,我需要先关闭当前打开的Tools菜单,然后重新寻找正确的颜色设置选项。让我点击一下Tools按钮把它关掉。\nAction: click(point='<point>220 71</point>')" }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image_4turn}" } } ] }, { "role": "assistant", "content": "Thought: 刚才在Tools菜单里没找到想要的选项,让我换个思路。我注意到顶部菜单栏有个\"Colors\"选项,这应该就是处理颜色设置的地方。我需要点击它来继续寻找将图片设置为基于调色板方式的选项。\nAction: click(point='<point>192 71</point>')" }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image_5turn}" } } ] }, { "role": "assistant", "content": "Thought: 我在Colors菜单里仔细浏览了一遍,发现这里并没有直接设置调色板的选项。看来得换个思路了 - 先把这个菜单关掉,然后去Edit菜单看看,那里应该能找到更多关于图像处理的选项。毕竟要实现基于调色板的设置,可能需要通过其他路径来实现。\nAction: click(point='<point>192 71</point>')" }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image_6turn}" } } ] }, { "role": "assistant", "content": "Thought: 我在Colors菜单里没找到想要的选项,让我换个思路。我注意到顶部菜单栏有个\"Edit\"选项,这应该就是处理颜色设置的地方。我需要点击它来继续寻找将图片设置为基于调色板方式的选项。\nAction: click(point='<point>65 71</point>')" }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image_7turn}" } } ] }, { "role": "assistant", "content": "Thought: 我在Edit菜单里发现了Preferences选项,这正是我需要的。通过这个选项,我应该能找到调整图片颜色模式的设置。让我点击它进入设置界面,这样就能把图片转换成基于调色板的方式了。\nAction: click(point='<point>96 602</point>')" }, { "role": "user", "content": [ { "type": "image_url", "image_url": { "url": f"data:image/{image_format};base64,{base64_image_8turn}" } } ] } ] response = inference(messages) print(response)
模型输出的Action
包含GUI操作类型(如click
/type
)和坐标,需:
import pyautogui from ui_tars.action_parser import parse_action_to_structure_output, parsing_response_to_pyautogui_code # 解析模型输出为坐标字典 parsed_dict = parse_action_to_structure_output(response, image_width, image_height, model_type="doubao") # 转换为PyAutoGUI可执行代码 py_code = parsing_response_to_pyautogui_code(parsed_dict, image_height, image_width) print(py_code) # 输出:pyautogui.click(x=450, y=417)
0
,top_p 请设置为 0.7
,无随机性的推理参数,以提高模型输出准确性。下面是模型可能返回的 action 值及对应值的含义。
Action名称 | 动作类型 | 参数 | 输出示例 |
---|---|---|---|
click | 鼠标左键单击 | start_box |
|
left_double | 鼠标左键双击 | start_box |
|
right_single | 鼠标右键单击 | start_box |
|
drag | 拖拽 | start_box |
|
hotkey | 热键 | key |
|
type | 键盘输入 | content |
|
scroll | 滚动屏幕 | start_box |
|
wait | 等待 |
| |
finished | 完成 | content |
|
Action 名称 | 动作类型 | 参数 | 输出示例 |
---|---|---|---|
click | 点击 | point |
|
long_press | 长按 | point |
|
type | 输入 | content |
|
scroll | 滚动 | point、direction |
|
open_app | 打开应用 | app_name |
|
drag | 拖拽 | start_point、end_point |
|
press_home | 返回主屏幕 | 无 |
|
press_back | 返回 | 无 |
|
finished | 完成 | content |
|