为人类而设计的 AI:goose 借助 MCP-UI 从“文字回复”走向“意图驱动的界面体验”
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
本文基于 documentation/blog/2025-10-14-designing-ai-for-humans/index.md 展开。核心议题不是“如何让模型更聪明”,而是“如何让 Agent 的产出对使用者更友好”。文章以 goose 内置的Auto Visualiser(自动可视化)扩展为主线,讲解 MCP-UI / MCP Apps 如何把纯文本聊天升级为可点击、可操作、可实时反馈的界面层,并给出“开发者为用户而非模型做设计”的完整思维框架与源码级实现依据。读完你将理解:什么是 Agentic UX、goose 中可视化工具是如何渲染成界面资源并被桌面端拾取、如何按本文提供的数据结构给 Auto Visualiser 喂数据,以及自己在构建 MCP 服务器时如何产出同样的交互界面。
从一段预算故事说起:AI 好不好用,取决于“展示方式”
博客作者用了一个很接地气的场景切入:母亲每周日记账时,面对一堆收据和计算器叹气——“我只是想知道钱都花到哪里去了”。在试用 goose 并开启Auto Visualiser后,几秒钟内她的预算就被渲染成一张彩色、可交互的图表,鼠标悬停在每个扇区上就能看到每一笔钱的去向。
这个案例的价值不在于“自动做图表”本身,而在于交互范式的变化:母亲不需要学习任何新软件、适应任何人的设计,可视化直接出现,她立刻就看懂了。作者由此提炼出全文核心判断——真正让 AI 走出“geek 玩具”定位的,不是技术能不能跑通,而是AI 是否以对用户有意义的方式“出现”。
“展示”而非“讲述”:MCP-UI 把聊天窗口变成界面层
博客指出,Agent 已经能规划、推理、执行,但大多数 Agent 的交流方式仍是“终端”:成段的文字输出,没有真正的交互。MCP-UI正是在这个断层上改变了规则——它给 Agent 一套“视觉语言”,并让用户在聊天窗口内直接与 Agent 互动:
- 一个按钮可以触发一条新 prompt,用户无需敲一个字;
- 一个下拉框可以在后台执行一次 tool call;
- 一个链接可以立刻为用户打开页面或资源;
- 通知可以在内嵌 UI 与宿主应用之间来回传递,保持状态同步。
这带来的是从“Prompt/Response 链条”到“接口层(interface layer)”的转变:Agent 不再用文字描述它“能做什么”,而是直接呈现真实、可点击的选项,并实时响应用户的选择。一句话总结博客的核心主张:
与其对你的 Agent 说“这是你的数据”,不如让它把数据展示出来,让你在数据上操作,并对你的选择做出反应。
goose 侧的规范演进:从 MCP-UI 到 MCP Apps
需要说明的是:原博客写作时这一套机制被统称为 MCP-UI,而当前 goose 仓库已将其落地为官方的MCP Apps规范。goose 的交互式界面文档明确写着:“MCP Apps 是交互式 UI 的官方 MCP 规范,新的交互式扩展应使用 MCP Apps”,详见 Using MCP Apps 与 Building MCP Apps。在源码层也可以看到对应证据:Auto Visualiser 声明的资源 MIME 类型为text/html;profile=mcp-app,注释中标注其来自 MCP Apps 规范(SEP-1865),见 autovisualiser/mod.rs。
MCP Apps 的核心思想是:MCP 服务器返回的可以不止是文本数据,还可以是一个可在聊天内渲染的交互组件。图表、按钮、表格、表单……服务端拥有对“数据长什么样”的完全控制权。
读源码:goose 内置 Auto Visualiser 是如何实现的
goose 的 Auto Visualiser 并不是一个神秘的黑盒,而是一个独立的 MCP 服务器扩展,全部实现位于 crates/goose-mcp/src/autovisualiser/mod.rs。从源码结构看,它对外暴露了两类 MCP 能力:
1. 一组 UI 资源(Resources)+ 一组渲染工具(Tools)
AutoVisualiserRouter 实现了ServerHandler,并同时声明enable_tools()与enable_resources()能力(mod.rs)。它向客户端注册了 8 个ui://资源,每个资源对应一种可视化模板:
| UI 资源 URI | 名称 | 对应渲染工具 |
|---|---|---|
ui://autovisualiser/chart | Chart | show_chart(折线/散点/柱状) |
ui://autovisualiser/sankey | Sankey Diagram | render_sankey |
ui://autovisualiser/radar | Radar Chart | render_radar |
ui://autovisualiser/donut | Donut/Pie Chart | render_donut |
ui://autovisualiser/treemap | Treemap | render_treemap |
ui://autovisualiser/chord | Chord Diagram | render_chord |
ui://autovisualiser/map | Interactive Map | render_map |
ui://autovisualiser/mermaid | Mermaid Diagram | render_mermaid |
每个工具通过meta = ui_resource_meta(...)将“工具”与“界面资源”绑定起来(工具返回结果时携带_meta.ui.resourceUri),客户端据此知道该把哪个 HTML 模板取来渲染当前结果,见 mod.rs 与各工具声明处的meta字段。
2. “模板无数据、数据走消息”的渲染机制
实现的关键设计在get_template_html与模板文件里:HTML 模板内联了所需的 JS 库,但不内置任何数据——数据通过 postMessage 在运行时传入(mod.rs 注释)。不同图表使用不同前端库:
- 折线/柱状/雷达/环形图模板内联Chart.js(
chart.min.js); - Sankey、Treemap、Chord 模板内联D3.js(
d3.min.js、d3.sankey.min.js); - 地图模板内联Leaflet与 markercluster 插件;
- Mermaid 模板内联mermaid.min.js;
- 所有模板共用
mcp-app-base.css与负责消息桥接的mcp-app-bridge.js。
这些静态资源全部位于 autovisualiser/templates(含 8 个*_template.html与assets/目录)。在read_resource返回资源内容时,扩展还会附加{"ui": {"prefersBorder": true}}元信息,告诉宿主端该界面适合带边框内联展示,见 mod.rs。
3. 服务端对 LLM 的“指令注入”
AutoVisualiserRouter::new()还维护了一段 instructions 文本(mod.rs),随服务器初始化信息一起提供给模型,内容是引导 Agent 何时使用可视化、如何选择图表类型并匹配数据格式,并列出 8 个可用工具。这就是“自动检测并挑选最合适图表”这一体验的幕后支撑:真正的类型判定由 LLM 结合这些指令完成,扩展只负责严格校验与渲染。
4. 数据校验与容错
每个渲染工具都定义了严格的 Rust 数据结构与校验逻辑,例如:
- Sankey 图要求
nodes/links均非空,且每个 link 的 source/target 必须存在于 nodes 中、value 必须为正(SankeyData::validate); - 雷达图要求每个 dataset 的数据点数量与 labels 数量一致(RadarData::validate);
- 地图要求 marker 的纬度在 -90~90、经度在 -180~180 范围内(MapData::validate);
- 折线/柱状图校验每个数值型 dataset 的长度与 x 轴 labels 长度匹配(ChartData::validate)。
值得注意的容错设计是lenient_data反序列化器(mod.rs):由于模型有时会把复杂参数双重编码成 JSON 字符串,扩展会先解析字符串再反序列化,降低工具调用失败率。所有工具在返回结构化数据的同时仍附带一段纯文本兜底摘要(如sankey diagram: 4 node(s), 3 link(s)),保证在不支持渲染的客户端中也有可读结果。
如何启用 Auto Visualiser
Auto Visualiser 是 goose 的内置扩展。官方配置说明见 Auto Visualiser Extension,两种启用方式:
方式一:goose Desktop在桌面端扩展(Extensions)页面中找到内置的Auto Visualiser并启用即可,无需额外安装依赖。
方式二:goose CLI
- 运行配置命令:
goose configure- 选择
Toggle Extensions(开启/关闭扩展):
┌ goose-configure │ ◇ What would you like you configure? │ Toggle Extensions │ ◆ Enable extensions: (use "space" to toggle and "enter" to submit) │ ● autovisualiser └ Extension settings updated successfully选中autovisualiser后回车,配置即生效。需要留意的是,Auto Visualiser 的可视化目前以MCP Apps方式渲染,官方说明指出这意味着“可视化可以内联显示在聊天中,并在 goose Desktop 里展开为全屏或画中画模式”。
一个可复现的实战示例:让 goose 分析季度销售数据
官方文档 autovisualiser-mcp.md 给出了完整的演练示例。向 goose 输入以下提示:
I have quarterly sales data for different product categories. Can you help me understand: 1. The hierarchical breakdown of revenue across our nested product categories 2. How our performance metrics compare across all four quarters 3. The customer flow through our sales funnel process Here's the data: - Electronics: Q1: $150k, Q2: $180k, Q3: $220k, Q4: $195k - Clothing: Q1: $120k, Q2: $140k, Q3: $160k, Q4: $175k - Home & Garden: Q1: $80k, Q2: $95k, Q3: $110k, Q4: $125kgoose 会识别出三个不同诉求,并分别调用三个渲染工具,一次回复同时给出三张交互图表:
- Treemap(树图)——回答“收入在嵌套类目下的层级分布”,方块面积与收入成比例;
- Radar(雷达图)——回答“四个季度的业绩指标对比”,三个品类形成三条多边形轮廓;
- Sankey(桑基图)——回答“客户在销售漏斗中的流转”,线条粗细代表转化量级。
下图为文档同款示例中的两张可视化截图:
拿到图表后 goose 还会在文本里给出解读要点(总收入、环比趋势、品类占比、季节规律等),说明界面负责“看懂”,文本负责“讲透”——两者互补,而不是互相替代。结合上文的表格,你可以在调试时快速判断自己的数据该走哪条工具:
| 数据类型 | 适合的可视化 | 官方文档描述的触发场景 |
|---|---|---|
| 节点与有向流转关系 | Sankey | 工作流、漏斗、流程类数据 |
| 多维指标对比 | Radar | 绩效指标、特性对比 |
| 分类占比(可多图) | Donut/Pie | 百分比构成、类别分布 |
| 层级嵌套数据 | Treemap | 嵌套类目、组织架构 |
| 实体间关系矩阵 | Chord | 网络连接、交叉引用 |
| 地理坐标数据 | Map(Leaflet) | 位置、坐标、地址 |
| 流程图/时序图等 | Mermaid | 架构图、时序图等图表需求 |
| 时间序列/趋势 | Line/Bar/Scatter | 历史数据、随时间变化的趋势 |
给扩展开发者:从“先想用户体验”开始,让 MCP 服务器“带界面返回”
博客最想传递给开发者的是设计理念的转变:别只为了模型做设计(prompt 结构、JSON 格式),要为用户下一步想做什么、想看到什么做设计。业界同期的 Google AI Mode 把搜索变成“意图驱动”体验,直接在结果页呈现机票、座位图与购买按钮——MCP-UI 在 Agent 世界复刻了同样的进化,让网页/服务“动态适应使用者正在做的事”。
具体到工程上,如果你在构建自己的 MCP 服务器,最自然的做法是:同时返回原始文本响应和一个可渲染的 UI 资源。仓库中的实战指南 2025-09-08 如何让任意 MCP 服务器具备 MCP-UI 兼容性 记录了完整的改造模式,其核心套路可归纳为:
- 生成 HTML:写一个函数,把业务结果转成自包含的 HTML 字符串(含预览、按钮等交互元素),交给宿主以 iframe
srcdoc方式渲染; - 同步尺寸:在 HTML 里用
ResizeObserver监听容器高度变化,通过postMessage发送ui-size-change,否则界面会被截断; - 注册 UI Actions:在
<script>中通过window.parent.postMessage发送动作消息,例如prompt(触发一轮新的对话)、link(打开外部链接),还有tool、intent、notify等其他动作类型,从而让“静态界面”变成能反向驱动 Agent 的交互工具; - 改造量极小:在工具处理器里把原来只返回文本的
content数组补上一个 UI 资源即可——多返回一个资源,Agent 侧就能渲染出完整界面。
更完整的官方入门路径在 Building MCP Apps(构建 MCP Apps 教程):它从npm install @modelcontextprotocol/sdk、初始化server.js、注册show_demo_app工具开始,一步步构建一个与宿主主题同步、并能在聊天内向用户反馈意图的交互式计数器应用。文中强调当前 MCP Apps 在 goose 中仍属实验特性、基于草案规范,行为与支持范围未来可能变化——这也呼应了博客里“规格与客户端实现都在活跃演进”的观察。
一个值得直接套用的设计练习是:想象你的 API 面向的是一个真实品牌或产品界面。例如一个 Shopify MCP 服务器可以返回看起来像店铺橱窗的商品列表,一个 Notion MCP 服务器可以在聊天里以块布局展示文档内容。当服务端完全掌控数据呈现方式后,用户经由 AI Agent 使用你的 API 时,依然能获得熟悉、一致的体验——这就是“AI 不再只用文本回复,而是针对当下情境给出正确界面”的未来形态,即博客定义的Agentic UX。
结语
回到最初的故事:下个月母亲记账时,她可能会主动问“你那个 goose 带来了吗”。一句再普通不过的提问,恰恰是 Agentic UX 生效的证明——当 AI 学会了“展示、让你操作、并对你的选择作出反应”,技术就不再是需要学习的使用对象,而成为融入日常的体验。
对开发者而言,行动建议非常明确:构建自己的 MCP 服务器时,先从“你希望用户获得什么体验”出发,再按上文的模式用 MCP-UI / MCP Apps 设计交互流程——像你自己作为使用者那样去打磨它。相关的配套资源都沉淀在本仓库中,可继续深入:Auto Visualiser 官方文档、Auto Visualiser 完整实现、可视化 HTML 模板与前端资产、goose 端 MCP Apps 使用指南 以及 把任意 MCP 服务器改造成可渲染界面的实战博客。
【免费下载链接】goosean open source, extensible AI agent that goes beyond code suggestions - install, execute, edit, and test with any LLM项目地址: https://gitcode.com/GitHub_Trending/goose3/goose
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考