Skip to content
风起
风起

一文看懂OpenAI Apps SDK

先直观的感受下,请看视频

问题:OpenAI Apps SDK到底是什么?是应用商店吗?或者是类似微信的超级应用吗?

回答:打个比方,应用商店和微信类比宿主,宿主上面的应用或小程序类比寄生体,寄生体的数据状态不开放,导致宿主无法感知并调度它们,而且宿主起初设计上也没想着要融合所有应用,因为起初AI模型没发展起来,无法自主决策智能调度。而随着AI发展,大脑决策成熟可用后, OpenAI Apps SDK 的诞生就是为了让ChatGPT再长出四肢来,变成一个具备思考和行动能力的智能机器人,各个服务商把自己的应用拆成一个个小的功能模块,通过SDK对接到ChatGPT上,SDK主要是为了打通数据以及对接上下文,ChatGPT通过上下文感知各个应用、理解用户意图,并进行智能调度。

问题:有什么影响?给我们什么启发?

回答:影响了搜索规则,改变了交互习惯,传统应用聚集地这种产品形态无法高效的将应用匹配给用户,智能调度应用协同会成为趋势。启发是出现了一种新的软件架构:以大模型为决策中枢进行应用协同,核心在于模型是否足够智能,上下文来自于前后端,属于应用维度的集成,暂且叫微应用吧。

问题:如何做到的?

上面把 OpenAI Apps SDK 的概况已经介绍了,下面主要讲的是感知融合机制。


1️⃣ AI 感知上下文的三层机制

📊 上下文数据流图

┌─────────────────────────────────────────────────────────────┐
│                    ChatGPT AI (编排层)                        │
│                                                               │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  对话历史上下文                                        │  │
│  │  - 用户说过的话                                        │  │
│  │  - AI 的回复                                          │  │
│  │  - 之前调用的 tools                                   │  │
│  └──────────────────────────────────────────────────────┘  │
│                          ↓                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  structuredContent 上下文 (来自 tools)                │  │
│  │  - Tool A 返回的数据                                  │  │
│  │  - Tool B 返回的数据                                  │  │
│  │  - Tool C 返回的数据                                  │  │
│  └──────────────────────────────────────────────────────┘  │
│                          ↓                                   │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  widgetState 上下文 (来自组件)                        │  │
│  │  - 用户在组件中的操作                                 │  │
│  │  - 选中的数据、过滤条件等                             │  │
│  └──────────────────────────────────────────────────────┘  │
│                          ↓                                   │
│               AI 推理和决策下一步动作                         │
└─────────────────────────────────────────────────────────────┘

机制 1:通过 structuredContent 理解数据

// MCP Server 返回结构化数据
return {
  structuredContent: {
    places: [
      { id: "1", name: "Tony's Pizza", rating: 4.8, city: "North Beach" },
      { id: "2", name: "Golden Boy Pizza", rating: 4.6, city: "North Beach" }
    ],
    searchCriteria: {
      city: "San Francisco",
      cuisine: "Pizza"
    }
  },
  content: [{ type: "text", text: "Found 2 pizza places" }]
};

AI 如何感知

  • 可读性:AI 可以"看到" structuredContent 的内容
  • 推理能力:知道有 2 家店、评分、位置
  • 上下文延续:用户说"第一个怎么样" → AI 知道指的是 Tony's Pizza

机制 2:通过 widgetState 理解用户操作

// 用户在组件中收藏了几家店
await window.openai.setWidgetState({
  __v: 1,
  favorites: ["1", "3", "5"],  // 收藏的店铺 ID
  viewMode: "map",
  filterRating: 4.5
});

AI 如何感知

用户对话: "帮我规划路线去这几家店"

AI 读取 widgetState.favorites = ["1", "3", "5"]

AI 理解: 用户想去 3 家收藏的店

AI 调用: route_planner_tool({ placeIds: ["1", "3", "5"] })

机制 3:通过 toolInput 理解调用参数

// 前端组件
const toolInput = window.openai?.toolInput as { city?: string };
// toolInput = { city: "San Francisco" }

// AI 记住了这个上下文
// 用户说 "换成纽约的" → AI 调用同一个 tool,传 { city: "New York" }

2️⃣ 不同开发商工具的融合机制

🔗 工具编排的场景分析

场景 1:串行调用(数据传递)

用户: "帮我找旧金山的披萨店,然后预订最好的那家"

AI 执行流程:
1. 调用 Developer A 的工具
   ├─ Tool: search_restaurants
   ├─ Input: { city: "San Francisco", cuisine: "pizza" }
   └─ Output: { 
       structuredContent: {
         places: [
           { id: "tony", name: "Tony's Pizza", rating: 4.8 },
           { id: "golden", name: "Golden Boy", rating: 4.6 }
         ]
       }
     }

