当前位置: 首页 > article >正文

Claude生成式UI的逆向与利用

Anthropic 在几个小时前宣布为 Claude 提供生成式 UI。交互式小部件 - 滑块、图表、动画 - 在 claude.ai 对话中内联渲染。不是图像。不是代码块。是在聊天中运行的 JavaScript 的实时 HTML 应用程序。这并不令人惊讶。Vercel 和其他公司已经推广生成式 UI 有一段时间了我知道 Anthropic 会做些什么。这也不是我第一次深入研究 Anthropic 的实现细节 - 我之前逆向工程了他们的沙箱架构并写过关于他们沙箱的文章。所以我带着特定的目的去了 claude.ai完全理解他们是如何实现它的。最终我为自己构建了一个版本用于 pi这是一个基于终端的编码代理。1、询问 Claude 关于它自己的 UI1.1 工具而不是 Markdown我的第一个假设是错误的。我认为 Claude 将 HTML 作为其 markdown 响应的一部分输出前端将其内联渲染。Claude 纠正了我“哈是的抓住了 - 这根本不是’markdown 输出的一部分’。我调用一个名为show_widget的工具并将 HTML 作为参数传递。”所以它是一个工具调用。与网络搜索或文件操作相同的机制。HTML 是参数负载而不是流式文本。以下是 Claude 描述的形状{ i_have_seen_read_me: true, title: snake_case_identifier, loading_messages: [First loading message, Second loading message], widget_code: ...styles...\n...html content...\n... }四个参数i_have_seen_read_me- 一个强制函数的布尔值。Claude 必须首先调用read_me工具来加载设计指南然后才能使用show_widget。这是文档合规性的编译时检查。title- 小部件的 snake_case 标识符。loading_messages- 在小部件渲染时显示的 1-4 个短字符串在内容出现之前你看到的启动粒子…消息。widget_code- 原始 HTML 片段。没有!DOCTYPE没有html没有head没有body。只有内容。1.2read_me模式 - 渐进式披露在 Claude 可以调用show_widget之前它必须使用modules参数调用read_me{ modules: [interactive, chart] }可用模块diagram、mockup、interactive、chart、art。每个模块返回不同的设计指南 -chart模块提供 Chart.js 模式art提供插图规则mockup提供 UI 组件标记。Claude 完美地描述了它“这是一个懒惰的文档系统 - 而不是将整个设计系统预先转储到我的上下文中这会在每条消息中花费昂贵的 token它只按需加载相关的子集。”这是应用于模型自身指令的渐进式披露。基本系统提示保持精简专业知识在任务需要时按需加载。1.3 不是 Iframe - 实时 DOM 注入我注意到小部件在 Claude 流式传输其响应时实时渲染。滑块和卡片在 Claude 完成生成widget_code参数之前就出现了。这不是 iframe 的工作方式 - iframe 需要完整的 HTML 才能渲染。Claude 最初声称它是一个沙箱化的 iframe但我反驳了“它在我的屏幕上实时渲染这意味着它以某种方式处理 HTML 的部分渲染。这不是一个沙箱。”Claude 的修订分析“流式行为完全暴露了这一点。如果是沙箱化的 iframe它必须在渲染之前等待完整的 HTML。但你看到它随着令牌的流入而渲染。只有当它直接注入到父页面的 DOM时这才是可能的。”证据CSS 变量工作-var(--color-text-primary)正确解析因为它是同一文档同一级联sendPrompt()工作- 父页面上的函数可被注入的代码访问背景是透明的- 没有 iframe 容器只有 DOM 中的节点没有加载闪烁- 没有 iframe 边框没有滚动条没有白色背景框沙箱几乎肯定只是父页面上的内容安全策略限制script src标记可以从哪些 CDN 域加载cdnjs.cloudflare.comcdn.jsdelivr.netunpkg.comesm.sh1.3 它与 Artifacts 的区别这是对话中的一个关键见解ArtifactsVisualizer (show_widget)Purpose可交付成果 - 你保留、下载、共享的文件内联增强 - 对话流程的一部分Display带有下载按钮的侧边栏聊天中内联透明背景Libraries预捆绑库的固定集CDN 允许列表中的任何库实时下载Persistence跨会话持久存在临时与消息绑定Trigger“为我构建一个计算器”可交付成果语言“向我展示复利如何运作”解释性语言CDN 点至关重要。Artifacts 有固定的一组可用库。可视化器从 CDN 实时下载 Chart.js、D3、Three.js - 无论它需要什么。这就是 CSP 允许列表存在的原因它是任意 CDN 获取的安全边界。1.4 流式架构综上所述以下是 claude.ai 渲染生成式 UI 的方式LLM 开始生成show_widget工具调用widget_code参数作为 JSON 字符串块逐令牌流式传输客户端对部分内容进行增量 HTML 解析DOM 节点通过innerHTML或类似方式实时插入页面CSS 变量立即解析同一文档style块和 HTML 结构在到达时渲染script标记在流式传输完成后执行这就是脚本放在最后的原因CDN 库异步加载图表/交互性在脚本运行后激活这解释了设计指南中说的构建代码以使有用内容尽早出现style短→ 内容 HTML →script最后。内容渐进式渲染脚本在最后激活它。2、为 Pi 构建它Pi 是一个基于终端的编码代理如果你好奇的话我比较了每个 CLI 编码代理。终端渲染文本和在现代终端中内联图像。没有办法在终端内渲染带有 JavaScript 的交互式 HTML。当你需要canvas、input typerange或 Chart.js 时你需要一个浏览器引擎。我的最初选择是终端图像协议Sixel、Kitty 图形 - 将 HTML 渲染为截图内联显示。没有交互性。本地 Web 服务器 浏览器- 在 localhost 上提供 HTML自动打开浏览器标签页。完全交互性但退出终端。TUI 近似- 解析 HTML渲染简化的文本版本。极其有限。这些都不符合 claude.ai 的体验。2.1 进入 Glimpse然后我发现了 Glimpse - 一个原生 macOS 微 UI 库。它通过带有 Node.js 包装器的微型 Swift 二进制文件在 50 毫秒内打开 WKWebView 窗口。没有 Electron没有浏览器没有运行时依赖。关键能力原生 WKWebView- 完整的浏览器引擎CSS、JS、Canvas、CDN 库50 毫秒以下启动- 感觉即时双向 JSON-window.glimpse.send(data)将数据从页面发送回 Node.js窗口模式- 浮动、无框、透明、点击穿透、跟随光标setHTML()- 在运行时替换页面内容send(js)- 在 WebView 中评估 JavaScript这是缺失的部分。一个真正的浏览器引擎可从 pi 扩展生成具有双向通信。2.2 扩展架构Pi 扩展是 TypeScript 模块可以注册自定义工具订阅生命周期事件并渲染自定义 TUI 组件。架构LLM 生成 show_widget 工具调用 │ ▼ ┌───────────────────┐ │ message_update │──── 流式传输拦截部分工具调用 JSON │ event │ 提取 widget_code尽早打开 Glimpse 窗口 └────────┬──────────┘ 在令牌到达时输入部分 HTML │ ▼ ┌───────────────────┐ │ tool_call │──── 完成最终 widget_code 可用 │ event │ └────────┬──────────┘ │ ▼ ┌───────────────────┐ │ execute() │──── 重用流式传输窗口或打开新窗口 │ │ 等待用户交互或窗口关闭 └────────┬──────────┘ 返回交互数据作为工具结果 │ ▼ ┌───────────────────┐ │ renderCall │──── TUIshow_widget compound interest 800×600 │ renderResult │──── TUI✓ compound interest 800×600 └───────────────────┘2.3 两个工具镜像 Claude 的模式visualize_read_me- 懒惰文档加载器。按模块返回设计指南interactive、chart、mockup、art、diagram。LLM 在其第一个小部件之前静默调用此方法仅将相关指南加载到上下文中。pi.registerTool({ name: visualize_read_me, label: Read Guidelines, description: Returns design guidelines for show_widget..., promptGuidelines: [ Call visualize_read_me once before your first show_widget call., Do NOT mention the read_me call to the user., ], parameters: Type.Object({ modules: Type.Array(StringEnum(AVAILABLE_MODULES)), }), async execute(_toolCallId, params) { return { content: [{ type: text, text: getGuidelines(params.modules) }], details: { modules: params.modules }, }; }, });show_widget- 接受 HTML/SVG 代码通过 Glimpse 打开原生 macOS 窗口返回用户交互数据。pi.registerTool({ name: show_widget, label: Show Widget, description: Show visual content in a native macOS window..., parameters: Type.Object({ i_have_seen_read_me: Type.Boolean(), title: Type.String(), widget_code: Type.String(), width: Type.Optional(Type.Number()), height: Type.Optional(Type.Number()), floating: Type.Optional(Type.Boolean()), }), async execute(_toolCallId, params, signal) { const { open } await import(GLIMPSE_PATH); const win open(wrapHTML(params.widget_code), { width: params.width ?? 800, height: params.height ?? 600, title: params.title.replace(/_/g, ), }); return new Promise((resolve) { win.on(message, (data) { resolve({ content: [{ type: text, text: User data: ${JSON.stringify(data)} }] }); }); win.on(closed, () { resolve({ content: [{ type: text, text: Window closed. }] }); }); }); }, });2.4 自定义 TUI 渲染Pi 扩展可以提供renderCall和renderResult函数用于自定义终端显示。而不是将原始 HTML 转储到终端我们显示紧凑的摘要renderCall(args, theme) { const title args.title.replace(/_/g, ); return new Text( theme.fg(toolTitle, theme.bold(show_widget )) theme.fg(accent, title) theme.fg(dim, ${args.width}×${args.height}), 0, 0 ); }, renderResult(result, { isPartial, expanded }, theme) { if (isPartial) return new Text(theme.fg(warning, ⟳ Widget rendering...), 0, 0); const details result.details; let text theme.fg(success, ✓ ) theme.fg(accent, details.title); if (expanded details.messageData) { text \n theme.fg(dim, Data: ${JSON.stringify(details.messageData)}); } return new Text(text, 0, 0); },3、流式传输挑战在 claude.ai 上小部件随着令牌的流入而渐进式渲染。HTML 在视觉上建立 - 你看到样式应用结构形成卡片和表格逐个出现然后当script在最后执行时图表弹出。我们想要相同的体验Glimpse 窗口应该尽早打开并实时显示内容构建。3.1 Pi 如何流式传输工具调用Pi 的 AI 层pi-ai将所有提供商Anthropic、OpenAI、Google 等的流式事件规范化为统一格式type AssistantMessageEvent | { type: toolcall_start; contentIndex: number; partial: AssistantMessage } | { type: toolcall_delta; contentIndex: number; delta: string; partial: AssistantMessage } | { type: toolcall_end; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage }关键发现pi-ai 已经在每个增量上解析部分 JSON。查看 Anthropic 提供商源代码block.partialJson event.delta.partial_json; block.arguments parseStreamingJson(block.partialJson);所以partial.content[index].arguments是一个渐进式解析的对象。在每个toolcall_delta上我们可以读取arguments.widget_code并获取到目前为止累积的 HTML - 不需要部分 JSON 解析器库。我们在发现这一点之前最初从 npm 安装了partial-json。立即删除了它。3.2 尝试 1在每个增量上调用setHTML()第一种方法监听message_update检测show_widget工具调用流式传输打开 Glimpse 窗口并在每个增量上调用win.setHTML(wrappedHTML)。pi.on(message_update, async (event) { const raw event.assistantMessageEvent; if (raw.type toolcall_delta streaming) { const block raw.partial.content[raw.contentIndex]; const html block.arguments?.widget_code; if (html html.length 20) { streaming.window.setHTML(wrapHTML(html)); } } });结果它工作了窗口打开并显示内容构建。但它极其卡顿。每次setHTML()调用都替换整个文档 - 完整页面重排滚动位置丢失未样式化内容的闪烁。每 80 毫秒整个页面闪烁。3.3 尝试 2Shell 页面 通过 JS Eval 的innerHTML而不是替换整个文档我们用包含空div idroot的 shell HTML 页面打开窗口一次。然后我们使用win.send()WebView 中的 JavaScript 评估仅更新该容器的 innerHTML// Shell HTML 加载一次 - 包含一个 div idroot 和一个脚本 // 定义 window._setContent(html) 来更新 root 的 innerHTML function shellHTML() { return ... div idroot/div // _setContent: 将 root.innerHTML 设置为提供的 html ...; } // 在每个增量上eval JS 更新内容 streaming.window.send(window._setContent(${escapeJS(html)}));结果更好 - 没有完整的文档替换。但仍然卡顿。innerHTML替换所有子节点因此现有内容在每次更新时都被销毁并重新创建。没有视觉连续性。3.4 尝试 3天真 DOM 追加我们尝试跟踪之前的内容长度只追加新的子节点window._setContent function(html) { var root document.getElementById(root); var tmp document.createElement(div); tmp.innerHTML html; // 仅追加超出我们已有的节点 for (var i root.childNodes.length; i tmp.childNodes.length; i) { var node tmp.childNodes[i].cloneNode(true); node.style.animation _fadeIn 0.3s ease both; root.appendChild(node); } // 更新最后一个现有节点它可能不完整 // ... };结果元素出现了但从未淡入。问题浏览器在解析部分内容时自动关闭未闭合的 HTML 标记。div classcardsdiv classc变为div classcards div classc/div !-- 浏览器自动关闭了这个 -- /div在下一次带有更多内容的更新中树结构根本改变 - 这不是在末尾追加新节点这是一个完全不同的树。追加逻辑无法跟踪什么是真正的新。3.5 尝试 4morphdom - DOM 差异化解决方案我们引入了 morphdom一个快速的 DOM 差异化库被 Marko 等框架使用。而不是替换 innerHTMLmorphdom 比较新旧 DOM 树并应用最小补丁- 更新更改的节点添加新的节点保持不变的节点不变。function shellHTML() { // 返回一个完整的 HTML 文档包含 // 1. 一个 _fadeIn CSS 动画opacity 0→1translateY 4px→0 // 2. 从 cdn.jsdelivr.net 加载的 morphdom // 3. 一个 _setContent(html) 函数它 // - 缓冲调用直到 morphdom 加载_morphReady 标志 // - 使用新 HTML 创建目标 div // - 使用回调调用 morphdom(root, target) // onBeforeElUpdated: 如果 from.isEqualNode(to) 则跳过 // onNodeAdded: 将 _fadeIn 动画应用于新元素 return ...; }morphdom 回调onBeforeElUpdated如果旧节点和新节点相同isEqualNode则完全跳过更新。现有内容在 DOM 中保持不变。onNodeAdded当树中出现真正的新节点时应用 CSS_fadeIn动画 - 0.3s ease微妙的 translateY 用于向上滑动效果。加载竞争条件morphdom 从 CDN 异步加载。如果在其加载之前调用_setContent则调用静默不执行任何操作。我们使用挂起的缓冲区解决了这个问题window._morphReady false; window._pending null; window._setContent function(html) { if (!window._morphReady) { window._pending html; return; } // ... morphdom 差异化 }; // 在 morphdom 加载上刷新 onloadwindow._morphReadytrue; if(window._pending){window._setContent(window._pending);window._pendingnull;}3.6 脚本执行innerHTML不执行script标记。当完整的 HTML 到达时在toolcall_end上我们需要激活脚本Chart.js 初始化事件监听器等window._runScripts function() { document.querySelectorAll(#root script).forEach(function(old) { var s document.createElement(script); if (old.src) { s.src old.src; } else { s.textContent old.textContent; } old.parentNode.replaceChild(s, old); }); };这会将每个script标记克隆到一个新元素浏览器将执行它并替换惰性原始元素。3.7 完整的流式传输流程toolcall_start (检测到 show_widget) │ ├── 流式传输状态已初始化 │ ▼ toolcall_delta (重复每个约令牌) │ ├── 读取 partial.content[index].arguments.widget_code ├── 去抖动 150ms ├── 第一次使用 shellHTML() 打开 Glimpse 窗口 │ └── morphdom 从后台 CDN 加载 ├── 后续win.send(_setContent(${escapedHTML})) │ └── morphdom 差异化旧 DOM 与新 DOM │ └── 新节点获得 _fadeIn 动画 │ └── 未更改的节点保持不变 │ ▼ toolcall_end │ ├── 最终的 _setContent 具有完整的 HTML ├── _runScripts() 激活脚本标记 │ └── Chart.js 从 CDN 加载 │ └── 图表渲染 │ └── 事件监听器附加 │ ▼ execute() 被调用 │ ├── 重用现有的流式传输窗口没有双重打开 ├── 等待 │ ├── window.glimpse.send(data) → 用户交互 │ ├── 窗口关闭 → 用户关闭 │ └── 120s 超时 → 自动解析 ├── 返回带有交互数据的工具结果 │ ▼ TUI 渲染紧凑摘要 ✓ compound interest 800×6003.8 字符串转义一个微妙但关键的细节HTML 内容通过win.send()作为 JavaScript 字符串文字注入。这意味着我们需要转义function escapeJS(s: string): string { return s .replace(/\\/g, \\\\) // 反斜杠 .replace(//g, \\) // 单引号我们的字符串分隔符 .replace(/\n/g, \\n) // 换行符 .replace(/\r/g, \\r) // 回车符 .replace(/\/script/gi, \\/script); // 闭合脚本标记 }\/script替换防止浏览器将我们 JavaScript 字符串中的字面/script解释为闭合外部脚本块。4、提取设计指南 - 逐字逐句我打开了浏览器开发工具检查了网络请求并在响应正文中发现了完整的工具调用负载 - 包括包含 Anthropic 实际设计指南的完整read_me工具结果。响应 JSON 具有以下结构{ chat_messages: [ { content: [ { type: tool_use, name: visualize:read_me, input: { modules: [interactive, chart] } }, { type: tool_result, name: visualize:read_me, content: [{ type: text, text: # Imagine - Visual Creation Suite\n\n## Modules\n... }] } ] } ] }tool_result中的那个text字段那是 Anthropic 提供给 Claude 的完整设计指南。不是摘要。不是 Claude 对它的描述。实际系统内容逐字逐句。4.1 重构模块系统通过在多条消息中触发具有不同模块组合的read_me我们提取了所有 5 个模块响应| 请求的模块 | 响应大小 | 包含的唯一部分 | | — | — | — | |[interactive]| 19K | Core UI components Color palette | |[chart]| 22K | Core UI components Color palette Charts (Chart.js) | |[mockup]| 19K | Core UI components Color palette | |[art]| 17K | Core SVG setup Art and illustration | |[diagram]| 59K | Core Color palette SVG setup Diagram types |每个响应共享相同的核心哲学、流式传输规则、排版、CSS 变量、sendPrompt()文档。然后每个模块附加其特定部分。一些部分在模块之间共享 -UI components出现在 interactive、chart 和 mockup 中SVG setup出现在 art 和 diagram 中。我们编写了一个脚本来解析对话 JSON在##标题边界处拆分每个read_me响应去重共享部分验证重新组合部分产生与原始内容字节相同的输出结果10 个唯一部分可以重新组合以完全再现任何模块响应4/5 完全匹配1 个有单个空白字符差异。4.2 里面有什么 - 设计系统指南是彻底的。这不是使用漂亮的颜色小册子。这是一个带有硬性规则的生产设计系统Core- 每个小部件必须遵循的基础流式传输优先架构style→ HTML →script最后没有渐变、阴影、模糊 - 它们在流式传输 DOM 差异化期间闪烁没有!-- comments --- 浪费 token 并破坏流式传输只有两个字体粗细400、500 - 从不 600 或 700到处都是句子大小写从不 Title Case 或 ALL CAPS所有颜色的 CSS 变量--color-text-primary、--color-background-secondary深色模式是强制性的 - 每种颜色必须在两种模式下都工作CDN 允许列表cdnjs.cloudflare.com、cdn.jsdelivr.net、unpkg.com、esm.shColor palette- 九个颜色坡道每个有 7 个从最浅到最深的停止点Purple: #EEEDFE → #CECBF6 → #AFA9EC → #7F77DD → #534AB7 → #3C3489 → #26215C Teal: #E1F5EE → #9FE1CB → #5DCAA5 → #1D9E75 → #0F6E56 → #085041 → #04342C Coral: #FAECE7 → #F5C4B3 → #F0997B → #D85A30 → #993C1D → #712B13 → #4A1B0C ...带有严格规则颜色编码含义而不是序列。每个小部件最多 2-3 个坡道。彩色背景上的文本必须使用相同坡道的 800/900 停止点 - 从不使用黑色。SVG setup- SVG 图表工程的大师课程ViewBox 安全检查清单完成前 5 个验证步骤带有实际渲染像素测量的字体宽度校准表预构建的 CSS 类c-blue、c-teal、t、ts、th、box、node、arr通过context-stroke自动继承描边颜色的箭头标记关于连接器路径上的fillnone的规则SVG 默认为fill: blackDiagram types- 到目前为止最大的部分导致大多数图表失败的两个规则箭头相交检查从标签长度的框宽度决策框架在动词上路由而不是名词“LLMs 如何工作” → Illustrative“transformer 架构” → Structural流程图、结构和说明性图表子规范复杂性预算每个副标题 ≤5 个词每个水平层 ≤4 个框UI components- 用于构建模型的标记卡片白色背景、0.5px 边框、radius-lg、填充 1rem 1.25rem预先样式化的按钮带有悬停/活动状态指标卡片、表单元素、骨架加载模式编辑视图与卡片视图与比较视图的布局规则Charts- Chart.js 特定指南Canvas 包装器大小position: relative明确高度始终禁用默认图例构建自定义 HTML 图例数字格式-$5M而不是$-5M仪表板布局模式4.3 使用真实指南我们将手写的指南替换为提取的原始指南。guidelines.ts文件现在是逐字逐句的 Anthropic 内容组织为懒惰加载的部分export function getGuidelines(modules: string[]): string { let content CORE; const seen new Setstring(); for (const mod of modules) { const sections MODULE_SECTIONS[mod]; if (!sections) continue; for (const section of sections) { if (!seen.has(section)) { seen.add(section); content \n\n\n section; } } } return content \n; }去重很重要如果你请求[interactive, chart]共享的UI components和Color palette部分只包含一次而不是两次。这完全匹配 claude.ai 的read_me工具的行为。5、我们学到了什么1. Claude 的生成式 UI 比看起来更简单它不是一个特殊的渲染引擎。它是一个返回 HTML 的工具调用随着令牌的流式传输而增量解析注入到 DOM 中。复杂性在于设计指南- 关于颜色、排版、深色模式、流式传输友好结构以及何时使用每种模式的数千个 token 的规则。2.read_me模式是天才的按需将文档懒惰加载到模型的上下文中是一个值得借鉴的模式。而不是一个巨大的系统提示你只在任务需要时加载专业知识。我们的扩展使用相同的架构5 个模块选择性加载。3. DOM 差异化解决流式传输平滑性你不能只在每个令牌上innerHTML- 它会导致全页面闪烁。你不能天真地追加节点 - 部分 HTML 解析创建不可预测的树结构。你需要 DOM 差异化morphdom、idiomorph 或类似来应用最小补丁并仅动画真正的新节点。4. Glimpse 使终端代理可视化终端不需要渲染 HTML。它需要生成渲染 HTML 的东西。Glimpse 的 50 毫秒以下 WKWebView 窗口与双向 JSON 通信完美地弥合了差距。终端保持终端视觉内容获得真正的浏览器引擎。5. pi-ai 的规范化流式传输事件是金Pi 的 AI 层将所有提供商的流式事件规范化为toolcall_start/toolcall_delta/toolcall_end并带有渐进式解析的arguments。这意味着无论模型是 Anthropic、OpenAI、Google 还是任何其他提供商流式传输方法都以相同的方式工作。我们不需要部分 JSON 解析器 - pi-ai 已经做到了。6、代码完整的扩展是两个文件中的约 350 行 TypeScriptindex.ts- 工具注册、流式传输拦截、Glimpse 集成、TUI 渲染guidelines.ts- 模块化设计指南核心 5 个懒惰加载的模块依赖项glimpseui- 原生 macOS WKWebView 窗口morphdomCDN在 WebView 中运行时加载 - 用于平滑流式传输的 DOM 差异化扩展位于.pi/extensions/generative-ui/中并在启动时由 pi 自动发现。无需配置。项目结构pi-generative-ui/ ├── .pi/ │ └── extensions/ │ └── generative-ui/ │ ├── index.ts # 扩展入口点 │ └── guidelines.ts # 懒惰加载的设计模块 ├── node_modules/ │ └── glimpseui/ # 原生 macOS WKWebView ├── package.json └── BLOG.md7、接下来是什么深色模式适应- Glimpse 在ready事件上提供appearance.darkMode。shell 可以注入匹配系统外观的 CSS 变量。sendPrompt()等效项- claude.ai 的小部件有一个sendPrompt(text)函数可以像用户输入一样向聊天发送消息。我们可以通过window.glimpse.send({ type: prompt, text: ... })实现这一点并让扩展调用pi.sendUserMessage()。持久小部件- 在多个回合中保持小部件窗口打开从工具结果推送实时更新。小部件库- 常见模式的预构建模板确认对话框、数据表、表单向导LLM 可以按名称引用。原文链接Claude生成式UI的逆向与利用 - 汇智网

