1. Chat‑first: ChatGPT 首先是聊天,其次才是应用
在前 6 个模块中,我们已经弄清了应用的各个方面:从 UI 和 MCP 到调试和部署。现在我们将再纵深一层,从各个侧面重新梳理。你们总不至于以为事情就这么简单吧?
我们先从 UX 讲起,更具体地说是官方的 UI 要求和 UX 指南。你当然希望你的应用能通过 review,对吧?很好,那就从最关键的认知转变开始,这点对习惯了 SPA/Next.js 的前端尤其重要: ChatGPT 的首要形态是对话界面,而 App 是这个对话中的客人。绝不是反过来。
OpenAI 在其指南中是这样表述的:应用应当扩展用户的能力,但不打断对话流。小部件不是新的浏览器标签页,而是对话中的一个恰到好处的插入——在纯文本已显吃力的地方提供结构化的帮助。
最容易记住的方法是区分角色。
GPT 和 App 的角色
在 ChatGPT 里有两个“角色”:
| 谁 | 职责 |
|---|---|
| GPT 助手 | 进行对话,提出澄清性问题,解释并总结 |
| App(小部件) | 展示复杂结构(列表、表格、表单),提供交互 |
GPT 仍然是主要的“讲述者”。它要用文字解释接下来会发生什么、为何建议使用 App、按钮的含义,并对小部件的结果进行总结。而 App 专注于可视化与操作:选项选择、筛选设置、分步向导等。
有一条非常重要的规则,需要像咒语一样重复: 所有重要决策都必须在 GPT 的文本回复中明确说出来,即使用户是在 UI 里点击完成的。用户没有义务读完小部件里的每一行内容——关键后果(例如“我们已经下单”或“你选择了这些参数”)必须在对话里说清。
2. 何时 App 的确需要:展示的判定标准
从技术角度讲,你可以在每条消息时都调用小部件。但从 UX 的角度看——这就像用户每输入一个字符就弹出一个全屏对话框。能工作——是的。好用——并不是。
OpenAI 和 Apps SDK 给出一个简单原则:当使用 App 比只用文本更便于思考时,它才是合适的。
具有结构和可复用流程的请求
App 在用户请求已暗示出结构时尤其合适:
- “为同事挑选 5 个不超过 $50 的礼物选项。”
- “比较这三种资费方案。”
- “制定一条东京 3 天行程路线。”
- “展示我这周的待办清单并帮我排列优先级。”
这些场景里有清晰的实体(礼物、资费、行程天数、任务)需要操作,以及明确的步骤:选择、筛选、比较、确认。此时带有卡片、复选框、筛选器的 UI 是合理甚至是救命的。
GiftGenius 的示例
以我们最爱的主角 GiftGenius 为例。一个典型请求:
需要为婚礼的 10 位来宾挑选礼物,预算和兴趣各不相同。
如果只用文本,GPT 也能列出 10 份清单,但读起来会很痛苦。更舒服的做法是:
- 展示包含来宾、预算和兴趣的表格,
- 提供“更便宜/更贵”的过滤,
- 为每位来宾展示一组卡片。
在这里 App 几乎是必需的:实体和参数太多了,无法只靠文本承载。
相较之下:
给兄弟送什么礼物,预算 5000 ₽?
这是一个一步完成的小问题。GPT 用 3–5 个点子直接文本回复即可;只有当用户进一步要求“给我一个可以按爱好和年龄筛选的界面”时,才可以顺滑地转到 App。
小型启发式
可以记住一个简单表格:
| 请求类型 | 最佳回应 |
|---|---|
| 1–2 个对象,一个动作 | GPT 文本 |
| 3–10 个对象,需要选择/比较 | GPT 文本 + inline App |
| 多步骤、复杂表单、长流程 | GPT + 全屏向导型 App |
关于 inline 和 fullscreen 我们会在后续课程详谈,但现在已经能看出:App 是为结构化、多步骤任务而生的工具,而不是用来应对每个“我有点丧,怎么办?”的问题。
3. 当 App 反而碍事:“聊天”模式与思考
我们已经看到在哪些情况下 App 的确能让生活更简单、让对话更有结构。但事情还有另一面:也有些情况下,任何 UI 都只会添堵。
关于“让我们画个 UI 吧”的讨论太多,往往导致一种反射: “哦,用户问了点什么——开小部件!”这正是你在 Store 审核里可能被扣 UX 分的地方。
有一类请求中,App 往往是负作用:
- 用户处于“想聊天”模式。 例如哲学式的思考、个人问题、职业困惑、情绪支持。在这些场景中,用户期待的是文字对话、澄清性提问,甚至是共情。此时硬塞卡片和筛选器就像广告横幅一般打扰。
- 关于服务的入门性提问。 如果有人写道“给我介绍一下 GiftGenius 能做什么?”——他需要的是概览,而不是马上一个 UI。此时 GPT 更适合先简述 App 的作用,可能给出一些请求示例,随后再礼貌地建议试用小部件。
- 一般性的理论问题。 “如何给内向的人挑礼物?”或“商店里的会员体系如何运作?”——这属于知识性而非交易性场景。GPT 可以给出良好的文字回答,最后不动声色地加一句:“如果你愿意,我可以打开 GiftGenius 来挑一些具体选项。”
凡是 UI 不提供新增价值、仅仅重复文本内容的场景,都应当保持在聊天里。这就是 UX 专家常说的对用户意图的尊重。
4. 如何提议 App:auto‑launch 与“谦逊交接”
即便你确信 App 是合适的,“如何启动它?”仍是个问题。粗暴的做法:小部件毫无预告地全屏弹出。正常的做法:GPT 先用文字解释将要发生的事,并征求同意或至少进行告知。
在 ChatGPT Apps 的 UX 文档里,强调了两个模式:auto‑launch 和 suggestion(humble handoff)。
Auto‑launch:当用户明确提出时
当用户明确表达意图时,auto‑launch 是合适的:
打开 GiftGenius。
进入 GiftGenius 的设置。
在 GiftGenius 中展示我的礼物购物车。
这里的规则很简单:
- GPT 简短写一句类似“正在打开 GiftGenius…”。
- 模型立即调用工具/小部件。
对话可能这样:
用户:打开 GiftGenius,我想给朋友挑礼物。
GPT:正在打开 GiftGenius 助手以便挑选礼物。
[出现 GiftGenius 小部件(内嵌或全屏)]
因为用户主动要求“打开”,所以无需额外的澄清就进行自动启动是合理的。
Suggestion(humble handoff):当意图并不明确时
在很多情况下,用户根本不知道你的应用。他会这样写:
需要给同事的生日想个点子,预算不高。
正确的模式是:
- GPT 分析请求并判断 App 可能有帮助。
- GPT 提出 1–2 个澄清问题,或直接用文字建议 App。
- 只有在得到同意或明确暗示后——再启动小部件。
示例:
用户:需要给同事的生日想个点子,预算不高。
GPT:我可以直接给一些点子,也可以打开 GiftGenius 应用,按预算和兴趣来筛选。你是想听建议,还是试试这个应用?
用户:试试应用吧。
GPT:正在打开 GiftGenius,帮你挑选礼物选项。
[出现小部件]
这种做法突出了:主动权仍然在用户手里,而 App 是一个选项,而非强加的广告。这也与 UX 指南中的“Respect user’s intent(尊重用户意图)”原则相契合。
TypeScript “意图分类器”的小示例
假设在你的后端侧已经对用户请求做了一个粗略分类(不要和 GPT 本身混淆,这只是辅助逻辑):
// 用户意图的简化类型
type UserIntent = 'chat' | 'ask_gift_advice' | 'open_app';
// 我们希望为 App 使用的触发方式
type AppTrigger = 'auto' | 'suggest' | 'avoid';
function decideAppTrigger(intent: UserIntent): AppTrigger {
if (intent === 'open_app') return 'auto'; // “打开 GiftGenius”
if (intent === 'ask_gift_advice') return 'suggest'; // 隐性请求
return 'avoid'; // 普通聊天,不使用 App
}
这段逻辑本身并不调用小部件——它更多是把你的 UX 思路形式化。接着你会把这些规则体现在 system‑prompt 和 App 描述里,让模型按照相同的准则行事。
5. 如何不去“接管”对话:好与坏的模式
在 OpenAI 的文档和针对 ChatGPT Apps 的 UX 文章里,有一个非常明确的“不要做”:不要“偷走”对话。也就是不要把聊天变成推广你界面的渠道。
反模式
最常见的痛点是“惊喜小部件”。当用户正进行深入对话时,一个他并未请求的全屏应用突然占满了屏幕。上下文没了,控制感也没了。
另一个常见问题是把 App 当作广告。例如,用户提出一个理论性问题,而模型回答:“我先打开我们的超级小部件,里面都有写”,然后展示一个 UI,其中一半是营销文本。官方指南直接把这类场景称为“poor use cases”。
第三个反模式是 UI 与文本之间频繁且无意义的切换。如果每个小的澄清都要开启并关闭 App,对话就像闪烁的彩灯。用户,尤其在移动端,会很快感到厌烦。
最佳实践
在所有你确实要打开 App 的场景里,尽量坚持三条简单的规则。
第一,提前告知。让 GPT 明确说明它将要打开应用,以及目的是什么。例如:“我现在打开 GiftGenius 助手,以卡片形式展示选项。”这 1–2 句话足以完全改变用户对这个跳转的感受。
第二,解释在 UI 里该怎么做。并非所有用户都熟悉这个新界面。GPT 可以补充文字:“下面会看到礼物卡片,可以翻页,并在任意选项上点击‘查看详情’。”如果小部件里有不寻常的东西(例如“再显示 N 个”或非常规筛选器),最好也用文字说明。
第三,用文本总结结果。当 App 完成某项工作(已挑选、已计算、已发送)后,GPT 应简要说明:“我挑选了 3 个礼物选项。前两个在 $50 以内,第三个略贵,但配送更快。要不要进一步缩小范围?”这对移动端和语音场景尤为重要:用户可能没看 UI,但能听到文字摘要。
6. system‑prompt 与 App 描述在 UX 管理中的作用
此前你已经看到 system‑prompt 如何定义 App 的“人格”,以及模型如何使用工具。现在要把UX 规则也加进去:何时建议 App、如何预告、何时避免使用。
在 system‑prompt 中该写什么
对 GiftGenius 而言,system‑prompt 可以包含一个“对话与 UX”章节。文档与文章建议用结构化的、独立的规则来描述。
片段示例(伪代码,贴近真实):
### 对话与 UX
1. 如果用户给出了礼物挑选条件(送给谁、预算、场合),
先用文本提出 1–2 个澄清问题。
2. 澄清后建议打开 GiftGenius App:
"我可以打开 GiftGenius 助手来展示礼物选项。要打开吗?"
3. 如果用户明确要求“打开 GiftGenius”或“展示礼物清单”,
回答“正在打开 GiftGenius...”并立即调用 App,无需额外提问。
4. 如果用户请求理论或通用建议(比如“如何挑礼物”),
用文本回答,不要打开 App,除非他自己提出。
5. 如果用户说“不要打开应用”或“只要文字回答”,
后续在本次对话中不要再主动提议 App。
6. 在 App 完成工作后,始终用文本进行简要总结。
这里浓缩了我们的 UX 原则:chat‑first、尊重用户拒绝、区分 auto‑launch 与 suggest、以及强制性的文本摘要。
用 TypeScript 配置来辅助
在真实项目中,把部分规则以结构化的形式保存会更方便(避免以后在 prompt 里到处找文本)。例如,可以准备一个简单的配置:
// App 的 UX 触发规则的示例类型
type AppUxRule = {
intent: 'gift_selection' | 'theory' | 'open_app';
trigger: 'auto' | 'suggest' | 'avoid';
askConfirmation?: boolean;
};
export const giftGeniusUxRules: AppUxRule[] = [
{ intent: 'open_app', trigger: 'auto' },
{ intent: 'gift_selection', trigger: 'suggest', askConfirmation: true },
{ intent: 'theory', trigger: 'avoid' },
];
模型本身并不会读取这个配置——它是给你(开发者)用的,把产品/设计达成的共识集中管理,再把它们稳妥地迁移到 system‑prompt、App 描述和文档中。
7. 示例:GPT 如何预告 GiftGenius 而不抢走对话
把一切串起来。假设用户第一次在聊天中写道:
我在给同事找礼物,预算大约 3000 ₽,他喜欢桌游。
结合我们的 system‑prompt,一个不错的模型回答可以是:
明白!我们先确认两个小细节,然后一起挑些主意。
请问他大概多大年纪?这是更正式的礼物,还是来自亲密朋友的心意?
(在你回复后,我可以打开 GiftGenius 助手,用卡片方式展示选项。)
在澄清之后,GPT 写道:
太好了,信息已经足够。
我现在会打开 GiftGenius 应用——在里面我会用卡片方式展示一些礼物选项,你可以查看详情,并按预算和游戏类型进一步缩小范围。
然后才启动 App。没有任何“惊喜”,一切都通过文字解释清楚。
小型 React 组件:“App 预告”放在小部件内部
从代码角度看,小部件通常在被调用时直接渲染。但即便它已经打开,你也可以在 UI 中贯彻“不抢走对话”的理念。
例如,GiftGenius 的第一个屏幕可以非常简洁:
// app/components/GiftGeniusIntro.tsx
export function GiftGeniusIntro() {
return (
<section style={{ padding: 16 }}>
<h2 style={{ fontSize: 20, marginBottom: 8 }}>
使用 GiftGenius 挑选礼物
</h2>
<p style={{ marginBottom: 12 }}>
我会以卡片的形式展示若干选项。你可以选择喜欢的,ChatGPT 会解释优缺点。
</p>
<p style={{ fontSize: 12, color: '#666' }}>
任何时候都可以回到普通聊天继续讨论。
</p>
</section>
);
}
这个组件从技术上并不“强大”,但从 UX 上看很重要:它提醒用户聊天仍然存在,GPT 的角色依然是中心。
接下来你会从这个引导屏进入礼物卡片、向导等内容,但那是后续课程的主题了。
8. 实践与练习
上面我们整理了一套原则——chat‑first、尊重用户意图、区分 auto‑launch 与“建议使用” App。为了巩固“何时以及如何展示 App”,不妨结合真实请求,明确区分哪些地方需要 App,哪些不需要。作为作业可以做两个小练习。
首先,以 GiftGenius 为例想出 5–7 个用户请求。对于每个请求,认真回答:
- 这里是否应该直接建议打开 App;
- 是否只把 App 作为一种选项提及;
- 或者最好完全不把回答与 App 关联。
例如:
- “给妻子的周年纪念准备点什么,预算 $1000 以内”——大概率先用文本进行 1–2 个澄清,然后建议打开 App。
- “怎么把礼物包装得更有创意?”——纯理论问题,可以不使用 App。
- “打开 GiftGenius,我想给整个团队选礼物”——直接 auto‑launch。
第二个练习——编写启动 App 的预告文案。尝试写 1–2 句话,让 GPT 用来向用户解释将要进入 App。对比不同语气:更正式的(“正在打开 GiftGenius…”)与更友好的(“我们来试试 GiftGenius 助手——这样更容易对比选项”)。
这样你不仅能以开发者的视角思考,也能以对话作者的视角构建体验。
9. 在“何时展示 App”这类 UX 上的常见错误
错误 №1:只要提到相关主题就展示 App。
常见的极端做法是:如果 App 是关于礼物的,那么对话中出现任何“礼物”一词就立刻触发小部件。用户问“怎么不给老板选礼物时踩雷”,结果得到的却是卡片 UI,而不是真诚的建议。这会被当作广告,并忽视了用户的真实意图,直接违背了官方 UX 指南与“Respect user’s intent”原则。
错误 №2:不加预告的全屏。
“惊喜小部件”突然占满整个屏幕,是最稳妥的“劝退”方式。尤其当它发生在一段长对话的中途,用户完全没预期从文本突然切到 UI。根据 OpenAI 的指南,这被视为坏例;应始终预告跳转,且尽可能征求同意。
错误 №3:用 UI 代替回答。
有时 App 的作者会想:“干嘛还要文本,我们的界面已经很漂亮了!”最后 GPT 几乎不说话,所有“答案”都埋在小部件里。用户,尤其在语音或移动端,甚至可能忽略重要细节。正确做法是:UI 补充答案,而不是替代它;App 展示细节与选项,GPT 解释这意味着什么。
错误 №4:无视用户拒绝使用 App。
如果用户明确说“不要打开应用”或“只要文本”,那么在接下来的对话中就应当把这当作硬性规则。每隔两句又来一次“要不要用 App”的提议,就像纠缠不休的“请给我们评分”弹窗。这会损害 UX,也可能影响 Store 审核。在 system‑prompt 里要明确写入对拒绝的尊重。
错误 №5:不区分 auto‑launch 与“建议使用”。
当开发者不区分明确与不明确的意图时,要么从不启动 App(哪怕用户已经直说了),要么总是启动(哪怕用户只是随口提到“也许以后试试你的 App”)。由此产生“只因为出现某个词就自动打开”的糟糕体验。将触发器形式化(auto / suggest / avoid),并在 system‑prompt 中设定清晰逻辑,能避免这种混乱。
错误 №6:在 system‑prompt 中完全缺失 UX 规则。
有时所有 UX 决策都只“在团队脑子里”,而 system‑prompt 仅写着“你是 GiftGenius 助手,帮忙挑礼物”。于是模型时而建议 App,时而忘了它,或在不合适的时机打开。把结构化的 UX 规则记录在 system‑prompt 与文档中,同 JSON 工具模式一样重要。
错误 №7:“以后再补 UX”。
常见做法是——先把功能跑起来,再“以后”考虑 UX。在 ChatGPT Apps 的语境里,这会导致你已经绑死在某些工具调用模式上,而要修改 system‑prompt 和 GPT 行为就更难了。更好的做法是在一开始就把基础的 UX 指南确立下来:chat‑first、尊重拒绝、清晰的展示标准,以及不做“惊喜小部件”。这样后续演进(inline 模式、全屏、语音)才能建立在健康的地基上。
GO TO FULL VERSION