2. AI 推理: "最好的" = rating 最高 = Tony's Pizza

3. 调用 Developer B 的工具
   ├─ Tool: book_reservation
   ├─ Input: { restaurantName: "Tony's Pizza", time: "7pm" }
   └─ Output: { confirmationCode: "ABC123" }

关键点

  • AI 自动提取 Tony's Pizza 从第一个 tool 的返回
  • 传递给第二个 tool
  • 不需要开发商之间协调接口

场景 2:并行调用(上下文聚合)

用户: "对比一下这家店在 Yelp 和 Google 的评价"

AI 执行流程:
1. 并行调用两个工具
   ├─ Yelp MCP (Developer A)
   │  └─ Output: { rating: 4.5, reviews: 234, highlights: ["great crust"] }
   └─ Google MCP (Developer B)
      └─ Output: { rating: 4.7, reviews: 456, photos: [...] }

2. AI 聚合结果
   "这家店在 Yelp 上是 4.5 分(234 条评价),在 Google 上是 4.7 分(456 条评价)"

场景 3:组件回调触发其他工具

// 用户在 Developer A 的地图组件中点击"预订"
function handleBookClick(placeId: string) {
  // 发送对话,触发 AI
  await window.openai.sendFollowupTurn({
    prompt: `Book a table at ${placeId} for tonight at 7pm`
  });
}

// AI 自动匹配 Developer B 的预订工具
// AI: "好的,我来帮你预订..."
// 调用: booking_service.book({ placeId, time: "7pm" })

3️⃣ 跨工具上下文共享的技术实现

A. 通过 structuredContent 共享业务数据

// Developer A: 餐厅搜索服务
server.registerTool("search_restaurants", {
  // ...
}, async ({ city, cuisine }) => {
  return {
    structuredContent: {
      restaurants: [
        { 
          id: "tony-pizza-123",
          name: "Tony's Pizza",
          address: "1570 Stockton St",
          coords: { lat: 37.8001, lng: -122.4098 }
        }
      ]
    }
  };
});

// Developer B: 地图服务(可以读取上面的数据)
// AI 自动传递 coords 给地图工具
server.registerTool("show_map", {
  // ...
}, async ({ locations }) => {
  // locations 来自 Developer A 的 structuredContent.restaurants
  return {
    structuredContent: {
      mapUrl: "...",
      markers: locations.map(loc => loc.coords)
    }
  };
});

B. 通过 widgetState 共享用户状态

// Developer A: 地图组件
// 用户在地图上选中了一个位置
await window.openai.setWidgetState({
  selectedLocation: { lat: 37.8001, lng: -122.4098 },
  selectedPlaceId: "tony-pizza-123"
});

// 用户对话: "附近还有什么好吃的"

// Developer B: 推荐服务
// AI 调用时会传递上下文
server.registerTool("nearby_recommendations", {
  // ...
}, async (params, context) => {
  // context 可能包含用户当前的位置信息
  // AI 从 widgetState 中提取 selectedLocation
  const { lat, lng } = context.currentLocation;
  // 搜索附近的推荐
});

C. 通过对话历史共享隐式上下文

用户: "帮我找旧金山的披萨店"
AI: [调用 Developer A 的搜索工具] "找到了 10 家店"

用户: "把它们标在地图上"
AI: [调用 Developer B 的地图工具]

    AI 从对话历史中知道:
    - "它们" = 刚才搜索的 10 家店
    - 自动传递这 10 家店的坐标给地图工具

用户: "预订评分最高的那家"
AI: [调用 Developer C 的预订工具]

    AI 从对话历史中知道:
    - "评分最高的" = Tony's Pizza (4.8 分)
    - 自动传递 restaurantId 给预订工具

4️⃣ AI 融合工具的智能决策机制

决策树示例

用户输入: "我想吃披萨,帮我找、订、去"

AI 分析:
├─ 意图识别: 
│  ├─ 找 → search_restaurants
│  ├─ 订 → book_reservation
│  └─ 去 → get_directions

├─ 工具匹配:
│  ├─ 搜索 → Developer A (餐厅搜索 MCP)
│  ├─ 预订 → Developer B (预订平台 MCP)
│  └─ 导航 → Developer C (地图服务 MCP)

├─ 执行顺序:
│  1. search_restaurants({ cuisine: "pizza" })
│  2. AI 推理: 选择评分最高的
│  3. book_reservation({ restaurantId: "..." })
│  4. get_directions({ destination: "..." })

└─ 上下文传递:
   - 步骤 1 → 步骤 2: 餐厅列表
   - 步骤 2 → 步骤 3: 选中的餐厅
   - 步骤 3 → 步骤 4: 餐厅地址

AI 的上下文感知能力

