写点什么

Chrome 推出 WebMCP 标准提案(Origin Trial):为智能体提供原生 Web 操作能力

作者:Bruno Couriol
  • 2026-06-18
    北京
  • 本文字数:4544 字

    阅读完需:约 15 分钟

谷歌近日宣布,WebMCP 已进入 Chrome 149 的 Origin Trial 阶段。WebMCP 是一项新的标准提案,它允许网站向浏览器内的 AI 智能体暴露可调用工具,例如 JavaScript 函数或 HTML 表单。这样一来,智能体便可以通过明确的接口完成用户操作,而不再需要依赖成本高昂且可靠性有限的“猜测式”交互方式,例如读取屏幕内容或解析 DOM 结构。

谷歌这样解释 WebMCP 的设计初衷:

通过定义这些工具,你可以明确告诉智能体应该如何以及在何处与网站交互。这样一来,智能体便能够调用面向机器的接口,在数秒内完成复杂任务,同时获得更高的可靠性、准确性和个性化能力。举例来说,假设用户正在规划一次多城市旅行。过去,用户只能看着智能体一步步填写旅行表单;而现在,用户可以授权智能体直接调用后端 API,瞬间生成结合天气因素优化过的个性化行程方案,并提交给用户确认。

在没有 WebMCP 的情况下,如果 AI 智能体希望代表用户完成某项操作,通常需要经历一套相当复杂的流程:首先下载相关网页的 DOM,然后分析页面中的按钮和控件作用,接着截取页面截图并进行图像识别。最后推断目标按钮在屏幕上的坐标位置,并模拟鼠标点击。正如业内经常提到的那样,这种方式不仅不够确定,而且 Token 消耗极高。一个简单的 CSS 布局变化,或者一个加载稍慢的广告组件,都可能导致整个自动化流程失效。与此同时,即便是低分辨率截图,其图像分析过程也会带来额外延迟和大量 Token 开销。

与主要面向后端场景的模型上下文协议(MCP)类似,WebMCP 也允许网站为 AI 智能体提供明确的接口,从而让其能够代表用户完成个性化任务。但两者的定位并不相同。WebMCP 完全运行在客户端侧,专门为浏览器环境设计,因此省略了 MCP 中许多服务器端概念,例如 Resources。从本质上讲,WebMCP 的目标是帮助智能体更可靠地理解 Web 界面。开发者可以通过定义 API,为智能体提供一组带有名称、类型和说明的操作菜单,让其直接调用,而不是依赖对页面结构的推测。

WebMCP 规范目前定义了两种 API 形式。第一种是声明式 API(Declarative API)。它允许开发者直接在现有 HTML 表单上添加自定义属性

<pre class=" language-html"><code class="prism  language-html"><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>form</span>  <span class="token attr-name">toolname</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>Search flights<span class="token punctuation">"</span></span>  <span class="token attr-name">tooldescription</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">"</span>This form searches flights and displays [...]<span class="token punctuation">"</span></span>  <span class="token attr-name">toolautosubmit</span><span class="token punctuation">&gt;</span></span></code></pre>
复制代码

第二种是命令式 API(Imperative API)。它通过 modelContext 接口注册工具。注册工具时需要提供工具名称、描述以及输入参数 Schema:

