大数跨境

Cogent 测试智能体插件:30+ 个浏览器工具,让智能体的执行力直接起飞

Cogent 测试智能体插件:30+ 个浏览器工具,让智能体的执行力直接起飞 慧测
2026-03-20
3
导读:大模型应用软件测试全栈:https://huicewang.com/testing/ 上一篇拆解了 AI 指

大模型应用软件测试全栈:https://huicewang.com/testing/ 


上一篇拆解了 AI 指令从 智能体到 DOM 操作的完整通信链路。这篇聚焦在工具层本身:MCP Server 的运行机制是什么,Cogent 开发了哪些工具,哪些工具是核心,背后的设计思路是什么。

工具的本质:一份给 AI 看的 JSON 契约

每个工具在 MCP 层都是一个结构固定的对象,三个字段缺一不可:

{
  name'page_navigate',
description'在当前标签页导航到指定 URL。适用于打开新页面或跳转链接',
inputSchema: {
    type'object',
    properties: {
      url: { type'string'description'URL地址' },
      waitUntil: {
        type'string',
        enum: ['load''domcontentloaded''networkidle'],
        description'等待条件:load=页面完全加载(默认);domcontentloaded=DOM就绪;networkidle=网络空闲',
        default'load'
      }
    },
    required: ['url']
  }
}

name 是工具的唯一标识;description 是给 AI 看的语义说明,AI 根据这段文字决定什么时候调用这个工具——这不是注释,是 Prompt 的一部分;inputSchema 是参数规范,AI 按照这个生成调用参数。

整个 mcp-server.js 里定义了 50+ 个工具,分属 9 个类别,按需开关:

const TOOL_CONFIG = {
basictrue,           // 基础页面操作
stabletrue,          // 稳定版(SPA 适配)
storagetrue,         // Cookie 管理
networktrue,         // 网络监控
smart_extractiontrue,// 智能文本提取
automationtrue,      // DSL 自动化脚本
exporttrue,          // 数据导出
tabstrue,            // 标签管理
extractionfalse,     // 旧版提取工具(默认关闭)
bookmarksfalse,      // 书签管理(默认关闭)
};

类别开关之外还有例外配置——即使类别启用,也能精确禁用某几个工具,不用改一行实现代码。

调用链路:从 AI 发出请求到浏览器执行

一次工具调用经历四层:

AI 客户端
    ↓ tools/call (JSON-RPC over HTTP)
MCP Server (3003端口)
    ↓ actionMap 映射
Native Messaging 管道 (chrome-native-messaging)
    ↓ 消息路由
Background Service Worker
    ↓ DOM操作 → Content Script / 特权API → Background 直接执行

第一层:MCP 协议处理

MCP Server 只暴露三个端点:

POST /mcp   → 处理所有 JSON-RPC 请求(初始化、工具列举、工具调用)
GET  /mcp   → 建立 SSE 长连接,服务器主动推送通知
DELETE /mcp → 终止会话,清理资源

每个会话有独立 ID,服务端维护 sessions Map,会话 30 分钟超时自动清理。AI 客户端第一次请求触发 initialize,拿到 sessionId;随后 tools/list 拉取工具列表;之后每次调用都是 tools/call

第二层:actionMap 名称转换

MCP 层的工具名和插件内部执行的 action 名是两套体系,callTool 函数里有一张完整的映射表:

const actionMap = {
'page_navigate':          'navigate',
'page_get_dom_smart':     'get_dom_optimized',
'page_operate_by_ref':    'operate_by_ref',
'page_fill_form':         'fill_form',
'page_execute_script':    'execute_script',
'storage_get_cookies':    'get_cookies',
'network_get_api_calls':  'get_api_calls',
'tab_list':               'list_tabs',
'page_run_dsl_script':    'run_dsl_script',
// ... 50+ 条映射
};

MCP 层命名追求语义清晰、前缀一致(page_storage_network_tab_);内部 action 名是历史命名,内部重构不影响外部接口,两套体系互不干扰。

第三层:Native Messaging 通信

MCP Server 通过 chrome-native-messaging 库和浏览器插件通信。这个库封装了 Chrome Native Messaging 协议的 4 字节长度前缀格式,发送和接收都通过 stdout/stdin 流。

每个请求分配自增 ID,用 Promise + 超时(30 秒)机制等待响应:

async callExtension(action, params) {
  return new Promise((resolve, reject) => {
    const id = ++this.messageId;
    const timeout = setTimeout(() => reject(new Error('调用超时')), 30000);
    this.messageHandlers.set(id, { resolve, reject });
    this.sendToExtension({ type'request', id, action, params });
  });
}

