1. 为什么需要 Product Feed
如果与传统电子商务相比,Product Feed 介于以下两者之间:
- 商品“橱窗”(带价格、库存、链接和媒体的目录);
- 以及一个技术契约,用来描述商家准备通过 ChatGPT 展示和/或售卖的具体 SKU。
OpenAI 在其规范中明确指出,feed 是关于商品的单一事实来源,搜索、推荐和结账数据准备都基于它。
在普通网店里,用户自己浏览页面、翻看分类、做筛选等。AI 电商中则相反:用户只需对模型说“给我为一位喜欢桌游的开发者朋友挑一份不超过 30 美元的数字礼物”——ChatGPT 会基于你的 Product Feed 自行决定哪些 SKU 合适、以什么顺序展示,并将其整理为卡片与后续的 Instant Checkout。
因此,Product Feed 同时解决多项任务。
首先,它为 ChatGPT 提供结构化的搜索数据。模型不仅依赖商品名称与描述,还会参考分类、标签、价格、可用性、语言区域、国家/地区限制等。
其次,它是结账的数据来源。当 ChatGPT 开始准备 checkout_session 时,SKU ID、价格、货币、seller URL 及其他商业信息都来自 feed。
最后,Product Feed 是你与平台之间的形式化契约。你明确声明:“这是 SKU 列表;其中哪些仅用于搜索(discovery),哪些还可在 Instant Checkout 中下单。”
为便于理解,可以画一个简单示意图。
flowchart TD A[GiftGenius DB] --> B[Feed Builder] B --> C["Product Feed (CSV/JSON/...)"] C --> D[OpenAI Ingestion] D --> E[搜索索引 + 排序] E --> F[ChatGPT/Agent 挑选礼物] F --> G["Instant Checkout (ACP)"]
左侧是你的内部数据库,其中存着“真实”的目录。右侧是向用户展示的 ChatGPT。中间是 Product Feed 以及其摄取与索引机制。本讲内容恰好位于 A 与 D 之间。
2. Product Feed 的格式与“物理形态”
OpenAI 规范对文件格式相当灵活:支持 TSV、CSV、XML 和 JSON。这样做是为了让多数现有系统(从自研单体到 Shopify)都能不折腾地导出 feed。
典型流程是:
- 你在自己的 HTTPS 服务器上托管 Product Feed 文件或 endpoint;
- 在 ChatGPT Merchants 门户中登记该地址;
- OpenAI 定期拉取 feed,进行校验并索引商品。
文档强调需要定期更新 feed(甚至可以每 10–15 分钟一次),以便用户能看到最新的价格与库存,尤其是在促销与流量高峰期。
在 GiftGenius 的教学示例中,我们将使用 JSON 格式,因为它更适合 TypeScript 开发者。但要明确:OpenAI 规范并不强制 JSON,只是对我们来说更方便。
最简单的 JSON feed 可能如下:
[
{
"id": "gg-coffee-sub-1m-usd",
"title": "1 个月咖啡订阅",
"description": "为开发者准备的每月一盒咖啡豆。",
"price": 2900,
"currency": "usd",
"availability": "in_stock",
"link": "https://giftgenius.app/gifts/coffee-subscription-1m",
"image_link": "https://cdn.giftgenius.app/images/coffee-1m.png",
"enable_search": true,
"enable_checkout": true
}
]
在真实场景中会有更多字段,其中一些是必填,另一些是推荐或可选。具体如何组织,我们稍后展开。
3. 产品 vs 变体(SKU):如何建模
一个很常见的问题是:“如何在 Product Feed 中体现同一商品的尺码、套餐、订阅时长等变体?”
Product Feed 规范以行/记录为基本单位,每条记录描述一个可售配置。行业推荐(且与 OpenAI feed 良好对齐)的架构模式是:每个独立配置(尺码、订阅时长、资费、地区)都是一条 feed 记录,即一个 SKU。
基础产品存在于你的内部模型中,而在 feed 中应以 SKU 为粒度工作。
例如你有一个服务,提供 1 个月、3 个月、6 个月订阅。从 product feed 的角度看,它们是不同的 SKU。如果一个服务可以以 20 种不同条件购买,那么在 product feed 中就应有 20 个 SKU。
在 TypeScript 中可以大致这样表达:
// GiftGenius 的内部模型
export interface GiftProduct {
id: string; // product_123
name: string;
description: string;
baseImageUrl: string;
}
// 将进入 Product Feed 的 SKU
export interface GiftSkuFeedItem {
id: string; // product_123_usd_1m
productId: string; // 指向 GiftProduct.id
title: string;
description: string;
price: number; // 最小货币单位(分)
currency: string; // "usd"
}
在 GiftGenius 内部,GiftProduct 与 GiftSkuFeedItem 可以是一对多关系。而在 feed 中,你输出的是“扁平化”的 SKU 列表。
为了让 ChatGPT 理解哪些 SKU 属于同一基础产品(例如 1、3、12 个月的订阅),通常会使用分组字段,如 item_group_id。不过这是一种架构模式,而非强制标准。
示例:
{
"id": "gg-coffee-sub-1m-usd", // 1 个月订阅的 SKU
"item_group_id": "gg-coffee-sub", // 你的产品 ID
"title": "咖啡订阅 — 1 个月",
"price": 2900,
"currency": "usd",
"enable_search": true,
"enable_checkout": true
}
而 3 个月订阅:
{
"id": "gg-coffee-sub-3m-usd", // 3 个月订阅的 SKU
"item_group_id": "gg-coffee-sub", // 同一产品 ID
"title": "咖啡订阅 — 3 个月",
"price": 7900,
"currency": "usd",
"enable_search": true,
"enable_checkout": true
}
这种做法既方便模型,也方便你的后端创建订单:SKU ID 成为唯一键,你总能准确找到用户购买的配置。
4. Product Feed 的必填字段及其对 UX 的影响
在 Product Feed 规范中,OpenAI 大致将字段分为三类:必填(required)、推荐(recommended)和可选(optional)。
具体名称与清单请以最新文档为准;出于教学目的,我们可以先参考如下“最低集”。
| 字段 | 用途 | 缺失时的影响 |
|---|---|---|
|
商家范围内唯一的 SKU 标识符 | 无法唯一识别商品 |
|
卡片的短标题 | 模型更难理解这是何种商品 |
|
更详细的描述 | 回答更泛化,个性化变差 |
|
以最小货币单位表示的价格 | 无法准备结账 |
|
ISO 4217 货币代码,通常小写 | 平台无法理解计价货币 |
|
商家侧的商品详情页 URL | 用户无法跳转到你的网站 |
|
库存状态(in_stock、out_of_stock 等) | 可能展示不可用商品 |
|
商品是否可用于搜索 | 若非 true,商品不会出现在结果中 |
|
是否支持 Instant Checkout 下单 | 仅做 discovery/link‑out |
重要细节:enable_search 与 enable_checkout 在逻辑上划分工作模式。
若 enable_search = true、enable_checkout = false,商品可参与搜索结果,但用户尝试购买时会通过你的链接(link)跳转至你的网站,而不是在 ChatGPT 内部进行 Instant Checkout(该处已绑卡)。
若 enable_checkout = true,且满足其他条件(受支持的地区、货币、有效的 ACP backend 等),商品即可在 ChatGPT 内一两次点击完成购买(显著提升转化)。
一个“最小可用”的 GiftGenius 结账对象示例:
{
"id": "gg-dev-notebook-plain-usd",
"title": "极简开发者笔记本",
"description": "黑色、无横线、120 页。适合手写规格说明的人。",
"price": 1500,
"currency": "usd",
"availability": "in_stock",
"link": "https://giftgenius.app/gifts/dev-notebook",
"image_link": "https://cdn.giftgenius.app/images/dev-notebook.png",
"enable_search": true,
"enable_checkout": true
}
注意:即使在此示例中我们也添加了图片(image_link)——形式上它可能是推荐字段而非必填,但没有它 UX 会差很多。
5. 推荐与可选字段:如何让 feed 更“香”
必填字段是“为了能跑起来”。但如果只停留在此,你得到的更像是会计用的最小可用 CSV,而不是一个出色的 AI 橱窗。
常见的推荐字段包括:
- 主图与附图 URL;
- 商品分类(常基于分类法,例如“gifts > experiences > online courses”);
- 品牌/商家名称;
- 颜色、尺码、材质等属性;
- 成人内容标记、年龄限制等。
你对商品描述越丰富,模型能生成的回答就越有意义。比如,如果你明确写出笔记本采用再生纸,适合“关心地球的开发者”,当用户提出环保诉求时,ChatGPT 就能有意识地推荐它。
在 GiftGenius 中,我们可以扩展该 SKU 的描述:
{
"id": "gg-dev-notebook-plain-usd",
"title": "环保开发者笔记本",
"description": "极简款、无横线,120 页再生纸。",
"price": 1500,
"currency": "usd",
"availability": "in_stock",
"link": "https://giftgenius.app/gifts/eco-dev-notebook",
"image_link": "https://cdn.giftgenius.app/images/eco-dev-notebook.png",
"category": "gifts > office > notebooks",
"brand": "GiftGenius Originals",
"enable_search": true,
"enable_checkout": true
}
category 与 brand 等附加属性不仅能改进搜索结果,还有助于分析:你可以观察哪些类目经由 ChatGPT 的转化更好,哪些较差。
可选字段通常对应更特定的场景(例如我们稍后要谈的价格地理参数,或自定义元数据)。应随项目成熟度按需补充,而非为“打勾”而加。
6. 商务标志与 discovery‑only 模式
让我们再次明确 enable_search 与 enable_checkout 的逻辑,因为这是通往后续 ACP 与 Instant Checkout 讲解的关键桥梁。
设想你刚作为 ChatGPT 商家起步。你有礼物目录,但 ACP backend 与 Delegated Payment 仍在开发中。你希望 ChatGPT 现在就能找到你的 SKU,并引导用户去你的网站支付。
此时你应:
- 为需要的 SKU 发布 enable_search = true 的 Product Feed;
- 将 enable_checkout 保持 = false,直到完成并通过 ACP 集成认证。
这样 ChatGPT 就能把你的礼物纳入用户回答中,展示卡片并提供“前往 GiftGenius 网站”的链接,但不会构建内部的 Instant Checkout UI。
当你实现 Agentic Checkout 与 Delegated Payment 后,可将部分商品切换为“可在 Instant Checkout 下单”的模式——只需将 enable_checkout 设为 = true,并满足所有数据要求(价格、货币、seller URL 等齐备)。
在规范层面,正是 Product Feed 中的字段将用于填充 checkout_session 的 line_items 与总额。
因此,feed 成为精细化操控的杠杆:哪些 SKU、以何种方式,ChatGPT 才有权代表你进行销售。
7. 语言区域、货币、地区与多地区定价
你当然知道,世界不止有 en-US 与美元。在本系列的本地化模块中,我们已讨论 locale 与 userLocation 如何影响业务逻辑。这里它更为关键:德国与美国的定价可能不同,某些礼物在一些国家/地区甚至不可售。
Product Feed 规范通过若干机制来应对这些情况。
首先,货币:currency 必须是有效的 ISO 4217 代码(例如 usd、eur、gbp)。
其次,可以使用描述地理相关价格与可用性的字段。文档给出了类似 geo_price 的属性示例,以及基于 ISO 3166 的地区代码。
有两种基本架构思路。
思路一:每个地区一个 feed。
- product-feed-us-en.json 面向美国;
- product-feed-de-de.json 面向德国;
- product-feed-br-pt.json 面向巴西。
每个 feed 中的 SKU 都已转换为该地区货币与语言区域。对 ChatGPT 更简单,但你需要维护多个 feed。
思路二:单一 feed + 地理字段。
在每条记录中保存价格数组或附加属性:
{
"id": "gg-dev-notebook-multi",
"title": "环保开发者笔记本",
"description": "兼顾你对整洁代码和地球的热爱。",
"prices": [
{ "region": "US", "currency": "usd", "price": 1500 },
{ "region": "DE", "currency": "eur", "price": 1400 }
],
"availability_by_region": [
{ "region": "US", "availability": "in_stock" },
{ "region": "DE", "availability": "out_of_stock" }
],
"enable_search": true,
"enable_checkout": true
}
多地区字段的具体结构取决于规范版本,但核心思想一致:feed 应使平台能够判断该 SKU 在哪些国家/地区存在、在那里售价多少。
从 GiftGenius 的角度,需要设计好以下映射:
- ChatGPT 所知的 locale 与 userLocation;
- 与 feed 中应当取用的价格与文本部分。
在商业场景中,你往往不会“全世界只有一条记录”,而是按国家/地区拆分为不同 SKU,以便更轻松地遵循税务、政策与商品限制。
8. 数据质量与政策:没有它们,Instant Checkout 起不来
Product Feed 不仅关乎格式,更关乎数据质量与遵守 OpenAI 的政策。
在数据质量方面,OpenAI 明确要求:
- 正确、稳定的标识符;
- 有效的 HTTPS URL 且返回 200;
- 价格与货币一致;
- 库存真实(不能把实际缺货的商品标为 in_stock)。
规范中也对文本长度有要求:例如,title 不应过长(动辄数百字符),而 description 则有合理上限(数千字符),以保证卡片美观,避免“长篇小说”。
另一个重点是禁售商品政策(Prohibited Products Policy)。这是不可通过 Instant Checkout 和/或 ChatGPT 售卖的商品/服务类别清单:例如非法商品、武器、某些医疗服务等。具体请以最新政策为准。对我们而言要认识到:Product Feed 不仅会检查格式,还会检查内容合规性。
若你的目录包含模糊类别(如酒类、博彩或与儿童相关内容),应格外谨慎。通常更容易做法是将它们保持 enable_checkout = false,只通过你自己的网站、配套完备的法律合规流程来售卖。
9. 实战:为 GiftGenius 组装最小 Product Feed
现在把上面的内容用起来,为三个 GiftGenius SKU 组装一个简单的 feed。假设我们有:
- 环保开发者笔记本;
- 1 个月咖啡订阅;
- “TypeScript 进阶”课程礼品卡。
先定义用于生成 feed 的 TypeScript 类型:
export interface GiftGeniusFeedItem {
id: string;
title: string;
description: string;
price: number; // 以分为单位
currency: "usd" | "eur";
availability: "in_stock" | "out_of_stock";
link: string;
image_link?: string;
enable_search: boolean;
enable_checkout: boolean;
}
然后在代码中创建一个数组并序列化为 JSON:
export const giftGeniusFeed: GiftGeniusFeedItem[] = [
{
id: "gg-eco-notebook-usd",
title: "环保开发者笔记本",
description: "极简款、无横线,使用再生纸。",
price: 1500,
currency: "usd",
availability: "in_stock",
link: "https://giftgenius.app/gifts/eco-dev-notebook",
image_link: "https://cdn.giftgenius.app/images/eco-dev-notebook.png",
enable_search: true,
enable_checkout: true
},
{
id: "gg-coffee-sub-1m-usd",
title: "开发者咖啡订阅 — 1 个月",
description: "每月一盒咖啡豆。应对紧迫截止日期也不在话下。",
price: 2900,
currency: "usd",
availability: "in_stock",
link: "https://giftgenius.app/gifts/coffee-subscription-1m",
image_link: "https://cdn.giftgenius.app/images/coffee-1m.png",
enable_search: true,
enable_checkout: true
},
{
id: "gg-ts-course-gift-usd",
title: "TypeScript 课程礼品卡",
description: "面向开发者的在线课程,终于把泛型学明白。",
price: 9900,
currency: "usd",
availability: "in_stock",
link: "https://giftgenius.app/gifts/ts-course",
image_link: "https://cdn.giftgenius.app/images/ts-course.png",
enable_search: true,
enable_checkout: false // 目前仅 discovery
}
];
接着可以做一个简单的工具,每隔 N 分钟用该结构生成 product-feed.json 并上传到你的 HTTPS 服务器。
import { writeFile } from "node:fs/promises";
import { giftGeniusFeed } from "./feed-data";
// 最简单的 JSON feed 生成器
async function buildProductFeed() {
const json = JSON.stringify(giftGeniusFeed, null, 2);
await writeFile("public/product-feed.json", json, "utf8");
}
buildProductFeed().catch(console.error);
当然,在真实项目中不会把整个 feed 放在代码里;数据应来自数据库。但先搭个这样的教学示例,有助于验证流水线:生成 → 发布 → 校验。
10. 反例:一个“糟糕”的 Product Feed 长啥样
为更直观地理解规范与 UX,看看一个形式上几乎能跑、实际上会出问题的 feed 示例:
{
"id": "1",
"title": "礼物",
"description": "很棒的礼物",
"price": 12.333333,
"currency": "usdollars",
"availability": "yes",
"link": "http://giftgenius.local/gift/1",
"enable_search": "true",
"enable_checkout": "maybe"
}
这里的问题一箩筐。
首先,id = "1" 既不稳定也不够丰富。若你未来迁移数据库或引入分片,这类 ID 很脆弱。最好使用在商家范围内唯一、语义清晰且足够长的 ID。
其次,price 用了带长尾的小数。规范与支付系统通常期望用最小货币单位(分、厘)以整数表示,避免浮点与舍入问题。
第三,currency = "usdollars" 与 availability = "yes" 不符合预期格式(ISO 4217 与可接受状态集合)。
第四,link 使用 http 且为本地域名——两者都不适用于真实生产;规范明确要求 HTTPS 与公开可访问。
第五,enable_search 与 enable_checkout 应为布尔值,而非字符串。否则 OpenAI 的解析要么拒绝该 feed,要么按默认值处理,结果可能令你意外。
这类问题可能导致严格校验错误(feed 被拒),也可能造成更糟的情况:表面上 feed 被接受,但部分 SKU 被忽略或行为与预期不同。因此应在你这一端先做好内部校验。
11. 使用 Product Feed 的常见错误
错误 1:将 feed 当作一次性的“导入 CSV”。
有的团队把 Product Feed 当作一次性“为集成而生成”的文件,然后就不管了。在 AI 电商里并非如此:feed 是实时的事实来源,必须定期更新。你改价、下架、做促销——都应及时反映到 feed。否则 ChatGPT 会推荐已无货或旧价格的商品,用户自然会不满。
错误 2:混淆产品模型与 SKU。
一个常见反模式是试图用一条 feed 记录加一堆“size1/size2/size3”或“duration1/duration2”字段来表达一个有许多选项的基础产品。结果是模型不清楚究竟在卖什么,而你的 ACP backend 在结账时也要痛苦地还原这些字段。更简单可靠的做法是:一个 SKU 一条 feed 记录,即使它只是某个产品的一个变体。
错误 3:忽视语言区域与地区。
做 MVP 时,开发者常常给所有东西都设 currency = "usd",enable_checkout = true,却没考虑 Instant Checkout 在你的地区是否可用,或某些商品在某些国家/地区是否禁售。等你进入新市场时,一切就开始“打架”:价格不对、税没算。更好的做法是从一开始就把 SKU 与地区和货币关联起来,即便你当前只有一个市场。
错误 4:把描述当作过时的 SEO 文案。
一些团队会把网站上的旧描述直接搬进 Product Feed,有时还是为“关键词与机器人”写的。对 ChatGPT 而言,这往往弊大于利:模型自己会写文本,它更需要结构化、真实、准确的事实。宁可简明扼要,也不要用营销话术把 description 塞满。
错误 5:不自行校验 feed。
仅依赖 OpenAI 端的校验,等同于在死线前熬夜。应在你的后端或 CI 做一个简单校验器,检查字段模式、可接受值、URL 与货币格式。即便用 TypeScript 也能做到,比如用 Zod 或自写校验。这样问题还没进生产就能被拦下。
错误 6:把“能塞的都塞进 Product Feed”。
有时会想把几千个 SKU 都塞进 feed,“万一用得上”。事实上,这会增加调试、分析与质量控制的难度。更合理的是从有限子集开始:只纳入你愿意维护且确实想通过 ChatGPT 售卖的类目与 SKU。其他的可以保持在 discovery 模式,或干脆不集成。
错误 7:Product Feed 与 ACP backend 不同步。
feed 与 ACP API 是同一枚硬币的两面。如果 feed 中出现了新 SKU,而你的后端还不会卖它(或反之,SKU 已从 feed 移除,但后端仍认为它存在),就会出现不同步、复杂 bug 与海量支持工单。最佳实践是拥有统一的领域模型,同时用于生成 feed 与处理结账。
GO TO FULL VERSION