pre class=" language-js"><code class="prism  language-js">document<span class="token punctuation">.</span>modelContext<span class="token punctuation">.</span><span class="token function">registerTool</span><span class="token punctuation">(</span><span class="token punctuation">{</span>  name<span class="token punctuation">:</span> <span class="token string">'toggle_layer'</span><span class="token punctuation">,</span>  description<span class="token punctuation">:</span> <span class="token string">'Control pizza layers (sauce, cheese). Use "add", "remove", or "toggle".'</span><span class="token punctuation">,</span>  inputSchema<span class="token punctuation">:</span> <span class="token punctuation">{</span>    type<span class="token punctuation">:</span> <span class="token string">'object'</span><span class="token punctuation">,</span>    properties<span class="token punctuation">:</span> <span class="token punctuation">{</span>      layer<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> <span class="token string">'string'</span><span class="token punctuation">,</span> <span class="token keyword">enum</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'sauce-layer'</span><span class="token punctuation">,</span> <span class="token string">'cheese-layer'</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>      action<span class="token punctuation">:</span> <span class="token punctuation">{</span> type<span class="token punctuation">:</span> <span class="token string">'string'</span><span class="token punctuation">,</span> <span class="token keyword">enum</span><span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'add'</span><span class="token punctuation">,</span> <span class="token string">'remove'</span><span class="token punctuation">,</span> <span class="token string">'toggle'</span><span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">,</span>    <span class="token punctuation">}</span><span class="token punctuation">,</span>    required<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token string">'layer'</span><span class="token punctuation">]</span><span class="token punctuation">,</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span>  execute<span class="token punctuation">:</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">{</span> layer<span class="token punctuation">,</span> action <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>    <span class="token keyword">await</span> <span class="token function">toggleLayer</span><span class="token punctuation">(</span>layer<span class="token punctuation">,</span> action<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token keyword">return</span> <span class="token template-string"><span class="token string">`Performed </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>action <span class="token operator">||</span> <span class="token string">'toggle'</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> on layer: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>layer<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">`</span></span><span class="token punctuation">;</span>  <span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
复制代码

注册完成后,工具可以直接执行页面逻辑、管理状态,并将执行结果直接返回给智能体

一位为 Chrome DevTools 开发 WebMCP Polyfill 的早期实践者表示,WebMCP 带来了非常明显的效率提升。根据他的测试结果,LLM 的 Token 消耗量最高可减少约 90%。他表示:

Playwright 和 Chrome DevTools MCP Server 目前已经成为智能体驱动 Web 应用测试的事实标准。但它们的 Token 利用效率非常差。截图、执行操作、再截图的循环会迅速耗尽上下文窗口。

我一直在使用浏览器自动化来替代 TDD(因为智能体生成的测试中过度使用 Mock),但必须解决 Token 膨胀问题。因此,我 Fork 了 Chrome DevTools MCP Server,让它能够直接执行来自客户端 JavaScript 的 WebMCP 工具。

初步测试显示,Token 使用量大约下降了 90%。更难量化但同样重要的收益来自执行速度和确定性,两者都得到了显著提升。

不过,WebMCP 并非没有风险。提案作者特别提醒开发者,大语言模型容易受到间接提示注入(Indirect Prompt Injection)攻击,而将网站原生能力直接暴露给智能体,也会引入新的安全挑战。因此,他们建议开发者在工具定义中显式提供安全提示信息。对于来自外部来源的数据,应添加 untrustedContentHint 标记,以提醒智能体对相关输入进行严格的安全审查。相反,对于不会修改状态的只读操作,则可以使用 readOnlyHint,帮助智能体判断是否能够跳过人工确认步骤。

除了安全问题之外,WebMCP 还会带来一些运营层面的风险。例如,一个退款工具可能已经开放调用,但背后的退款政策却已经过时。此时,智能体仍然能够准确执行操作,只不过执行的是错误的业务逻辑。又或者,某位用户虽然能够访问某个页面,但实际上并不满足对应业务规则要求。过去,人类操作过程中可能会通过经验判断避免错误,而浏览器智能体则可能直接暴露这种权限设计漏洞。因此,开发者被建议针对关键用户旅程开展 AI Eval 测试,以验证智能体在真实场景下的行为是否符合预期。

一些早期采用者也发现,虽然 WebMCP 为智能体提供了更友好的网站接口,但这并不意味着智能体已经拥有完成任务所需的全部知识。它仍然需要准确了解”业务政策、用户状态、产品规则、资格条件、异常处理流程,以及人工干预路径。

谷歌还建议开发者尽量保持工具描述和返回结果的简洁性。目前推荐的长度限制包括:工具描述不超过 500 个字符;参数描述不超过 150 个字符;工具名称和参数名称不超过 30 个字符;单次工具输出不超过 1500 个字符。

在 I/O 2026 大会上,Chrome 团队将 WebMCP 作为其浏览器 AI 战略的重要组成部分之一进行了发布。与 WebMCP 一同公布的还包括面向浏览器的 Agentic Browsing 能力、内置 AI API,以及帮助开发者构建 AI 智能体的相关开发工具。

查看英文原文:WebMCP Standard Proposal for Agentic Web Actuation Now Available in Chrome (Origin Trials) - InfoQ