From 6f39b960d06123b0815a59330a59c7e9c9e2b0e1 Mon Sep 17 00:00:00 2001 From: xinbao Date: Sun, 14 Jun 2026 15:01:42 +0800 Subject: [PATCH] update --- pages/demo/adoption-plan.md | 28 +- pages/demo/devtools-workflow.md | 44 ++- pages/demo/platform-api.md | 36 +- pages/demo/release-scan.md | 46 ++- pages/demo/webmcp-contract.md | 43 +++ pages/demo/webmcp-project.md | 40 +++ pages/demo/webmcp-script.md | 41 +++ pages/outline.md | 18 +- pages/overview.md | 16 +- plan/part2.md | 97 ++++++ public/demo/index.html | 583 ++++++++++++++++++++++++++++++++ public/demo/webmcp/app.js | 277 +++++++++++++++ public/demo/webmcp/index.html | 148 ++++++++ public/demo/webmcp/styles.css | 346 +++++++++++++++++++ slides.md | 22 +- 15 files changed, 1709 insertions(+), 76 deletions(-) create mode 100644 pages/demo/webmcp-contract.md create mode 100644 pages/demo/webmcp-project.md create mode 100644 pages/demo/webmcp-script.md create mode 100644 plan/part2.md create mode 100644 public/demo/index.html create mode 100644 public/demo/webmcp/app.js create mode 100644 public/demo/webmcp/index.html create mode 100644 public/demo/webmcp/styles.css diff --git a/pages/demo/adoption-plan.md b/pages/demo/adoption-plan.md index 16e03f5..ca074fa 100644 --- a/pages/demo/adoption-plan.md +++ b/pages/demo/adoption-plan.md @@ -1,33 +1,37 @@ -# 模拟展示 4:团队落地清单 +# Demo 4:本地兜底,不抢官方主线
-
本周可做
+
本地页面做什么
-- 建一个 Chrome 更新跟踪文档 -- 选 1 个 DevTools 工作流做内部演示 -- 为 1 个新能力写最小 demo -- 标注生产可用与仅实验的边界 +- 官方资料导航 +- 三路径对比仪表盘 +- 现场讲述卡片 +- 网络不可用时继续演示
-
不要直接做
+
本地页面不做什么
-- 只因 Chrome 支持就上线 -- 忽略 Safari / Firefox 用户 -- 把实验能力写进核心链路 -- 跳过权限与隐私评估 +- 不复刻所有 Chrome API +- 不依赖 flags 才能讲完 +- 不做厂商 SDK 接入教程 +- 不把实验能力讲成稳定能力
+
+打开本地兜底页:/demo/index.html。它是演示资料台,不是生产方案样板。 +
+ diff --git a/pages/demo/devtools-workflow.md b/pages/demo/devtools-workflow.md index d6c64a7..25971ef 100644 --- a/pages/demo/devtools-workflow.md +++ b/pages/demo/devtools-workflow.md @@ -1,32 +1,50 @@ -# 模拟展示 2:DevTools 排查链路 +# Demo 2:AI 操作 Web 的三种路径
```mermaid {scale: 0.82} flowchart LR - A[用户反馈卡顿] --> B[Performance 录制] - B --> C[定位长任务] - C --> D[Network 查资源瀑布] - D --> E[Coverage 查无效代码] - E --> F[形成优化清单] + A[用户一句话任务] --> B{Agent 如何操作网页?} + B --> C[看截图
Vision] + B --> D[读结构
DOM / A11y] + B --> E[调工具
WebMCP] + C --> F[慢 / 贵 / UI 敏感] + D --> G[更结构化 / 仍易误点] + E --> H[语义工具 / 参数明确 / 可控] ```
-
+
-
-
演示素材
-
准备一个加载慢、交互卡顿、资源偏大的页面作为示例。
+
+
视觉识别
+
通用,不改页面;但每一步都要观察、推理、点击,token 与耗时容易升高。
-
观众收获
-
把 DevTools 从“会打开”变成“按链路定位问题”。
+
DOM / A11y
+
比截图更结构化;但复杂组件、隐藏状态、错误点击仍然会影响可靠性。
+
+
WebMCP
+
页面主动暴露工具,Agent 调业务能力,不再猜按钮和表单。
+
+ +
+ +
+示例任务:创建“订单管理”模块,包括词条、菜单、角色权限绑定。案例数据只说明趋势,不承诺所有项目都有相同收益。
diff --git a/pages/demo/platform-api.md b/pages/demo/platform-api.md index ee00c57..465f6b1 100644 --- a/pages/demo/platform-api.md +++ b/pages/demo/platform-api.md @@ -1,28 +1,27 @@ -# 模拟展示 3:Web 平台能力评估卡 +# Demo 3:Chrome 官方新特性快闪
-
能力示例
+
Agentic Web 相关
-- CSS 新布局与交互能力 -- View Transitions -- File System / Clipboard / Share APIs -- PWA 安装与离线体验 -- 本地 AI 与浏览器内置能力探索 +- WebMCP:页面暴露工具给 Agent +- Modern Web Guidance:给 AI 编程工具补现代 Web 知识 +- DevTools for agents:让 Agent 看见浏览器运行时 +- Prompt API:浏览器内置 AI 能力
-
评估维度
+
体验与平台能力
-- 用户价值:解决什么真实问题? -- 兼容性:Chrome-only 还是跨浏览器? -- 降级方案:不可用时如何处理? -- 风险:权限、隐私、性能、安全 +- HTML-in-Canvas:真实 DOM 进入 Canvas / 3D +- Baseline:判断哪些 Web 能力可以放心评估 +- View Transitions:页面状态切换更自然 +- Navigation API:更现代的导航状态管理
@@ -30,9 +29,18 @@
-推荐输出格式:能力名称 / Chrome 支持状态 / 业务场景 / Demo 链接 / 风险 / 下一步。 +只讲位置,不展开 API:这些官方 demo 共同说明 Chrome 正在同时升级 Agent 交互、开发工作流和用户体验。
diff --git a/pages/demo/release-scan.md b/pages/demo/release-scan.md index 00a988f..2b80151 100644 --- a/pages/demo/release-scan.md +++ b/pages/demo/release-scan.md @@ -1,44 +1,58 @@ -# 模拟展示 1:快速扫一版 Chrome 更新 +# Demo 1:演示交付物总览
-
信息源
+
PPT 讲什么
-- Chrome Developers Blog -- ChromeStatus -- DevTools Release Notes -- MDN Baseline +- 分别介绍新增能力 +- 说明解决的问题 +- 标注成熟度和限制 +- 给出官方资料来源
-
筛选标准
+
工程演示什么
-- 是否默认启用 -- 是否跨浏览器可用 -- 是否影响现有代码 -- 是否带来明显产品收益 +- WebMCP 可运行页面 +- 声明式表单工具 +- 指令式 registerTool +- 工具 schema 和调用日志 +- mock runtime 兜底
-
输出物
+
官方快闪
-- 3 个可试验能力 -- 2 个需要关注的变更 -- 1 个团队落地建议 +- Modern Web Guidance +- DevTools for agents +- Prompt API / HTML-in-Canvas +- Baseline / View Transitions
+
+原则:WebMCP 至少要有可运行工程;其他 Chrome 新能力用官方 demo 快闪,避免把现场变成环境配置课。 +
+ diff --git a/pages/demo/webmcp-contract.md b/pages/demo/webmcp-contract.md new file mode 100644 index 0000000..f08ff50 --- /dev/null +++ b/pages/demo/webmcp-contract.md @@ -0,0 +1,43 @@ +# Demo 2:WebMCP 到底演示什么? + +
+ +
+
一句话
+
+ +WebMCP 让网页把业务能力暴露成结构化工具,Agent 看到的是工具名、描述、参数 schema 和执行结果,而不是只靠截图或 DOM 猜按钮。 + +
+navigator.modelContext.registerTool(...) +
+ +
+
+ +
+
两种 API
+
+ +- 声明式:给标准 HTML 表单添加工具属性 +- 指令式:用 JavaScript 注册复杂工具 +- 共同目标:把页面能力变成 Agent 可理解的契约 +- 演示口径:提高可靠性,不承诺零错误率 + +
+
+ +
+ +
+实验边界:Chrome 官方文档标注 WebMCP 仍处于 proposed / origin trial / flag 阶段;现场 demo 必须有 mock 兜底。 +
+ + diff --git a/pages/demo/webmcp-project.md b/pages/demo/webmcp-project.md new file mode 100644 index 0000000..8f925ba --- /dev/null +++ b/pages/demo/webmcp-project.md @@ -0,0 +1,40 @@ +# Demo 3:WebMCP 原始工程能跑起来 + +
+ +
+
工程文件
+ +```txt +public/demo/webmcp/ +├── index.html # 业务 UI + 声明式表单工具 +├── styles.css # 演示界面样式 +└── app.js # registerTool + mock runtime + 执行日志 +``` + +
+ +
+
运行入口
+
+ +- 启动:`pnpm dev` +- 打开:`/demo/webmcp/index.html` +- 无 WebMCP 环境:走本地 mock runtime +- 有 WebMCP 环境:优先调用 `navigator.modelContext` + +
+
+ +
+ +
+这页要现场打开工程,不只讲链接。观众能看到“页面 UI”和“Agent 工具视角”同时存在。 +
+ + diff --git a/pages/demo/webmcp-script.md b/pages/demo/webmcp-script.md new file mode 100644 index 0000000..b89579d --- /dev/null +++ b/pages/demo/webmcp-script.md @@ -0,0 +1,41 @@ +# Demo 4:现场操作脚本 + +
+ +
+
1. 人类 UI
+
+提交售后工单表单,说明原有页面流程没有被替换。 +
+
+ +
+
2. 工具发现
+
+右侧展示工具名、描述、schema:这是 Agent 看到的契约。 +
+
+ +
+
3. 单工具调用
+
+点击查询订单、生成回复、退款审核,观察状态和日志变化。 +
+
+ +
+
4. 复合任务
+
+执行复合任务:查询订单 → 进入审核 → 生成回复草稿。 +
+
+ +
+ +
+讲解结论:WebMCP 不是让 Agent 更会点击,而是让网页直接声明“我有哪些可调用能力”。敏感动作仍然要保留用户确认、权限和审计。 +
+ + diff --git a/pages/outline.md b/pages/outline.md index 3e42893..986bd7c 100644 --- a/pages/outline.md +++ b/pages/outline.md @@ -4,30 +4,30 @@
01
-
Chrome 更新怎么看
-
Release Notes · ChromeStatus · Baseline · Origin Trials
+
浏览器的新使用者
+
Human UI · Agent layer · Structured actions
02
-
Web 平台新能力
-
CSS · Web APIs · PWA · Media · AI-adjacent APIs
+
AI 操作网页为什么难
+
Vision · DOM / A11y · Tool calling
03
-
DevTools 工作流
-
Performance · Network · CSS Overview · Recorder
+
MCP / WebMCP
+
Tool schema · Structured actions · Safety boundary
04
-
落地与风险
-
兼容性 · 安全边界 · 灰度策略 · 团队清单
+
官方 demo 快闪
+
MWG · DevTools agents · Prompt API · HTML-in-Canvas
diff --git a/pages/overview.md b/pages/overview.md index b48900c..864fd12 100644 --- a/pages/overview.md +++ b/pages/overview.md @@ -6,10 +6,10 @@
听众能获得
-- Chrome 近期值得关注的新能力地图 -- 哪些能力已经适合进入生产评估 -- 如何用 DevTools 更快定位性能与兼容性问题 -- 如何把浏览器更新转成团队行动项 +- 理解 AI Agent 操作网页为什么困难 +- 看懂 Chrome 新增能力各自解决什么问题 +- 知道 PPT 与项目代码分别如何演示这些能力 +- 建立实验能力的风险边界
@@ -19,9 +19,9 @@
- 不逐条朗读全部 release notes -- 不做浏览器内核源码分析 -- 不承诺所有实验能力都可直接上线 -- 不替代真实项目的兼容性验证 +- 不做厂商 SDK 接入教程 +- 不复刻每一个 Chrome 实验 API +- 不承诺实验能力可直接进入生产核心链路
@@ -29,5 +29,5 @@ diff --git a/plan/part2.md b/plan/part2.md new file mode 100644 index 0000000..a5f9457 --- /dev/null +++ b/plan/part2.md @@ -0,0 +1,97 @@ +# Part 2 Demo Plan: 官方优先的 Agentic Web 演示 + +## 目标和产物 + +第二部分用于支撑 40 分钟分享中的 demo 段,目标不是泛泛介绍概念,而是生成两类明确产物: + +1. **PPT 主线**:分别介绍 Chrome 最近新增或正在推进的关键能力,说明每个功能解决什么问题、处在什么成熟度、适合用什么官方材料展示。 +2. **项目代码演示**:创建并维护一个配套前端项目,用稳定页面串起官方 demo、功能对比和现场备用流程,让每个重点功能都有可打开、可讲述、可兜底的演示入口。 + +它不是落地教程,也不是厂商 SDK 接入课;目标是让对 Chrome 新特性不熟悉的 Web 开发者看懂: + +- AI 操作 Web 为什么容易慢、贵、不稳定。 +- WebMCP 为什么从“猜 UI”转向“调用页面暴露的工具”。 +- Chrome 相关新能力如何作为这个方向的证据链,而不是每个都现场复刻。 +- 哪些是官方能力或标准探索,哪些只是厂商实现概念。 + +## 总原则 + +1. **官方优先**:优先使用 Chrome 官方文档、官方 demo、官方 demo collection、官方命令示例和官方截图/录屏作为展示材料。 +2. **本地兜底**:只有官方材料不能稳定现场展示,或无法串起叙事时,才用当前仓库补一个本地演示。 +3. **不复刻重实验能力**:不在本地项目里复刻 Prompt API、HTML-in-Canvas、Chrome DevTools for agents 等环境依赖重、版本敏感或 origin trial 依赖强的能力。 +4. **保持科普口径**:所有 token、耗时、成功率数据都作为具体案例,不当作普适结论。 +5. **实验能力明确标注**:WebMCP、Prompt API、HTML-in-Canvas 等能力需要标注实验性、origin trial、渐进增强或浏览器支持边界。 +6. **剔除厂商私货**:OpenTiny、VAgent、WebAgent、Remote、WebSkills、遥控器组件、SDK 版本等只可作为原始材料背景,不作为 PPT 主概念。若需要表达类似思想,使用中立说法:“Agent 操作说明”“流程说明”“工具调用编排”。 + +## Demo 结构 + +### 1. Demo 导航页 + +先给观众一张总览:第二部分会按“新增功能介绍”和“项目代码演示”展开。 + +- 新增功能介绍:WebMCP、Modern Web Guidance、DevTools for agents、Prompt API、HTML-in-Canvas、Baseline / View Transitions。 +- 项目代码演示:用本地前端页面承接官方链接、功能卡片、三路径对比和现场备用讲述。 +- 兜底原则:本地项目不承担全部 Chrome API 复刻,只承担稳定讲述和演示组织。 + +### 2. 主线演示:AI 操作 Web 的三种方式 + +任务设定:在后台系统中完成“创建订单管理模块”,包括创建词条、创建菜单、绑定角色权限。 + +对比三种路径: + +- 视觉识别:靠截图理解界面。优点是通用;问题是慢、token 高、UI 变化敏感。 +- DOM / 可访问性树识别:靠页面结构找元素。比纯视觉结构化,但仍可能被复杂组件、隐藏状态和错误点击影响。 +- WebMCP / 工具调用:页面主动暴露工具和参数,Agent 调用业务能力,不再猜 UI。 + +展示方式优先级: + +1. 使用原始材料中的录屏或截图结论做 PPT 叙事。 +2. 如无可用视频,则用表格和流程图描述三种路径。 +3. 如现场需要互动,再打开本地 demo 页面作为“对比仪表盘”。 + +### 3. 新增功能介绍:官方 demo 快闪 + +每个能力只讲“它是什么、解决什么问题、现场怎么展示”,不展开完整 API 课。 + +- **WebMCP**:使用官方 imperative API 文档中的 `document.modelContext.registerTool`、pizza layer、order status 示例说明“页面暴露工具”。 +- **Modern Web Guidance**:使用官方 `npx modern-web-guidance@latest install` 和 `search/retrieve` 命令说明“给 AI 编程工具补现代 Web 知识”。 +- **Chrome DevTools for agents**:使用官方 DevTools MCP 资料说明“让 AI 看到浏览器运行时、性能 trace、network、console”。 +- **Prompt API**:使用官方 Prompt API demos / playground 说明“浏览器内置 AI 能力,适合渐进增强”。 +- **HTML-in-Canvas**:使用官方 origin trial 文章和 demo collection 说明“DOM 进入 Canvas / 3D 场景,同时保留可访问性、搜索、翻译等能力”。 +- **Baseline / View Transitions**:使用 webstatus.dev、Baseline、view-transitions.chrome.dev 说明“哪些能力可以评估,哪些能力提升交互体验”。 + +## 项目代码演示职责 + +当前仓库的本地 demo 只承担三件事: + +1. 提供一个稳定的“官方 demo 导航页”,列出每个新增功能对应的官方资料、推荐讲法和现场备用链接。 +2. 提供一个“AI 操作 Web 三路径对比”页面,用表格、流程和状态卡讲清楚视觉识别、DOM/可访问性识别、WebMCP/工具调用的差异。 +3. 提供一个“本地兜底说明”:如果官方 demo 现场不可用,如何用项目页面和 PPT 中的截图/流程继续讲,不中断分享。 + +不做以下事情: + +- 不把本地项目做成真实 WebMCP SDK 接入教程。 +- 不实现所有 Chrome 新特性。 +- 不把实验 API 当作生产可用能力演示。 +- 不要求现场浏览器开启 flags 才能完成主流程。 +- 不把 WebSkills / WebAgent / VAgent / Remote 等厂商概念写成标准能力。 + +## 时间分配 + +第二部分建议 15 分钟左右: + +- 2 分钟:demo 导航与官方优先说明。 +- 6 分钟:三种 AI 操作 Web 路径对比。 +- 5 分钟:Chrome 官方 demo 快闪。 +- 2 分钟:本地兜底和关键风险提示。 + +## 参考资料 + +- WebMCP imperative API: https://developer.chrome.com/docs/ai/webmcp/imperative-api +- Prompt API: https://developer.chrome.com/docs/ai/prompt-api +- Modern Web Guidance: https://developer.chrome.com/docs/modern-web-guidance +- Chrome DevTools for agents: https://developer.chrome.com/docs/devtools/agents/get-started +- HTML-in-Canvas origin trial: https://developer.chrome.com/blog/html-in-canvas-origin-trial +- Baseline: https://web.dev/baseline +- View Transitions demos: https://view-transitions.chrome.dev/ +- Chrome demos index: https://chrome.dev/ diff --git a/public/demo/index.html b/public/demo/index.html new file mode 100644 index 0000000..e99ae76 --- /dev/null +++ b/public/demo/index.html @@ -0,0 +1,583 @@ + + + + + + Part 2 Demo - Agentic Web + + + +
+ + +
+
+
+