相关文章:

Claude生成式UI的逆向与利用

Anthropic 在几个小时前宣布为 Claude 提供生成式 UI。交互式小部件 - 滑块、图表、动画 - 在 claude.ai 对话中内联渲染。不是图像。不是代码块。是在聊天中运行的 JavaScript 的实时 HTML 应用程序。 这并不令人惊讶。Vercel 和其他公司已经推广生成式 UI 有一段时间了&…...

看不见的飓风:电动汽车如何重塑全球经济版图

当第一批电动汽车悄然驶上街头时,很少有人预料到,这不仅仅是一场动力系统的更换,而是一场席卷全球产业链、就业市场和能源秩序的“经济飓风”。这场飓风正在以三种方式重塑我们的经济世界。传统汽车工业带陷入“静默地震”。德国斯图加特&…...

运维实战---多种方式在Linux中部署并初始化MySQL

运维实战—多种方式在Linux中部署并初始化MySQL 前言实验环境介绍一、源码包安装MySQL 1、配置MySQL&编译安装2、初始化数据库3、配置环境变量 二、yum安装MySQL三、rpm安装MySQL 前言 MySQL是常用的关系型数据库,具有以下特点: 1、开源&#xff…...

轻松上手Nginx Proxy Manager:安装、配置与实战

轻松上手Nginx Proxy Manager:安装、配置与实战 安装部署 概述安装Docker和Docker Compose创建项目目录创建Docker Compose文件启动数据存储方式说明 Web管理控制台 访问Web界面登录 基本使用 域名与IP绑定添加代理主机配置说明保存并应用配置一键申请SSL证书 申请…...

