news 2026/10/23 2:41:39

给 AI 看的界面长什么样——Agent 规模化之后,我把后台按这三层适配

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
给 AI 看的界面长什么样——Agent 规模化之后,我把后台按这三层适配

本文是「Agent 工程实战」系列的第 09 篇,属于界面线。
系列索引(21 篇阅读路线):Agent 放权前,先补权限、出站、发现这三道口子

摘要:OpenAI 发布 Agents API 后,Agent 会话越来越长,你的后台界面正在被当成"生产环境"。但后台仍是按人眼设计的,Agent 靠可访问性树或截图来"看"页面。本文从感知、操作、反馈三层讲透后台界面如何适配 Agent:感知层把 div 换成真 button、补上 label,让 Agent 看得准;操作层放大命中区到 44px、拉开间距,让 Agent 点得准;反馈层用 aria-busy、loading 和 toast 让状态可见,Agent 才知道做没做成;高频写操作再开一条 MCP/HTTP 结构化通道兜底。文末附可直接照抄的检查清单,三分钟自检你的后台页面。

文章目录

    • 从 OpenAI Agents API 说起
    • 同一张页面,两套读者
    • 第一层:感知层,让 Agent 看得准
    • 第二层:操作层,让 Agent 点得准
    • 第三层:反馈层,让 Agent 知道做完没
    • 兜底:给 Agent 一条"后门"
    • 这套适配到底值不值

从 OpenAI Agents API 说起

9月10号 OpenAI 正式发布了 Agents API,公开测试,一次 API 调用就能建一个生产级的 agent,跑的还是 Codex 那套 harness。帖子在 Hacker News 拿了两百多分,一路冲到首页前排,评论区吵成一团。

大家聊的都是"Agent 能干什么"。多子任务并行、程序化工具调用、还支持 MCP——看着确实猛。我看到的倒是另一件事。

官方博客反复强调的能力里,有两件事指向同一句潜台词:Agent 会话会越来越长,要在你的系统里连轴跑好几小时甚至跨几天。一条会话跑小半天,意味着它中间要访问你公司的后台、点击你系统的页面、处理真实业务数据。做 Agent 的人,已经把你家的内部系统当成"生产环境"了。

但问题是——那个后台,还是按给人眼看设计的。上一篇写完"AI 都能自己点界面了,前端反而机会大了",有读者问:机会到底在哪?这篇就把一件事讲透:后台界面凭什么能被 Agent 用,以及改起来到底改什么。

同一张页面,两套读者

先说清楚 Agent 是怎么"看"界面的。市面上做界面操作的 agent 分成两大流派,感知和操作各两套:

  • 感知层:一类靠截图喂给视觉模型(你让它看什么它就看什么),一类靠浏览器渲染出的可访问性树(Accessibility Tree)拿语义化文本
  • 操作层:一类是像素坐标点击,一类是拿元素定位去触发

注意,这两条轴是交叉的——截图派多数配坐标点,语义树派多数配元素定位,但组合不是死的。具体用哪套,取决于 Agent 的产品怎么实现。

对做界面的人来说,这就够了:你没法挑 Agent 用哪种方案,但只要界面把两套都伺候好,来什么 Agent 都能用。给你看同一张订单页,两种"读者"各自看到什么:

人眼版本 可访问性树版本(Agent 视野) ┌────────────────────┐ ┌──────────────────────────────┐ │ 订单后台 │ │ heading "订单后台" │ │ [搜索] [导出] [刷新] │ │ button "搜索" │ │ ┌────────────────┐ │ │ button "导出" │ │ │ 已支付 1000.00 │ │ │ button "刷新" │ │ │ 待支付 250.00 │ │ │ row "已支付 1000.00" │ │ └────────────────┘ │ │ row "待支付 250.00" │ │ 颜色区分状态、布局自然 │ │ role + name + state │ └────────────────────┘ └──────────────────────────────┘

人的眼睛扫的是颜色、位置、留白;Agent 拿到的是一棵全是 role、name、state 的树,或者是一张像素图。这篇文章讲的适配,本质就一句话:让第二列"列得清楚",同时不拆第一列。

