ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Agent验证技能开发实战:从创建到维护的完整指南

Agent验证技能开发实战:从创建到维护的完整指南 最近我在折腾 pstack 的验证技能核心解决一件事Agent 用自然语言生成操作指令之后怎么知道它真的把应用改对了。以前很多 Agent 只能说“我已完成”但页面到底是不是按预期变化、接口有没有返回正确、数据有没有落库它自己并不确定。pstack 新增的创建与维护验证技能就是把“验收应用”这件事拆成可被 Agent 调用的技能从打开页面、点击、输入、截图到断言、汇总报告全部按固定流程执行。这个方向最适合正在做 AI Agent 开发、应用 QA以及想用 Agent 跑回归测试的人。这篇不会讲太深奥的 Agent 理论更多是我实际创建和调验证技能时踩过的点。1. 验证技能在 Agent 里的定位先搞清它是工具还是流程1.1 Agent 跑通不等于验证通过很多团队会告诉 Agent“去新增一个用户”Agent 也确实执行完了打开后台、点新建、填表单、提交最后还回了一句“已完成”。如果你只看这一步会觉得 Agent 很能干。但真正的问题在后面新增用户真的出现在列表里了吗用户名和填写的表单一致吗账号能正常登录吗这些都不该靠 Agent 本身的“感觉”判断而要靠一个可重复的验证流程。这个差异就是验证技能存在的原因。它把“验证”从 Agent 的随机行为里剥离出来变成一个固定的执行单元。Agent 只负责理解任务、调用技能、解释结果而技能内部用确定性的步骤完成检查和断言。我之前踩过一种典型状况Agent 说创建成功实际是接口返回 200但页面上因为权限校验用户列表根本没有刷新出来。如果只依赖 Agent 自身判断这个问题会被漏掉。加一层验证技能后操作完立刻检查列表里是否有目标用户名问题当场暴露。1.2 验证技能与普通 MCP 工具的差别“Agent Skill 和 MCP 有什么区别”这个问题最近经常被问到。简单说MCP 更像给 Agent 一根“可调用的管子”通过标准接口暴露某个工具能力而 Skill 通常包含更完整的执行上下文目标、步骤、提示词、默认参数、错误处理策略。验证应用这件事尤其适合做成 Skill而不是裸 MCP 工具。因为验证不是单次动作而是“打开页面→等待元素→填写表单→提交→等待跳转→断言结果→截图”这样的流程。如果每一步都拆成独立 MCP 工具交给 Agent 临时拼装很容易漏掉等待条件和断言步骤结果就是操作都成功但验证并不过关。pstack 里做验证技能时我会把整个验证链路写在一个技能定义里。这样 Agent 调用时只需要说“验证一下登录流程”技能内部自动执行完整链路而不是让 Agent 现场决定先调哪个工具。1.3 把验证分成“行为操作”和“结果断言”两部分验证技能设计时最核心的一点是把“用户怎么操作”和“结果怎么判断”分开。行为操作包括打开 URL、输入账号密码、点击登录按钮、等待页面跳转、填写表单、提交。这部分解决的是“像真实用户一样”的行为路径。结果断言包括当前 URL 是否包含 /dashboard、页面上是否出现“欢迎回来”、列表里是否存在目标用户名、接口返回的 code 是否为 0、数据库或接口查询结果是否符合预期。这部分解决的是“这个应用真的符合预期吗”。如果只写行为操作那就是一个自动化脚本不叫验证如果只写断言那又没法让 Agent 真正去操作应用。两个部分合在一起Agent 才能既执行又验收。2. 创建首个验证技能前先把环境、对象和验收标准列清楚2.1 环境条件本地浏览器、测试应用、账号和数据隔离创建验证技能之前不要急着写配置。先确认环境。我一般先列一个最小清单pstack 服务可用Agent 能正常调用技能。验证环境里有可访问的浏览器驱动或自动化运行时。测试应用有独立地址、测试账号和测试数据。网络策略允许 Agent 执行容器访问目标应用。有日志和截图输出目录权限要放开。这里最容易忽略的是网络策略。Agent 运行在一个容器或远程执行环境里时本地机器能访问的localhost它不一定能访问。我第一次配置验证技能时总是报“页面打不开”排查半天发现是容器里访问不到宿主机上的测试应用地址。测试账号也要提前准备。验证登录、创建用户、修改配置这类流程时如果只能用生产账号或管理员账号风险很大。最好准备一套测试专用账号并且每次验证后能清理测试数据避免多个 Agent 任务之间互相影响。2.2 验证对象拆解页面、接口、流程、权限、数据一致性验证技能不能笼统地说“验证这个应用”。要把验证对象拆到可断言的颗粒度。页面层元素是否可见、文本是否正确、跳转 URL 是否符合预期、按钮是否可点击。接口层请求返回状态码、业务 code、响应字段、耗时。流程层登录是否进入首页、新建后是否出现成功提示、审核流程能否走通、报错时是否有合理提示。权限层普通用户看不见管理入口、未登录访问受保护页面是否跳转登录、越权操作是否被拒绝。数据一致性界面显示的数据和接口返回是否一致操作完成后数据库或列表是否更新。一个验证技能不必覆盖所有层但设计时要想清楚这次验证要覆盖哪几层。比如验证“登录”时至少覆盖页面层和接口层验证“新建用户”时至少要覆盖页面跳转、接口返回、列表数据更新三层。2.3 把“像真实用户一样”翻译成可判断断言“像真实用户一样”听起来很抽象。落到验证技能里其实就是回答几个具体问题用户打开应用时能看到什么是登录页面还是首页。用户登录后进入哪个页面跳转地址是什么。用户点新建按钮后表单是否出现光标是否进入第一个输入框。提交成功后页面有没有成功提示列表有没有新数据。如果输入的手机号已存在页面会不会给出明确错误文案。这些都可以写成断言。不用关心这个断言“像不像人”只要它来自真实用户的使用路径并且结果可判断就是有效验证。我建验证技能时会先手工走一遍流程把每一步在浏览器里看到的实际状态记下来。比如“登录成功后 URL 从 /login 变成 /dashboard”“新建用户成功后出现 toast创建成功”。然后把这些状态翻译成技能里的断言条件。这样比凭空设计更可靠。3. 用 pstack 创建验证技能的实操流程3.1 技能目录与基本结构pstack 里一个验证技能通常由三部分组成技能说明、执行脚本、配置文件。具体目录名可以根据你安装的版本调整但思路通用。我习惯用这样的结构skills/ verify_login_flow/ skill.yaml verify.py README.md assets/skill.yaml 负责描述这个技能是干什么的、Agent 在什么场景下应该调用它、参数怎么传、超时时间是多少。verify.py 负责真正执行浏览器自动化操作和断言。assets 放截图或报告。skill.yaml 里一般包含 name、description、version、parameters、timeout 这些字段。description 尤其重要因为 Agent 是否想起用这个技能主要靠 description 判断。写得太窄Agent 该用的时候不会用写得太宽不该用的时候反而乱用。示例配置# 示例配置字段名以你实际安装的 pstack 版本为准 name: verify_login_flow description: 验证登录流程。当用户希望检查登录功能是否正常、登录页面是否可用时调用。 version: 0.1.0 parameters: - name: base_url description: 测试环境访问地址 required: true - name: username description: 测试账号 required: true - name: password description: 测试密码 required: true timeout: 60description 里我建议写清楚“验证”两个字同时写清楚适用场景。比如“当用户希望检查登录功能是否正常时调用”这比“执行登录”更贴合验证技能定位。3.2 先写最小验证用例打开页面、点击、断言第一次创建验证技能不要想着一步到位写复杂业务流。先写一个最小用例把链路跑通。以“验证登录流程”为例最小用例是打开登录页面。输入测试账号和密码。点击登录按钮。等待页面跳转或元素出现。断言 URL 是否进入 /dashboard。截图保存。返回验证报告。对应脚本核心部分可以是# 示例伪代码实际写法取决于 pstack 封装的浏览器 API from pstack import PlaywrightSkill, assertion class VerifyLoginFlow(PlaywrightSkill): async def run(self, context): page await context.new_page() await page.goto(self.params.base_url /login) await page.fill(input[nameusername], self.params.username) await page.fill(input[namepassword], self.params.password) await page.click(button[typesubmit]) await page.wait_for_url(**/dashboard, timeout10000) assertion.assert_contains( page.url, /dashboard, 登录成功后应跳转到 dashboard ) await page.screenshot(pathassets/login_success.png) return { status: pass, message: 登录流程验证通过, screenshot: assets/login_success.png }这里有一个关键点点击登录按钮之后不要立刻断言。要等页面跳转完成或者目标元素出现否则断言可能执行太快导致误报失败。等待条件优先用wait_for_url或wait_for_selector而不是固定 sleep。固定 sleep 在快机器上浪费时间在慢机器上又不够稳定。3.3 接入应用访问地址和测试账号技能方案里最好不要把测试账号和密码写死在脚本里。不同的环境、不同的账号验证结果会完全不同。我更建议把这类信息做成参数在调用技能时传入。这样同一个技能可以复用到多个环境也方便隔离测试数据。调用示例pstack run verify_login_flow \ --param base_urlhttps://demo.example.com \ --param usernametest_user_01 \ --param password******如果你的 pstack 没有命令行运行方式也可以在 Agent 对话里让模型根据上下文自动填充参数。不过自动填充的风险是模型可能猜错地址所以至少 base_url 要提前配置好。账号和密码这类敏感信息建议走环境变量或密钥管理不要在 skill.yaml 里明文出现。验证技能本质上也是一个程序密钥泄露问题同样存在。3.4 注册技能并让 Agent 调用创建完技能之后需要让 pstack 能发现它。一般需要把技能目录放到 pstack 配置的技能加载路径里或者在管理界面点击“扫描技能”/“重新加载”。加载成功后可以做一个快速测试打开 Agent 对话直接输入“请验证一下登录流程使用我提供的测试账号”。理想情况是 Agent 能自动匹配到这个验证技能并执行完整流程。如果 Agent 没有匹配到先检查技能的 description 和名称是否和用户表达相关。比如用户说“检查登录页能不能用”技能描述里如果只有“验证登录流程”而没有提到“检查”“登录页”匹配度可能不高。第一次调用成功后再进入复杂场景不要一上来就让 Agent 验证一个完整的“新增用户→分配权限→模拟登录→数据清理”流程。复杂流程排查起来会非常麻烦。4. 验证技能维护日志、重试、用例更新和版本控制4.1 从单条用例到多场景用例集单个验证用例跑通之后很快会遇到新需求登录验证完了还要验证新增用户、修改密码、导出数据。这时候不要为每个场景都新建一个完全独立的技能而是考虑维护多场景用例集。我一般会把同属于一个应用的验证用例放在同一个技能目录下每个用例是一个独立脚本或独立函数。比如skills/ verify_management_console/ skill.yaml cases/ test_login.py test_create_user.py test_update_password.py test_export_data.py common/ selectors.py这样 Agent 可以调用整个技能指定跑某个用例也可以一次跑全部回归用例。用例之间要尽量互相独立。比如 test_create_user 不能依赖 test_login 已经执行成功因为验证技能可能只被调用其中一个用例。每个用例最好自己完成前置登录、业务操作、断言和清理。4.2 失败重试不能无脑重复要看失败类型验证技能在 Agent 工作流里常见的一个问题是失败了Agent 又盲目重试结果还是失败。浪费时间还可能污染测试数据。我自己的处理方式是先分类失败类型。第一类环境类失败。比如应用没启动、网络超时、页面加载太慢。这类可以重试通常重试一两次就能恢复。第二类定位类失败。比如选择器找不到、按钮文案变化、页面改成异步加载。这类重试没有意义应该直接输出失败原因提示维护技能里的选择器。第三类业务类失败。比如提交后接口返回报错、数据没有写入、权限校验未通过。这类可能是应用有 bug更不该让 Agent 反复重试而是要把结果留给人去确认。可以在技能里加一个简单的失败分类字段把错误类型带回给 Agent。这样 Agent 在判断是否重试时就有了依据。4.3 维护周期与日志规范验证技能不是建完就结束了。应用页面结构一变技能里的选择器、断言、流程就可能失效。所以维护是关键步骤。维护周期要跟着应用迭代走。前端发布后至少跑一遍核心验证技能后端接口变更后检查接口断言是否还成立测试账号变更时同步更新参数配置。日志必须规范。我每次执行验证技能都会记录以下信息执行时间、技能版本、目标环境。输入参数脱敏后。每个关键步骤的开始和结束时间。页面截图、接口响应摘要。每个断言的预期结果、实际结果。失败时的错误类型和堆栈。没有日志的验证技能等于没验证。出问题时你不知道是哪个步骤挂了也不知道是环境问题还是应用问题只能重新跑一遍效率很低。4.4 技能和 MCP 的边界什么时候拆、什么时候合维护过程中你会反复调整技能边界。这里给一个我自己用的判断标准如果验证流程里某个能力需要被多个不同技能复用比如“读取短信验证码”“查询数据库用户状态”那这个能力适合做成独立工具通过 MCP 暴露。如果是一整套带有业务步骤和断言逻辑的流程适合继续留在技能里因为把步骤拆给 Agent 临时组合会失去稳定性。比如“登录验证”是一个技能“查询用户状态”是一个通用工具。登录验证技能内部可以调用查询用户状态这个 MCP 工具但不需要把它改成 MCP。这样技能负责编排工具负责单点能力边界最清晰。另外注意技能和 MCP 不是互斥的。好的 Agent 工程实践里两者常常配合使用。Pstack 里新增和修改验证技能时也可以把技能执行时需要的底层能力配置到对应的工具服务里。5. 实际运行效果和判断标准5.1 一次典型验证流程的过程我以一个“后台管理系统新建用户”的验证技能为例把实际运行过程拆一遍。技能入口用户提供 base_url 和测试账号。Agent 调用技能。步骤执行打开后台登录页。用测试账号登录。进入用户管理列表。点击新建按钮。填写用户名、手机号、角色。点击提交。等待成功提示。在列表里搜索该用户名确认出现。调用接口查询该用户名是否存在。截图并返回验证报告。这个过程能做到“像真实用户”到什么程度取决于等待条件和断言是否贴近真实。真实用户不会点击提交后 200 毫秒就判断成功他会等一下看到提示再到列表里确认。验证技能也要有同样的节奏。5.2 结果判定通过、失败、告警、跳过验证结果不要只返回 pass 或 fail我建议增加告警和跳过状态。通过所有断言符合预期操作路径完整截图正常保存。失败至少一个关键断言未通过比如用户名没有出现在列表里或者接口返回错误码。失败时技能应该提供现场证据方便定位。告警功能主线通过但存在非关键问题。比如页面加载时间超过预设值、控制台有警告信息、某个非关键元素延迟出现。告警不阻塞流程但值得后续跟踪。跳过前置条件不满足。比如没有测试账号、目标功能未上线、找不到对应的测试环境地址。跳过时不能算通过也不能算失败要留下原因。这套状态设计能让 Agent 在后续决策时更准确。否则明明该跳过Agent 却把结果当作“验证通过”那这个验证就是假验证。5.3 资源占用和速度判断验证技能要不要长期在后台跑主要看资源占用和执行速度。在常见环境下单个 UI 验证流程耗时通常在十几秒到一分钟不等。涉及页面截图、接口查询和报告生成时时间会更长。速度的判断标准不是“尽可能快”而是“能不能在任务不超时的情况下稳定完成”。资源方面重点关注浏览器实例数量、内存占用和并发数。不要一上来就开十个浏览器实例并行验证很可能把测试环境搞崩。我一般先用单实例跑确认稳定后再压到 2 到 3 个并发观察测试应用和 Agent 运行环境的负载。如果技能用于定时回归比如每天一次反而没必要追求高并发。稳定大于速度。如果用于 Agent 对话中的即时验证则要控制单次执行时间尽量在 30 秒内给出结果否则用户体验很差。6. 常见问题与排查链路6.1 Agent 调用验证技能时报错先看现象再看输入再看环境最后改技能。现象层面是技能没有被调用还是被调用了但执行报错如果 Agent 直接回复“我已完成”但没有执行验证技能很可能是技能描述不清晰Agent 没有把该任务识别为验证场景。这时调大 description 的关键词覆盖范围。如果技能确实被调用了但执行报错先看返回错误是超时、选择器失败、还是参数缺失。超时优先看网络和页面加载速度选择器失败优先看页面结构参数缺失优先看 Agent 传参是否正确。6.2 验证结果误报先看选择器和等待条件验证结果不稳定经常是以下原因之一。选择器不稳定。很多前端组件会生成动态 id比如iduser-23232。这类选择器不能用于断言否则下一次执行很可能找不到元素。优先使用稳定的属性或文本定位。等待条件不合适。固定写死 sleep 3 秒是硬伤。页面慢时 3 秒不够页面快时又白白等待。改成等待某个元素出现、等待 URL 变化、等待接口返回。同页面有多个相同元素。比如页面上有多个“确定”按钮定位时要用更具体的上下文比如指定某个弹窗范围内的确定按钮。排查顺序是先看截图确认执行到哪一步再看日志确认等待条件是否生效最后打开页面手工看元素确认选择器仍然存在。6.3 验证技能卡在某个步骤卡住通常不是技能逻辑写错了而是外部因素变化。优先检查目标应用是否可访问。常见情况应用服务重启后地址变了、测试环境过载、页面出现验证码。第二检查 Agent 运行环境。容器里没有浏览器依赖、磁盘写满、截图目录权限不足都会导致卡在等待阶段。第三检查并发冲突。多个验证任务使用同一个测试账号一个把另一个的会话踢下线就可能导致操作到一半页面跳回登录页。排查时看一下有没有其他任务在同时运行。6.4 安全合规操作验证技能也是程序执行时要注意数据安全。不要在技能文件里留真实密码、生产密钥、身份证号、手机号。测试环境要用脱敏数据。涉及删除、修改数据的验证流程尽量用测试专用数据并且增加二次确认。比如技能里可以做一个 require_confirm 开关默认关闭只让 Agent 在明确需要时传入 true。如果应用启用了验证码或风控不要想着绕过。正确做法是在测试环境关闭验证码或者使用专门的测试通道。安全红线不能碰验证技能也一样。最后我个人的建议是验证技能真正落地时最该盯住的不是它能覆盖多少页面而是单个验证流程是否稳定、断言是否贴近真实用户、失败时能不能快速定位。先把一条登录链路跑稳再逐步扩到复杂业务流比一次性铺开大量用例更稳妥。
返回列表