在普通前端应用里,Renderer 常被理解为“把数据变成节点”的一层。但当界面描述来自智能体时,它同时承担了翻译、验证和授权。它决定哪些意图可以进入应用,也决定哪些操作可以离开应用。

先翻译,再渲染

智能体输出的组件名并不等于真实组件。Renderer 需要先在注册表里找到宿主认可的实现,再根据 Schema 校验属性。未知组件不是“尽量猜一下”,而应该稳定降级;不合法属性也不能悄悄穿透到运行时。

模型负责提出 UI 意图,宿主负责解释意图;解释权就是控制权。

Action 比组件更敏感

一个组件渲染失败,通常只影响当前表面;一个未经验证的 Action 却可能跨越网络、改变数据甚至触发外部系统。因此 Action 不应该只按名称查找,而需要同时校验能力范围、任务上下文与参数大小。

UI intent
  → component registry
  → props schema
  → local interaction
  → action allowlist
  → host transport

好的边界也带来更好的体验

安全边界不是只为阻止错误。它也让产品行为更可预测:未知动作可以明确禁用,离线状态可以保留本地输入,重复提交可以被任务标识拦截。用户得到的不是更多限制,而是一套不会因为模型偶然输出而失去一致性的交互。

当 Renderer 被看作信任边界,组件设计、协议设计与产品体验就不再是三个分离的话题。它们共同回答同一个问题:系统愿意把多大的解释权交给智能体。

分层校验,不把前端当成最终授权者

Renderer 的授权范围是客户端允许哪些能力被调用;业务接口是否允许当前用户执行操作,仍由服务端决定。一个合理的顺序是先验证结构,再验证引用与资源约束,最后在动作执行处校验身份和业务权限。

边界示例检查失败处理
消息结构版本、属性类型、消息大小拒绝当前更新并记录原因
组件图未知组件、重复 ID、循环引用、深度隔离有问题的表面
内容与资源链接协议、图片来源、富文本安全占位或明确提示
客户端动作动作名、参数范围、任务有效期禁用或拒绝发送
服务端操作会话、资源归属、幂等约束返回明确错误,不修改数据

限制名称并不足够:一个允许的 openLink 动作仍可能收到危险 URL;一个允许的删除动作仍可能携带别人的资源 ID。需要同时校验参数和当前上下文。

一个容易误判的重复提交

用户点击确认后网络变慢,界面重新连接并重试。即使按钮已经禁用,服务端仍可能收到两次请求。宿主应给一次业务意图分配稳定的请求标识,重试复用该标识,服务端在当前用户和操作范围内处理幂等。

仅在浏览器内记一个“已提交”布尔值挡不住重放;仅用任务 ID 去重也可能错误阻止同一任务中的后续合法操作。标识的粒度需要对应业务意图,而不是页面或整个会话。

把拒绝路径也当成产品功能

未知组件显示可理解的降级提示,网络中断保留草稿,权限错误引导重新登录或返回可访问内容。日志记录版本、Surface 标识和错误类型即可定位多数问题,避免把完整输入、会话令牌和私人数据写进去。

验证时至少覆盖:合法请求成功、未知动作被拒绝、跨用户资源被拒绝、重复请求不重复写入。最后一种需要用真实服务端行为证明,不能只看按钮是否置灰。

继续阅读:A2UI 运行时、前端工程化的验证边界。参考 OWASP Authorization Cheat Sheet。