第一层:感知层,让 Agent 看得准

这层改的是"Agent 眼里这张页面长什么样"。对语义树派来说,它读到的就是树上那些 role 和 label。树列得对不对,直接决定它能不能找到按钮。下面示例都可从 Chrome DevTools 的 Accessibility 面板直接验证(浏览器自带的,不用另装东西)。我先说我见过的典型翻车写法,后台里特别常见这种"假按钮":

<!-- 运行时:div 冒充 button,看着是按钮 --><divclass="submit-btn"onclick="submitOrder()">提交订单</div>

CSS 一伪装,人眼完全看不出来。但在可访问性树里,它不是一个按钮,身份是 generic:

可访问性树(devtools → Elements → Accessibility 面板): <div class="submit-btn"> role: generic name: 提交订单 focusable: false ← 键盘和语义工具都拿它当"不可点的文本"

Agent 拿到这棵树,能不能猜到"这里的提交订单可以点"?大概率能,靠的是猜——猜就有翻车的概率。第一类翻车往往不是 Agent 蠢,是你给它的树本身写得含糊。改法很朴素,用真正的语义:

<buttontype="submit">提交订单</button><!-- 如果样式上必须保留原有视觉效果,不冲突 -->
可访问性树(改后): <button type="submit"> role: button ← 明确是按钮 name: 提交订单 focusable: true ← 可聚焦可激活

一行改动,树里从"疑似可点"变成"确认可点"。再补一个常见的:输入框不绑定 label。

<!-- 坏味道:placeholder 当标签用 --><inputtype="text"placeholder="请输入订单号"/>
可访问性树:无 name,Agent 只知道"有个输入框",不知道填什么 改:<label for="order-id">订单号</label> <input id="order-id" type="text" placeholder="请输入订单号" /> 树变成:textbox name:"订单号" ← 语义对上了

边界说明:这层主要对语义树派的 Agent 有效。截图派根本不读这棵树,你标不标它都是看像素。反过来,截图派要的是对比度、字号够不够清楚。所以这两件事都得做,但别指望"改了语义截图派也受益"。

我之前接一个内部项目,当时觉得做无障碍是合规需求,拖到验收才补。现在回头看,那是一棵现成的"给 Agent 看的界面"分级地图——角色标得越干净的地方,Agent 越不会走错。

第二层:操作层,让 Agent 点得准

感知层解决"看得见",操作层解决"点得上"。坐标点击派的 Agent 有一个很实际的毛病:它按像素找目标。按钮太小、两个按钮挨太近,它就容易点偏——点错一个,后面全乱。

我们自己后台之前有个运营功能,一排小图标按钮(编辑、删除、导出),每个命中区域也就二十来像素见方。人肉用没问题,让 agent 连续操作的时候,编辑和删除之间经常点歪,我得盯着回放一路看。改法也不复杂,给可点击元素放大命中区域:

/* 原来:只有文字区域可点 */.toolbar .icon-btn{font-size:14px;}/* 改后:明面区域 + 内边距共同组成命中区 */.toolbar .icon-btn{font-size:14px;padding:10px;/* 额外命中空间 */margin-right:8px;/* 相邻按钮拉开间隔 */min-height:40px;display:inline-flex;align-items:center;justify-content:center;}
效果(实测回放): 改前:跑一整轮十几步点选,平均每轮都偏一两次,多半歪到"删除" 改后:同样的一轮动作连着跑了大半天,没再点偏过

按现在的无障碍最佳实践,可交互元素的目标尺寸建议做到 44px 见方这个量级,间距至少单边留一点空隙。不是给人用不方便,是给"手抖的 Agent"用方便。

边界说明:操作层这条只对坐标派有效,语义树派不考虑像素,它靠元素定位,这层的收益是零。同时这个尺寸只是"建议起点"不是"万能解",表格里的行内编辑这种高频操作值得做,一次性配置弹窗就不必为它折腾。

第三层:反馈层,让 Agent 知道做完没

这层是我认为最容易被忽略、出事也最隐蔽的。人在后台点"保存",点完哪怕只是按钮变灰再变回来,也会心里有数"成了"。Agent 的判断依据要苛刻得多:它的"成了"必须体现在可见状态上——视觉的,或者语义树里的。

