航班预订示例:自定义 Lightning Types 输入和输出
本示例展示如何使用自定义 Lightning Types 来覆盖 Agent Action 的默认输入和输出 UI。我们将使用 FlightAgent Apex 类查找可用航班,创建两个自定义 Lightning Type:flightResponse(输出渲染器——以精美的卡片布局展示航班)和 flightFilter(输入编辑器——带标签的表单字段收集价格和折扣输入)。
Apex 类设计
FlightAgent — 主 InvocableMethod
- @InvocableMethod(label='Find Flights' description='Finds available flights')
- 输入:FlightRequest(originCity、destinationCity、dateOfTravel、filters)
- 输出:FlightResponse → AvailableFlight → List<Flight>
数据类结构
| 类 | 字段 |
|---|---|
| Flight | flightId (String), numLayovers (Integer), isPetAllowed (Boolean), price (Long), discountPercentage (Double), durationInMin (Integer) |
| AvailableFlight | global List<Flight> flights |
| FlightRequestFilter | price (Long), discountPercentage (Double) — 可选搜索过滤器 |
| FlightRequest | originCity, destinationCity, dateOfTravel, filters (FlightRequestFilter) |
示例硬编码了四个航班(演示用,生产环境应从外部服务获取):IX 2814(1 次转机,$1000,20.2% 折扣,70 分钟)、6E 488(2 次转机,$2000,15.15% 折扣,120 分钟)、6E 523(1 次转机,$3000,13.14% 折扣,75 分钟)、6E 6166(2 次转机,$4000,14.14% 折扣,130 分钟)。
创建 Agent Action 和默认 UI 问题
使用 FlightAgent 类创建 Agent Action 后,默认 UI 存在严重问题:
默认输入 UI 问题
- 只显示基本字段(出发城市、目的城市、旅行日期)
- 过滤器字段(价格和折扣百分比)完全不可见——用户无法筛选航班
默认输出 UI 问题
- 航班数据以原始 JSON 格式返回
- 无标签、布局混乱、难以理解
- 无视觉层次或样式 —— 用户必须手动解析 JSON 才能比较航班
// 默认输出 —— 原始 JSON
{"aFlight": {"flights": [
{"flightId": "IX 2814", "price": 1000, "numLayovers": 1, ...},
{"flightId": "6E 488", "price": 2000, "numLayovers": 2, ...}
]}}
目标:创建两个自定义 Lightning Type —— flightResponse 将原始 JSON 转换为精美的航班卡片,flightFilter 显示带标签的价格和折扣输入字段。
自定义输出 UI:flightResponse CLT
目录结构
lightningTypes/
flightResponse/
schema.json
lightningDesktopGenAi/
renderer.json
schema.json
引用 Apex 类类型,告诉系统这个自定义类型映射到哪个数据结构:
{
"title": "My Flight Response",
"description": "My Flight Response",
"lightning:type": "@apexClassType/c__AvailableFlight"
}
renderer.json — 用自定义 LWC 覆盖默认渲染
使用顶级 renderer(覆盖整个输出组件):
{
"renderer": {
"componentOverrides": {
"$": {
"definition": "c/flightDetails"
}
}
}
}
LWC:flightDetails 组件
- Target:
lightning__AgentforceOutput(在 js-meta.xml 中) - sourceType:
c__flightResponse - HTML 布局:lightning-card 展示每个航班——航班 ID + 折扣标签、价格(粗体)、持续时间、出发/到达时间线、转机次数、宠物政策
- JS 逻辑:将持续时间从分钟格式化为 "X hr Y min"、计算到达时间、将 petAllowed 映射为 Yes/No
渠道支持:lightningDesktopGenAi 文件夹用于桌面 Agentforce 聊天,可额外配置 enhancedWebChat 文件夹用于 Web 聊天渠道。
集成步骤
- 打开 Agent Action → 编辑 aFlight 的 Output Rendering
- 选择 flightResponse 自定义 Lightning Type
- 保存(忽略 "Unsupported Data Type" 提示——无害)
- 测试前重新加载 Agent 页面
自定义输入 UI:flightFilter CLT
目录结构
lightningTypes/
flightFilter/
schema.json
lightningDesktopGenAi/
editor.json
schema.json
{
"title": "Flight Filter",
"description": "Flight Filter",
"lightning:type": "@apexClassType/c__FlightRequestFilter"
}
editor.json — 用自定义 LWC 覆盖默认输入表单
{
"editor": {
"componentOverrides": {
"$": {
"definition": "c/flightRequestFilter"
}
}
}
}
LWC:flightRequestFilter 组件
- Target:
lightning__AgentforceInput - targetType:
c__flightFilter - HTML:lightning-card "Price and Discount Percentage" 包含两个 lightning-input 字段——Price(数字,min 1000 / max 20000 / step 1)、Discount Percentage(数字,min 0 / max 100 / step 1)
关键模式 — handleInputChange()
这是输入数据绑定的核心:
connectedCallback()—— 加载已有值handleInputChange()—— 捕获用户输入、更新组件状态、派发valuechangeCustomEvent(包含 {price, discountPercentage} detail)通知父 Planner 组件、使用stopPropagation()阻止不需要的事件传播
集成
- 打开 Agent Action → 编辑 filters 的 Input Rendering
- 选择 flightFilter 自定义 Lightning Type → 保存
- 重新加载 Agent 页面后测试
- 注意:确保子代理指令正确引导 LLM 使用 UI 表单输入,而非文本输入
改造前后对比
输出改造
| 方面 | 改造前(默认) | 改造后(flightResponse CLT) |
|---|---|---|
| 展示方式 | 原始 JSON 无格式 | 精美卡片布局 + 航班图标 |
| 标签 | 无 | 航班 ID + 折扣标签、价格加粗、出发/到达时间线 |
| 可读性 | 难以扫描和比较 | 一目了然比较航班差异 |
输入改造
| 方面 | 改造前(默认) | 改造后(flightFilter CLT) |
|---|---|---|
| 可见字段 | 仅基本字段(origin、destination、date) | 新增 Price 和 Discount Percentage 卡片 |
| 过滤器能力 | 无法筛选航班 | 带约束的数字输入(min/max/step) |
核心技术模式总结
| 模式 | 用途 | 关键配置 |
|---|---|---|
| 顶级 Renderer | 覆盖整个输出显示 | "renderer": {"componentOverrides": {"$": {"definition": "c/xxx"}}} |
| 顶级 Editor | 覆盖输入表单显示 | "editor": {"componentOverrides": {"$": {"definition": "c/xxx"}}} |
| schema.json | 映射 Apex 类类型 | "lightning:type": "@apexClassType/c__ClassName" |
| LWC Target | 输出组件 | lightning__AgentforceOutput |
| LWC Target | 输入组件 | lightning__AgentforceInput |
| 输入数据绑定 | 实时更新 Planner | handleInputChange() + valuechange CustomEvent |
通过 schema.json 引用 Apex 类型、renderer.json 覆盖输出渲染、editor.json 覆盖输入表单,配合自定义 LWC 组件,你可以将 Agent Action 的默认原始 JSON UI 完全改造为品牌化、专业级的用户体验。