AI Agent验证技能:从创建到维护的完整实践指南

发布时间:2026/9/1 16:41:16
AI Agent验证技能:从创建到维护的完整实践指南 在实际的 AI Agent 工程里模型能给出方案是一回事Agent 能确认“应用确实按预期工作了”又是另一回事。很多团队在搭建 Agent 时重点放在规划、工具调度、多轮对话上但最后验收环节仍然依赖人工点击页面或者维护一批不断失效的临时脚本。pstack 新增的创建与维护验证技能解决的是这个容易被忽略的断层把验证能力变成 Agent 技能体系里的一等公民让 Agent 可以像真实用户一样打开应用、操作关键路径、观察页面反馈、给出可复用的验证结论。这篇文章面向正在做 AI Agent 开发、需要为 Agent 补充端到端验证能力或者希望把应用验证流程自动化治理起来的开发者。全文会先解释技能与验证技能的区别再从最小验证技能入手完成创建、注册、调用、结果返回的完整链路然后重点说明维护技能时的版本控制、失败分类和排错路径。文中的代码和命令属于通用示例落地时结合你使用的 pstack 版本、包名和项目结构调整。1. 先理解“技能Skill”在 Agent 体系中的位置1.1 技能是模型判断和确定性执行之间的中间层大语言模型擅长的是意图理解、任务拆解和文本生成但它不擅长每次都稳定地完成同一套精确操作。比如“检查登录流程是否正常”这件事模型知道要访问地址、填写账号、点击按钮可如果让它自由发挥每次输入的字段、等待方式、成功条件都可能不一致结果也就不具备可比性。技能Skill的存在就是把这类“已经明确做什么、按什么顺序做、怎样算成功”的流程固化下来。模型只负责决定“要不要调用这个技能、传入什么参数”技能内部则是确定性的代码、配置和执行步骤。这样做的好处有三个结果可复现同一套技能在相同输入下每次执行逻辑一致。行为可审查技能内容可以被阅读、测试和版本管理。反馈可回归技能更新后能重新执行确认没有破坏既有验证能力。在 pstack 这类技能管理体系中技能不是一段孤立的脚本而是带有元信息、输入声明、执行入口、输出结构的完整单元。1.2 验证技能和普通技能到底差在哪里在 Agent 项目里很多技能属于“动作型技能”例如查询天气、创建工单、调用搜索接口。它们的核心目标是完成动作并返回结果。验证技能虽然也执行动作但核心目标完全不同它要回答“当前应用是否满足预期”。这个区别会直接影响技能设计方式。动作型技能在调用失败时通常只需要把异常返回给 Agent验证技能失败时则必须进一步判断是应用本身有 Bug是技能里的选择器过期还是依赖环境不稳定。这个分类决定了技能该由谁来修、怎么修。下面的表格可以用于快速区分两种技能的设计差异。维度动作型技能验证型技能核心目标完成某个业务动作判定应用行为是否符合预期输入用户请求、业务参数应用地址、测试数据、预期条件输出动作结果、返回信息状态、证据、断言结果、可读说明失败处理返回错误信息区分应用问题、技能问题、环境问题更新驱动业务需求变化应用页面结构变化、交互变化、数据变化复用重点动作可复用验证逻辑和判定规则可复用1.3 pstack 新增“创建与维护验证技能”要解决什么问题从实操经验看团队里最容易出问题的不是写不出验证脚本而是验证脚本散落各处、没有统一生命周期。今天这里加一个临时脚本明天那里改一个断言时间一长没有人知道哪些验证还在生效哪些已经悄悄过期。pstack 这类技能框架正是为了收敛这个问题。它提供的是创建入口用统一结构定义验证技能包括元信息、输入参数、执行步骤和输出格式。注册管理把技能纳入统一列表支持查询、启用、停用和版本管理。执行调度由技能运行器根据 Agent 传入的参数执行技能并返回结构化结果。维护能力技能可以被升级、对比、回滚失败信息可以被记录和追踪。所以“创建与维护验证技能”并不是多了一个测试框架而是让验证能力成为 Agent 工具链中可以管理和演进的组成部分。2. 创建验证技能前先把“像真实用户验证应用”拆成能力项2.1 真实用户验证应用时关注哪些检查点写验证技能前先不要急着写代码而是把真实用户在应用里会重点验证的事情列出来。通常不会只有“页面能打开”这一项至少包含以下类别入口可达应用地址能访问登录态能建立没有 500 和网络错误。核心链路通顺注册、登录、创建资源、查询列表等主流程能够走通。页面反馈正确按钮可点击表单提交后有跳转、提示或状态更新。数据准确列表展示的数据、表单提交后的落库结果和页面展示一致。异常场景合理输入错误时有明确提示不会出现卡死或白屏。验证技能的价值就是把这类“用户觉得没问题”的模糊判断用代码和断言转换为可检查、可重试、可留证的具体行为。2.2 验证技能的最小执行闭环一个可运行的验证技能至少要包含五个阶段准备接收外部传入的应用地址、账号、预期条件等参数。执行打开应用并按照真实用户路径操作。等待等待异步请求和页面渲染完成。捕获记录页面 URL、标题、截图、关键元素状态。断言对捕获结果和目标预期进行比较输出 PASS 或 FAIL。这个闭环是验证技能的最小骨架。骨架稳定后再针对不同业务增加更多检查点例如校验接口返回、检查数据库落库结果、调用第三方系统后验证回调。2.3 环境准备与依赖选择创建验证技能前先确认运行环境。不同团队会使用不同技术栈本文给出的是一套常用的最小环境用于说明思路不代表唯一选型。资源推荐版本用途说明操作系统Linux/macOS/Windows运行技能生产环境建议 Linux 容器Python3.10编写验证逻辑选择 Python 仅作示例也可用 Node.jsPlaywright保持最新稳定版浏览器自动化需要安装对应浏览器内核requests 或 httpx稳定版接口调用和响应断言根据技能类型选择pstack 技能运行器按项目版本注册和执行技能命令以实际版本为准环境配置完成后建议先跑一个最小 Playwright 示例确认浏览器内核可以正常启动再进入技能创建环节。3. 从零创建一个登录流程验证技能3.1 技能目录结构与元信息定义验证技能建议使用独立的目录结构。这里以“验证登录流程”为例技能目录结构如下verify_login_skill/ ├── skill.yaml ├── verify_actions.py ├── assertions.py └── README.md其中skill.yaml用于声明技能的元信息和运行参数verify_actions.py是执行动作的主脚本assertions.py负责把预期条件拆成可复用函数README.md记录维护历史和使用方式。在skill.yaml中用 YAML 方式定义技能。一个最小示例name: verify_login_flow description: 验证 Web 应用登录主流程是否符合预期包括打开页面、提交登录表单、等待跳转并捕获结果 version: 1.0.0 inputs: base_url: type: string required: true description: 应用首页地址 username: type: string required: true description: 登录账号 password: type: string required: true description: 登录密码 secret: true expected_redirect: type: string required: false default: /dashboard description: 登录成功后期望跳转的路径 steps: - open_page - fill_login_form - submit_login_form - wait_redirect - snapshot_page - assert_result output: status: string evidence: object message: string这里有几点值得注意。description不只是给人看的它会被 Agent 用于技能选择所以必须写清楚“这个技能验证什么、什么时候该调用”。“我建议把password标记为 secret避免在日志和技能输出中暴露密码。steps描述的是执行顺序便于排查时定位是哪一步出问题。3.2 动作执行层代码动作执行层负责控制浏览器完成真实用户的操作路径。这里以 Playwright 的同步 API 为例from playwright.sync_api import sync_playwright class LoginVerifier: def __init__(self, base_url, username, password, expected_redirect): self.base_url base_url.rstrip(/) self.username username self.password password self.expected_redirect expected_redirect or /dashboard def run(self): with sync_playwright() as p: browser p.chromium.launch(headlessTrue) page browser.new_page() try: page.goto(self.base_url, timeout15000) page.fill([nameusername], self.username) page.fill([namepassword], self.password) page.click(button[typesubmit]) page.wait_for_url( f{self.base_url}{self.expected_redirect}, timeout10000 ) snapshot { url: page.url, title: page.title(), screenshot_hex: page.screenshot(full_pageTrue).hex(), } return { status: PASS, evidence: snapshot, message: login redirect ok, } except Exception as exc: return { status: FAIL, evidence: { url: page.url, title: page.title(), }, message: str(exc), } finally: browser.close()动作执行层有几个设计要点headlessTrue是为自动化运行准备的适合 CI 和 Agent 调用如果需要排查渲染问题可以临时改为headlessFalse。使用wait_for_url而不是固定time.sleep是为了避免网络波动时固定等待时间不足或过长。捕获截图并转换为十六进制字符串是为了把证据随结果返回后续可以存储或解析。finally中必须关闭浏览器否则长时间运行的 Agent 会产生大量残留进程。3.3 断言层把用户预期变成可判定条件断言层尽量独立成模块不要在动作脚本里到处写if判断。这样当登录场景的断言逻辑被其他技能复用时可以直接引用。# assertions.py def assert_redirect(page_url, expected_url): return page_url.rstrip(/) expected_url.rstrip(/) def assert_page_has_key_elements(page, selectors): missing [] for selector in selectors: if page.locator(selector).count() 0: missing.append(selector) return missing这段代码定义了两种常见断言比较最终跳转地址是否符合预期检查页面上是否存在关键元素。这里刻意把断言拆成了返回布尔值或缺失列表的小函数而不是在函数内直接抛异常。原因在于验证技能的结果最好以结构化数据返回给 Agent异常更适合用于中断执行而不是作为最终判定结果。3.4 在 pstack 中注册并运行验证技能把技能目录准备好后需要将技能注册到 pstack。下面的命令是通用示意实际命令名以你使用的 pstack 版本为准。pstack skill add verify_login_flow \ --manifest ./skill.yaml \ --entry verify_actions.py注册完成后可以先查看技能列表确认元信息是否正确加载pstack skill list然后运行一次技能传入登录验证需要的参数pstack skill run verify_login_flow \ --param base_urlhttp://localhost:8080 \ --param usernametest_user \ --param passwordsecret这一步是验证链路的关键检查点。如果技能能成功注册并运行说明技能的基础结构已经打通后续要做的是逐步把更多断言和更多应用场景加入技能。3.5 运行结果分析一次成功运行的结果可能是这样的{ status: PASS, evidence: { url: http://localhost:8080/dashboard, title: 控制台, screenshot_hex_length: 88230 }, message: login redirect ok }从这个结果可以看到Agent 并不需要重新打开浏览器去理解页面它可以直接根据status判断结论根据evidence提供佐证根据message向用户说明原因。如果结果是 FAIL那么 message 中会包含异常信息例如Timeout 10000ms exceeded waiting for expected url。此时需要进入排查环节而不是简单地把技能标记为不可用。4. 让 Agent 正确调用验证技能关键在设计输入输出协议4.1 技能描述决定了 Agent 能否选对技能Agent 选择技能时主要依赖技能名称和 description。如果描述写得过于笼统例如“验证应用”Agent 在遇到登录验证、购物车验证、权限验证等多个技能时就无法区分该调用哪一个。推荐描述写法是“场景 验证对象 判断条件”。例如验证 Web 应用登录主流程是否符合预期包括打开页面、提交登录表单、等待跳转并捕获结果这个描述既告诉 Agent 技能适用的应用类型也说明了技能内部会做什么。保持描述语义稳定也很重要频繁修改技能描述会导致 Agent 的行为不稳定。4.2 返回结果必须包含判定、证据和消息验证技能给 Agent 的返回值至少应该分成三类信息判定状态PASS、FAIL、UNKNOWN。PASS 表示预期通过FAIL 表示验证不通过UNKNOWN 用于表示技能无法得出明确结论。证据材料页面 URL、标题、截图、控制台日志等供人审阅和后续排查。可读说明用一句话解释为什么通过或失败。字段用途示例值statusAgent 做决策的主要依据PASSevidence给人和 Agent 的佐证材料url、title、screenshotmessage面向阅读者的可读原因login redirect okrun_id可追踪本次执行的日志 IDrun_20260801_183012_9f2a把 run_id 放入返回值非常有用。后续需要排查时可以通过 run_id 查看技能执行日志而不需要用户重新复述现象。4.3 关键参数与默认值设计验证技能的参数设计会影响执行稳定性。常见参数和推荐默认值如下参数含义默认值调大影响调小影响推荐场景timeout单步操作超时时间10s更能容忍慢接口能更快发现卡死按接口 P95 耗时设置retries技能级重试次数1能处理偶发抖动可能掩盖稳定问题生产环境保留 1 到 2 次headless是否无头运行浏览器true便于观察真实渲染执行更快但不便调试CI 和 Agent 调用使用 truescreenshot是否截图留证true证据更完整减少存储占用验证关键流程时开启参数并不是越大越好。超时设置过长Agent 会长时间等待重试设置过多一次真实的应用故障会被重试掩盖成“不稳定”。建议把重试控制在 1 到 2 次并且把重试后的结果连同首次失败原因一起保留。5. 验证技能的维护链路与一次真实变更演练5.1 维护的驱动力来自哪里创建验证技能只是项目开始。真正让技能长期有价值的是维护。应用会持续迭代页面结构调整、按钮文案变化、登录方式升级都会让验证技能失效。如果不建立维护链路技能会在某个版本迭代后彻底失去作用。维护的驱动力通常来自三个方向应用变更前端重构、接口变更、登录策略升级。验证反馈技能持续返回 FAIL需要归类根因。业务演进验证范围需要覆盖新模块和新流程。无论是哪种驱动力都会落到一个动作上更新技能并发布新版本。5.2 失败分类是维护的起点技能返回 FAIL 时不要直接改代码。先完成失败分类。通常可以分成三类应用 Bug应用本身行为不符合预期技能是对的需要修复应用。技能失效应用行为正常但技能的选择器、等待条件或断言逻辑过期。环境不稳定网络抖动、测试数据缺失、外部依赖变更导致失败。三者的处理方式完全不同。应用 Bug 应该进入开发修复流程技能失效需要更新技能环境不稳定要先恢复环境再重跑。5.3 页面结构变化导致的修复过程假设登录表单的输入框从原来的[nameusername]改成了#email-input技能会执行fill时超时返回结果类似Timeout 30000ms exceeded waiting for locator(input[nameusername])此时先检查页面 DOM确认输入框选择器确实已经变化然后更新verify_actions.pypage.fill(#email-input, self.username)同时更新版本号和变更说明version: 1.0.1 changelog: - 修复登录页输入框选择器变更username 改为 email-input再把更新后的技能重新注册pstack skill upgrade verify_login_flow \ --manifest ./skill.yaml \ --entry verify_actions.py这里的关键不是换一个选择器而是把“为什么换”记录下来。如果不记录下一次页面结构变化时维护人员仍然需要重新猜测选择器变更的原因。5.4 技能版本管理和同步验证技能应该像业务代码一样做版本管理。版本号递增规则建议采用三段式主版本号变化表示验证流程整体重构次版本号变化表示新增验证步骤或断言补丁版本号变化表示修复选择器、超时等细节。技能版本更新后还要注意 Agent 端的技能索引同步。如果 Agent 在选择技能时依赖注册中心里的描述升级技能后需要同步最新的描述和参数否则 Agent 可能仍然按旧描述选择技能导致参数传入错误。6. 常见问题与排错链路6.1 排错顺序验证技能出问题时建议按以下顺序排查不要一开始就怀疑是框架或模型的问题检查技能入参是否匹配尤其是 base_url、账号、预期跳转地址。检查应用环境是否可达直接访问页面看是否正常。检查选择器是否过期对比页面 DOM 和技能里的定位表达式。检查等待条件是否合理确认是否存在固定等待导致的不稳定。检查权限和登录态确认测试账号是否被失效、锁定或缺少权限。检查 Agent 层是否传错参数查看 Agent 调用技能时实际传入的 JSON。查看技能执行日志定位到具体失败步骤。6.2 典型问题对照表问题现象常见原因检查方式处理建议技能返回 FAIL提示元素超时选择器过期或应用响应慢打开页面检查 DOM抓包看接口耗时更新选择器或调大该步骤 timeout技能能跑但不被 Agent 调用description 不清晰查看技能列表中的描述文本重写描述并同步技能索引同一技能时而 PASS 时而 FAIL外部依赖不稳定对比多次运行的日志和返回时间区分只读步骤和可重试步骤合理设置 retries本地运行通过生产环境失败环境和数据差异对比 base_url、表单项、登录账号使用独立测试数据维护单独技能配置技能执行很快但断言总是失败断言条件过于严格或过期查看断言函数的预期值重新确认业务预期条件6.3 Agent 调用验证技能超时另一种常见问题是 Agent 调用技能时超时。这通常表现为 Agent 侧报错例如执行超时但技能脚本本身可能还在运行。可能原因有两个技能执行链路太长或者 Agent 的超时阈值设置得太短。处理方式有两种把一个大技能拆成多个小技能让单个技能在较短时间内完成验证。把技能执行改为异步任务先触发执行后续通过回调或查询结果获取验证结论。在电商下单等长流程场景推荐使用异步方案避免 Agent 在等待期间阻塞后续任务。6.4 日志和证据的保留验证技能运行后建议保留三类证据技能输出结果、浏览器截图、步骤级日志。日志中要记录技能版本、入参、出参、失败步骤和耗时。这样当应用方质疑验证结果时可以直接通过 run_id 回溯完整过程。7. 生产环境中的验证技能维护建议7.1 学习环境与生产环境的差异很多团队在演示环境把验证技能跑通后就直接拿到生产环境使用结果发现各种不稳定。原因是两者对验证技能的要求完全不同。维度学习环境生产环境运行方式手动运行单个技能CI 触发、平台定时触发、Agent 按需调用测试数据固定账号和数据独立测试账号、动态数据隔离超时配置可以放宽方便调试必须设置上限避免资源占用技能更新直接改文件走版本评审、灰度、回滚机制监控看命令行输出看失败率、时长、错误类型告警证据保留可临时保存需要设置保留周期和存储策略7.2 可复用的验证技能维护清单在团队里维护验证技能时以下清单可以直接作为发布前的检查参照每次应用发布后至少跑一遍核心流程的验证技能。技能更新后version 必须递增并更新 changelog。技能返回 FAIL 时先归类为应用问题、技能问题还是环境问题再决定处理方式。不要把测试账号密码硬编码进技能文件改成从配置或密钥系统读取。技能运行结果要保留截图和日志设置合理的保留周期。技能描述保持稳定只在语义确实变化时更新。每周检查一次技能失败率连续失败超过阈值时要优先排查。移除不再使用的验证技能避免 Agent 在技能列表里选错对象。7.3 接下来可以扩展的方向验证技能从单点场景走向覆盖更多业务后有几个扩展方向值得关注。多步骤复合验证把“注册到登录再到创建资源”合并为一个长链路技能但要保证单个步骤的失败信息可定位。移动端验证使用移动端自动化能力让 Agent 验证原生应用的登录、推送和权限弹窗。与 CI/CD 集成把验证技能的运行结果回传到代码评审和发布平台让 Agent 自动检查版本质量。多 Agent 协作一个 Agent 负责规划验证策略多个验证技能并行执行再汇总结果。此时每个技能的返回结构必须足够规整方便汇总层解析。验证技能在 Agent 体系里的价值并不体现在“写出来能跑”的那一刻而是体现在应用不断迭代时它仍然能稳定地告诉 Agent 和应用团队现在这个版本的核心流程是否真的可用。pstack 提供的创建与维护能力把验证技能从临时脚本变成了可以被注册、版本化、修复和演进的一部分 Agent 基础设施。对团队来说最值得投入的不是第一次把技能跑通而是把从失败反馈到技能更新的闭环建立起来让验证技能真正伴随应用长期保持有效。