This commit is contained in:
2026-06-14 15:01:42 +08:00
parent 67d79b58bb
commit 6f39b960d0
15 changed files with 1709 additions and 76 deletions
+16 -12
View File
@@ -1,33 +1,37 @@
# 模拟展示 4:团队落地清单
# Demo 4:本地兜底,不抢官方主线
<div class="grid grid-cols-2 gap-8 mt-8">
<div class="card-green">
<div class="font-semibold mb-3">本周可做</div>
<div class="font-semibold mb-3">本地页面做什么</div>
<div class="space-y-2 text-sm">
- 建一个 Chrome 更新跟踪文档
- 选 1 个 DevTools 工作流做内部演示
- 为 1 个新能力写最小 demo
- 标注生产可用与仅实验的边界
- 官方资料导航
- 三路径对比仪表盘
- 现场讲述卡片
- 网络不可用时继续演示
</div>
</div>
<div class="card-red">
<div class="font-semibold mb-3">不要直接做</div>
<div class="font-semibold mb-3">本地页面不做什么</div>
<div class="space-y-2 text-sm">
- 只因 Chrome 支持就上线
- 忽略 Safari / Firefox 用户
- 把实验能力写进核心链路
- 跳过权限与隐私评估
- 不复刻所有 Chrome API
- 不依赖 flags 才能讲完
- 不做厂商 SDK 接入教程
- 不把实验能力讲成稳定能力
</div>
</div>
</div>
<div class="mt-8 card-blue text-sm">
打开本地兜底页:<span class="font-mono">/demo/index.html</span>。它是演示资料台,不是生产方案样板。
</div>
<!--
这一页把分享从“知道了”落到“接下来做什么”。建议最后留一个简单清单,让团队每月复盘一次 Chrome 更新,并把值得试验的能力进入工程 backlog。
这一页对应 plan/part2.md 的本地 demo 项目职责。后续如果官方 demo 或网络临时不可用,就打开 /demo/index.html 页面继续讲官方链接、三路径对比和风险边界。
-->
+31 -13
View File
@@ -1,32 +1,50 @@
# 模拟展示 2:DevTools 排查链路
# Demo 2:AI 操作 Web 的三种路径
<div class="mt-8">
```mermaid {scale: 0.82}
flowchart LR
A[用户反馈卡顿] --> B[Performance 录制]
B --> C[定位长任务]
C --> D[Network 查资源瀑布]
D --> E[Coverage 查无效代码]
E --> F[形成优化清单]
A[用户一句话任务] --> B{Agent 如何操作网页?}
B --> C[看截图<br/>Vision]
B --> D[读结构<br/>DOM / A11y]
B --> E[调工具<br/>WebMCP]
C --> F[慢 / 贵 / UI 敏感]
D --> G[更结构化 / 仍易误点]
E --> H[语义工具 / 参数明确 / 可控]
```
</div>
<div class="grid grid-cols-2 gap-6 mt-8">
<div class="grid grid-cols-3 gap-5 mt-8">
<div class="card">
<div class="font-semibold mb-2">演示素材</div>
<div class="text-sm text-gray-400">准备一个加载慢、交互卡顿、资源偏大的页面作为示例。</div>
<div class="card-red">
<div class="font-semibold mb-2">视觉识别</div>
<div class="text-sm text-gray-500">通用,不改页面;但每一步都要观察、推理、点击,token 与耗时容易升高。</div>
</div>
<div class="card-green">
<div class="font-semibold mb-2">观众收获</div>
<div class="text-sm text-gray-400">把 DevTools 从“会打开”变成“按链路定位问题”。</div>
<div class="font-semibold mb-2">DOM / A11y</div>
<div class="text-sm text-gray-500">比截图更结构化;但复杂组件、隐藏状态、错误点击仍然会影响可靠性。</div>
</div>
<div class="card-blue">
<div class="font-semibold mb-2">WebMCP</div>
<div class="text-sm text-gray-500">页面主动暴露工具,Agent 调业务能力,不再猜按钮和表单。</div>
</div>
</div>
<div class="mt-8 card-amber text-sm">
示例任务:创建“订单管理”模块,包括词条、菜单、角色权限绑定。案例数据只说明趋势,不承诺所有项目都有相同收益。
</div>
<!--
这一页用于现场演示细节。建议讲一个真实或模拟页面,从 Performance 开始抓主线程问题,再用 Network 和 Coverage 找资源问题,最后输出可执行的优化清单。
这一页参考中文实战材料中的三种方案对比,但剔除厂商封装概念。讲述重点不是某个 SDK 强,而是说明 AI 更适合处理结构化工具,而不是在复杂 UI 中不断猜测。
建议讲法:
1. 先说同一个后台任务:创建词条、创建菜单、绑定角色。
2. 视觉识别能做,但每步都需要截图和推理。
3. DOM / A11y 识别更接近结构,但仍可能点错或遗漏状态。
4. WebMCP 把动作变成工具:createEntry、createMenu、bindRole。
5. 结论:从“AI 猜 UI”转向“网页提供工具”。
-->
+22 -14
View File
@@ -1,28 +1,27 @@
# 模拟展示 3:Web 平台能力评估卡
# Demo 3:Chrome 官方新特性快闪
<div class="grid grid-cols-2 gap-8 mt-8">
<div class="card-blue">
<div class="font-semibold mb-3">能力示例</div>
<div class="font-semibold mb-3">Agentic Web 相关</div>
<div class="space-y-2 text-sm">
- CSS 新布局与交互能力
- View Transitions
- File System / Clipboard / Share APIs
- PWA 安装与离线体验
- 本地 AI 与浏览器内置能力探索
- WebMCP:页面暴露工具给 Agent
- Modern Web Guidance:给 AI 编程工具补现代 Web 知识
- DevTools for agents:让 Agent 看见浏览器运行时
- Prompt API:浏览器内置 AI 能力
</div>
</div>
<div class="card">
<div class="font-semibold mb-3">评估维度</div>
<div class="font-semibold mb-3">体验与平台能力</div>
<div class="space-y-2 text-sm text-gray-300">
- 用户价值:解决什么真实问题?
- 兼容性:Chrome-only 还是跨浏览器?
- 降级方案:不可用时如何处理?
- 风险:权限、隐私、性能、安全
- HTML-in-Canvas:真实 DOM 进入 Canvas / 3D
- Baseline:判断哪些 Web 能力可以放心评估
- View Transitions:页面状态切换更自然
- Navigation API:更现代的导航状态管理
</div>
</div>
@@ -30,9 +29,18 @@
</div>
<div class="mt-8 card-amber text-sm">
推荐输出格式:能力名称 / Chrome 支持状态 / 业务场景 / Demo 链接 / 风险 / 下一步。
只讲位置,不展开 API:这些官方 demo 共同说明 Chrome 正在同时升级 Agent 交互、开发工作流和用户体验。
</div>
<!--
这里可以把每个新 API 都变成一张评估卡。不要只问“能不能用”,而是问“能解决什么问题、什么时候可上线、不能用时怎么降级”。
官方快闪顺序建议:
1. WebMCP: https://developer.chrome.com/docs/ai/webmcp/imperative-api
2. Modern Web Guidance: https://developer.chrome.com/docs/modern-web-guidance
3. DevTools for agents: https://developer.chrome.com/docs/devtools/agents/get-started
4. Prompt API: https://developer.chrome.com/docs/ai/prompt-api
5. HTML-in-Canvas: https://developer.chrome.com/blog/html-in-canvas-origin-trial
6. Baseline: https://web.dev/baseline
7. View Transitions: https://view-transitions.chrome.dev/
讲法:每个只用 30-45 秒。不要现场深入配置,避免偏离 WebMCP 主线。
-->
+30 -16
View File
@@ -1,44 +1,58 @@
# 模拟展示 1:快速扫一版 Chrome 更新
# Demo 1:演示交付物总览
<div class="grid grid-cols-3 gap-5 mt-8">
<div class="card-blue">
<div class="font-semibold mb-3">信息源</div>
<div class="font-semibold mb-3">PPT 讲什么</div>
<div class="space-y-2 text-sm">
- Chrome Developers Blog
- ChromeStatus
- DevTools Release Notes
- MDN Baseline
- 分别介绍新增能力
- 说明解决的问题
- 标注成熟度和限制
- 给出官方资料来源
</div>
</div>
<div class="card-green">
<div class="font-semibold mb-3">筛选标准</div>
<div class="font-semibold mb-3">工程演示什么</div>
<div class="space-y-2 text-sm">
- 是否默认启用
- 是否跨浏览器可用
- 是否影响现有代码
- 是否带来明显产品收益
- WebMCP 可运行页面
- 声明式表单工具
- 指令式 registerTool
- 工具 schema 和调用日志
- mock runtime 兜底
</div>
</div>
<div class="card-amber">
<div class="font-semibold mb-3">输出物</div>
<div class="font-semibold mb-3">官方快闪</div>
<div class="space-y-2 text-sm">
- 3 个可试验能力
- 2 个需要关注的变更
- 1 个团队落地建议
- Modern Web Guidance
- DevTools for agents
- Prompt API / HTML-in-Canvas
- Baseline / View Transitions
</div>
</div>
</div>
<div class="mt-8 card text-sm">
原则:WebMCP 至少要有可运行工程;其他 Chrome 新能力用官方 demo 快闪,避免把现场变成环境配置课。
</div>
<!--
这一页可以模拟现场打开 release notes。重点不是最新版本号,而是演示方法:先看默认启用与兼容性,再看是否影响我们现有业务,最后只挑少数真正需要行动的条目。
官方资料入口:
- WebMCP imperative API: https://developer.chrome.com/docs/ai/webmcp/imperative-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
- Prompt API: https://developer.chrome.com/docs/ai/prompt-api
- HTML-in-Canvas: https://developer.chrome.com/blog/html-in-canvas-origin-trial
- Chrome demos index: https://chrome.dev/
讲法:先告诉观众“这不是现场复刻所有实验 API,而是用官方 demo 建立可信证据链”。这样可以降低现场失败风险。
-->
+43
View File
@@ -0,0 +1,43 @@
# Demo 2:WebMCP 到底演示什么?
<div class="grid grid-cols-2 gap-8 mt-8">
<div class="card-blue">
<div class="font-semibold mb-3">一句话</div>
<div class="space-y-3 text-sm">
WebMCP 让网页把业务能力暴露成结构化工具,Agent 看到的是工具名、描述、参数 schema 和执行结果,而不是只靠截图或 DOM 猜按钮。
<div class="font-mono text-xs opacity-80">
navigator.modelContext.registerTool(...)
</div>
</div>
</div>
<div class="card-green">
<div class="font-semibold mb-3">两种 API</div>
<div class="space-y-2 text-sm">
- 声明式:给标准 HTML 表单添加工具属性
- 指令式:用 JavaScript 注册复杂工具
- 共同目标:把页面能力变成 Agent 可理解的契约
- 演示口径:提高可靠性,不承诺零错误率
</div>
</div>
</div>
<div class="mt-8 card-amber text-sm">
实验边界:Chrome 官方文档标注 WebMCP 仍处于 proposed / origin trial / flag 阶段;现场 demo 必须有 mock 兜底。
</div>
<!--
官方依据:
- https://developer.chrome.com/docs/ai/webmcp
- https://developer.chrome.com/docs/ai/webmcp/imperative-api
- https://developer.chrome.com/docs/lighthouse/agentic-browsing/registered-webmcp-tools
讲法:不要说“零错误率”。更稳妥的表达是“减少 Agent 猜 UI 的步骤,提高性能、可靠性和任务完成准确率”。
-->
+40
View File
@@ -0,0 +1,40 @@
# Demo 3:WebMCP 原始工程能跑起来
<div class="grid grid-cols-[1.05fr_0.95fr] gap-8 mt-8">
<div class="card">
<div class="font-semibold mb-3">工程文件</div>
```txt
public/demo/webmcp/
├── index.html # 业务 UI + 声明式表单工具
├── styles.css # 演示界面样式
└── app.js # registerTool + mock runtime + 执行日志
```
</div>
<div class="card-blue">
<div class="font-semibold mb-3">运行入口</div>
<div class="space-y-3 text-sm">
- 启动:`pnpm dev`
- 打开:`/demo/webmcp/index.html`
- 无 WebMCP 环境:走本地 mock runtime
- 有 WebMCP 环境:优先调用 `navigator.modelContext`
</div>
</div>
</div>
<div class="mt-8 card-green text-sm">
这页要现场打开工程,不只讲链接。观众能看到“页面 UI”和“Agent 工具视角”同时存在。
</div>
<!--
现场建议:
1. 先打开 http://localhost:3030/demo/webmcp/index.html 或实际 dev server URL。
2. 展示左侧 HTML 表单和右侧工具列表。
3. 再切到 app.js,解释 registerTool 的 name / description / inputSchema / execute。
-->
+41
View File
@@ -0,0 +1,41 @@
# Demo 4:现场操作脚本
<div class="grid grid-cols-4 gap-4 mt-8">
<div class="card-blue">
<div class="font-semibold mb-3">1. 人类 UI</div>
<div class="text-sm">
提交售后工单表单,说明原有页面流程没有被替换。
</div>
</div>
<div class="card-green">
<div class="font-semibold mb-3">2. 工具发现</div>
<div class="text-sm">
右侧展示工具名、描述、schema:这是 Agent 看到的契约。
</div>
</div>
<div class="card-amber">
<div class="font-semibold mb-3">3. 单工具调用</div>
<div class="text-sm">
点击查询订单、生成回复、退款审核,观察状态和日志变化。
</div>
</div>
<div class="card-red">
<div class="font-semibold mb-3">4. 复合任务</div>
<div class="text-sm">
执行复合任务:查询订单 → 进入审核 → 生成回复草稿。
</div>
</div>
</div>
<div class="mt-8 card text-sm">
讲解结论:WebMCP 不是让 Agent 更会点击,而是让网页直接声明“我有哪些可调用能力”。敏感动作仍然要保留用户确认、权限和审计。
</div>
<!--
不要现场陷入标准细节。演示后马上回到大图:Chrome 通过 WebMCP、DevTools for agents、Modern Web Guidance 等能力,让 Web 逐步变成 Agent 可以协作的运行环境。
-->
+9 -9
View File
@@ -4,30 +4,30 @@
<div class="card p-5">
<div class="text-blue-400 text-sm font-semibold mb-2">01</div>
<div class="text-xl font-bold mb-2">Chrome 更新怎么看</div>
<div class="text-sm text-gray-400">Release Notes · ChromeStatus · Baseline · Origin Trials</div>
<div class="text-xl font-bold mb-2">浏览器的新使用者</div>
<div class="text-sm text-gray-400">Human UI · Agent layer · Structured actions</div>
</div>
<div class="card-green p-5">
<div class="text-emerald-400 text-sm font-semibold mb-2">02</div>
<div class="text-xl font-bold mb-2">Web 平台新能力</div>
<div class="text-sm text-gray-400">CSS · Web APIs · PWA · Media · AI-adjacent APIs</div>
<div class="text-xl font-bold mb-2">AI 操作网页为什么难</div>
<div class="text-sm text-gray-400">Vision · DOM / A11y · Tool calling</div>
</div>
<div class="card-amber p-5">
<div class="text-amber-400 text-sm font-semibold mb-2">03</div>
<div class="text-xl font-bold mb-2">DevTools 工作流</div>
<div class="text-sm text-gray-400">Performance · Network · CSS Overview · Recorder</div>
<div class="text-xl font-bold mb-2">MCP / WebMCP</div>
<div class="text-sm text-gray-400">Tool schema · Structured actions · Safety boundary</div>
</div>
<div class="card-red p-5">
<div class="text-red-400 text-sm font-semibold mb-2">04</div>
<div class="text-xl font-bold mb-2">落地与风险</div>
<div class="text-sm text-gray-400">兼容性 · 安全边界 · 灰度策略 · 团队清单</div>
<div class="text-xl font-bold mb-2">官方 demo 快闪</div>
<div class="text-sm text-gray-400">MWG · DevTools agents · Prompt API · HTML-in-Canvas</div>
</div>
</div>
<!--
建议讲法:先讲信息入口,再讲能力分类,最后讲如何落地。这样听众不会只记住几个孤立 API,而是学会建立自己的 Chrome 更新雷达。
建议讲法:第一部分先建立 Agentic Web 概念,第二部分用官方 demo 和本地兜底页证明“从猜 UI 到调用工具”的转变。Chrome 其它新特性只做快闪,不抢 WebMCP 主线。
-->
+8 -8
View File
@@ -6,10 +6,10 @@
<div class="font-semibold mb-3">听众能获得</div>
<div class="space-y-2 text-sm">
- Chrome 近期值得关注的新能力地图
- 哪些能力已经适合进入生产评估
- 如何用 DevTools 更快定位性能与兼容性问题
- 如何把浏览器更新转成团队行动项
- 理解 AI Agent 操作网页为什么困难
- 看懂 Chrome 新增能力各自解决什么问题
- 知道 PPT 与项目代码分别如何演示这些能力
- 建立实验能力的风险边界
</div>
</div>
@@ -19,9 +19,9 @@
<div class="space-y-2 text-sm text-gray-300">
- 不逐条朗读全部 release notes
- 不做浏览器内核源码分析
- 不承诺所有实验能力都可直接上线
- 不替代真实项目的兼容性验证
- 不做厂商 SDK 接入教程
- 不复刻每一个 Chrome 实验 API
- 不承诺实验能力可直接进入生产核心链路
</div>
</div>
@@ -29,5 +29,5 @@
</div>
<!--
这一页是分享定位。Chrome 更新频率很高,真正有价值的不是把每个版本的新字段都念一遍,而是帮助团队快速判断:哪些变化影响我们现在的产品,哪些能力值得试验,哪些 DevTools 工作流可以马上提高排查效率。
这一页是分享定位。第一部分讲概念,第二部分讲 demo。第二部分的产物是 PPT 加项目代码:PPT 分别介绍新增加的功能,项目代码配合官方材料完成现场演示与兜底。
-->
+97
View File
@@ -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/
+583
View File
@@ -0,0 +1,583 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Part 2 Demo - Agentic Web</title>
<style>
:root {
color-scheme: light;
--ink: #17202a;
--muted: #64717f;
--line: #d9e1e8;
--panel: #f7f9fb;
--paper: #ffffff;
--blue: #2357d4;
--green: #0f7d58;
--amber: #aa6a00;
--red: #bb3e37;
--violet: #5d4cc2;
--shadow: 0 18px 60px rgb(45 62 80 / 0.13);
}
* {
box-sizing: border-box;
}
body {
margin: 0;
font-family:
ui-sans-serif,
"PingFang SC",
"Microsoft YaHei",
"Noto Sans SC",
sans-serif;
color: var(--ink);
background:
linear-gradient(90deg, rgb(23 32 42 / 0.05) 1px, transparent 1px),
linear-gradient(rgb(23 32 42 / 0.05) 1px, transparent 1px),
#eef3f7;
background-size: 32px 32px;
}
a {
color: inherit;
text-decoration: none;
}
.shell {
display: grid;
grid-template-columns: minmax(280px, 360px) minmax(0, 1fr);
gap: 24px;
min-height: 100vh;
padding: 28px;
}
.rail,
.stage {
border: 1px solid var(--line);
background: rgb(255 255 255 / 0.88);
box-shadow: var(--shadow);
}
.rail {
position: sticky;
top: 28px;
align-self: start;
min-height: calc(100vh - 56px);
padding: 24px;
}
.eyebrow {
margin: 0 0 12px;
color: var(--blue);
font-size: 12px;
font-weight: 800;
letter-spacing: 0.08em;
text-transform: uppercase;
}
h1,
h2,
h3,
p {
margin-top: 0;
}
h1 {
max-width: 11ch;
margin-bottom: 18px;
font-family: Georgia, "Times New Roman", serif;
font-size: clamp(42px, 5vw, 74px);
line-height: 0.92;
letter-spacing: 0;
}
.lead {
color: var(--muted);
font-size: 16px;
line-height: 1.75;
}
.quick {
display: grid;
gap: 10px;
margin: 26px 0;
}
.quick button {
width: 100%;
border: 1px solid var(--line);
background: var(--paper);
color: var(--ink);
cursor: pointer;
display: grid;
grid-template-columns: 26px 1fr;
align-items: center;
gap: 10px;
min-height: 44px;
padding: 10px 12px;
text-align: left;
font: inherit;
}
.quick button:hover,
.quick button.active {
border-color: var(--blue);
background: #eef4ff;
}
.num {
display: grid;
place-items: center;
width: 26px;
height: 26px;
background: var(--ink);
color: white;
font-size: 12px;
font-weight: 800;
}
.note {
border-left: 4px solid var(--amber);
padding: 12px 14px;
background: #fff7e8;
color: #6f4b12;
font-size: 13px;
line-height: 1.65;
}
.stage {
padding: 28px;
}
.hero {
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(280px, 0.8fr);
gap: 22px;
align-items: stretch;
margin-bottom: 24px;
}
.statement {
min-height: 280px;
padding: 28px;
color: white;
background:
linear-gradient(135deg, rgb(23 32 42 / 0.94), rgb(35 87 212 / 0.82)),
radial-gradient(circle at 15% 20%, rgb(255 255 255 / 0.18), transparent 28%);
}
.statement h2 {
max-width: 720px;
margin-bottom: 18px;
font-size: clamp(28px, 4vw, 54px);
line-height: 1.02;
}
.statement p {
max-width: 760px;
color: rgb(255 255 255 / 0.78);
font-size: 17px;
line-height: 1.75;
}
.metric-grid {
display: grid;
gap: 12px;
}
.metric {
border: 1px solid var(--line);
background: var(--panel);
padding: 18px;
}
.metric strong {
display: block;
margin-bottom: 4px;
font-size: 28px;
}
.metric span {
color: var(--muted);
font-size: 13px;
}
.section {
margin-top: 24px;
}
.section h2 {
margin-bottom: 12px;
font-size: 26px;
}
.cards {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 14px;
}
.path-card,
.resource-card {
border: 1px solid var(--line);
background: var(--paper);
padding: 18px;
}
.path-card {
min-height: 250px;
}
.tag {
display: inline-flex;
align-items: center;
min-height: 24px;
margin-bottom: 14px;
padding: 3px 9px;
color: white;
font-size: 12px;
font-weight: 800;
}
.tag.red {
background: var(--red);
}
.tag.green {
background: var(--green);
}
.tag.blue {
background: var(--blue);
}
.tag.violet {
background: var(--violet);
}
.path-card h3,
.resource-card h3 {
margin-bottom: 8px;
font-size: 20px;
}
.path-card p,
.resource-card p {
color: var(--muted);
line-height: 1.65;
}
.path-card ul {
margin: 14px 0 0;
padding-left: 18px;
color: var(--muted);
line-height: 1.7;
}
.table {
width: 100%;
border-collapse: collapse;
overflow: hidden;
background: var(--paper);
}
.table th,
.table td {
border: 1px solid var(--line);
padding: 14px;
text-align: left;
vertical-align: top;
}
.table th {
background: var(--ink);
color: white;
font-size: 13px;
}
.table td {
color: var(--muted);
line-height: 1.55;
}
.resources {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
}
.resource-card {
position: relative;
min-height: 165px;
transition:
transform 160ms ease,
box-shadow 160ms ease;
}
.resource-card:hover {
box-shadow: 0 12px 32px rgb(35 87 212 / 0.13);
transform: translateY(-2px);
}
.resource-card .url {
color: var(--blue);
font-size: 13px;
overflow-wrap: anywhere;
}
.fallback {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
.fallback > div {
border: 1px solid var(--line);
padding: 18px;
background: var(--panel);
}
.fallback h3 {
margin-bottom: 8px;
}
.fallback p {
color: var(--muted);
line-height: 1.65;
}
@media (max-width: 980px) {
.shell,
.hero,
.fallback {
grid-template-columns: 1fr;
}
.rail {
position: static;
min-height: auto;
}
.cards,
.resources {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<main class="shell">
<aside class="rail">
<p class="eyebrow">Part 2 Demo Desk</p>
<h1>Agentic Web</h1>
<p class="lead">
官方 demo 优先,本地页面只负责串联叙事和兜底。现场不依赖实验 flags,也不复刻所有 Chrome API。
</p>
<nav class="quick" aria-label="Demo sections">
<button class="active" data-target="paths"><span class="num">1</span><span>三种操作路径</span></button>
<button data-target="webmcp"><span class="num">2</span><span>WebMCP 可运行 demo</span></button>
<button data-target="resources"><span class="num">3</span><span>官方 demo 资料</span></button>
<button data-target="fallback"><span class="num">4</span><span>现场兜底讲法</span></button>
</nav>
<div class="note">
讲述原则:案例数据只说明趋势,不代表所有项目;实验能力必须标注支持边界和渐进增强。
</div>
</aside>
<section class="stage">
<div class="hero">
<section class="statement">
<p class="eyebrow">Core Message</p>
<h2>从“AI 猜 UI”到“网页暴露工具”。</h2>
<p>
视觉识别和 DOM 识别让 Agent 尝试理解页面表象;WebMCP 的方向是让页面主动提供结构化能力,
让 Agent 调用工具、传入参数、拿到结果。
</p>
</section>
<aside class="metric-grid" aria-label="Demo principles">
<div class="metric">
<strong>官方</strong>
<span>优先展示 Chrome 官方文档、demo 和命令示例</span>
</div>
<div class="metric">
<strong>本地</strong>
<span>WebMCP 提供可运行工程,其他实验能力用官方 demo 快闪</span>
</div>
<div class="metric">
<strong>15 分钟</strong>
<span>建议 demo 段控制在 12-15 分钟</span>
</div>
</aside>
</div>
<section id="paths" class="section">
<h2>同一个后台任务,三种 Agent 操作路径</h2>
<div class="cards">
<article class="path-card">
<span class="tag red">Vision</span>
<h3>看截图</h3>
<p>Agent 通过视觉模型识别菜单、按钮、输入框,再一步步点击。</p>
<ul>
<li>优点:不需要改造页面</li>
<li>风险:慢、贵、UI 变化敏感</li>
<li>适合:临时探索和低风险页面</li>
</ul>
</article>
<article class="path-card">
<span class="tag green">DOM / A11y</span>
<h3>读结构</h3>
<p>Agent 读取 DOM 或可访问性树,通过结构化信息定位交互元素。</p>
<ul>
<li>优点:比截图更结构化</li>
<li>风险:复杂组件和隐藏状态仍会误导</li>
<li>适合:语义清晰的表单页面</li>
</ul>
</article>
<article class="path-card">
<span class="tag blue">WebMCP</span>
<h3>调工具</h3>
<p>页面暴露工具名、描述、参数 schema 和执行逻辑,Agent 直接调用业务能力。</p>
<ul>
<li>优点:语义明确、速度快、过程可控</li>
<li>风险:仍需权限、确认和审计边界</li>
<li>适合:复杂后台和重复流程</li>
</ul>
</article>
</div>
</section>
<section class="section">
<h2>对比讲述表</h2>
<table class="table">
<thead>
<tr>
<th>维度</th>
<th>视觉识别</th>
<th>DOM / A11y</th>
<th>WebMCP</th>
</tr>
</thead>
<tbody>
<tr>
<td>交互方式</td>
<td>观察截图后猜测点击位置</td>
<td>读取结构后定位元素</td>
<td>调用页面声明的语义工具</td>
</tr>
<tr>
<td>稳定性</td>
<td>受视觉布局影响明显</td>
<td>受 DOM 结构和组件状态影响</td>
<td>受工具设计、权限和业务逻辑影响</td>
</tr>
<tr>
<td>现场讲法</td>
<td>“像让 AI 蒙着眼睛找按钮”</td>
<td>“给了地图,但地图可能不完整”</td>
<td>“给了工具入口和参数说明”</td>
</tr>
</tbody>
</table>
</section>
<section id="webmcp" class="section">
<h2>WebMCP 原始工程 demo</h2>
<div class="fallback">
<div>
<h3>运行入口</h3>
<p>
打开 <a href="./webmcp/index.html">/demo/webmcp/index.html</a>,展示声明式表单工具、
指令式 JS 工具、工具 schema 面板和复合任务调用日志。
</p>
</div>
<div>
<h3>讲述重点</h3>
<p>
先让人提交表单,再让工具面板执行同一类任务。观众会看到 Agent 不需要猜 UI,
它看到的是工具名、描述、参数 schema 和执行结果。
</p>
</div>
</div>
</section>
<section id="resources" class="section">
<h2>官方 demo 与资料入口</h2>
<div class="resources">
<a class="resource-card" href="https://developer.chrome.com/docs/ai/webmcp/imperative-api" target="_blank" rel="noreferrer">
<span class="tag blue">WebMCP</span>
<h3>Imperative API</h3>
<p>使用 document.modelContext.registerTool 暴露工具,官方示例包含 pizza layer 和 order status。</p>
<div class="url">developer.chrome.com/docs/ai/webmcp/imperative-api</div>
</a>
<a class="resource-card" href="https://developer.chrome.com/docs/modern-web-guidance" target="_blank" rel="noreferrer">
<span class="tag green">MWG</span>
<h3>Modern Web Guidance</h3>
<p>给 AI 编程工具补充现代 Web 知识、兼容性和最佳实践。</p>
<div class="url">developer.chrome.com/docs/modern-web-guidance</div>
</a>
<a class="resource-card" href="https://developer.chrome.com/docs/devtools/agents/get-started" target="_blank" rel="noreferrer">
<span class="tag violet">DevTools</span>
<h3>Chrome DevTools for agents</h3>
<p>让 coding agent 访问真实浏览器、console、network、performance trace 和 Lighthouse。</p>
<div class="url">developer.chrome.com/docs/devtools/agents/get-started</div>
</a>
<a class="resource-card" href="https://developer.chrome.com/docs/ai/prompt-api" target="_blank" rel="noreferrer">
<span class="tag blue">Prompt API</span>
<h3>Built-in AI</h3>
<p>浏览器内置语言模型能力,适合作为渐进增强展示。</p>
<div class="url">developer.chrome.com/docs/ai/prompt-api</div>
</a>
<a class="resource-card" href="https://developer.chrome.com/blog/html-in-canvas-origin-trial" target="_blank" rel="noreferrer">
<span class="tag red">Canvas</span>
<h3>HTML-in-Canvas</h3>
<p>把真实 DOM 放入 Canvas / WebGL / WebGPU 场景,同时保留浏览器能力。</p>
<div class="url">developer.chrome.com/blog/html-in-canvas-origin-trial</div>
</a>
<a class="resource-card" href="https://view-transitions.chrome.dev/" target="_blank" rel="noreferrer">
<span class="tag green">UX</span>
<h3>View Transitions</h3>
<p>官方交互 demo,用于快闪展示 Web 体验能力升级。</p>
<div class="url">view-transitions.chrome.dev</div>
</a>
</div>
</section>
<section id="fallback" class="section">
<h2>现场兜底讲法</h2>
<div class="fallback">
<div>
<h3>如果官方 demo 打不开</h3>
<p>
继续使用本页的卡片和对比表讲主线:AI 不擅长猜复杂 UI,WebMCP 的价值是结构化暴露工具。
官方链接可作为会后资料。
</p>
</div>
<div>
<h3>如果有人追问落地</h3>
<p>
只回答原则:渐进增强、权限继承、高危确认、审计日志、工具按需暴露。
不在本场扩展到厂商 SDK 选型和企业架构。
</p>
</div>
</div>
</section>
</section>
</main>
<script>
const buttons = Array.from(document.querySelectorAll(".quick button"));
buttons.forEach((button) => {
button.addEventListener("click", () => {
buttons.forEach((item) => item.classList.remove("active"));
button.classList.add("active");
document.getElementById(button.dataset.target)?.scrollIntoView({
behavior: "smooth",
block: "start",
});
});
});
</script>
</body>
</html>
+277
View File
@@ -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 = `
<h3>${tool.name}</h3>
<p>${tool.description}</p>
<span class="pill">${tool.source}</span>
<pre class="schema">${escapeHtml(JSON.stringify(tool.inputSchema, null, 2))}</pre>
`;
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 = `<strong>${title}</strong><pre>${escapeHtml(JSON.stringify(payload, null, 2))}</pre>`;
logEl.prepend(entry);
}
function escapeHtml(value) {
return String(value)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll('"', "&quot;");
}
+148
View File
@@ -0,0 +1,148 @@
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>WebMCP Demo - Tool Contracts</title>
<link rel="stylesheet" href="./styles.css" />
</head>
<body>
<header class="topbar">
<div>
<p class="eyebrow">Runnable demo</p>
<h1>WebMCP 工具契约演示</h1>
</div>
<div class="runtime">
<span id="native-status" class="pill">检测中</span>
<a href="https://developer.chrome.com/docs/ai/webmcp" target="_blank" rel="noreferrer">Chrome 官方文档</a>
</div>
</header>
<main class="layout">
<section class="workspace">
<div class="intro">
<p>
这个页面模拟一个售后后台:左侧是人能操作的业务 UI,右侧是页面暴露给 Agent 的工具契约。
如果当前 Chrome 没有开启 WebMCP,本页面会使用本地 mock,让现场仍然能看清楚“工具注册”和“工具调用”的流程。
</p>
</div>
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow">Declarative API</p>
<h2>声明式:把 HTML 表单变成工具</h2>
</div>
<span class="mode">form attributes</span>
</div>
<form
id="ticket-form"
class="business-form"
toolname="create_support_ticket"
tooldescription="Create a support ticket from user supplied issue details."
>
<label>
客户邮箱
<input name="email" type="email" required value="dev@example.com" />
</label>
<label>
问题类型
<select name="category" required>
<option value="refund">退款</option>
<option value="delivery">物流</option>
<option value="account">账号</option>
</select>
</label>
<label>
问题描述
<textarea name="description" required>订单 CHR-2026-0614 到货后发现配件缺失。</textarea>
</label>
<button type="submit">提交工单</button>
</form>
<pre class="code"><code>&lt;form
toolname="create_support_ticket"
tooldescription="Create a support ticket from user supplied issue details."&gt;
&lt;input name="email" type="email" required /&gt;
&lt;select name="category" required&gt;...&lt;/select&gt;
&lt;textarea name="description" required&gt;&lt;/textarea&gt;
&lt;/form&gt;</code></pre>
</section>
<section class="panel">
<div class="panel-head">
<div>
<p class="eyebrow">Imperative API</p>
<h2>指令式:用 JavaScript 注册业务工具</h2>
</div>
<span class="mode">registerTool()</span>
</div>
<div class="order-grid">
<article>
<span>订单号</span>
<strong>CHR-2026-0614</strong>
<small>已签收,缺件风险</small>
</article>
<article>
<span>客户等级</span>
<strong>Enterprise</strong>
<small>允许优先退款审核</small>
</article>
<article>
<span>当前状态</span>
<strong id="order-state">等待处理</strong>
<small>由工具调用更新</small>
</article>
</div>
<div class="action-row">
<button data-run-tool="lookup_order_status">运行 lookup_order_status</button>
<button data-run-tool="draft_customer_reply">运行 draft_customer_reply</button>
<button data-run-tool="approve_refund_review">运行 approve_refund_review</button>
</div>
<pre class="code"><code>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 }) =&gt; lookupOrder(orderId)
});</code></pre>
</section>
</section>
<aside class="agent">
<section class="agent-panel">
<p class="eyebrow">Agent view</p>
<h2>已暴露工具</h2>
<div id="tool-list" class="tool-list"></div>
</section>
<section class="agent-panel">
<p class="eyebrow">Run script</p>
<h2>现场演示步骤</h2>
<ol class="steps">
<li>先提交左侧表单,说明“人类 UI 仍然可用”。</li>
<li>看右侧工具列表,说明 Agent 看到的是名称、描述和 JSON Schema。</li>
<li>点击工具运行按钮,说明 Agent 不需要猜按钮位置,而是调用明确工具。</li>
<li>点击“执行复合任务”,串起查询、决策和回复草稿。</li>
</ol>
<button id="run-workflow" class="primary">执行复合任务</button>
</section>
<section class="agent-panel log-panel">
<p class="eyebrow">Execution log</p>
<h2>调用日志</h2>
<div id="log" class="log"></div>
</section>
</aside>
</main>
<script type="module" src="./app.js"></script>
</body>
</html>
+346
View File
@@ -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;
}
}
+18 -4
View File
@@ -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 正在做什么?
<div class="pt-4 text-sm op-60">分享项目模板 · 首页 · 大纲 · 模拟展示详情页</div>
<div class="pt-4 text-sm op-60">Part 1 科普 · Part 2 官方优先 demo 演示</div>
---
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
---