

用 ChatGPT Annotations 收集针对正确界面组件的反馈,并附上必要上下文
用 ChatGPT Annotations 收集针对正确界面组件的反馈,并附上必要上下文
预览页上有好几张卡片时,一句“这张卡片太挤了”很难让开发者知道用户指的是哪一张。Browser Annotation API 可以让查看者选中整个组件,附带少量背景信息,再选择期望的方案,然后在 ChatGPT 中讨论。下面的示例约需 20 分钟,需要通过 HTTPS 或 localhost 提供的测试页,以及支持此功能的 ChatGPT 桌面应用内置浏览器。
网站准备上下文,用户决定是否发送反馈。 打开批注编辑器不会自动发送聊天消息。如果你还在区分 ChatGPT Browser、浏览器扩展与 Computer Use,可先阅读那篇文章。本文专注于你自己网站上的接口。
准备工作
工具是 OpenAI 文档中的 Browser Annotation API。文档面向 DevDay 2026 版本及之后的 ChatGPT 桌面应用。对于受支持的安全顶层页面,JavaScript 入口是 document.oai.annotation。普通 Chrome 标签页、iframe 或旧版应用不一定有这个接口。调用前应逐一检测方法,并在相关 DOM 元素创建后初始化。
**先确认可用范围:**OpenAI 表示,Browser Annotation API 目前不适用于 ChatGPT Enterprise 或 Edu 工作区。如果团队只有这两类工作区,请把本文示例当作设计参考,先确认环境,再安排部署。
准备一个包含两张预览卡片和一个反馈按钮的测试页。使用虚构数据,不要在 HTML 中放入凭据或客户资料。如果你的任务只是截取应用窗口来起草内容,可以采用 ChatGPT Desktop 与 Appshots 工作流程,无需修改网站。
分步操作
1. 为每张卡片设置可选中的名称
在 Annotation mode 中,浏览器原本就能选择 DOM 元素。但对于包含标题、说明和按钮的卡片,查看者往往想评论整张卡片。在外层区域添加 oai-annotation-container,在每张卡片上添加 oai-annotatable。后者的值会作为用户和模型看到的名称,因此相邻卡片要有不同且清楚的名称。
<section id="preview" oai-annotation-container>
<article id="profile-card" oai-annotatable="成员资料卡">
<h2>成员资料</h2>
<p>团队成员信息与职责。</p>
</article>
<article id="summary-card" oai-annotatable="数据摘要卡">
<h2>数据摘要</h2>
<p>本周最重要的三个指标。</p>
</article>
</section>
<button id="discuss-profile" type="button" hidden>讨论成员资料卡</button>
进入 Annotation mode,将指针移到卡片标题或说明上,整张卡片应被高亮。仅在 container 之外放置 oai-annotatable,不会改变选择行为。container 之外的区域仍保持默认行为。
如果希望评论某一句文字,可在文本区域添加 oai-annotation-container-text。查看者拖动选择文字,单击不会创建批注。同一元素同时设置文本和 DOM 选择属性时,文本选择优先。先确定用户要选整个对象还是一段话,再设置属性。
2. 添加少量有用的上下文
“成员资料卡”并不能说明它位于哪个页面、属于哪个版本。可在已标记的目标上用 oai-annotation-metadata 添加不敏感的信息:
<article
id="profile-card"
oai-annotatable="成员资料卡"
oai-annotation-metadata='{"screen":"团队页面","variant":"预览版"}'
>
<h2>成员资料</h2>
<p>团队成员信息与职责。</p>
</article>
这段代码应替换第一步中的资料卡,不要创建重复的 id。Metadata 会随批注进入对话。OpenAI 只允许小型、扁平的 JSON 对象:最多六个属性,键不超过 64 个字符,字符串值不超过 256 个字符,序列化后总大小不超过 2,048 字节。不支持嵌套对象或数组;无效数据可能被浏览器忽略。
只放入查看者和 ChatGPT 都有权看到的信息。Metadata 用来让反馈更明确,不会赋予 ChatGPT 读取数据库或修改应用的权限。
3. 从网站自己的按钮打开批注
你可以把反馈按钮放在组件旁边。在 DOM 元素都已存在之后加入下面的脚本。若浏览器没有 request(),按钮会保持隐藏;否则在用户点击的处理函数中直接调用它:
const card = document.getElementById("profile-card");
const button = document.getElementById("discuss-profile");
const annotation = document.oai?.annotation;
button.hidden = typeof annotation?.request !== "function";
button.addEventListener("click", () => {
if (typeof annotation?.request !== "function") return;
const result = annotation.request(card, {
initialComment: "请评价这张成员资料卡是否清晰易懂。",
});
if (!result.accepted) {
console.info("Annotation request was not accepted.");
}
});
result.accepted 只表示浏览器接收并验证了请求,不代表编辑器已打开、批注已保存或消息已发送。initialComment 可由用户编辑,长度最多 240 个 UTF-16 代码单元。不要先 await 网络请求再调用 request(),否则可能丢失直接点击所提供的用户交互状态。编辑器已打开或 ChatGPT 正在控制浏览器时,请求也可能被拒绝。
如需指向准确段落,request() 也接受 DOM Range。范围必须包含当前文档中非空、可见的文字,长度最多 20,000 个 UTF-16 代码单元。文本范围只支持默认编辑器,mode: "advanced" 会被拒绝。页面上的按钮应称为“讨论”或“反馈”,因为最后的发送动作仍由用户完成。
4. 让查看者先选一个方案
当设计问题有少数几个明确答案时,可注册 select 控件。以下示例让查看者选择资料卡的信息密度。把这段代码放在第三步的 card 和 annotation 声明之后:
let registration;
if (typeof annotation?.registerControls === "function") {
try {
registration = annotation.registerControls({
targets: card,
controlsHeading: "卡片布局",
controlsMode: "replace",
controls: [
{
type: "select",
label: "信息密度",
callback: "layoutDensity",
options: [
{ label: "宽松", value: "relaxed" },
{ label: "紧凑", value: "compact" },
],
defaultValue: "relaxed",
},
],
});
} catch (error) {
console.error("Could not register annotation controls.", error);
}
}
function cleanupAnnotationControls() {
registration?.dispose();
}
controlsMode: "replace" 对此目标只显示你注册的控件;"extend" 会同时显示内置控件。本例只是收集选择,不会立即改变网页。由于没有设置 currentValue,即使查看者不改动,初始选项也会包含在批注中。ChatGPT 和批注历史接收的是用户看到的“宽松”或“紧凑”等标签,而不是把内部 value 字符串当作选项文案。标签要让不看代码的人也能理解。
如果要实时预览间距或颜色,可以使用 range 或 color 控件,处理 oaiannotationcontrolchange 事件。它的 preview、preview-original 和 reset 动作各自带有应应用的值;取消预览后要恢复原样。预览不会自动保存到应用。一个注册最多可含 12 个控件,无效配置可能同步抛错。组件移除时,调用 dispose(),并清除事件监听器及你创建的预览状态。
5. 按真实使用流程测试
在受支持的 ChatGPT 桌面应用内置浏览器中打开测试页,从浏览器界面进入 Annotation mode。逐一选择两张卡片,检查高亮范围、名称和 metadata。点击反馈按钮,修改预填评论,选择“紧凑”,保存批注,再从附件预览中打开。最后随测试消息一起发送,确认 ChatGPT 收到正确的对象、上下文和可见选项标签。
再用没有此 API 的浏览器打开同一页。专用按钮应隐藏,但两张卡片仍能正常使用。移除组件并调用清理函数。如果后来加入 CSS 预览,还要试着改动选项、与原状态对比并取消,确认界面复原。**示例代码已对照 OpenAI 文档并通过 JavaScript 语法检查,但尚未在真实 ChatGPT 桌面账户中测试交互。**上线前仍需完成浏览器实测。
预期结果示例
查看者选中“成员资料卡”,选择“紧凑”,并写下:“成员职责不够醒目,请提高它的视觉优先级。”对话会带上卡片名称、screen: 团队页面、variant: 预览版 和可见标签“紧凑”。开发者能判断反馈对应哪个版本。这是根据 API 规范推导的预期结果,不是运行中的演示日志。
让结果更可靠的做法
先从一组卡片和一个控件开始。用查看者熟悉的名称标记 oai-annotatable,避免 CardV2 之类的内部代号。Metadata 应说明页面或版本,不应塞入整份客户档案。批注把选择和反馈带入对话;如果希望 AI 在网站上执行操作,还需要 Site tools 等其他能力。若要把编码代理深度集成到内部工具,可阅读 Codex SDK 与 App Server 的选择指南。
若应用在状态变化时重新创建 DOM 节点,应保存注册句柄,以便更新目标或在组件移除时销毁。注册时捕获的是现有元素,不会自动追踪未来的选择器匹配。若日后设置 currentValue,应使用应用的正常值,包括尚未保存的编辑,而不是临时预览值,这样前后对比才准确。
使用限制
功能是否可用取决于桌面应用版本、站点权限和站点设置。网站主动发起的某些请求可能需要用户授权。API 面向内置浏览器中的安全顶层文档,不适合在 iframe 内试用这个示例。权限和界面可能变化,正式部署前应重新核对 OpenAI 文档。
选中的内容与 metadata 会进入对话,应把它视为数据共享路径,并遵守组织规定。示例控件只提出讨论选项,不会修改代码、保存设置或发送邮件。涉及访问权限、价格、法律和产品决策的反馈,仍需负责人核查后再执行。
常见问题
普通 Chrome 标签页能使用这个 API 吗? OpenAI 文档描述的是受支持的 ChatGPT 桌面应用内置浏览器中的 document.oai.annotation。应检测功能,不要假设普通标签页有此接口。
ChatGPT Enterprise 或 Edu 能使用吗? 按 OpenAI 当前文档,这两类工作区暂不支持 Browser Annotation API。若发布范围变化,请重新核实。
点击反馈按钮会直接发送消息吗? 不会。request() 只是请求打开批注。用户仍决定是否编辑、保存并发送。accepted: true 不等于消息已送达。
能选择一句话而不是整张卡片吗? 可以。用 oai-annotation-container-text 在 Annotation mode 中拖动选择,或从网站按钮向 request() 传入有效的 DOM Range。
自定义控件会自动保存网站的修改吗? 不会。它可以收集选项或触发预览。实际修改仍需应用自身的保存流程和负责人审核。
主要来源:Annotations Extensibility,OpenAI Learn 官方文档。核对日期:2026 年 10 月 5 日。#ChatGPT #Annotations #Website #AI编程 #VibeCoding





