Skip to content

ChatGPT Apps SDK 从理论到实践

本文档特点:

  • 理论+实践结合: 每个官方概念都对照实际代码
  • 精确定位: 标注代码行号,快速查找
  • 避坑指南: 标注常见错误和正确做法
  • 开箱即用: 完整代码可直接复制使用

适用人群:

  • 准备开发ChatGPT App的开发者
  • 需要理解Apps SDK工作原理的技术人员
  • 想要快速上手MCP协议的工程师

一、架构对比

1.1 官方标准架构

根据OpenAI官方文档,Apps SDK的标准架构如下:

核心组件:

  • ChatGPT客户端: 理解用户意图,决定何时调用工具
  • MCP Server: 定义工具、提供Widget HTML、处理业务逻辑
  • Skybridge iframe: 安全沙箱,运行Widget UI
  • Widget: 自定义UI组件,可以是React/Vue/纯JS

1.2 本项目实现架构

本项目(YouTube视频学习助手)的实际架构:


1.3 数据流程详解

关键洞察:

  1. 数据不是预填充的,而是事件驱动推送
  2. ChatGPT通过_meta字段知道要加载哪个Widget
  3. Widget必须订阅openai:set_globals事件才能接收数据

二、开发准备

2.1 官方要求

来源: OpenAI Apps SDK官方文档

硬性要求:

  1. ChatGPT订阅账号
    • Plus账号 - 可以使用Connectors和开发者模式
    • Pro账号 - 可以使用Connectors和开发者模式
    • Team账号 - 可以使用Connectors和开发者模式
    • Enterprise账号 - 可以使用Connectors和开发者模式
    • 免费账号 - 无法使用Connectors功能和开发者模式
  2. HTTPS端点
    • 开发: 使用ngrok等隧道工具
    • 生产: 部署到HTTPS域名

技术栈选择 (官方支持):

技术栈官方SDK适用场景
Python@modelcontextprotocol/python-sdk
FastMCP (第三方,推荐)
快速原型、AI/ML集成
TypeScript/Node.js@modelcontextprotocol/sdk全栈JavaScript项目
其他语言实现MCP协议即可Go、Rust等

2.2 本项目技术选型

后端:

  • Python 3.11 + FastMCP 2.12.4
  • HTTP with SSE (Server-Sent Events)
  • 异步处理 (async/await)

前端:

  • React 18 (使用useSyncExternalStore)
  • esbuild (快速打包)
  • 单文件HTML bundle

为什么选这个组合?

FastMCP优势:

  • 官方推荐,社区活跃
  • 自动处理MCP协议细节
  • 内置工具装饰器,开发效率高

React 18优势:

  • useSyncExternalStore Hook专为订阅外部数据设计
  • 完美适配ChatGPT的事件驱动机制
  • 生态成熟,组件丰富

⚠️ 重要限制:

  • FastMCP的ToolResult不支持_meta字段
  • 必须混用低级MCP API返回CallToolResult

三、产品定位与黄金问题集

3.1 官方方法论

来源: 研究用例 - Apps SDK文档

什么是黄金问题集?

黄金问题集(Golden Prompt Set)是用于测试工具召回率和精确度的标准提示词列表。

为什么需要黄金问题集?

  • ChatGPT通过工具的descriptioninstructions决定何时调用
  • 精心设计的问题集可以持续验证工具是否被正确触发
  • 避免误触发(精确度)和漏触发(召回率)

官方要求的三类提示词

  1. 直接提示词 (至少5个)

    • 明确引用产品名称或关键动词
    • 例如: "显示我的Jira看板"
  2. 间接提示词 (至少5个)

    • 陈述目标但不提及工具
    • 例如: "发布前我被什么阻碍了?"
  3. 负面提示词

    • 不应该触发你的App
    • 用于衡量精确度

3.2 本项目实践 ⭐

我们的产品定位

应用名称: Heliki Video Learning (YouTube视频学习助手)

核心用例: 快速理解YouTube视频内容

适合场景分类:

  • 快速查询 - 视频元数据、统计数据
  • 可视化展示 - 视频缩略图、评论列表
  • 即时有价值 - 无需离开ChatGPT即可获取信息

匹配官方"良好用例"的条款:

  • [x] 自然融入对话 (用户发YouTube链接时触发)
  • [x] 有时间限制 (快速查看视频信息)
  • [x] 提供即时有价值的信息 (标题、评论、时长)
  • [x] 可视化总结 (卡片式展示)

我们的黄金问题集

直接提示词 (明确引用YouTube)
1. "分析这个YouTube视频 https://youtube.com/watch?v=xxx"
2. "这个YouTube视频讲了什么?"
3. "帮我看看这个视频的评论"
4. "提取这个视频的字幕"
5. "总结一下这个视频的内容"
间接提示词 (不提YouTube,但意图明确)
1. "我想快速了解这个视频 [粘贴链接]"
2. "这个视频的评论怎么说?"
3. "视频主要讲了哪些要点?"
4. "有没有字幕可以看?"
5. "视频时长多久?"
负面提示词 (不应触发)
1. "下载这个YouTube视频" (下载功能,不在范围)
2. "转换视频格式为MP4" (格式转换,不在范围)
3. "上传视频到YouTube" (上传功能,不在范围)
4. "YouTube的首页推荐有什么?" (推荐算法,不在范围)

🔒

付费内容

此内容仅限 Heliki AI 社区会员访问

还不是会员?

加入 Heliki AI 社区

加入后可在星球内获取最新访问密码


七、关键洞察总结

为什么这个实现生效?

三个关键突破:

  1. 理解了ChatGPT的事件驱动机制

    • 数据不是预填充,而是通过 openai:set_globals 事件异步推送
    • 必须使用 useSyncExternalStore 订阅事件
  2. 绕过了FastMCP的限制

    • FastMCP的 ToolResult 不支持 _meta 字段
    • 直接使用低级MCP API返回 CallToolResult
  3. 正确解析了数据格式

    • ChatGPT传递的 toolOutput 已经是解包后的数据
    • 直接读取 toolOutput.video,不需要再找 structuredContent

易错点清单

错误后果正确做法
使用FastMCP的ToolResultWidget无法加载使用CallToolResult
期待预填充数据toolOutput永远是null订阅openai:set_globals事件
URI格式错误ChatGPT无法识别使用ui://widget/前缀
CSP只写域名外部资源加载失败使用完整HTTPS URL
解析structuredContent数据读取失败直接读取toolOutput.video

八、参考资源

官方文档

官方示例

技术文档


最后更新: 2025-10-20 作者: 暴躁哐哐Heliki AI社区 项目: heliki-video-learning

反馈和讨论: