跳到主要内容

05 · Agent 侧:从目录到合法 UI

本章讲什么: 前面四章都在讲「客户端怎么渲染」。这章看反方向——agent 怎么被引导生成合法的 A2UI。内容主要基于设计文档 agent_sdks/agent_sdk_guide.md(一份架构/移植指南),故凡描述 SDK 行为处,均按「指南所述设计」对待,而非逐行实现核验。

1. Agent SDK 负责什么

协议规范把 A2UI 的使用收敛成一个三步循环(a2ui_protocol.md:1133-1146):

  1. Prompt: 把「想要的 UI + A2UI schema(含目录)+ 合法 JSON 例子」拼进给 LLM 的 prompt。
  2. Generate: 送给 LLM,拿到生成的 JSON。
  3. Validate: 按 schema 校验;合法就发给客户端,不合法就把错误回喂给 LLM 让它自我修正。

Agent SDK 就是把这三步工程化的库,职责是能力管理 + prompt 工程 + 输出校验(agent_sdk_guide.md:5-6)。它的数据流(agent_sdk_guide.md:9-15):定义能力(加载目录)→ 生成 prompt(注入 schema + few-shot)→ 流式解析 LLM 输出 → 校验 → 封装传输。

2. 四个核心接口

指南把 SDK 拆成四个关键接口(agent_sdk_guide.md:21-95):

接口干什么
CatalogConfig / A2uiCatalog定义/加载目录,提供「渲染成 LLM 指令」和校验能力
InferenceStrategy组装系统 prompt(角色+工作流+UI 描述);标准实现 A2uiSchemaManager(动态注入 schema+例子)与 A2uiTemplateManager(用预定义模板)
A2uiStreamParser流式解析 LLM 输出,边流边产出 UI 消息
PayloadFixer + A2uiValidator安全网:先修常见格式错,再做深度语义校验

3. Prompt 工程:token 省着花

SDK 的主要价值是生成动态、省 token 的系统 prompt(agent_sdk_guide.md:113-133):

  • 剪枝 schema: agent 只用 Text+Button,就只把这两个的 schema 放进 prompt,省 token。
  • 注入 few-shot 例子: 从目录的 examples/ 加载,对 LLM 准确率关键。
  • 标准信封标签: prompt 要求 LLM 把 A2UI 输出包在 <a2ui-json>...</a2ui-json> 里,以便确定性解析。

注意:generate_system_prompt 的签名暴露了一组很实用的开关——allowed_componentsallowed_messagesinclude_schemainclude_examplesvalidate_examples(agent_sdk_guide.md:56-74)。这让同一份目录能按场景裁出不同大小的 prompt。

4. 流式解析:正则块提取

A2uiStreamParser基于正则的块解析从 LLM 文本流里抓 A2UI JSON(agent_sdk_guide.md:137-180):

LLM 流: "这是你的表单 <a2ui-json> [ {...} ] </a2ui-json> 还需要什么?"
│ │
缓冲并透传对话文本 检测到闭合标签 → 正则抽出 JSON 块
▼ ▼
产出 text part 产出 a2ui_json part(发给客户端)

机制(agent_sdk_guide.md:159-180):

  • 缓冲: 文本块追加进缓冲,见到 <a2ui-json> 前的都当对话文本透传。
  • 正则抽取: 开闭标签都到齐后,用 <a2ui-json>(.*?)</a2ui-json>(DOTALL)抽 JSON。
  • 清洗: 抽出后去掉 LLM 可能误加的 ```json 围栏。
  • 多块: 支持一段流里多个块,交替产出 text / json part。

5. 校验:比 JSON Schema 更深

A2uiValidator 做的不止 schema 校验,还有图结构层面的完整性检查(agent_sdk_guide.md:88-94):

检查防什么
JSON Schema 校验字段类型/必填不合规
组件完整性ID 唯一、存在合法 root
拓扑与可达性循环引用(含自引用)、从 root 不可达的孤儿组件
递归深度限制嵌套过深(如 50 层)、函数调用过深(如 5 层),防客户端栈溢出
路径语法JSON Pointer 绑定路径语法

「拓扑可达性」这条对邻接表模型尤其重要:因为树是靠 ID 引用隐式拼的,很容易出现 root 指不到的孤儿或自指环,光靠 JSON Schema 查不出来,得专门走图遍历。PayloadFixer 则在结构解析前先修 LLM 常见的「尾逗号、漏引号、括号没闭合」(agent_sdk_guide.md:84-85)。

6. 封装传输

校验过的 payload 要上网。在典型 Agent-to-App(A2A)拓扑里包成 DataPart(agent_sdk_guide.md:198-206):

  • MIME 类型: A2UI JSON 标 application/a2ui+json,告诉前端怎么解读这段流。
  • createA2uiPart 助手: 自动完成封装。
  • 产出策略: 既支持 LLM 说完后的完整对象,也支持流式解析器的增量产出(配合客户端的渐进渲染)。

7. 跨语言一致性靠 conformance 套件

SDK 是多语言生态(Python 为参考,另有 Kotlin 等)。为保证各语言行为一致,仓库维护一套语言无关的 conformance 测试套件(agent_sdks/conformance/,agent_sdk_guide.md:286-289):用集中的 YAML 用例(suites/parser.yamlvalidator.yamlstreaming_parser.yaml 等)验证不同语言实现「在流式与校验边界上行为相同」。移植新语言 SDK 时,跑这套件就能确认行为对齐(agent_sdk_guide.md:243-265 的分阶段移植指南)。

8. 这章与前几章如何对接

[本章: Agent 侧] [01-04 章: Client 侧]
目录 ──► prompt ──► LLM ──► 流式解析 ──► 校验 ──► DataPart ──► MessageProcessor ──► 渲染
│ │ (01 章) (02-04 章)
└── 同一份目录(白名单)── 两头共享 ─────┘

关键洞察:agent 侧和 client 侧共享同一份目录定义——agent 用它生成 prompt 和校验,client 用它渲染和守安全边界。目录是把两端钉在一起的契约。

9. 代码地图

主题文件符号
Agent SDK 架构agent_sdks/agent_sdk_guide.mdA2uiSchemaManagerInferenceStrategy
流式解析设计同上A2uiStreamParserprocess_chunk
校验设计同上A2uiValidatorPayloadFixer
conformance 套件agent_sdks/conformance/suites/parser.yamlvalidator.yamlstreaming_parser.yaml
客户端能力生成(实现侧)renderers/web_core/src/v0_9/processing/message-processor.tsgetClientCapabilitiesgetClientDataModel
三步循环规范specification/v1_0/docs/a2ui_protocol.md「prompt-generate-validate loop」节

差异点回顾: 客户端能力对象在 v0_9 实现里用的键是 'v0.9'(message-processor.ts:75getClientDataModelversion: 'v0.9',message-processor.ts:198),而 v1.0 规范用 'v1.0'(a2ui_protocol.md:1266)。再次印证「规范候选 vs 实现 v0.9」的错位。