前言¶
在 DeepSeek Harness(DSH)里,模型往往一次吐出并列参数、步骤对比、表格或图表说明,读者只能顺着长段落自己扫读、脑内重组。生成式界面(Generative UI)的思路是:让模型写一份声明式 spec,客户端按 spec 渲染成卡片,拖动、切换在浏览器本地完成,只有用户点提交才把结果作为普通消息送回模型。an-an-618/dsh-intelligent-ui 是面向 DSH 的客户端插件:Host 把 spec 编译成纯 JSON program,Client 用不执行模型代码的解释器渲染,并通过 presentationMeta 挂到 toolview 与 turnTail。下面介绍它解决什么问题、怎么装、怎么用。
这是什么¶
维护者 an-an-618,分类为 客户端。一句话定位(README):模型写声明式 spec,Host 编译成 JSON program,Client 解释器在本地维护状态并渲染交互卡片;显式提交才回传,本地操作不消耗 token。
架构借鉴社区实现 @comeonzhj/dsh-intelligent-ui 的分层(声明式 spec、宿主编译、presentationMeta、toolview + turnTail、本地交互、显式提交),但 v4 起不执行任何模型生成的 JavaScript,只解释 Host 编译出的纯数据 program。
当前包版本 6.5.0(package.json),许可证 MIT,要求 DSH >=0.2.1-rc.2。
核心功能¶
两个工具¶
| 工具 | 用途 | 提交 |
|---|---|---|
render_ui |
交付卡:信息、表格、图表、参数预览;卡片即回答,调用后停下 | 无提交按钮;滑块/开关只驱动卡片内部展示 |
ask_with_ui |
提问卡:需要确认、选择或填写参数,并把结果交回模型 | 底部一个提交按钮,可带可选备注 |
二者都接受 spec 对象,或紧凑 JSON 文本 source(二选一)。source 适合长卡片:流式阶段工具行先出现只读预览,控件逐步出现;settle 后由 turnTail 渲染完整可交互卡片,编译产物与对象模式一致。
提交回模型的是普通用户消息,例如:
[Intelligent UI] Team plan estimate
- seats: 10
- yearly: on
note: 4 月开始,需要发票
spec 能表达什么¶
spec.controls 是递归节点树,容器最多 4 层、整卡 120 个节点。布局含 section、box、row、columns、grid、tabs、list 等;展示含标题、表格、键值、步骤条、代码块、迷你折线、图片等;交互含滑块、开关、下拉、输入、评分、choice 等;图表支持 bar、line、area、pie、donut、scatter、heatmap,带 id 的部分图表可点击 category 并提交。
表达式写作 {= 表达式 }(旧写法 {{ }} 编译器仍接受,但系统提示词里不得出现双花括号,否则 DSH 会当成模板变量导致每轮失败)。控件与字段限制见仓库 CONTRACT.md 与 Host 系统提示词段。
系统提示词默认 应出尽出:回答里只要有并列信息、参数、步骤、对比、数据、表格、图表、代码或可调选择,就优先出卡片;纯文字留给一句话事实和闲聊。可通过配置改为平衡模式(见下文)。
Host 与 Client 分工¶
| 文件 | 作用 |
|---|---|
index.js |
Host:注册工具、编译 spec、挂系统提示词 |
client.js |
浏览器半体:解释 program、本地状态、提交、turnTail |
lib/compile.js 等 |
编译、表达式 AST(不 eval)、控件目录与校验 |
安装与启用¶
插件以当前 DSH 进程权限运行;安装前建议浏览 GitHub 仓库 源码与 MIT 许可证。DSH 生态是「一切皆插件」;SkillHub 目录页 等社区站点与 DeepSeek / 幻方无官方从属关系,索引源需自行添加。
从插件市场安装(推荐)¶
- 打开「插件 → 发现」,在索引源里添加:
https://cdn.jsdelivr.net/gh/an-an-618/dsh-intelligent-ui@main/market/index.json
- 搜索
Intelligent UI或「智能界面」,安装后 重启 DSH。索引指向固定 commit,安装可复现。
直接安装(固定 commit)¶
plugin_manager(action: "install_bundle", target: "git+https://github.com/an-an-618/dsh-intelligent-ui.git#289674809a88fbd347f0e3c2f0c12f3b8b3ae807")
安装后重启 DSH 生效。
从本地目录安装(开发)¶
plugin_manager(action: "install_bundle", target: "/absolute/path/to/intelligent-ui")
开发者在装进 desktop 前可先跑自检,并在隔离 profile 或新会话试一轮,确认无 turn/end error:
node scripts/check.mjs
移除 bundle:
plugin_manager(action: "remove_bundle", target: "@an-an-618/dsh-intelligent-ui")
配置¶
cordis.patch.yml 中常见项:
| 设置 | 默认 | 说明 |
|---|---|---|
prompt |
true |
是否把 spec 说明挂到系统提示词 |
language |
zh |
工具描述与 ask 默认按钮语言(zh / en) |
outputPolicy |
cards-first |
cards-first 应出尽出;balanced 仅在结构化回答时优先卡片 |
imageHosts |
[] |
图片主机白名单;空表示不限制主机 |
allowHttpImages |
false |
默认仅 https:// 图片;私有地址永远拒绝 |
改 outputPolicy 后需重新加载插件(移除再安装或重启 DSH)。若环境提供 Settings 服务,可在 插件 → 智能界面 页面切换「应出尽出 / 平衡模式」并保存到 profile patch。
典型用法¶
先做一张带本地计算的交付卡,模型调用 render_ui 并传入如下结构的 spec(节选自 README):
{
"spec": {
"title": "Team plan estimate",
"description": "每月约 ${= seats * 29 },按年付 ${= seats * 29 * 12 }/年",
"state": { "seats": 8, "yearly": true },
"controls": [
{ "kind": "heading", "text": "席位与周期" },
{ "kind": "slider", "id": "seats", "label": "席位数", "min": 1, "max": 50, "step": 1 },
{ "kind": "switch", "id": "yearly", "label": "按年付费" },
{ "kind": "stat", "label": "预计月费", "value": "${= seats * 29 }", "hint": "不含税" },
{ "kind": "chart", "chart": "bar", "categories": ["Q1", "Q2", "Q3", "Q4"],
"series": [{ "name": "收入", "values": [12, 18, "{= seats * 2}", "{= seats * 3}"] }], "height": 180 }
]
}
}
需要用户确认参数并回传时,改用 ask_with_ui,对交互控件可加 "required": true;提交前会校验当前可见必填项,不满足则不发送并在字段旁提示。
嵌套布局示例(section / row / columns):
{
"kind": "section",
"title": "季度概览",
"children": [
{ "kind": "row", "children": [
{ "kind": "stat", "label": "收入", "value": "$12,480" },
{ "kind": "badge", "text": "**+12%**", "tone": "success" }
] },
{ "kind": "columns", "columns": [
{ "children": [{ "kind": "chart", "chart": "area", "categories": ["Q1","Q2","Q3"], "series": [{ "values": [12, 18, 24] }] }] },
{ "children": [{ "kind": "keyValue", "items": [{ "label": "客户", "value": "Acme" }] }] }
] }
]
}
经过上面的步骤,同一轮对话里卡片可承载科目、难度、选项与开始按钮;选择在本地完成,提交后作为一条普通用户消息继续对话。
适用场景与注意¶
适合希望在 DSH 对话里把结构化回答变成可扫读、可微调的界面,又不想为每次交互多烧 token 的开发者与用户。render_ui 适合展示与预览;需要回传选择或参数时必须用 ask_with_ui。
已知限制(README):
- 工具调用行只显示摘要;完整可交互卡片在本轮末尾 turnTail。追问请用卡片本身或
ask_with_ui。 - 卡片草稿存在当前标签页
sessionStorage,刷新可恢复;换会话、关标签或提交成功后不保留。 - 表达式仅算术、比较、逻辑、三元与
item.field一级属性,无函数、循环或数组索引。 - 流式预览只读:控件禁用、无提交、无 required 校验;完整交互等最终卡片。
- 不支持 HTML、原始 CSS、事件回调;图片与链接仅 http/https。
开发与回归可零依赖运行:
node test/host.test.mjs
node test/client.test.mjs
结尾¶
dsh-intelligent-ui 把「一段文字」拆成「文字 + 声明式卡片」:Host 编译、Client 本地解释、显式提交才回模型。安装走市场索引或 plugin_manager 固定 commit;行为与策略在 cordis.patch.yml 与插件设置页可调。