【2026年最新600套毕设项目分享】springboot数字博物馆系统(14128)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告/任务书)远程调试控屏包运行一键启动项目&…...

【2026年最新600套毕设项目分享】springboot“校园淘”二手交易平台(14127)

有需要的同学,源代码和配套文档领取,加文章最下方的名片哦 一、项目演示 项目演示视频 二、资料介绍 完整源代码(前后端源代码SQL脚本)配套文档(LWPPT开题报告/任务书)远程调试控屏包运行一键启动项目&…...

(五)Spring Cloud Alibaba 2023.x:Seata 分布式事务配置与实现

目录 前言 准备 安装seata 下载seata 配置seata数据库 创建undo_log表 seata配置文件 启动seata服务 项目集成 引入seata依赖 yml文件配置seata 模拟下单 生产者提供扣减库存 消费者进行下单 模拟下单 前言 在微服务架构中,分布式事务是确保多个服务…...

(七)Spring Cloud Alibaba 2023.x:RocketMQ 消息队列配置与实现

目录 前言 准备 安装RocketMq服务 下载rocketmq服务 下载rocketmq 控制台 项目集成 引入依赖 生产者服务配置 消费者服务配置 发送队列消息 前言 在微服务架构中,异步消息通信是实现系统解耦、提高性能和增强系统可靠性的重要手段。在 Spring Cloud Alib…...

