资讯详情

DeepSeek Harness Design插件:给AI聊天窗口装上可视化点选改页面

📅 2026/10/26 16:24:15 | 华诺云谱 👁 阅读
DeepSeek Harness Design插件:给AI聊天窗口装上可视化点选改页面
大多数人刚装好 DeepSeek Harness 的时候都把它当一个纯粹的聊天窗口用。我这边情况不太一样——我手上管着好几套网页模板和内部组件的改版每天有接近一半的精力浪费在“把代码复制到浏览器、刷新页面、截图、再贴回聊天窗口里告诉 AI 哪里不对”的循环上。后来我干脆给 Harness 写了一个 Design 插件让聊天界面的右侧实时渲染目标页面鼠标在页面上一指一点AI 就知道你点的是哪个元素改完立刻看到结果整个过程不用再切窗口。这篇博文就来聊聊这个插件的设计思路、实现链路以及我在实际开发里踩进去又爬出来的那些坑。适合两类人看一类是想给 DeepSeek Harness 扩展功能的插件开发者另一类是天天跟 AI 协作调页面、被来回切工具折磨得够呛的同学。1. 为什么非要做这个Design插件聊天和页面之间的“最后一公里”1.1 实际痛点AI 改页面时上下文是断开的先描述一个很常见的场景。我有一份产品宣传页的 HTML 片段想要把 hero 区域的标题换成更醒目一点的样式同时把整个区块的背景改成深色。按照传统流程我得做下面这几步把 HTML 和 CSS 完整复制给 AI告诉它“帮我改一下”。AI 返回修改后的代码我再复制回编辑器保存。打开浏览器刷新发现颜色改对了但字体大小变化不符合预期。重新截图贴回聊天窗口补充一句“标题再大一点背景想再深一点”。继续等 AI 回复继续刷新页面。这个流程里最消耗精力的不是“改代码”本身而是来回传递信息时的信息损耗。AI 只能看到我贴给它的文本它并不知道页面在浏览器里真实渲染成什么样子我自己在脑子里想象的“稍微深一点”和 AI 在代码里执行的“深一点”又往往不是同一个值。上下文断在两处第一AI 看不到渲染效果只能靠猜第二我表达修改意图时缺少一个可以直接指向目标元素的交互手段只能靠文字描述“那个标题”“左边那个按钮”。1.2 Design 插件想解决的是给对话补上“视觉上下文”所以这个插件的核心定位很简单在 DeepSeek Harness 的聊天界面旁边增加一个“可视化预览面板”。这个面板可以加载本地 HTML 片段也可以加载用户给定的网页地址。页面在面板里渲染出来之后用户可以像在浏览器里一样滚动、点击、查看具体元素当我点中某个元素时插件会把“你选中的元素路径、当前样式、你给出的修改要求”一起组装成一条结构清晰的上下文消息送到对话流里给 AI 参考。这样一来AI 获得的信息从“一段代码文本”变成了“代码结构 渲染位置 用户选点标记 修改意图”。上下文闭合了AI 的修改动作自然也准了很多。实测下来以前要三四轮来回才能改对的一个页面区域现在通常一轮就能给出正确修改偶尔需要两轮也只是因为用户自己把需求说得太模糊。1.3 和现成方案的对比为什么截图流、DevTools 流都不够顺有人可能会问我不装插件直接把页面截图发给 AI让它看着图改不是一样吗这个方案我也用过效率和准确率确实比纯文本高但仍有两个硬伤。第一截图是静态的AI 能“看”到布局却拿不到准确的 DOM 结构和样式值它只能根据图片猜测元素关系猜错是常有的事。第二截图流程里没有“点选”这一环。我哪怕想改一个很明确的小元素也得在图片描述里花大量文字给 AI 指路比如“第二段第三行的那个蓝色链接”完全没有直接点到元素上高效。用浏览器 DevTools 自己改当然最精准但它需要我手动改样式、手动刷新、手动对比AI 在这个流程里完全帮不上忙等于退回了纯手工时代。Design 插件走的是第三条路把人工检查的精准和 AI 改代码的高效结合起来。用户负责“点哪里”AI 负责“改什么”插件负责“把改动安全地应用回页面”。我把几种做法放在一起对比过差异非常直观方案能否看到实时渲染能否点选目标元素AI 能否参与修改来回切换成本纯文本复制代码不能不能能极高截图喂给 AI能静态不能能高DevTools 手动改能能不能中Design 插件能实时能能低2. 插件整体架构把 Design 面板做成聊天窗口的可交互副驾2.1 插件由三块组成预览面板、页面注入脚本、IPC 桥接层一个 Harness 插件要跑起来首先得遵循这套桌面应用插件的基本结构。我做的 Design 插件由三个主要部分组成预览面板WebView 宿主这是用户直接看到的界面承载目标页面的渲染。它的本质是一个 WebView 组件我在其中加载 HTML 片段或在线页面。内容注入脚本在 WebView 页面加载完成后注入一小段 JavaScript。这段脚本负责两件事一是给页面加一层透明的交互监听捕获用户的点击行为二是维护一个高亮指示器当我用鼠标移过某个元素时它会给元素描边或加半透明背景让用户确认自己即将选中的对象。IPC 桥接层负责在 WebView、插件宿主和 Harness 主进程之间传递消息。点击事件被内容脚本捕获后通过 IPC 发给插件主逻辑再由插件主逻辑把格式化后的上下文注入到当前对话消息队列里。这三个组件各司其职加在一起才构成了完整的“边聊边看”体验。2.2 消息环流从点击到 AI 回复再回到页面这个插件最关键的设计是“页面—用户—AI—页面”的闭环数据流。整个链路大概是这样的用户在预览面板里移动鼠标内容脚本高亮候选元素。用户按下鼠标左键选中目标元素内容脚本提取该元素的 DOM 信息。插件主逻辑把 DOM 信息选择器、标签名、类名、关键样式整理成结构化描述连同用户在聊天框里写的修改要求一起包装成一条消息插入对话流。AI 收到这条上下文后返回结构化的修改指令而不是直接输出一段不可控的代码。插件解析 AI 返回的修改指令在预览面板的页面 DOM 上执行修改。修改完成后插件截取新渲染结果或提取新样式摘要回传给 AI 作为“已修改”的确认。第 4 步是整条链路里我最坚持的部分。AI 一旦直接输出整段 HTML/CSS插件就很难保证“只改用户点中的那个元素”而且很容易把页面样式改坏。所以我的插件约定AI 只负责返回精确的修改对象例如“把 #hero-title 的 font-size 改为 48px”插件的校验层负责检查这个修改是否落在允许范围内然后再应用。这样即使 AI 产生幻觉想出一个很离谱的新值插件也能拦住。2.3 为什么用 WebView 而不是自研渲染器我一开始也纠结过是不是应该把目标页面“解析”成一个内部对象模型用自己的渲染器画出来后来很快放弃了这个念头。原因很简单目标页面本身就是 HTML、CSS、JavaScript 组成的世界市面上没有比 WebView 更成熟的 HTML 渲染引擎。用 WebView 加载意味着我不用重新造渲染轮子而且任何合法的网页都能直接渲染兼容性从第一天就有保障。DeepSeek Harness 本身是一个跨平台的桌面应用在不同操作系统上需要一致的行为。WebView 正好能提供这种一致性Windows 上可以用 Edge 内核macOS 上可以用系统 WebKitLinux 上也有对应的嵌入式浏览器方案。插件只需要面对一套相对统一的 DOM 接口就能让同一套预览代码跑在不同平台上。这里需要补充一个实际使用习惯如果目标只是一个 HTML 片段例如用户从项目里拷出来的一段组件代码插件就直接把它包装成完整的 HTML 文档再渲染完全不需要网络请求非常安全。如果目标是一个在线页面插件会先请求用户授权再尝试加载并把外部请求限制在用户主动同意的域名范围内。离线局域网场景下也可以配置页面资源走内网地址数据完全不出本地环境。2.4 权限设计插件不能“什么都碰”写插件时最容易忽略的是权限边界。Harness 本身运行着用户对话的所有数据Design 插件要是权限太宽理论上可以访问用户在聊天里粘贴的所有代码这非常危险。所以我的 manifest 文件里明确声明了插件能访问的资源和能执行的操作只允许读写当前 Design 面板 WebView 的 DOM不触碰 Harness 其他页面。只允许访问用户明确添加的白名单地址包括本地文件路径和经过授权的外部域名。只允许实例化样式修改类指令禁止执行任意 JavaScript 脚本。所有对话消息注入操作都必须带有一个带标签的上下文前缀方便用户随时在聊天记录里回溯。把权限写清楚不只为了安全也方便后续把插件发布到 dsh 插件市场时能更快通过审核。插件市场对越权行为的审查非常严我最初版本把权限声明写得太宽喷回来改了几轮才过。3. “点哪里改哪里”是怎么实现的从点击事件到 AI 可读的修改指令3.1 点击捕获与选择器生成不只是一个“点中的元素”那么简单很多人以为“点哪里改哪里”就是把鼠标落点坐标传给 AI 就行这恰恰是本插件实现里最容易出错的环节。浏览器页面布局是动态的单纯靠坐标定位元素极不可靠因为滚动、窗口尺寸变化都会让坐标失效。真正可靠的做法是从鼠标点击事件目标的 DOM 节点出发向上回溯生成一个稳定的 CSS 选择器路径。我采用的生成规则按优先级排列如果元素本身有 id直接使用 id例如 #hero-title。如果元素没有 id但有明确的 class组合父级路径生成选择器例如 .hero-wrapper .title-text。如果 class 也不明确则使用带有标签名和索引的组合例如 div:nth-child(2) span:nth-child(1)。这还不够。网页中的元素可能是动态渲染的一个选择器在生成时有效但等 AI 返回修改指令时页面结构可能已经变化。为了应对这个情况我在生成选择器的同时会把目标元素的祖先链快照也记录下来。这样即使 DOM 发生变化导致选择器失效插件也能通过快照找到最接近的祖先节点再重新定位目标子节点。3.2 把“点选 意图”翻译成 AI 看得懂的上下文选中元素只是第一步真正让 AI 明白用户意图的是“上下文消息的组装”。假设用户选中了页面上的一个标题元素然后在对话框里输入“改大一点颜色改成和品牌主色接近的深蓝”插件实际向对话流注入的消息会是这样{ type: design_selection, element: { selector: #hero-title, tagName: h1, classes: [hero-title], currentStyles: { font-size: 32px, color: #333333, font-weight: 700 }, parentSummary: .hero-wrapper h1 }, userIntention: 改大一点颜色改成和品牌主色接近的深蓝, constraints: [仅修改该元素不修改其它区域] }这条消息同时包含了三样东西确切的目标位置、用户的原话意图、当前样式基线。AI 不需要自己猜用户说的是页面上哪个“大一点”也不需要去推断这个元素现在多大。实测下来AI 在这种上下文下的修改准确率比“只发代码 文字描述”高出一大截因为它不再需要做元素定位这个最容易出错的任务。3.3 AI 返回修改指令但不直接操作 DOM为了让修改过程可控我要求 AI 以结构化的形式返回修改指令而不是自由输出代码。插件收到的“修改指令”是一个更精简的 JSON[ { selector: #hero-title, operation: setStyle, property: font-size, value: 48px }, { selector: #hero-title, operation: setStyle, property: color, value: #0a1f44 } ]收到指令后插件会先做一轮校验选择器是否在允许列表里、操作类型是否合法、属性是否属于允许修改的样式白名单颜色、字号、间距、边距、背景色、圆角等。校验通过后才会真正作用到页面上。一旦校验失败插件会把错误原因回传给 AIAI 会自行修正并重试。这个“AI 提议 插件执行 插件校验”的模式把大模型的创造性和本地程序的安全性分离开来是我这次开发中最满意的一个设计。3.4 修改后的反馈让 AI 知道自己做对了改完页面不能让 AI 处于“两眼一抹黑”的状态。插件会在完成修改后把目标元素的新样式提取出来连同修改前后的样式对比一起回传给对话流。AI 看到对比后能确认自己执行成功如果用户继续追加需求它也能基于最新样式做下一轮判断。这个反馈机制看起来不起眼实际使用中它是降低对话轮数的大功臣。没有反馈时用户改完一个地方经常还要追问一句“改好了吗”AI 就只能回答“我已经给出代码了”互相隔着一层纱。有了反馈后用户可以直接说“下一个把那个按钮也改成圆角”整个对话顺滑得像操作一个本地工具。4. 开发时踩过的那些坑以及对应的补救方案4.1 嵌入页面被 CSP 和跨域策略挡住第一次把在线网页加载进 Design 面板我就遇到了空白页面。打开调试器一看典型的 Content-Security-Policy 报错。很多网站通过 CSP 限制了自己页面里的资源来源也禁止被第三方以 WebView 形式加载直接用 URL 嵌入这条路走不太通。我的解决办法分三层优先支持 HTML 片段渲染这种场景不涉及真实网络请求没有 CSP 问题。对在线页面插件在加载前先尝试抓取页面源码再过滤掉有风险的脚本标签把剩余的 HTML 和样式重组后以本地数据形式渲染。这样既能展示页面视觉又规避了跨域加载的障碍。如果遇到必须保留完整交互的在线页面就明确要求用户添加域名白名单通过 Harness 侧配置的代理通道加载。这里需要额外提醒一点过滤脚本标签意味着页面上依赖 JavaScript 才能显示的内容会丢这是精力的权衡。我的实践经验是绝大多数“改页面样式”的需求并不依赖复杂的 JS 交互纯 HTML CSS 渲染出来的视觉结果已经足够定位问题。4.2 大模型“幻觉修改”上下文不足导致的改错位置插件初版上线后我遇到过一个很典型的翻车场景。用户点选了一个页面底部的页脚文字要求“把它改大一点”。AI 返回的修改指令是把页面中所有包含相同 class 名称的文字都放大了一轮。原因在于这个页面里多个区域复用了同一个通用 class而我的上下文消息里没有把“当前点选元素与其它同名元素的差异”说清楚。这个坑的根源是上下文信息不足。补救方案是多管齐下在上下文消息里增加“兄弟元素对比”信息列出同 class 下其它元素与点选元素的样式差异让 AI 明白它们不是同一个目标。在修改指令里强制带上“仅命中以下路径”的后缀让选择器必须包含元素唯一路径靠通用 class 直接命中会被校验层直接拦截。应用修改前插件会在页面上用高亮框标出将要被修改的元素用户确认后才会落地。这个中间确认步骤虽然多了一步但换来的是绝对的精准尤其是在页面有大量重复元素时。4.3 WebView 沙箱对消息长度的隐性限制Design 插件运行时存在一个典型的性能问题当页面非常复杂或者用户一次性粘贴了很长的 HTML 时通过 IPC 传递上下文会出现明显的卡顿甚至消息直接丢失。一开始我以为是消息格式的问题排查很久才发现是 WebView 沙箱对 postMessage 消息体大小有隐性限制超长消息会被静默截断。解法其实很朴实无论如何都不要把整份 HTML 塞进对话上下文。AI 并不需要完整页面源码才能理解用户意图它需要的只是“目标元素那一段”。我把上下文改成了摘要模式只提取点选元素自身及最近两层祖先的 outerHTML并对长代码做单行截断处理。这个改动立竿见影IPC 消息体积缩小了几个数量级页面再大也不卡了。经验总结是上下文不是给得越多越好给得“准”远比给得“全”重要。你把整页代码塞进去AI 反而容易淹没在无关信息里既增加 token 消耗又降低准确率。4.4 选择器漂移页面一改前面的标记就全失效还有一个坑非常隐蔽。用户连续修改多个元素时第一次修改后页面样式变了第二次再选元素时整个 DOM 结构看似没变但某些元素的位置已经移动了。此时插件根据鼠标重新生成的选择器可能是正确的而 AI 上下文里记录的旧选择器却失效了。一旦后一次修改不小心引用了旧选择器就会改到完全不相关的元素。我的解决方案是引入“快照定位”。插件每完成一次修改就把当前页面的 DOM 结构哈希记录一次。下一次选择元素时插件会先对比前一次快照如果结构差异超过阈值就会重新计算上下文中的选择器路径确保 AI 拿到的每一个引用的都是“当前页面状态下的有效路径”。这个额外的快照逻辑帮我消灭了几乎所有的选择器漂移问题。4.5 点击事件被覆盖层吞掉插件需要在页面上覆盖一层交互层来捕获点击但这个覆盖层如果做得太“实”会把页面原有的所有点击交互全部拦截。用户想在预览面板里点一下链接跳转、折叠展开一个板块都没反应。我把交互模式改成了“双态”默认状态下覆盖层完全透明且不拦截任何事件页面保持原生可交互只有用户按住键盘上的 Alt 键时插件才会进入“选取模式”此时鼠标移过元素会显示高亮描边点击则触发选中操作。松开 Alt 键页面恢复到正常状态。这个设计让预览面板同时具备了“浏览器”和“设计工具”双重身份切换成本几乎为零。5. 插件怎样分发、安装以及还能往哪些方向扩展5.1 插件包结构一个标准的 dsh 插件长什么样完成功能开发后接下来是打包和分发。DeepSeek Harness 的插件格式和大多数桌面应用插件类似核心是一个 manifest 文件加若干资源文件。我的 Design 插件目录结构大致是design-plugin/ ├── manifest.json ├── preview.html ├── content.js ├── bridge.js └── README.mdmanifest.json 是插件的入口描述里面的关键字段包括插件名称、版本、描述、入口文件地址以及它在 Harness 里声明的权限范围。在 preview.html 里我定义了整个设计面板的界面content.js 是最后注入到 WebView 页面里的交互脚本bridge.js 运行在插件宿主层负责和 Harness 主进程的 IPC 通信。打包时只需要把整个目录压缩按 Harness 插件规范生成一个带数字签名的归档文件就能上传到 dsh 插件市场或内部私有插件仓库。5.2 安装与离线局域网部署安装方式有两种。一种是从插件市场直接搜索安装这个最简单打开 Harness 的插件面板找到 Design 插件点击安装重启应用后就能在侧边栏看到图标。另一种是离线安装把插件包拷贝到 Harness 的 plugins 目录下在插件管理页面触发“扫描本地插件”应用重启后同样能加载完成。离线模式是我个人非常看重的场景。Harness 本身支持完全本地或局域网部署模型推理可以通过接入本地模型服务完成插件资源也全部在本地。也就是说在一个完全断外网的内网环境里只要把插件包分发到各开发机Design 插件依然可以完整工作。我团队里在一个隔离网段里验证过整个流程页面是本地 HTML模型走局域网 API插件不出本地数据全程没有经过任何外部服务效果和连外网时没有明显差别。这一点对做内部系统的人特别有价值毕竟很多企业前端模板根本不允许被传到公网。5.3 扩展方向同一个插件框架不只能改网页整个插件开发到后期我把“预览载具”抽象成了一个独立层。所谓载具就是“被修改的目标页面”的来源它不一定是网页 URL还可以是 HTML 片段、Markdown 文档甚至是导出成 DOM 树的数据面板。只要目标对象能渲染成 DOM后面那一整套“点选 → 生成选择器 → 组装上下文 → AI 返回修改指令 → 校验应用”的逻辑全部可以复用。我用这同一个框架做过两个很有意思的扩展。第一个是把 Markdown 预览变成可视化编辑器Markdown 渲染成 HTML 后点中一个标题元素让 AI 把它的字号调大、颜色加深AI 返回的是对应 CSS 规则的修改插件自动映射回 Markdown 样式主题。第二个是给内部数据面板做样式微调面板页面里有各种指标卡片点中某张卡片的背景区域让 AI 调整卡片间距或圆角帮助前端设计师快速试出视觉方案。这两个扩展基本没有改插件主逻辑只是换掉了“载具加载器”和“修改落地器”的少量代码。所以我认为这个插件的天花板并不只在改网页凡是“能渲染成 DOM”的目标都有机会变成它的修改对象。5.4 给 Harness 插件开发者的几条经验建议最后聊几个实践里沉淀下来的小建议按重要程度排个序一定要把“选择器 当前样式 用户意图”结构化地存进日志。AI 修改出现问题时回放日志能立刻看到它在哪一步跑偏调试效率能提升一个量级。上下文注入要让用户看得到。每次插件向对话流注入的设计上下文都在聊天框里以清晰的引用块形式展示用户能一眼看出 AI 是依据什么信息给出的修改避免“黑箱”感。改动落地前加一道视觉确认。我在预览面板里用一个高亮描边框标出即将被修改的元素用户按下快捷键确认后才执行。这个步骤挡住了大量因误触而引发的错误修改。优先保证“一个元素一轮改对”。宁可多花点 token 在结构化上下文上也不要让用户来回纠偏。每一次纠偏都会打断“边聊边看”的沉浸感而这种沉浸感正是这个插件存在的意义。我自己的体会是写这个插件的技术门槛并不高真正难的是把“用户意图、页面状态、AI 动作”这三件事对齐。最开始版本里我太关注怎么让 AI 输出代码反而忽略了“让 AI 看到用户看到的东西”才是核心。当我把点选、样式快照、修改确认闭环跑通之后这个插件才真正从玩具变成了天天离不开的日常工具。反正现在让我回到以前那种“复制代码、截图、贴回去、再刷新”的流程我是真回不去了。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