📢 转载信息
原文链接:https://www.freecodecamp.org/news/how-to-use-the-chatgpt-apps-sdk/
原文作者:Shola Jegede
🚀 掌握 ChatGPT Apps SDK:打造你的第一个交互式披萨应用
OpenAI 最近推出了基于全新 Apps SDK 和模型上下文协议(MCP)的 ChatGPT Apps 功能。
你可以将这些 App 视为 ChatGPT 的增强插件:
- 你可以在对话中自然地调用它们。
- 它们可以在 ChatGPT 内部渲染自定义的交互式用户界面(如地图、轮播图、视频等)。
- 它们运行在你控制的 MCP 服务器上,该服务器定义了 App 提供的工具、资源和组件。
在本篇分步指南中,你将使用官方的 Pizza App 示例 来构建一个 ChatGPT App。这个 App 将演示 ChatGPT 如何根据你的本地服务器,渲染披萨地图或轮播图等 UI 组件。
🛠️ 你将学到什么
通过本教程,你将学会如何:
- 使用 OpenAI Apps SDK 设置并运行一个 ChatGPT App。
- 理解核心构建模块:工具(tools)、资源(resources)和组件(widgets)。
- 使用开发者模式将你的本地 App 服务器连接到 ChatGPT。
- 直接在 ChatGPT 对话中渲染自定义 UI。
目录导航
- 你将学到什么
- 目录导航
- ChatGPT App 的工作原理(宏观视角)
- 步骤 1. 克隆示例仓库
- 步骤 2. 运行披萨 App 服务器
- 步骤 3. 暴露你的本地服务器
- 步骤 4. 深入解析披萨 App 代码
- 步骤 5. 在 ChatGPT 中启用开发者模式
- 挑战(尝试自己动手)
- 结论
🌟 ChatGPT App 的工作原理(宏观视角)
架构的简单解释如下:
ChatGPT (前端) | /
MCP 服务器 (你的后端) | /
组件 (在 ChatGPT 内部显示的 HTML/JS 标记)
- ChatGPT 发送请求,例如:“给我看一个披萨轮播图。”
- MCP 服务器 回复包含资源(HTML 标记)和工具逻辑。
- 组件 会内联渲染在 ChatGPT 界面中。
1. 🚀 步骤 1. 克隆示例仓库
OpenAI 提供了一个包含 Pizza App 的官方示例仓库。克隆它并使用以下命令安装依赖项:
git clone https://github.com/openai/openai-apps-sdk-examples.git
cd openai-apps-sdk-examples
pnpm install
2. 💻 步骤 2. 运行披萨 App 服务器
导航到 Pizza App 服务器目录并启动它:
cd pizzaz_server_node
pnpm start
如果成功,你应该会看到类似以下输出:
Pizzaz MCP server listening on http://localhost:8000 SSE stream: GET http://localhost:8000/mcp Message post endpoint: POST http://localhost:8000/mcp/messages
这意味着你的服务器已在本地运行。
3. 🌐 步骤 3. 暴露你的本地服务器
为了让 ChatGPT 能够与你的 App 通信,你的本地服务器需要一个公共 URL。ngrok 提供了一种在开发过程中快速暴露本地端口的便捷方法。
3.1 获取 ngrok
访问 ngrok.com 注册并复制你的 认证令牌 (authtoken)。
3.2 安装 ngrok
macOS:
brew install ngrok
Windows:
- 下载并解压 ngrok。
- 可选:将其所在文件夹添加到你的系统 PATH 中。
3.3 连接你的账户
ngrok config add-authtoken <your_authtoken>
3.4 启动隧道
ngrok http 8000
这将为你提供一个公共的 HTTPS URL(例如 https://xyz.ngrok.app/mcp
)。
4. 🧩 步骤 4. 深入解析披萨 App 代码
完整的 Pizza App 服务器代码较长,我们将它分解成易于理解的部分。
4.1 导入与设置
import { createServer } from "node:http";
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { z } from "zod";
Server
和SSEServerTransport
来自 Apps SDK。zod
用于验证输入,确保 ChatGPT 发送正确的参数。
4.2 定义披萨组件 (Widgets)
组件是 App 的核心,每个组件代表一个 ChatGPT 可以显示的 UI 块。
以下是披萨地图组件的示例:
{ id: "pizza-map", title: "Show Pizza Map", templateUri: "ui://widget/pizza-map.html", html: ` <div id="pizzaz-root"></div> <link rel="stylesheet" href=".../pizzaz-0038.css"> <script type="module" src=".../pizzaz-0038.js"></script> `, responseText: "Rendered a pizza map!"
}
id
→ 组件的唯一名称。templateUri
→ ChatGPT 获取 UI 的方式。html
→ 实际的标记和资产。responseText
→ 在聊天中显示的确认消息。
该 App 定义了五个组件:
- 披萨地图 (Pizza Map)
- 披萨轮播图 (Pizza Carousel)
- 披萨相册 (Pizza Album)
- 披萨列表 (Pizza List)
- 披萨视频 (Pizza Video)
4.3 将组件映射到工具和资源
接下来,组件被转换为工具(ChatGPT 可以调用的功能)和资源(ChatGPT 可以渲染的 UI 标记)。
const tools = widgets.map((widget) => ({ name: widget.id, description: widget.title, inputSchema: toolInputSchema, title: widget.title, _meta: widgetMeta(widget)
}));
const resources = widgets.map((widget) => ({ uri: widget.templateUri, name: widget.title, description: `${widget.title} widget markup`, mimeType: "text/html+skybridge", _meta: widgetMeta(widget)
}));
这使得每个组件都可被调用和显示。
4.4 处理请求
MCP 服务器响应 ChatGPT 的请求。例如,当 ChatGPT 调用一个组件工具时:
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const widget = widgetsById.get(request.params.name);
const args = toolInputParser.parse(request.params.arguments ?? {});
return { content: [{ type: "text", text: widget.responseText }], structuredContent: { pizzaTopping: args.pizzaTopping }, _meta: widgetMeta(widget) };
});
这会:
- 找到请求的组件。
- 验证输入(
pizzaTopping
)。 - 返回文本和元数据,以便 ChatGPT 可以渲染组件。
4.5 创建服务器
最后,服务器绑定到 HTTP 端点(/mcp
和 /mcp/messages
),以便 ChatGPT 可以与它进行消息流式传输:
const httpServer = createServer(async (req, res) => {
// 处理对 /mcp 和 /mcp/messages 的请求
});
httpServer.listen(8000, () => {
console.log("Pizzaz MCP server running on port 8000");
});
5. ⚙️ 步骤 5. 在 ChatGPT 中启用开发者模式
5.1 启用开发者模式
- 打开 ChatGPT
- 前往 设置 (Settings) → Apps & 连接器 (Apps & Connectors) → 高级设置 (Advanced Settings)
- 切换 开发者模式 (Developer Mode) 开关
当 开发者模式 启用后,ChatGPT 的界面应该如下所示:
5.2 创建 App
- 返回 设置 (Settings) → Apps & 连接器 (Apps & Connectors)
- 点击 创建 (Create)
- 接下来:
- 名称 (Name): 为你的 App 输入一个名称(例如:Pizza App)
- 描述 (Description): 输入任何描述(或留空)
- MCP 服务器 URL (MCP Server URL): 粘贴你的 MCP 端点的公共 HTTPS URL。确保它直接指向
/mcp
,而不仅仅是服务器根目录。 - 身份验证 (Authentication): 选择 无需身份验证 (No authentication)
- 勾选 我信任此应用程序 (I trust this application)
- 点击 创建 (Create) 完成设置
一旦你的 App 连接到 ChatGPT,它将显示如下:
当你点击返回图标时,你应该能看到你的 App 以及其他可以连接和使用 ChatGPT 的 App:
5.3 使用你的 App
要使用你的 App:
- 打开一个新的 ChatGPT 对话
- 点击 + 图标
- 向下滚动到 更多 (more)
- 你会看到你的 App
- 选择 Pizza App 开始使用你的 App
以下是一些你可以在 ChatGPT 中尝试的、与你的披萨 App 相关的指令:
- Show me a pizza map with pepperoni topping (用意大利辣香肠配料显示披萨地图)
- Show me a pizza carousel with mushroom topping (用蘑菇配料显示披萨轮播图)
- Show me a pizza album with veggie topping (用素食配料显示披萨相册)
- Show me a pizza list with cheese topping (用芝士配料显示披萨列表)
- Show me a pizza video with chicken topping (用鸡肉配料显示披萨视频)
每个指令都会告诉 ChatGPT 渲染哪个组件,你可以随意替换配料。
以下是示例截图:
- 意大利辣香肠配料的地图:
- 额外芝士的轮播图:
- 蘑菇配料的相册:
🏆 挑战(尝试自己动手)
这里有三种扩展你的 Pizza App 的实际方法。每种方法都直接关联到你已经看过的代码。
挑战 A:添加一个“披萨特价”组件(纯文本)
目标: 创建一个仅显示简短消息的组件,例如“今日特价:玛格丽特披萨配罗勒。”
修改位置:
resources.widgets
→ 复制一个现有条目,并赋予它新的id
/title
。tools
→ 将其注册为一个新工具。CallTool
处理程序 → 检测调用(if (request.params.name === "pizza-special")
)并返回你的特价信息。
提示:
这个组件不需要额外的 CSS/JS 文件。只需将其 html
保持为类似 <div>🍕 Today’s special: Margherita</div>
的内容即可。关键在于展示组件可以像纯 HTML 一样简单。
挑战 B:支持多种配料
目标: 允许用户订购多于一种配料的披萨,例如 ["pepperoni", "mushroom"]
。
修改位置:
toolInputSchema
→ 将z.string()
更改为z.array(z.string())
。CallTool
处理程序 → 解析后,args.pizzaTopping
将是一个数组。将其连接成一个字符串后再插入到 HTML/响应中。- 组件 HTML → 更新显示,以列出所有选定的配料。
提示:
首先在控制台中 console.log
解析后的 args
以确认你确实收到了一个数组。然后尝试类似以下代码:
const toppings = args.pizzaTopping.join(", ");
return { responseText: `Pizza ordered with ${toppings}`, content: [...] };
挑战 C:从外部 API 获取真实披萨数据
目标: 不再硬编码内容,而是获取真实的披萨信息。例如,你可以调用 Yelp API 来列出特定地点的披萨店,或者使用免费的占位符 API 来模拟数据。
修改位置:
- 在你的组件
CallTool
处理程序内部。 - 用一个
fetch(...)
调用替换静态 HTML,该调用根据响应构建动态 HTML。
提示:
从小处着手,使用像 JSONPlaceholder 这样的免费 API。例如:
const res = await fetch("https://jsonplaceholder.typicode.com/posts?_limit=3");
const data = await res.json();
const html = ` <ul> ${data.map((p: any) => `<li>${p.title}</li>`).join("")} </ul>
`;
return { responseText: "Fetched pizza places!", content: [{ type: "text/html", text: html }] };
一旦这个功能奏效,就可以替换成真实的 API,如 Yelp 或谷歌地图地点,来渲染实际的披萨店信息。
🎉 结论
你刚刚使用 OpenAI Apps SDK 构建了你的第一个 ChatGPT App。只需少量 JavaScript 和 HTML,你就创建了一个可以与 ChatGPT 通信的服务器,并在聊天窗口中渲染了交互式组件。
虽然这个例子侧重于 OpenAI 提供的披萨 App 示例,但你可以构建任何东西:
- 天气仪表板,
- 电影查找器,
- 金融数据查看器,
- 甚至一个小游戏。
该 SDK 使我们能够以强大的新方式融合 对话 + 交互式 UI。
深入研究 OpenAI Apps SDK 文档,开始构建你自己的应用程序吧!
🚀 想要体验更好更全面的AI调用?
欢迎使用青云聚合API,约为官网价格的十分之一,支持300+全球最新模型,以及全球各种生图生视频模型,无需翻墙高速稳定,文档丰富,小白也可以简单操作。
评论区