(CICD)自动化构建打包、部署(Jenkins + maven+ gitlab+tomcat)

一、平滑发布与灰度发布 **什么叫平滑:**在发布的过程中不影响用户的使用,系统不会因发布而暂停对外服务,不会造成用户短暂性无法访问; **什么叫灰度:**发布后让部分用户使用新版本,其它用户使用旧版本&am…...

企业碳排放权交易会计信息处理规范 免费下载

企业碳排放权交易会计信息处理规范(T/GDES 1—2016) 一、团体官方承诺 广东省节能减排标准化促进会发布的T/GDES 1—2016《企业碳排放权交易会计信息处理规范》团体标准遵循开放、公平、透明、协商一致和促进贸易和交流的原则,按照在本平台…...

鸿蒙原生应用开发进阶之路:Flutter工程师的鸿蒙转型与金融/保险应用实战

引言 随着鸿蒙系统(HarmonyOS)的持续演进和生态扩张,其“一次开发,多端部署”的理念吸引了众多开发者的目光。对于拥有Flutter开发经验的工程师而言,鸿蒙原生开发既是新的机遇,也是技术升级的挑战。特别是…...

什么是 OpenClaw

OpenClaw(曾用名 Clawdbot、Moltbot)是一款开源的个人 AI 助手平台,于 2026 年初在GitHub 上迅速走红,成为近年来增长最快的开源项目之一。它能够在用户自己的设备上本地运行,通过 WhatsApp、Telegram、Discord、飞书、…...

端侧AI 的定义与发展背景

大模型技术经历了参数竞赛与生成能力的突破后,行业焦点已从纯粹的“模型能力”转向“落地能力”。回顾人工智能近年来的发展,其主战场正经历一次深刻的转移。随着技术逐渐趋于同质化,AI 的下一步竞争,不再是“谁的模型更强”&…...

OmoFun 1.1.4 | 追番神器官方APP下载.官网入口

OmoFun动漫(又称“动漫共和国”)是一个深受二次元爱好者喜爱的高品质动漫聚合平台,致力于为用户提供全方位、无广告的沉浸式追番体验。该平台由专业团队运营,拥有庞大的内容储备,涵盖日本新番、国产原创动画、欧美热门…...

打卡信奥刷题(2949)用C++实现信奥题 P5878 奖品

P5878 奖品 题目描述 学校刚开完运动会,准备为尽可能多的同学评奖,并为每个人颁发一份奖品。一份奖品包括 NNN 个物品,如:555 支铅笔、101010 本练习薄等。每份奖品完全一样。虽然学校的保管室里还有一些办去年运动会后剩余的物品…...

某奢侈品品牌虚拟零售AI架构案例:用AI驱动的高端服务提升品牌价值

某奢侈品品牌虚拟零售AI架构案例:用AI驱动的高端服务提升品牌价值 引言:当奢侈品遇上AI,重新定义“高端服务” 凌晨1点,巴黎近郊的LuxuryX虚拟私域门店里,用户Elsa(一位连续3年的VVIP)正对着屏幕…...

