1. 项目概述当AI智能体学会“看图说话”如果你和我一样长期在软件开发和测试自动化的一线摸爬滚打那你一定对“文档与实现脱节”这个老问题深恶痛绝。产品经理用Axure画了一堆带标注的原型图开发照着实现测试再根据另一份Word文档写自动化脚本——信息在传递中不断失真、滞后最后UI流程的自动化测试成了最耗时、最容易出错的环节。最近我在探索如何让AI智能体比如Claude、Cursor里的AI助手更深入地参与到我们的工作流中时发现了一个有趣的解决方案Multimodal UI Flow Analyzer。这本质上是一个“Agent Skill”智能体技能它能让AI学会“看图说话”——分析带标注的UI截图和Markdown文档然后自动生成一份机器可读、智能体可执行的UI流程规范。这听起来有点抽象我举个实际场景你就明白了。假设你的团队设计了一个新的用户登录流程包含手机号验证码登录和第三方授权登录。设计师给了一组带箭头和文字说明的截图说明了点击哪里、输入什么、出现什么反馈。传统上你需要人工阅读这些图片和文档然后将其转化为Playwright或Cypress的测试代码。而现在你可以把这个技能“安装”到你的AI编码助手比如Cursor里然后直接对它说“multimodal-ui-flow-analyzer请分析docs/login-flow.md里的登录流程。”AI就能理解图片和文档中的意图输出结构化的步骤、元素定位建议甚至自动化代码片段。这个项目的核心价值在于它定义了一种标准化的“技能包”格式让不同平台Cursor、Claude、自定义Agent的AI都能获得同一种专业能力。它不是另一个需要独立部署的复杂系统而是一个轻量级、可版本控制、即插即用的知识模块。对我而言这意味着可以将UI自动化测试的“领域知识”和“最佳实践”封装起来让团队里的AI助手随时具备专家级分析能力从而大幅提升从设计到自动化测试的转化效率和准确性。2. Agent Skills 核心机制与设计哲学在深入这个UI流程分析器的具体用法前我们必须先理解其基石——Agent Skills规范。这绝不仅仅是一个文件格式它背后是一套让AI智能体变得“专业化”和“可组合”的设计哲学。2.1 为什么需要“技能”过去我们增强AI能力的方式要么是喂给它长篇的上下文文档容易遗忘或混淆要么是训练一个昂贵的专用模型成本高、不灵活。Agent Skills找到了一条中间路径将针对特定任务的、程序性的知识封装成一个独立的、可复用的模块。你可以把它想象成给AI安装的“软件包”或“插件”。比如一个“SQL优化技能包”里包含了如何阅读执行计划、识别常见慢查询模式的规则和示例而这个“UI流程分析技能包”里则封装了如何解读界面标注、如何将视觉元素映射为自动化操作指令的知识。这种设计带来了几个关键优势关注点分离AI的核心模型负责通用推理和语言理解技能包提供领域专长。两者解耦技能可以独立迭代更新。可移植性一个按照规范编写的技能可以理论上在任何支持该规范的AI平台上运行避免了平台锁定。可组合性你可以让AI同时加载“UI分析”、“API测试生成”、“性能瓶颈分析”等多个技能来处理一个复杂的端到端质量保障任务。知识沉淀与传承团队的最佳实践、内部规范可以通过技能包的形式固化下来新成员通过AI助手就能立即应用这些经验降低了学习成本和人为错误。2.2 技能包的解构SKILL.md 的奥秘一个Agent Skill的核心就是一个名为SKILL.md的Markdown文件。它采用了一种“前端元数据YAML 主体指令Markdown”的混合结构。这种结构非常巧妙YAML前端元数据相当于技能的“说明书”和“身份证”供AI平台或工具快速识别和索引技能。--- name: multimodal-ui-flow-analyzer description: Analyze annotated UI screenshots and markdown to generate agent-consumable UI flow specifications. license: MIT metadata: author: boweneos version: 1.0 ---name技能的全局唯一标识通常使用小写和连字符。description一句话告诉AI这个技能是干什么的AI会根据这个描述决定何时调用该技能。metadata可以存放作者、版本号等扩展信息方便管理。Markdown主体指令则是技能的“大脑”和“操作手册”。这部分是直接给AI阅读和执行的。一个设计良好的技能指令不应该只是罗列功能而应该像在教导一位聪明但对该领域不熟悉的新同事。它需要明确输入输出清晰地告诉AI你需要给我什么如带标注的截图、步骤描述文档我会还给你什么如JSON格式的流程规范、Playwright代码片段。定义分析框架指导AI按照什么逻辑去思考。例如UI流程分析可能会要求AI先识别“用户目标”再分解为“操作步骤”对每个步骤分析“界面元素”、“交互动作”、“预期结果”。提供结构化模板给出输出格式的范例确保AI生成的内容是规范且可被下游工具解析的。项目assets/templates/目录下的文件就是干这个用的。包含启发式规则和边界案例分享人类专家的经验。比如“如果截图中一个按钮被红色圆圈标注通常表示这是当前步骤的核心操作点”“对于表单验证除了成功流还应考虑手机号格式错误、验证码过期等异常流的分析提示”。注意技能指令的质量直接决定了AI执行任务的效果。指令模糊AI的输出就随机指令精确且富含逻辑AI就能表现出惊人的专业性。在编写自定义技能时这是最需要下功夫的部分。3. Multimodal UI Flow Analyzer 深度实操指南了解了技能的基础我们现在聚焦到这个具体的UI流程分析器。我将结合自己的使用经验拆解它的核心能力、最佳使用姿势以及如何最大化其价值。3.1 核心能力拆解不止于“看图”这个技能包的名字里“Multimodal”多模态是关键。它要求AI模型具备视觉理解能力如Claude 3.5 Sonnet, GPT-4V能够结合图片和文字进行推理。其工作流程可以概括为以下几步输入消化AI接收用户提供的材料——通常是几张带箭头、方框、文字标注的UI截图以及一份描述流程的Markdown文档。意图识别AI需要从材料中提取用户的“核心目标”。例如是分析一个“用户注册流程”还是一个“商品下单到支付的完整闭环”元素与步骤解构这是核心环节。AI会识别界面元素根据标注确定每个步骤涉及哪些UI组件按钮、输入框、下拉菜单、弹窗。推断交互动作点击、输入、滑动、等待。建立前后关联理解步骤A的输出如“登录成功提示”如何成为步骤B的输入如“跳转到个人中心页面”。规范生成将解构后的信息填充到预设的结构化模板中生成最终输出。项目提供的几种输出模板非常有价值step-output.json: 生成机器可读的JSON数据适合集成到自动化流水线中驱动测试脚本生成。flow-output.md: 生成清晰的人类可读文档用于评审、存档或作为进一步开发的依据。automation-hints.md: 生成针对Playwright、Cypress等框架的自动化提示包括语义化选择器建议如使用rolebutton和aria-label而非脆弱的XPath、等待策略、断言点等。3.2 安装与集成三种主流场景详解根据你使用的AI平台集成方式有所不同。以下是经过实测的详细步骤场景一在 Cursor IDE 中使用最流畅的体验Cursor是目前对Agent Skills原生支持最好的IDE之一集成过程近乎无缝。获取技能仓库地址确保你拥有https://github.com/boweneos/ui-flow-agent-skills这个地址。打开Cursor设置使用快捷键CmdShiftJ(Mac) 或CtrlShiftJ(Windows/Linux)。添加远程规则在设置界面导航到Rules选项卡 → 点击Add Rule→ 选择Remote Rule (Github)。输入仓库URL在弹出的输入框中粘贴上述GitHub仓库地址。Cursor会自动拉取仓库并识别根目录下的SKILL.md文件。验证与使用添加成功后你在AI聊天框中输入应该能看到multimodal-ui-flow-analyzer的自动补全选项。使用时直接提及它并给出指令即可。multimodal-ui-flow-analyzer 请分析 assets/login_flow_annotated.png 这张截图和 docs/login_guide.md 文档为我生成一份Playwright可用的自动化提示重点关注元素定位的稳定性。实操心得在Cursor中技能是以“规则”的形式加载的。这意味着你可以为不同项目配置不同的技能组合。我通常会为前端项目加载UI分析技能为后端项目加载API测试生成技能实现环境隔离。场景二在 Claude (Web/API) 中使用Claude本身没有直接的“技能商店”但我们可以通过系统提示词System Prompt注入技能指令。这是一种非常灵活的方式尤其适合在自动化流水线中调用Claude API。克隆或下载技能内容首先你需要将SKILL.md文件的内容获取到本地或者直接读取其原始内容。构造系统提示词在你的应用或脚本中将技能内容作为系统提示词的一部分发送给Claude。项目README中给出的XML格式是一种清晰的结构化方式用于告诉Claude“你拥有这些可用的工具/技能”。在实际的API调用中你可以更直接地将技能指令文本拼接进去。import anthropic from pathlib import Path client anthropic.Anthropic(api_keyyour-api-key) # 读取技能指令 skill_path Path(./ui-flow-agent-skills/SKILL.md) skill_instructions skill_path.read_text() # 构造包含技能指令的系统提示词 system_prompt f 你是一个专业的软件测试自动化工程师。你拥有以下专项技能请在相关任务中运用它们 【技能UI流程分析】 {skill_instructions} 当用户要求分析UI流程时请主动运用上述技能。 # 调用Claude API message client.messages.create( modelclaude-3-5-sonnet-20241022, max_tokens4096, systemsystem_prompt, messages[ {role: user, content: 请分析我提供的登录流程截图和文档生成测试用例。} # 实际使用中你需要通过多模态接口或文本描述上传图片和文档内容 ] ) print(message.content)注意事项Claude的上下文长度有限。如果技能指令非常长你需要进行精心的摘要和裁剪只保留最核心的分析逻辑和输出模板避免占用过多Token影响主要对话。场景三在自定义AI Agent框架中集成如果你是基于LangChain、AutoGen或自研框架构建AI Agent集成方式更为自由。核心思想是将技能指令作为“工具”的描述动态加载到Agent的上下文或工具集中。# 一个简化的概念示例 class UIFlowAnalyzerSkill: def __init__(self, skill_path): with open(skill_path, r) as f: self.instructions self._parse_skill_file(f.read()) # 解析YAML和Markdown self.name self.instructions[metadata][name] def execute(self, agent, task_description, screenshot_paths, doc_path): # 1. 将技能指令注入本次任务的Agent上下文 agent.add_to_context(self.instructions[body]) # 2. 构建包含用户输入图片、文档的具体提示 user_prompt self._build_prompt(task_description, screenshot_paths, doc_path) # 3. 让Agent执行并期望它按照技能指令的格式输出 response agent.query(user_prompt) # 4. 解析响应提取结构化输出如JSON structured_output self._parse_response(response) return structured_output # 在Agent初始化时加载技能 my_agent MyCustomAgent() ui_skill UIFlowAnalyzerSkill(./skills/ui-flow-agent-skills/SKILL.md) my_agent.register_skill(ui_skill)3.3 提供高质量输入决定输出上限的关键AI技能再强大也遵循“垃圾进垃圾出”的原则。要让UI Flow Analyzer发挥最大效能你必须精心准备输入材料。根据我的经验一个优秀的输入包应包含高保真、带清晰标注的截图标注工具使用Figma、Sketch的标注模式或专业的截图标注工具如Greenshot、Snagit。标注规范使用箭头明确指示操作位置。使用编号对操作步骤进行编号①②③。文字说明简洁在标注旁用简短文字说明动作如“点击登录按钮”、“输入用户名”。包含状态变化对于弹窗、页面跳转等最好提供“操作前”和“操作后”的对比截图。格式PNG或JPEG确保关键文字和UI元素清晰可辨。结构化的Markdown辅助文档 截图是“视觉流”文档是“逻辑流”。文档应补充截图无法表达的信息。# 用户登录流程规范 ## 流程概述 本流程支持已注册用户通过手机号验证码登录。 ## 前置条件 - 用户已安装App并拥有已注册的手机号。 - 网络连接正常。 ## 主流程步骤 1. **启动App**进入登录首页。 2. **输入手机号** - 定位到手机号输入框。 - 输入11位有效中国大陆手机号如13800138000。 3. **获取验证码** - 点击“获取验证码”按钮。 - **预期结果**按钮变为“60s后重新获取”并开始倒计时手机收到6位数字短信验证码。 4. **输入验证码** - 定位到验证码输入框。 - 输入收到的6位数字验证码。 5. **点击登录** - 点击“登录”按钮。 - **预期结果**页面跳转至用户个人主页本地存储用户登录态Token。 ## 异常流 - A1: 手机号格式错误 - **触发条件**输入非11位数字或格式不正确的手机号。 - **预期结果**输入框下方显示红色提示文字“请输入正确的手机号”“获取验证码”按钮保持不可点击状态。 - A2: 验证码错误或过期 - **触发条件**输入错误的验证码或验证码超过60秒后输入。 - **预期结果**点击登录后页面顶部出现Toast提示“验证码错误请重新获取”。这样的文档为AI提供了明确的业务规则、数据边界和成功/失败标准能极大提升生成规范的准确性。4. 从分析结果到自动化代码实战工作流技能输出的是一份“规范”我们的最终目标往往是可执行的“自动化代码”。这里我分享一个将技能输出融入真实Playwright测试开发工作流的实践。4.1 解析技能输出并生成测试骨架假设技能为我们输出了如下结构的JSON简化版{ flow_name: 用户登录流程, steps: [ { step_id: 1, description: 在首页点击‘登录/注册’入口, target_element: { suggested_selectors: [text登录/注册, data-testidlogin-entry], element_type: button }, action: click, expected_outcome: 导航到登录页面页面标题为‘手机号登录’ }, { step_id: 2, description: 在登录页输入手机号, target_element: { suggested_selectors: [placeholder请输入手机号, [typetel]], element_type: input }, action: fill, action_data: 13800138000, expected_outcome: 输入框内显示‘13800138000’ } // ... 更多步骤 ], preconditions: [应用已启动, 用户未登录], postconditions: [用户登录态已建立, 跳转至个人主页] }我们可以编写一个简单的脚本将这个JSON转化为Playwright测试文件的骨架import json import os def generate_playwright_skeleton(flow_spec_json, output_pathtest_login.spec.js): with open(flow_spec_json, r) as f: spec json.load(f) test_code fimport {{ test, expect }} from playwright/test; test.describe({spec[flow_name]}, () {{ test.beforeEach(async ({{ page }}) {{ // 前置条件: {, .join(spec[preconditions])} await page.goto(https://your-app.com); }}); test(主流程 - {spec[flow_name]}, async ({{ page }}) {{ for step in spec[steps]: selector step[target_element][suggested_selectors][0] # 取第一个推荐选择器 action step[action] data step.get(action_data, ) if action click: test_code f // 步骤{step[step_id]}: {step[description]}\n test_code f await page.locator({selector}).click();\n elif action fill: test_code f // 步骤{step[step_id]}: {step[description]}\n test_code f await page.locator({selector}).fill({data});\n # 可以扩展更多 action 类型如 select, check, wait_for_selector 等 # 添加预期结果断言这里需要根据expected_outcome灵活生成 if expected_outcome in step and 跳转 in step[expected_outcome]: test_code f // 预期: {step[expected_outcome]}\n test_code f await expect(page).toHaveURL(/.*dashboard.*/); // 示例断言\n test_code \n test_code f // 后置条件验证: {, .join(spec[postconditions])} await expect(page.locator(text欢迎回来)).toBeVisible(); }}); }}); with open(output_path, w) as f: f.write(test_code) print(fPlaywright测试骨架已生成至: {output_path}) # 使用示例 generate_playwright_skeleton(flow_output.json)这个脚本生成的只是一个骨架里面的选择器和断言可能需要人工微调但它完成了从视觉规范到代码框架的80%的转化工作节省了大量重复性编码时间。4.2 利用Automation Hints优化测试脚本技能生成的automation-hints.md文件往往包含更具体的优化建议这些是真正的“干货”。例如它可能会建议优先使用角色定位page.getByRole(button, { name: 登录 })比page.locator(.btn-primary)更稳定。添加明确等待在触发弹窗或页面跳转的操作后建议使用await page.waitForURL(**/*home*)或await expect(locator).toBeVisible()。处理动态内容对于验证码倒计时按钮建议使用await expect(button).toHaveText(/\\ds后重新获取/)进行正则匹配。我们应该将这些提示手动整合到生成的测试骨架中使其成为健壮的、可维护的自动化测试。5. 创建与定制你自己的Agent Skill当你熟悉了使用现有技能后很可能会遇到需要定制化能力的情况。比如你的公司有一套内部的设计系统组件库或者有特殊的业务流程需要分析。这时创建自己的Agent Skill就非常有必要了。5.1 技能开发四步法定义技能范围与输入输出明确边界这个技能到底解决什么问题是“将PRD转化为API接口文档”还是“分析日志文件定位错误模式”范围要清晰、聚焦。设计输入用户需要提供什么格式的信息如Swagger JSON、错误日志文本、数据库Schema SQL。设计输出技能应该产出什么如Markdown接口文档、错误分类报告、实体关系图Mermaid代码。编写SKILL.md文件撰写清晰的YAML头确保name,description准确。编写详尽的主体指令这是核心。假设你在教一个新手专家完成任务。指令应包括任务目标。逐步思考框架Chain of Thought引导AI先做什么后做什么。输出格式模板直接给出一个理想的输出范例让AI模仿。常见陷阱与处理方式告诉AI如果遇到某种模糊情况该如何决策。本地测试与迭代将你的SKILL.md文件放在一个独立的文件夹里。使用skills-ref工具进行格式验证pip install skills-ref skills-ref validate your-skill-folder。在Cursor或Claude中手动加载这个本地技能文件夹进行真实场景测试根据AI的输出结果反复调整指令的措辞和结构。发布与分享你可以将技能文件夹推送到GitHub仓库像本项目一样。在团队内部共享仓库地址其他人就可以通过Cursor的“Remote Rule”功能添加你的技能了。5.2 一个自定义技能示例API测试用例生成器假设我想创建一个技能根据Swagger/OpenAPI规范JSON自动生成对应API接口的Playwright或Postman测试用例。SKILL.md内容节选--- name: api-test-generator description: Generate comprehensive API test cases from OpenAPI/Swagger specification. license: MIT metadata: author: your-name version: 1.0 --- # API测试用例生成技能 ## 技能目标 当你获得一个OpenAPI 3.0规范文件JSON/YAML格式时调用本技能。我将指导你分析其中的API端点并为每个端点生成正例、反例参数错误、鉴权失败等的测试用例输出格式包括Playwright API测试代码片段和Postman集合片段。 ## 输入要求 请用户提供 1. OpenAPI规范内容直接粘贴或提供文件路径。 2. 可选基础URL如 https://api.example.com/v1。 3. 可选通用的认证头信息如 Authorization: Bearer token。 ## 你的思考与分析步骤 1. **解析规范**首先梳理出所有的paths对象。关注每个路径如/users下的HTTP方法GET, POST等。 2. **分析单个端点**针对一个端点提取 - **请求**URL路径、方法、必需的参数路径参数、查询参数、请求体Schema、请求头尤其是认证头。 - **响应**成功的状态码如200, 201及其响应体Schema、错误的状态码如400, 401, 404, 500。 3. **设计测试用例** - **正向测试**使用有效的参数和正确的认证验证返回成功状态码和符合Schema的响应体。 - **负向测试** - 缺失必需参数。 - 参数类型/格式错误如字符串传入数字。 - 无效的认证令牌。 - 访问不存在的资源ID。 4. **生成代码/配置** - **Playwright**使用request上下文构造fetch或apiRequest调用并添加断言。 - **Postman**构造请求对象包含在item数组中。 ## 输出格式模板 请严格按照以下JSON结构组织你的输出... 后续附上详细的模板和示例通过这种方式你可以将团队在API测试领域的经验和规范固化成一个可复用的AI技能赋能整个团队。6. 常见问题与效能提升技巧在实际使用和推广Agent Skills的过程中我遇到并总结了一些典型问题和优化方法。6.1 问题排查速查表问题现象可能原因解决方案Cursor中无法通过提及技能1. 远程规则添加失败。2. 仓库根目录没有SKILL.md文件。3. 技能名称不符合规范。1. 检查网络重新添加规则。2. 确认仓库克隆完整且SKILL.md在根目录。3. 技能名应为小写字母和连字符。AI忽略了技能指令输出不符合预期1. 技能指令过于冗长或模糊。2. AI的上下文窗口限制技能指令被挤到后面。3. 用户提问方式未触发技能。1. 精简指令使用更明确、结构化的语言。2. 在Claude等平台确保技能指令在系统提示词中靠前。在Cursor中直接使用技能名开头。3. 在提问中明确引用技能名和关键输入。生成的UI流程规范遗漏关键步骤1. 输入截图或文档本身不完整、模糊。2. 技能指令中未强调分析“异常流”或“边界条件”。1. 提供更详细、步骤分解更细的输入材料。2. 在给AI的指令中明确要求“请同时分析主流程和至少两种常见的异常流程。”技能输出的选择器在实际测试中失效1. AI推荐的选择器基于静态截图而实际页面元素动态生成。2. 使用了基于绝对位置或易变样式的选择器。1.永远不要完全信任AI生成的选择器必须人工审查和测试。2. 优先采用AI建议的语义化选择器如>在自定义Agent中集成技能后响应慢1. 每次调用都加载完整的技能指令文本占用大量Token。2. 未对技能进行缓存。1. 对技能指令进行摘要化只保留核心逻辑框架。2. 实现技能缓存机制避免重复读取和解析文件。6.2 提升技能使用效能的技巧组合使用技能不要孤立使用一个技能。例如可以先使用ui-flow-analyzer生成流程规范再将其输出作为另一个“playwright-test-generator”技能的输入让后者直接生成完整的测试文件。通过串联技能构建自动化工作流。为技能提供上下文在请求技能时除了核心输入多提供一点背景信息。例如“这是一个移动端H5的登录流程运行在微信浏览器内”这能帮助AI做出更准确的判断比如考虑移动端特有的交互。建立团队技能库在GitHub组织下建立一个内部仓库收集和沉淀团队创建的各种技能如“公司设计系统组件识别”、“业务领域特定规则校验”。新成员加入后只需配置一次技能库地址就能立即让AI助手具备所有团队知识。技能版本化由于技能就是文件你可以用Git来管理技能的版本。当业务流程更新时同步更新对应的技能指令并通过Git提交记录来追踪技能的演变实现知识管理的可追溯性。这个项目的意义远不止于提供了一个好用的UI分析工具。它更像是一把钥匙为我们打开了一扇门如何以标准化、可协作的方式将人类专家的领域知识“灌输”给AI智能体让它们从通才助手变为专业伙伴。从我自己的实践来看从读懂一张截图到产出一份可用的测试骨架时间从小时级压缩到了分钟级而且分析过程更加标准化。虽然目前仍需人工进行最后的校验和微调但已经极大地解放了生产力让工程师能更专注于更复杂的测试场景设计和业务逻辑验证。