Core Message

+

从“AI 猜 UI”到“网页暴露工具”。

+

+ 视觉识别和 DOM 识别让 Agent 尝试理解页面表象;WebMCP 的方向是让页面主动提供结构化能力, + 让 Agent 调用工具、传入参数、拿到结果。 +

+
+ +
+ +
+

同一个后台任务,三种 Agent 操作路径

+
+
+ Vision +

看截图

+

Agent 通过视觉模型识别菜单、按钮、输入框,再一步步点击。

+
    +
  • 优点:不需要改造页面
  • +
  • 风险:慢、贵、UI 变化敏感
  • +
  • 适合:临时探索和低风险页面
  • +
+
+
+ DOM / A11y +

读结构

+

Agent 读取 DOM 或可访问性树,通过结构化信息定位交互元素。

+
    +
  • 优点:比截图更结构化
  • +
  • 风险:复杂组件和隐藏状态仍会误导
  • +
  • 适合:语义清晰的表单页面
  • +
+
+
+ WebMCP +

调工具

+

页面暴露工具名、描述、参数 schema 和执行逻辑,Agent 直接调用业务能力。

+
    +
  • 优点:语义明确、速度快、过程可控
  • +
  • 风险:仍需权限、确认和审计边界
  • +
  • 适合:复杂后台和重复流程
  • +