上下文类型感知方式示例
对话历史自然语言理解"它" "那个" "刚才的"
工具返回数据读取 structuredContent餐厅 ID、评分、地址
组件状态读取 widgetState收藏列表、过滤条件
用户位置读取 _meta["openai/userLocation"]当前城市、坐标
用户语言读取 _meta["openai/locale"]en-US, zh-CN
时间上下文系统时间"今晚" = 今天 19:00

5️⃣ 融合的关键技术点

技术点 1:标准化的数据结构

// 所有 MCP Server 都遵循相同的协议
{
  "structuredContent": {
    // 业务数据,AI 可读
  },
  "content": [
    // 可选的文本描述
  ],
  "_meta": {
    // 仅组件可见,AI 不可见
  }
}

好处:AI 知道如何解析任何 MCP 的返回

技术点 2:语义化的 Tool 描述

server.registerTool("search_restaurants", {
  title: "Search Restaurants",
  description: "Find restaurants by city, cuisine, price range, and rating",
  inputSchema: {
    city: z.string().describe("The city to search in"),
    cuisine: z.string().optional().describe("Type of food (e.g., 'pizza', 'sushi')"),
    minRating: z.number().optional().describe("Minimum rating (1-5)")
  }
});

好处:AI 知道何时调用这个 tool,以及如何传参

技术点 3:事件驱动的通信

// 组件可以监听其他 tool 的调用
window.addEventListener("openai:tool_response", (e) => {
  if (e.detail.tool.name === "book_reservation") {
    // Developer B 预订成功了
    // Developer A 的地图组件可以更新 UI
    showSuccessMarker(e.detail.tool.args.restaurantId);
  }
});

好处:不同开发商的组件可以响应彼此的动作

技术点 4:OAuth 统一用户身份

// 所有 MCP Server 都收到相同的 access_token
async function handleToolCall(params, context) {
  const userToken = context.auth.accessToken;
  
  // Developer A 和 Developer B 都能识别同一个用户
  const user = await verifyToken(userToken);
  
  // 共享用户数据:收藏、历史记录等
}

6️⃣ 实际融合案例分析

案例:旅行规划助手

用户: "帮我计划明天的旧金山一日游"

AI 编排的工具链:
┌──────────────────────────────────────────────────┐
│ 1. Weather Service (Developer A)                 │
│    Input: { city: "San Francisco", date: "tomorrow" }
│    Output: { temp: 65, condition: "sunny" }      │
└──────────────────────────────────────────────────┘
            ↓ (AI 推理: 天气好,适合户外)
┌──────────────────────────────────────────────────┐
│ 2. Attractions Search (Developer B)              │
│    Input: { city: "SF", category: "outdoor" }    │
│    Output: { places: [金门大桥, 渔人码头, ...] }  │
└──────────────────────────────────────────────────┘
            ↓ (用户在地图组件中调整顺序)
┌──────────────────────────────────────────────────┐
│ 3. Map Component (Developer C)                   │
│    显示景点 + 用户拖拽排序                         │
│    widgetState: { route: [place1, place2, ...] } │
└──────────────────────────────────────────────────┘
            ↓ (用户说 "帮我订午餐")
┌──────────────────────────────────────────────────┐
│ 4. Restaurant Service (Developer D)              │
│    Input: { near: place2.coords, time: "12pm" }  │
│    Output: { restaurant: "..." }                 │
└──────────────────────────────────────────────────┘
            ↓ (AI 自动调用)
┌──────────────────────────────────────────────────┐
│ 5. Booking Service (Developer E)                 │
│    Input: { restaurantId: "...", time: "12pm" }  │
│    Output: { confirmationCode: "ABC123" }        │
└──────────────────────────────────────────────────┘

上下文传递路径

  1. 天气 → 推荐(AI 根据天气选择活动类型)
  2. 推荐 → 地图(坐标传递)
  3. 地图 → 餐厅(用户在地图中的位置)
  4. 餐厅 → 预订(餐厅 ID 传递)

总结:融合的核心原理

AI 作为"智能粘合剂"

传统模式(开发商需要互相对接):
App A ←→ API 对接 ←→ App B
  └─ 需要协商接口格式、认证方式等

Apps SDK 模式(AI 自动融合):
App A → MCP Protocol → ChatGPT AI ← MCP Protocol ← App B

        AI 自动提取数据、传递上下文、编排流程

🔑 关键技术

  1. 标准化协议:MCP 统一了通信方式
  2. 语义化描述:Tool description 让 AI 理解功能
  3. 结构化数据structuredContent 让 AI 提取信息
  4. 状态共享widgetState 让 AI 理解用户操作
  5. 对话记忆:AI 的上下文窗口记住历史
  6. 事件机制openai:tool_response 让组件协作