Python基于flask-django考研学习系统的设计与实现

目录系统需求分析技术选型系统模块设计开发流程关键问题解决参考资源项目技术支持可定制开发之功能创新亮点源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作系统需求分析 明确考研学习系统的核心功能需求,包括用户管理、学习资源…...

关于keil中编译器版本,也就是库不兼容问题的解决办法

问题现象:Error: C9511E: Unable to determine the current toolkit. Check that ARM_TOOL_VARIANT is set correctly. Check that your license details are correct in the License Management dialog of MDK. Additional information is available at:http://www…...

【最全】2026年OpenClaw(Clawdbot)本地6分钟部署及使用喂饭级流程

【最全】2026年OpenClaw(Clawdbot)本地6分钟部署及使用喂饭级流程。OpenClaw(前身为Clawdbot/Moltbot)作为开源、本地优先的AI助理框架,凭借724小时在线响应、多任务自动化执行、跨平台协同等核心能力,成为…...

【有参考文献】事件触发模型 可实现倒立摆控制仿真实验 simulink模型可直接运行

【有参考文献】事件触发模型 可实现倒立摆控制仿真实验 simulink模型可直接运行 含详细参考文献倒立摆这个玩具般的控制对象,总能让工程师们玩得停不下来。它那摇摇欲坠的姿态就像在挑衅:"有本事就来稳住我啊!"传统控制方法像永不停…...

电脑端制作泳道图超便捷 零基础快速做出专业业务流程图

在企业管理、软件开发、流程梳理等工作场景中,泳道图作为一种清晰呈现多角色、多部门协作流程的可视化图表,被广泛应用于需求分析、业务流程优化、系统设计等环节。对于职场从业者和开发者而言,快速绘制出规范、专业的泳道图,能够…...

数据中心U位管理与DCIM、ITAM/CMDB系统的协同机制及实践路径

摘要:在数据中心数字化、集约化运维趋势下,机柜U位作为物理资源的核心计量单元,其精细化管理水平直接影响数据中心资产利用率、运维效率及业务连续性。本文从数据中心运维架构出发,系统剖析U位管理的核心价值,明确其与…...

LLM的可信度边界--人类思考的可信边界

本文为个人想法分享,是一种幻觉创作,只图一乐。作者自愿放弃全部内容的一切权利,不作任何原创确权;内容由 AI 辅助生成,未参考任何特定文章,仅使用公有科学公式 / 概念,非商用,尊重所…...

ssm+java2026年毕设社区外来人员【源码+论文】

本系统(程序源码)带文档lw万字以上 文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容一、选题背景关于社区警务管理问题的研究,现有研究主要以传统纸质档案管理和单一功能的信息化系统为主,专门针对社区…...