+
+
+
+ +
+

对比讲述表

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
维度视觉识别DOM / A11yWebMCP
交互方式观察截图后猜测点击位置读取结构后定位元素调用页面声明的语义工具
稳定性受视觉布局影响明显受 DOM 结构和组件状态影响受工具设计、权限和业务逻辑影响
现场讲法“像让 AI 蒙着眼睛找按钮”“给了地图,但地图可能不完整”“给了工具入口和参数说明”
+
+ +
+

WebMCP 原始工程 demo

+
+
+

运行入口

+

+ 打开 /demo/webmcp/index.html,展示声明式表单工具、 + 指令式 JS 工具、工具 schema 面板和复合任务调用日志。 +

+
+
+

讲述重点

+

+ 先让人提交表单,再让工具面板执行同一类任务。观众会看到 Agent 不需要猜 UI, + 它看到的是工具名、描述、参数 schema 和执行结果。 +

+
+
+
+ +
+

官方 demo 与资料入口

+ +
+ +
+

现场兜底讲法

+
+
+

如果官方 demo 打不开

+

+ 继续使用本页的卡片和对比表讲主线:AI 不擅长猜复杂 UI,WebMCP 的价值是结构化暴露工具。 + 官方链接可作为会后资料。 +

+
+
+

如果有人追问落地

