智能体表单

声明式 API 通过属性将标准 HTML <form> 元素转换为 WebMCP 工具。浏览器会根据表单输入合成 JSON 架构,并处理智能体交互。

Angular 信号表单: 请勿向使用 @angular/forms/signals 中的 form() 构建的表单添加 toolname/tooldescription。而应将 provideExperimentalWebMcpForms() 添加到应用提供程序,并将 experimentalWebMcpTool: { name, description } 选项传递给 form()。然后,Angular 通过命令式 API 注册表单,根据信号模型构建架构,并将其连接到验证和提交。同时使用这两种方法会导致同一表单注册两次。

表单属性

  • toolname:工具的唯一名称。
  • tooldescription:工具的功能以及智能体应在何时使用该工具。请勿列出表单的字段、选项或限制:浏览器已将这些内容包含在它根据表单控件构建的架构中。
  • toolautosubmit:(可选)如果存在,代理可以提交表单,而无需等待用户互动。
  • toolparamdescription:(可选)提供了一种在 JSON 架构中定义属性说明的方法。请使用此文本来说明该值的含义(例如,使用示例值),而不是重复控件的选项或限制。
    • 解析顺序:浏览器会使用 toolparamdescription(如果存在)。如果不存在,则使用关联的 <label> 的 textContent(跳过可添加标签的后代)。如果不存在标签,则会回退到 aria-description。
    • 分组(字段集):如需为一组相关元素(例如 <input type="radio"> 按钮)添加说明,请将 toolparamdescription 放置在最近的父级 <fieldset> 元素上,以便将其应用于整个参数组。

示例

<form toolname="search-cars" 
      tooldescription="Perform a car make/model search" 
      toolautosubmit>
  <label for="make">Vehicle Make</label>
  <input type="text" id="make" name="make" required>
  
  <label for="model">Vehicle Model</label>
  <input type="text" id="model" name="model" toolparamdescription="e.g., 330i, F-150" required>
  
  <button type="submit">Search</button>
</form>

在 JavaScript 中处理提交

当客服人员提交表单时,SubmitEvent 会包含 agentInvoked(布尔值)和 respondWith(promise)。

document.querySelector('form').addEventListener('submit', (event) => {
  event.preventDefault();

  // Validate the form
  const formValidationErrors = myFormIsValid();

  if (formValidationErrors.length > 0) {
    if (event.agentInvoked) {
      const errorString =
        'Validation failed: ' +
        formValidationErrors
          .map((err) => `${err.field} (${err.message})`)
          .join(', ');

      event.respondWith(Promise.resolve(errorString));
    }
    return;
  }

  const resultPromise = performAsyncSearch(new FormData(event.target));

  // Return the result directly to the agent without navigation
  if (event.agentInvoked) {
    event.respondWith(resultPromise);
  }
});

生命周期事件

document.modelContext 会在智能体开始或停止与工具交互时发出事件:toolactivated 会在工具开始执行时触发,toolcancel 会在工具执行被取消时触发。

// Starting in Chrome 156, these events are dispatched on `document.modelContext`.
// Older versions dispatch them on `window`. Feature-detect the event handler
// property to pick the right target for backward compatibility.
const targetFor = (type, listener, options) =>
  (`on${type}` in (document.modelContext ?? {}) ? document.modelContext : window)
    .addEventListener(type, listener, options);

targetFor('toolactivated', ({ toolName }) => {
  console.log(`Tool "${toolName}" started execution.`);
});

targetFor('toolcancel', ({ toolName }) => {
  console.log(`Tool "${toolName}" execution is cancelled.`);
});

视觉反馈 (CSS)

当代理与表单互动时,使用伪类突出显示表单:

  • :tool-form-active:应用于智能体正在使用的 <form> 元素。
  • :tool-submit-active:当浏览器暂停以供用户审核时,应用于提交按钮(如果省略 toolautosubmit)。
form:tool-form-active {
  outline: 2px dashed blue;
  background-color: rgba(0, 0, 255, 0.05);
}

button:tool-submit-active {
  outline: 2px dashed red;
  animation: pulse 2s infinite;
}

表单适用性(何时应避免使用)

声明式 API 最适合自包含的标准表单。在以下场景中,它不是一个好的选择:

  • 高度依赖的字段:表单中的输入会根据其他输入改变选项或可见性。合成架构无法很好地表达这些依赖项。
  • 自定义界面组件:依赖于非标准输入(例如画布、富文本编辑器)且不会自动序列化值的表单。
  • 多步向导:需要多次提交表单的复杂工作流。在这种情况下,命令式 API 或标准 DOM 交互更适合。

何时使用 toolautosubmit

  • 只读操作和查询:搜索、过滤、提取详细信息或检查状态(例如,搜索车型、搜索目录、检查库存情况)。
  • 低风险、可逆的操作:用户可以轻松手动撤消或优化表单操作(例如,将商品添加到购物车、应用优惠券代码、保存草稿或设置临时布局选项)。

何时省略 toolautosubmit

  • 破坏性或不可逆的操作:删除记录、重置系统配置或清除数据库。
  • 财务和交易操作:提交结账表单、转账、授权订阅付款或最终下单。
  • 高影响力的用户通信:提交最终工作申请、向其他真实用户发送电子邮件/消息,或发布面向公众的内容。
  • 敏感账号设置:更改密码、修改用户角色/权限,或更新结算/个人资料信息。

后备策略

WebMCP 声明式 API 可在所有浏览器中安全使用。不支持 WebMCP 的浏览器会忽略 tool* 属性,并且 <form> 将继续作为普通 HTML 表单运行。无需进行特征检测。