MySQL迁移中的兼容性实践难点复盘:从语法一致到行为对齐

MySQL迁移中的兼容性实践难点复盘:从语法一致到行为对齐 在当前信创项目加速落地的背景下,金仓数据库(KingbaseES)因其对MySQL生态的深度适配能力,正被大量金融、政务及央国企单位纳入核心系统替换评估范围。然而&…...

在pyCharm 中命令打包生成exe文件方法

在 PyCharm 中打包 Python 文件,最常用、最可靠的方法是结合使用 PyInstaller 工具。针对你之前编写的生成 UFF 文件的脚本,下面我会介绍两种在 PyCharm 中操作的方式,并重点说明如何确保依赖项(如 numpy, pyuff)和可能…...

gorm底层框架解析

我来为您解析 GORM 底层框架的核心原理和架构设计。这是一个深度技术话题,让我系统性地拆解:GORM 架构全景 ┌─────────────────────────────────────────┐ │ Application Layer │ │…...

leijmdas的godi注入方式先进性

leijmdas 的 godi 框架具体的依赖注入实现方式,给你准确的技术细节。 我来详细介绍 leijmdas 的 godi 框架的依赖注入方式。这是一个基于 代码生成 的工业级 DI 框架,设计非常独特。godi 的核心注入方式1. 结构体标签驱动注入(Tag-Based Inje…...

基于单片机的超声波水塔液位测量系统protues仿真 本设计基于单片机的超声波水塔液位测量和智...

基于单片机的超声波水塔液位测量系统protues仿真 本设计基于单片机的超声波水塔液位测量和智能控制系统主要由硬件与软件两部分组成,硬件是基于AT89C51芯片为核心的超声波水塔液位测量,采用AT89C51单片机进行控制及数据处理,给出了超声波发射…...

DigVPS 测评 - 蔭雲(YINNET)上新法國ISP VPS 产品,新品七折出售中。

规格: 摘要: 硬件: 速率: IPv4 质量: ICMP 延迟: TCP 延迟: BGP: 如对该产品感兴趣,想要持续关注其实时与历史数据表现,欢迎访问我们的站点进行长期跟踪。也可…...