第四层:Background 路由分发

Background 收到消息后判断执行位置:需要访问 DOM 的工具转发给 Content Script,需要 chrome.tabschrome.cookies 等特权 API 的工具直接在 Background 执行。

核心工具详解

DOM 获取 + 元素操作:最重要的两个工具

page_get_dom_smart + page_operate_by_ref 是整个工具集的基石,几乎所有复杂页面操作都依赖这对组合。

page_get_dom_smart 提取页面所有可交互元素,每个元素附带唯一 ref 编号:

// 返回的元素格式
ref'e42'tag'button'role'button'text'提交'selector'#submit-btn' }

page_operate_by_ref 拿着 ref 编号直接操作,支持 click / input / select / focus / scroll:

{
  name'page_operate_by_ref',
  description'通过 page_get_dom_smart 返回的 ref 编号精确操作元素。比 CSS 选择器更稳定可靠,是复杂页面的首选操作方式',
  inputSchema: {
    properties: {
      ref: { type'string' },
      operation: { type'string'enum: ['click''input''select''focus''scroll'] },
      value: { type'string' }
    },
    required: ['ref''operation']
  }
}

为什么用 ref 而不是 CSS 选择器?现代 SPA 页面大量使用构建时生成的动态 class 名(比如 btn-a8f3c2d),每次打包都会变。ref 是当前页面快照里临时分配的稳定编号,不依赖任何 DOM 属性,天然抗变化。

表单填写:React/Vue 受控组件的正确打开方式

直接设置 element.value = 'xxx' 在 React/Vue 受控组件里不起作用——框架有自己的状态管理,绕过框架改 DOM 值,框架感知不到。

page_fill_form_element 模拟真实用户输入的完整事件序列:focus → input 事件 → change 事件 → blur。支持所有表单类型:text、password、email、checkbox、radio、select、contenteditable(富文本编辑器)。还有 fallbackSelectors 机制——主选择器失败时依次尝试备用列表,同一套脚本在多个环境版本都能跑通。

page_fill_form 是批量版本,一次传入多个字段,字段间有可配置延迟,提供统一的成功/失败报告:

// 一次调用搞定整个登录表单
{
  formData: [
    { selector'#username'value'test@example.com'type'email' },
    { selector'#password'value'password123'type'password' }
  ],
  delay100  // 字段间 100ms 延迟,模拟真实输入节奏
}

稳定版工具:为 SPA 页面设计的容错版本

基础工具假设页面元素随时可用,对静态页面没问题。但 React/Vue 的 SPA 页面经常有异步加载、骨架屏、动画过渡,基础工具时机不对会直接扑空。

稳定版工具在操作前会等待元素进入可操作状态,失败后自动重试:

  • page_click_stable:自动等待元素可见可点击,失败自动重试
  • page_input_stable:等待输入框可编辑,输入后验证内容是否生效
  • page_scroll_stable:滚动后等待内容加载完成,适合无限滚动页面
  • page_wait_stable:支持等待元素出现或自定义 JS 条件,超时 30 秒

工具 description 里明确写了适用场景,AI 会自己判断用哪个版本。

网络监控:给 AI 装上抓包能力

这组工具让 AI 能看到页面产生的网络请求,是纯 UI 操作工具做不到的。

network_start_monitor 基于 chrome.webRequest API 启动监控,持续记录 URL、Method、状态码、耗时、请求头、响应头。network_get_api_calls 是便捷封装,自动过滤出 XHR/Fetch 类型的接口调用:

{
  name'network_get_api_calls',
  description'获取 API 接口请求(自动筛选 xmlhttprequest/fetch 或 URL 含 /api/ 的请求),可额外传 urlPattern 正则进一步缩小范围',
}

典型用法:执行一个操作前后各抓一次接口记录,对比验证接口是否如预期触发、响应数据是否正确。

Cookie 管理:跳过登录流程直取测试入口

storage_set_cookie 写入 Cookie,storage_get_cookies 读取,storage_clear_cookies 批量清除。

核心价值在于:测试开始前注入已有的 session token,跳过登录流程直接进入被测页面,把每次测试的准备时间从几十秒压缩到接近零。

智能文本提取:语义理解而非盲目抓取

传统文本提取靠 CSS 选择器指定容器,换个网站就要重写。智能提取先理解页面结构,再按语义范围提取。

