目录
一、概论
二、代码实现
分层设计
模块 1:Request 请求参数封装(OparetionRequest)
1. 模块定位
2. 核心设计解析
模块 2:Controller 接口层(OperationController)
1. 模块定位
2. 核心设计解析
模块 3:Service 业务抽象层(OparetionService)
1. 模块定位
2. 核心设计解析
模块 4:Service 实现层(OparetionServiceImpl)
1. 模块定位
2. 核心设计解析
三、核心总结
四、结果演示
五、结语
一、概论
GUI-Plus 可基于屏幕截图和自然语言指令来解析用户意图,并转换为标准化的图像用户界面(GUI)操作(如点击、输入、滚动等),供外部系统决策或执行。相较于通义千问VL系列模型,提升了GUI操作的准确性。
简单来说:GUI-Plus 只需一张屏幕截图 + 你说的自然语言指令,就能看懂你想对界面做什么,还能转换成点击、输入、滚动这类标准化的 GUI 操作给其他系统用,而且它在 GUI 操作的准确性上,比通义千问 VL 系列模型更靠谱。
现在我们先简单的按照官网给的例子来写一个后端的接口出来
二、代码实现
这段代码是一个多模态 GUI 操作解析接口,核心能力是接收「屏幕截图 URL + 自然语言指令」,调用阿里云百炼 GUI-Plus 模型,将用户意图转换为标准化的 GUI 原子操作(点击、输入、滚动等),返回 JSON 格式结果。
分层设计
遵循 Spring MVC 经典分层思想,职责边界清晰:
- Request:参数封装层(DTO)
- Controller:接口入口层(接收请求、转发业务)
- Service:业务抽象层(定义接口)
- ServiceImpl:业务实现层(核心逻辑,调用 GUI-Plus 模型)
模块 1:Request 请求参数封装(OparetionRequest)
import lombok.Data; /** * @author DELL */ @Data public class OparetionRequest { private String text; private String imageUrl; }1. 模块定位
作为数据传输对象(DTO),仅封装前端传入的核心请求参数,是前后端数据交互的载体。
2. 核心设计解析
- 用 Lombok 的
@Data注解:自动生成 getter/setter/toString/equals 等模板代码,精简代码量; - 字段设计:仅保留
text(指令)和imageUrl(截图)两个核心字段,完全匹配 GUI-Plus 模型的「文本 + 图片」多模态输入要求,无冗余字段。
模块 2:Controller 接口层(OperationController)
package gzj.spring.ai.Controller; import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.exception.UploadFileException; import gzj.spring.ai.Request.OparetionRequest; import gzj.spring.ai.Service.OparetionService; import org.springframework.web.bind.annotation.CrossOrigin; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @author DELL */ @RestController @RequestMapping("/api/Operation") @CrossOrigin // 跨域支持 public class OperationController { private final OparetionService oparetionService; public OperationController(OparetionService oparetionService) { this.oparetionService = oparetionService; } @RequestMapping("/operation/easy") public String oparetion(@RequestBody OparetionRequest request) throws NoApiKeyException, UploadFileException { return oparetionService.oparetion(request); } }1. 模块定位
对外暴露 HTTP 接口,是「前端请求 → 后端业务」的入口,仅负责请求转发,不包含业务逻辑。
2. 核心设计解析
@RestController:标识为 REST 接口,返回 JSON 而非视图;@CrossOrigin:快速开启跨域支持,适配前端本地调试场景;- 构造器注入
OparetionService:Spring 推荐的依赖注入方式(优于@Autowired),避免空指针,便于单元测试; @RequestBody:接收 JSON 格式请求体,绑定到OparetionRequest对象;- 异常抛出:直接抛出 SDK 定义的异常(
NoApiKeyException、UploadFileException),交由上层处理。
模块 3:Service 业务抽象层(OparetionService)
import com.alibaba.dashscope.exception.NoApiKeyException; import com.alibaba.dashscope.exception.UploadFileException; import gzj.spring.ai.Request.OparetionRequest; import org.springframework.web.bind.annotation.RequestBody; /** * @author DELL */ public interface OparetionService { String oparetion(@RequestBody OparetionRequest request) throws NoApiKeyException, UploadFileException; }1. 模块定位
定义业务逻辑的抽象接口,解耦「接口定义」与「实现逻辑」,符合「面向接口编程」思想。
2. 核心设计解析
- 仅定义一个核心方法
oparetion:入参为请求 DTO,抛出模型调用的特定异常,返回模型输出的 JSON 字符串; - 无具体实现:将业务逻辑交给
ServiceImpl层,便于后续扩展(如新增通义千问 VL 模型的实现类)。
模块 4:Service 实现层(OparetionServiceImpl)
package gzj.spring.ai.Service.ServiceImpl; // 导入依赖... @Service public class OparetionServiceImpl implements OparetionService { @Value("${spring.ai.dashscope.api-key}") private String apiKey; @Override public String oparetion(OparetionRequest request) throws NoApiKeyException, UploadFileException { // 1. 初始化多模态对话客户端 MultiModalConversation conv = new MultiModalConversation(); // 2. 构造系统提示词(核心:定义GUI-Plus输出规则) MultiModalMessage systrmMsg = MultiModalMessage.builder() .role(Role.SYSTEM.getValue()) .content(Arrays.asList(Collections.singletonMap("text", "## 1. 核心角色..."))) // 超长提示词 .build(); // 3. 构造用户消息(图片+文本) MultiModalMessage userMessage = MultiModalMessage.builder() .role(Role.USER.getValue()) .content(Arrays.asList( Collections.singletonMap("image", request.getImageUrl()), Collections.singletonMap("text", request.getText()))) .build(); // 4. 配置模型参数 MultiModalConversationParam param = MultiModalConversationParam.builder() .apiKey(System.getenv("DASHSCOPE_API_KEY")) // 读取环境变量API Key .model("gui-plus") // 指定GUI-Plus模型 .messages(Arrays.asList(systrmMsg,userMessage)) .build(); // 5. 调用模型并返回结果 MultiModalConversationResult result = conv.call(param); String resText = result.getOutput().getChoices().get(0).getMessage().getContent().get(0).get("text").toString(); System.out.println(resText); return resText; } }1. 模块定位
核心业务逻辑层,负责「组装多模态消息 → 调用 GUI-Plus 模型 → 解析返回结果」,是整个接口的核心。
2. 核心设计解析
@Service:标识为 Spring 服务 Bean,纳入 IOC 容器;@Value注入 API Key:从配置文件读取百炼 API Key,避免硬编码;- 系统提示词构造:这是核心中的核心!通过精细化的系统指令,定义 GUI-Plus 的输出规则(JSON 格式、Action 类型、参数模板、思维框架),保证模型输出的标准化和准确性;
- 多模态消息组装:将用户的
imageUrl(图片)和text(指令)组装为百炼 SDK 要求的格式; - 模型参数配置:指定模型名(
gui-plus)、API Key(优先环境变量)、消息列表; - 结果解析:提取模型返回的文本结果(标准化 GUI 操作 JSON)并返回。
三、核心总结
代码完整实现了 GUI-Plus 模型的调用流程,架构上遵循 Spring MVC 分层思想,核心亮点是「精细化的系统提示词设计」保证了 GUI 操作解析的准确性;
四、结果演示
五、结语
这里我们用的是官方给的图片如图:
模型通过 得出 定位信息,再将信息传给相关脚本进行处理。
当然,要做到实用,我们肯定需要搞本地地图,然后通过对自己的电脑进行多张截图,才有办法做出多自动化的效果在后续的文章中我将会实现这个功能。
如果觉得这份修改实用、总结清晰,别忘了动动小手点个赞👍,再关注一下呀~ 后续还会分享更多 AI 接口封装、代码优化的干货技巧,一起解锁更多好用的功能,少踩坑多提效!🥰 你的支持就是我更新的最大动力,咱们下次分享再见呀~🌟