举一个真实排查过的例子。我们有个流程,agent 步骤走到"点击保存按钮",然后紧接着"等待结果"。结果它一直卡在等待,超时之后把整轮操作算作失败重试,连着重试了好几轮,堆出一批脏数据。回放一看,点击明明成功了。

问题出在哪?保存按钮点击后不到半秒接口就返回了,但页面上没有任何状态变化——没有 loading,没有成功提示,按钮样式也没变。对 Agent 来说,"点了"和"没点"没有任何可观察的区别。它只能靠猜,猜一次两次可能蒙对,长任务里必翻车。给操作加反馈状态,视觉信号和语义信号一起上:

<buttonid="save-btn"type="submit"aria-busy="false">保存</button>
asyncfunctionsaveAndTell(){constbtn=document.getElementById("save-btn");// 1. 立刻进入"处理中"状态,视觉和语义同步btn.setAttribute("aria-busy","true");btn.disabled=true;btn.textContent="保存中…";try{constres=awaitapi.save();// 2. 成功:状态从 busy 回到 ready,并给可感知的结果提示btn.removeAttribute("aria-busy");btn.disabled=false;btn.textContent="保存";showToast(`保存成功,单号${res.id}`);}catch(e){// 3. 失败:同样要显性化,别让它"无声失败"btn.removeAttribute("aria-busy");btn.disabled=false;btn.textContent="保存";showToast(`保存失败:${e.message}`);}}
语义树状态流转(Agent 视角): 点击前: button "保存" busy=false, disabled=false 处理中: button "保存中…" busy=true, disabled=true 成功: button "保存" busy=false, disabled=false + live region "保存成功,单号 xxx" 失败: button "保存" busy=false, disabled=false + live region "保存失败:xxx"

把"状态有没有变化"这件小事做成常态,是把接口失败的脏数据风险按回去的最便宜的方式。核心心法一句话:Agent 不需要你告诉它"我成功了",它需要你让它"看得到"成功。

边界说明:反馈层对所有 Agent 有效,但"显性反馈"不等于"把状态栏写成大字报"。异步任务用 live region 播报,滚动面板别全屏弹窗,别为了 Agent 把操作反馈做成打断式。

兜底:给 Agent 一条"后门"

三层都做了,还有一类场景绕不开:老系统没有 API、只有界面。你想让 Agent 在十多年前用 Java 写的老系统里导出报表,语义做得再漂亮,它也只能靠点击。这时候别硬改界面,给高频写操作单独开一条结构化通道——一个 MCP server,一个 HTTP 接口,把"导出报表"变成一个工具,而不是一段界面操作序列。

方案对比: 纯界面走通:Agent 打开页面 → 点筛选 → 点导出 → 等文件 → 下载 结构化通道:Agent 调工具 exportReport(筛选条件) → 拿结果 结构化通道的额外收益:可权限校验、可审计、出错可重放

官方那篇博客里我注意到一个细节:Agents API 支持 MCP 工具,把"工具"跟"harness"分开编排。这暗示了方向——给 Agent 用,结构化通道比界面操作更适合做写路径;界面留给读路径和无法改造的场景。

边界说明:这条路只在"接口可控"时成立。第三方系统不愿意开接口、或者你只是想快速验证 Agent 能不能跑通业务流程,那就返回界面操作,别为造接口而造接口。我自己那阵子就干过一回——给一个只有界面的老后台补了个只读导出接口,Agent 从"十几步界面点选"变成"一次接口调用",回放里点偏造成的错文件再没出现过。成本是一次接口,收益是把操作链变成了可审计的调用链。

这套适配到底值不值

回头看这三层,其实都在回答同一个问题:怎么让 Agent 在你的系统里"用得动"。感知层把角色、标签写对,Agent 看得准;操作层给大目标、留间距,Agent 点得准;反馈层让状态可见、成功失败显性化,Agent 知道做没做成;高频写操作再给一条结构化通道兜底。改造成本都不算高,大多是"改成语义正确"级别的改动,人眼那一列基本不变。受益的是两套读者。

最后给一份可以直接照抄的检查清单,按优先级排好(★ 越高越优先做,性价比也越高):

层级检查项改法成本对哪类 Agent 有效优先级
感知按钮是真 button 不是 div换语义标签,别用 div+onclick 冒充低语义树派★★★★★
感知输入框都有 label / aria-labelplaceholder 不顶用,补 label低语义树派★★★★
操作高频按钮命中区 ≥44pxpadding + 间距低坐标派★★★★
操作相邻操作按钮留间距margin 拉开低坐标派★★★
反馈保存/提交有 loading 态disabled + aria-busy + 文案中两派★★★★★
反馈成功/失败有可见结果toast / live region中两派★★★★
兜底高频写操作有 API/MCP 通道老系统单独开接口高两派★★★(看场景)

拿到这张表,你可以顺手做个三分钟自检:用 Chrome 打开自己最常用的那个后台页面,按 F12 进 Elements 下面的 Accessibility 面板,看看那些点起来挺好看的按钮在树里是不是真的 button;再找个会保存的表单,提交完留意按钮有没有 loading 和结果提示。三项里两项不过关的页面,就是这套适配最该先排期的对象。

我的判断如下:Agent 规模化是真的,界面被当成"生产环境"也是真的。前端在 Agent 时代的新活法之一,就是把这些细节做对——既让人的同事用着舒服,也让跑你系统的 Agent 别天天翻车。这件事的窗口期不会太长,等基建方把"语义化界面"变成硬性要求再动手,就晚了。

这里不展开聊 WAI-ARIA 的规范细节了,贴两篇官方资料,想深挖的可以自己看:

  • OpenAI:Introducing the Agents API
  • W3C:WAI-ARIA 1.2

「Agent 工程实战」系列

  • 路线:界面线(computer use / Agent UI)
  • 上一篇:08 库存被点没了
  • 下一篇:10 A 公司数据记到 B 公司
  • 系列索引(21 篇阅读路线):Agent 放权前,先补权限、出站、发现这三道口子
  • 专栏:Agent 工程实战
  • 如果这篇对你有用,欢迎收藏;想追更可以关注「Agent 工程实战」专栏。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/23 2:40:17

agents-generator - template-filling-guide

模板填写指南 在填写 assets/*.md 中的模板占位符时&#xff0c;请遵循这些具体性规则。输出必须像 references/example-output/README.md 中的示例一样具体。 快速决策表 完整的检测逻辑在 decision-matrix.md 中。这是用于选择模板的快速参考表&#xff1a;SignalDecisionwor…

作者头像 李华
网站建设 2026/10/23 2:38:58

PCL2 Minecraft 启动器:装整合包,五分钟进游戏

PCL2 Minecraft 启动器&#xff1a;装整合包&#xff0c;五分钟进游戏 刚下完一个整合包却不知道怎么玩&#xff1f;Plain Craft Launcher 2&#xff08;PCL2&#xff09;就是为这种场景准备的&#xff1a;一个免费、开源的 Minecraft 启动器&#xff0c;把网上找到的整合包文…

作者头像 李华
网站建设 2026/10/23 2:36:21

Docker 一键启动:快速搭建 cain-agent AI 渗透 Agent 运行环境

【免费下载链接】cain-agent Real-world AI penetration testing engineer for authorized assessments — built-in cloud module covering AWS/Azure/GCP Aliyun/Tencent/Huawei clouds. Built on Claude Agent SDK 项目地址&#xff1a; https://gitcode.com/gh_mirrors/ca…

作者头像 李华
网站建设 2026/10/23 2:34:58

C++20 ranges与多线程:惰性视图的线程安全陷阱与正确并行姿势

1. 一次多线程撞上惰性视图的崩溃现场1.1 场景回放&#xff1a;某后台批处理服务里的 ranges 改造前阵子给一个后台批处理服务做 C 重构&#xff0c;目标是老旧的 STL 循环改成std::ranges管道风格。原逻辑不复杂&#xff1a;一批记录进来&#xff0c;先过滤掉无效字段&#xf…

作者头像 李华