detect_page_regions 识别页面语义分区(主内容、导航、侧边栏、评论、页眉、页脚),返回结构概览。extract_text_smart 按范围提取:

{
  scope: {
    enum: ['full-page''main-content''article''navigation''sidebar''footer''header''comments''custom']
  }
}

extract_structured_content 更进一步,自动识别页面类型并提取对应字段——文章页提取 title/author/publishDate/content/tags,商品页提取 name/price/description/specs/rating/reviews,论坛帖子提取楼层列表。

DSL 自动化脚本:把 N 次调用压缩成 1 次

page_run_dsl_script 支持 AI 一次性提交一段脚本,按顺序执行多步操作:

- navigate:https://example.com/login
-wait:"#username"
-input:
    selector:"#username"
    text:testuser@example.com
-input:
    selector:"#password"
    text:password123
-click:"#login-btn"
-wait:".dashboard"
-screenshot

在流程固定的场景(登录、表单提交、导航序列),AI 和工具之间的来回次数从 N 次减少到 1 次。脚本支持 YAML 和 JSON 两种格式,YAML 更易读,JSON 适合程序生成。

标签管理:多标签页协调作战

tab_list 列出所有标签页(含 tabId、标题、URL、激活状态)。tab_switch 支持四种定位方式:tabId 精确定位、index 按位置、url 精确匹配、title 模糊匹配。

有了这组工具,AI 可以在多个标签页之间来回切换——在一个标签页里登录,在另一个标签页里执行测试,再切回来验证结果。

智能选择器工具:自动化脚本的可靠性保障

selector_generate_robust 为指定元素生成多个稳定的 CSS 选择器,优先使用 ID / data-* / ARIA 属性,按稳定性评分排序,附带备用选择器。selector_evaluate_stability 评估现有选择器的稳定性(0-100分),检测动态类名、位置依赖等潜在问题。

这两个工具主要面向"生成自动化测试脚本"的场景——AI 在写测试脚本时先评估选择器稳定性,不稳定的自动替换为更健壮的版本。

工具描述:Prompt 工程,不是写注释

description 字段直接进入 AI 的推理上下文,影响 AI 的工具选择和参数生成。写工具 description,本质上是在做 Prompt 工程。

看 page_get_dom_smart 的 description:

获取页面可交互元素列表(按钮/输入框/链接/下拉框等),每个元素附带唯一 ref 编号、CSS 选择器和角色信息。配合 page_operate_by_ref 使用

主动告诉 AI"拿到 ref 之后用配套工具操作",引导 AI 走正确的调用路径,而不是自己构造 CSS 选择器去试。

再看 page_click 和 page_click_stable 的描述:

page_click:若页面复杂或选择器不唯一,优先用 page_get_dom_smart 获取 ref 后改用 page_operate_by_ref
page_click_stable:适合动态加载、SPA页面;普通页面用 page_click 即可

两个工具互相说明对方的适用场景,AI 在选择时自然就会权衡。

再看 extract_text_smart 的 description,直接内嵌了用户意图到 scope 参数的映射规则:

AI 根据用户意图选择 scope:说"获取所有文本"→ full-page;"提取主要内容"→ main-content;"获取文章"→ article

有了这段描述,AI 不需要额外推理就能精准选参。

市面上很多 MCP 工具实现不差,但 description 写得含糊,AI 用起来总是出错。工具开发有一半是工程问题(怎么实现),另一半是 Prompt 工程问题(怎么让 AI 在正确的时候调用、用正确的参数调用)。

工具开发的三步规律

读完这套工具集,可以总结出一条规律:每增加一类工具,背后都对应一类浏览器自动化的具体痛点。

基础工具 → 稳定版工具,解决的是异步页面的时机问题。静态页面和 SPA 页面的行为差异大到需要两套工具来覆盖。

page_input → page_fill_form_element,解决的是框架受控组件的兼容问题。看似同一个功能,底层实现完全不同。

CSS 选择器 → ref 编号,解决的是 SPA 动态 class 名的稳定性问题。旧的工具没有废弃,而是在描述里引导 AI 优先使用新工具。

每一类问题都值得单独一篇来展开讲。下一篇会换个方向:当 AI 不只是操控浏览器,而是要理解测试意图、生成测试用例的时候,整个系统是怎么工作的。

欢迎进群技术交流

huice666
图片
danwen668




【声明】内容源于网络
0
0
慧测
专注人工智能前沿技术落地企业实战应用
内容 404
粉丝 0
慧测 专注人工智能前沿技术落地企业实战应用
总阅读104
粉丝0
内容404