+

+ 只回答原则:渐进增强、权限继承、高危确认、审计日志、工具按需暴露。 + 不在本场扩展到厂商 SDK 选型和企业架构。 +

+
+
+
+
+
+ + + + diff --git a/public/demo/webmcp/app.js b/public/demo/webmcp/app.js new file mode 100644 index 0000000..0d7049d --- /dev/null +++ b/public/demo/webmcp/app.js @@ -0,0 +1,277 @@ +const logEl = document.querySelector("#log"); +const toolListEl = document.querySelector("#tool-list"); +const nativeStatusEl = document.querySelector("#native-status"); +const orderStateEl = document.querySelector("#order-state"); + +const nativeModelContext = window.navigator.modelContext; +const registry = new Map(); + +const demoOrders = { + "CHR-2026-0614": { + orderId: "CHR-2026-0614", + status: "delivered", + risk: "missing_accessory", + customerTier: "enterprise", + nextAction: "open_refund_review", + }, +}; + +const modelContext = nativeModelContext ?? createMockModelContext(); + +nativeStatusEl.textContent = nativeModelContext + ? "Native WebMCP detected" + : "Mock WebMCP runtime"; +nativeStatusEl.className = `pill ${nativeModelContext ? "native" : "mock"}`; + +registerDeclarativeForms(); +registerImperativeTools(); +renderTools(); +log("runtime.ready", { + nativeWebMcp: Boolean(nativeModelContext), + registeredTools: Array.from(registry.keys()), +}); + +document.querySelector("#ticket-form").addEventListener("submit", async (event) => { + event.preventDefault(); + const form = event.currentTarget; + const toolName = form.getAttribute("toolname"); + const payload = Object.fromEntries(new FormData(form).entries()); + const result = await runTool(toolName, payload); + log("form.submit", result); +}); + +document.querySelectorAll("[data-run-tool]").forEach((button) => { + button.addEventListener("click", async () => { + const name = button.getAttribute("data-run-tool"); + const input = sampleInputFor(name); + const result = await runTool(name, input); + log(`tool.${name}`, result); + }); +}); + +document.querySelector("#run-workflow").addEventListener("click", async () => { + log("agent.plan", { + task: "客户反馈缺少配件,请查询订单、判断是否进入退款审核,并生成回复草稿。", + }); + const order = await runTool("lookup_order_status", { orderId: "CHR-2026-0614" }); + const refund = await runTool("approve_refund_review", { + orderId: order.orderId, + reason: "missing_accessory", + }); + const reply = await runTool("draft_customer_reply", { + email: "dev@example.com", + category: "refund", + orderId: order.orderId, + }); + log("agent.workflow.complete", { order, refund, reply }); +}); + +function createMockModelContext() { + return { + registerTool(tool) { + registry.set(tool.name, tool); + return Promise.resolve({ name: tool.name, mock: true }); + }, + }; +} + +function registerDeclarativeForms() { + document.querySelectorAll("form[toolname]").forEach((form) => { + const name = form.getAttribute("toolname"); + const description = form.getAttribute("tooldescription") || `Submit ${name}`; + const inputSchema = schemaFromForm(form); + + registerTool({ + source: "declarative", + name, + description, + inputSchema, + execute: async (input) => { + const ticketId = `SUP-${Date.now().toString().slice(-6)}`; + return { + ticketId, + status: "created", + summary: `${input.category} issue for ${input.email}`, + visibleUpdate: "工单已创建,页面保留原有人类操作流程。", + }; + }, + }); + }); +} + +function registerImperativeTools() { + registerTool({ + source: "imperative", + name: "lookup_order_status", + description: "Look up order status, risk and recommended next action by order id.", + inputSchema: { + type: "object", + properties: { + orderId: { type: "string", description: "Order id shown in the support workspace." }, + }, + required: ["orderId"], + }, + execute: async ({ orderId }) => { + const order = demoOrders[orderId] ?? { + orderId, + status: "unknown", + risk: "not_found", + customerTier: "unknown", + nextAction: "ask_user_for_more_information", + }; + orderStateEl.textContent = order.nextAction; + return order; + }, + }); + + registerTool({ + source: "imperative", + name: "approve_refund_review", + description: "Move an eligible order into refund review after checking business policy.", + inputSchema: { + type: "object", + properties: { + orderId: { type: "string" }, + reason: { + type: "string", + enum: ["missing_accessory", "damaged_item", "delivery_delay"], + }, + }, + required: ["orderId", "reason"], + }, + execute: async ({ orderId, reason }) => { + orderStateEl.textContent = "已进入退款审核"; + return { + orderId, + reason, + approvedForReview: true, + needsHumanConfirmation: true, + message: "敏感动作只进入审核,不直接退款。", + }; + }, + }); + + registerTool({ + source: "imperative", + name: "draft_customer_reply", + description: "Draft a support reply based on customer issue category and order id.", + inputSchema: { + type: "object", + properties: { + email: { type: "string", format: "email" }, + category: { type: "string", enum: ["refund", "delivery", "account"] }, + orderId: { type: "string" }, + }, + required: ["email", "category", "orderId"], + }, + execute: async ({ email, category, orderId }) => ({ + to: email, + category, + orderId, + draft: + "我们已经定位到该订单的缺件问题,并将它提交到退款审核。审核完成前不会自动扣改账户,请等待人工确认。", + }), + }); +} + +function registerTool(tool) { + registry.set(tool.name, tool); + const nativePayload = { + name: tool.name, + description: tool.description, + inputSchema: tool.inputSchema, + execute: tool.execute, + }; + + try { + modelContext.registerTool(nativePayload); + } catch (error) { + log("register.error", { tool: tool.name, message: error.message }); + } +} + +async function runTool(name, input) { + const tool = registry.get(name); + if (!tool) { + throw new Error(`Unknown tool: ${name}`); + } + const result = await tool.execute(input); + return { tool: name, input, output: result }; +} + +function schemaFromForm(form) { + const properties = {}; + const required = []; + form.querySelectorAll("input[name], select[name], textarea[name]").forEach((field) => { + const name = field.getAttribute("name"); + properties[name] = { + type: inputTypeToJsonSchema(field), + description: field.closest("label")?.firstChild?.textContent?.trim() || name, + }; + if (field.hasAttribute("required")) { + required.push(name); + } + }); + return { type: "object", properties, required }; +} + +function inputTypeToJsonSchema(field) { + if (field.tagName === "SELECT" || field.tagName === "TEXTAREA") { + return "string"; + } + if (field.type === "number" || field.type === "range") { + return "number"; + } + if (field.type === "checkbox") { + return "boolean"; + } + return "string"; +} + +function renderTools() { + toolListEl.innerHTML = ""; + registry.forEach((tool) => { + const card = document.createElement("article"); + card.className = "tool-card"; + card.innerHTML = ` +

${tool.name}

+

${tool.description}

+ ${tool.source} +
${escapeHtml(JSON.stringify(tool.inputSchema, null, 2))}
+ `; + toolListEl.append(card); + }); +} + +function sampleInputFor(name) { + const samples = { + create_support_ticket: { + email: "dev@example.com", + category: "refund", + description: "订单 CHR-2026-0614 到货后发现配件缺失。", + }, + lookup_order_status: { orderId: "CHR-2026-0614" }, + approve_refund_review: { orderId: "CHR-2026-0614", reason: "missing_accessory" }, + draft_customer_reply: { + email: "dev@example.com", + category: "refund", + orderId: "CHR-2026-0614", + }, + }; + return samples[name] ?? {}; +} + +function log(title, payload) { + const entry = document.createElement("div"); + entry.className = "entry"; + entry.innerHTML = `${title}
${escapeHtml(JSON.stringify(payload, null, 2))}
`; + logEl.prepend(entry); +} + +function escapeHtml(value) { + return String(value) + .replaceAll("&", "&") + .replaceAll("<", "<") + .replaceAll(">", ">") + .replaceAll('"', """); +} diff --git a/public/demo/webmcp/index.html b/public/demo/webmcp/index.html new file mode 100644 index 0000000..118e4f0 --- /dev/null +++ b/public/demo/webmcp/index.html @@ -0,0 +1,148 @@ + + + + + + WebMCP Demo - Tool Contracts + + + +
+
+

Runnable demo

+

WebMCP 工具契约演示

+
+
+ 检测中 + Chrome 官方文档 +
+
+ +
+
+
+

+ 这个页面模拟一个售后后台:左侧是人能操作的业务 UI,右侧是页面暴露给 Agent 的工具契约。 + 如果当前 Chrome 没有开启 WebMCP,本页面会使用本地 mock,让现场仍然能看清楚“工具注册”和“工具调用”的流程。 +

+
+ +
+
+
+

Declarative API

+

声明式:把 HTML 表单变成工具

+
+ form attributes +
+ +
+ + + + +
+ +
<form
+  toolname="create_support_ticket"
+  tooldescription="Create a support ticket from user supplied issue details.">
+  <input name="email" type="email" required />
+  <select name="category" required>...</select>
+  <textarea name="description" required></textarea>
+</form>
+
+ +
+
+
+

Imperative API

+

指令式:用 JavaScript 注册业务工具

+
+ registerTool() +
+ +
+
+ 订单号 + CHR-2026-0614 + 已签收,缺件风险 +
+
+ 客户等级 + Enterprise + 允许优先退款审核 +
+
+ 当前状态 + 等待处理 + 由工具调用更新 +
+
+ +
+ + + +
+ +
navigator.modelContext.registerTool({
+  name: "lookup_order_status",
+  description: "Look up order status by order id.",
+  inputSchema: {
+    type: "object",
+    properties: { orderId: { type: "string" } },
+    required: ["orderId"]
+  },
+  execute: async ({ orderId }) => lookupOrder(orderId)
+});
+
+
+ + +
+ + + + diff --git a/public/demo/webmcp/styles.css b/public/demo/webmcp/styles.css new file mode 100644 index 0000000..1825ec7 --- /dev/null +++ b/public/demo/webmcp/styles.css @@ -0,0 +1,346 @@ +:root { + color-scheme: light; + --ink: #161a1d; + --muted: #60717c; + --paper: #fffdfa; + --panel: #f3f0e8; + --line: #d9d2c2; + --blue: #174ea6; + --green: #116b4f; + --amber: #9a5c00; + --red: #a7352a; + --code: #1b2430; + --shadow: 0 20px 70px rgb(50 45 34 / 0.16); +} + +* { + box-sizing: border-box; +} + +body { + margin: 0; + color: var(--ink); + background: + linear-gradient(90deg, rgb(22 26 29 / 0.06) 1px, transparent 1px), + linear-gradient(rgb(22 26 29 / 0.06) 1px, transparent 1px), + #e7e1d6; + background-size: 28px 28px; + font-family: ui-sans-serif, "PingFang SC", "Microsoft YaHei", "Noto Sans SC", sans-serif; +} + +button, +input, +select, +textarea { + font: inherit; +} + +a { + color: var(--blue); + font-weight: 800; + text-decoration: none; +} + +.topbar { + display: flex; + align-items: flex-end; + justify-content: space-between; + gap: 24px; + padding: 28px 32px 18px; +} + +.eyebrow { + margin: 0 0 8px; + color: var(--blue); + font-size: 12px; + font-weight: 900; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +h1, +h2, +p { + margin-top: 0; +} + +h1 { + margin-bottom: 0; + font-family: Georgia, "Times New Roman", serif; + font-size: clamp(34px, 5vw, 68px); + line-height: 0.95; + letter-spacing: 0; +} + +h2 { + margin-bottom: 0; + font-size: 22px; + letter-spacing: 0; +} + +.runtime { + display: flex; + align-items: center; + gap: 14px; + margin-bottom: 8px; +} + +.pill, +.mode { + display: inline-flex; + align-items: center; + min-height: 28px; + border: 1px solid var(--line); + padding: 4px 10px; + background: var(--paper); + color: var(--muted); + font-size: 12px; + font-weight: 900; +} + +.pill.native { + border-color: rgb(17 107 79 / 0.35); + background: #e8f4ee; + color: var(--green); +} + +.pill.mock { + border-color: rgb(154 92 0 / 0.35); + background: #fff3d8; + color: var(--amber); +} + +.layout { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(360px, 440px); + gap: 22px; + padding: 0 32px 32px; +} + +.workspace, +.agent { + display: grid; + gap: 18px; + align-content: start; +} + +.intro, +.panel, +.agent-panel { + border: 1px solid var(--line); + background: rgb(255 253 250 / 0.92); + box-shadow: var(--shadow); +} + +.intro { + padding: 18px 20px; +} + +.intro p { + margin-bottom: 0; + color: var(--muted); + line-height: 1.75; +} + +.panel, +.agent-panel { + padding: 22px; +} + +.panel-head { + display: flex; + justify-content: space-between; + gap: 16px; + margin-bottom: 18px; +} + +.business-form { + display: grid; + gap: 14px; +} + +label { + display: grid; + gap: 7px; + color: var(--muted); + font-size: 13px; + font-weight: 800; +} + +input, +select, +textarea { + width: 100%; + border: 1px solid var(--line); + background: #fff; + color: var(--ink); + padding: 11px 12px; +} + +textarea { + min-height: 92px; + resize: vertical; +} + +button { + border: 1px solid var(--ink); + background: var(--ink); + color: #fff; + cursor: pointer; + min-height: 42px; + padding: 10px 14px; + font-weight: 900; +} + +button:hover { + transform: translateY(-1px); +} + +.primary { + width: 100%; + background: var(--blue); + border-color: var(--blue); +} + +.code { + overflow: auto; + margin: 18px 0 0; + border: 1px solid #303a47; + background: var(--code); + color: #d7e2ef; + padding: 16px; + font-size: 13px; + line-height: 1.55; +} + +.order-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 12px; +} + +.order-grid article { + border: 1px solid var(--line); + background: var(--panel); + padding: 14px; +} + +.order-grid span, +.order-grid small { + display: block; + color: var(--muted); + font-size: 12px; +} + +.order-grid strong { + display: block; + margin: 8px 0 6px; + font-size: 18px; +} + +.action-row { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 10px; + margin-top: 14px; +} + +.action-row button { + min-height: 56px; + background: #fff; + color: var(--ink); +} + +.agent { + position: sticky; + top: 18px; +} + +.tool-list { + display: grid; + gap: 12px; +} + +.tool-card { + border: 1px solid var(--line); + background: var(--panel); + padding: 14px; +} + +.tool-card h3 { + margin: 0 0 8px; + font-size: 16px; +} + +.tool-card p { + margin-bottom: 10px; + color: var(--muted); + font-size: 13px; + line-height: 1.55; +} + +.schema { + overflow: auto; + max-height: 150px; + border: 1px solid var(--line); + background: #fff; + padding: 10px; + color: #384551; + font-size: 12px; + line-height: 1.5; +} + +.steps { + margin: 0 0 16px; + padding-left: 20px; + color: var(--muted); + line-height: 1.7; +} + +.log { + display: grid; + gap: 10px; + max-height: 370px; + overflow: auto; +} + +.entry { + border-left: 4px solid var(--blue); + background: #fff; + padding: 10px 12px; + font-size: 13px; + line-height: 1.5; +} + +.entry strong { + display: block; + margin-bottom: 5px; +} + +.entry pre { + margin: 0; + white-space: pre-wrap; +} + +@media (max-width: 980px) { + .topbar, + .layout { + padding-left: 18px; + padding-right: 18px; + } + + .topbar, + .layout { + display: grid; + grid-template-columns: 1fr; + } + + .agent { + position: static; + } + + .order-grid, + .action-row { + grid-template-columns: 1fr; + } +} diff --git a/slides.md b/slides.md index 838b12b..f319743 100644 --- a/slides.md +++ b/slides.md @@ -4,7 +4,7 @@ colorSchema: light title: What's New in Chrome info: | ## Chrome 新特性分享 - 面向前端、产品与技术团队的浏览器能力更新速览 + 面向 Web 开发者的 Agentic Web 与 Chrome 新能力科普 transition: slide-left mdc: true drawings: @@ -17,9 +17,9 @@ layout: intro # What's New in Chrome -Web 平台能力、DevTools 工作流与产品落地机会 +AI Agent 要操作网页了,Chrome 正在做什么? -
分享项目模板 · 首页 · 大纲 · 模拟展示详情页
+
Part 1 科普 · Part 2 官方优先 demo 演示
--- src: ./pages/overview.md @@ -33,12 +33,26 @@ src: ./pages/outline.md layout: new-section --- -# 模拟展示:从 Chrome Release Notes 到团队落地 +# Part 2:Demo 演示 + +PPT 讲新增功能,项目代码配合现场演示 --- src: ./pages/demo/release-scan.md --- +--- +src: ./pages/demo/webmcp-contract.md +--- + +--- +src: ./pages/demo/webmcp-project.md +--- + +--- +src: ./pages/demo/webmcp-script.md +--- + --- src: ./pages/demo/devtools-workflow.md ---