vault backup: 2026-04-29 19:01:34
This commit is contained in:
@@ -1,25 +1,19 @@
|
||||
---
|
||||
Description: ""
|
||||
date: "2026-03-16"
|
||||
lastmod: ""
|
||||
tags: []
|
||||
title: 第十章:A2UI 协议(流式 UI 组件)
|
||||
weight: 10
|
||||
tags: [eino, ai-development, go, quickstart, a2ui, sse]
|
||||
create time: 2026-04-29 16:00
|
||||
---
|
||||
|
||||
本章目标:实现 A2UI 协议,将 Agent 的输出渲染为流式 UI 组件。
|
||||
# 第十章:A2UI 协议(流式 UI 组件)(最终章)
|
||||
|
||||
## 重要说明:A2UI 的边界
|
||||
## 概述
|
||||
|
||||
A2UI 并不属于 Eino 框架本身的范畴,它是一个业务层的 UI 协议/渲染方案。本章把 A2UI 集成进前面章节逐步构建出来的 Agent,是为了提供一个端到端、可落地的完整示例:从模型调用、工具调用、工作流编排,到最终把结果以更友好的 UI 方式呈现出来。
|
||||
本章作为 ChatWithEino Quickstart 的最终章,引入 **A2UI 协议**——把 Agent 的事件流以 JSONL/SSE 的形式推送到前端,渲染为可增量更新的 UI 组件树。你将掌握 Agent 到 Web 的端到端集成方案,理解为什么 AI 应用需要从纯文本走向结构化、可交互的 UI 呈现。
|
||||
|
||||
在真实业务场景中,你完全可以根据产品形态选择不同的 UI 形式,例如:
|
||||
> [!tip] 一句话理解 A2UI
|
||||
>
|
||||
> **A2UI = Agent 输出 × UI 组件映射**。它定义了"Agent 做了什么"如何变成"用户看到了什么":文本 → Text 组件、工具调用 → Chip 卡片、进度更新 → 实时更新……一切通过声明式的组件树实现。
|
||||
|
||||
- Web / App:自定义组件、表格、卡片、图表等
|
||||
- IM/办公套件:消息卡片、交互式表单
|
||||
- 命令行:纯文本或 TUI(终端 UI)
|
||||
|
||||
Eino 更关注“可组合的智能执行与编排能力”,至于“如何呈现给用户”,属于业务层可以自由扩展的一环。
|
||||
---
|
||||
|
||||
## 代码位置
|
||||
|
||||
@@ -32,11 +26,11 @@ Eino 更关注“可组合的智能执行与编排能力”,至于“如何呈
|
||||
|
||||
## 前置条件
|
||||
|
||||
与第一章一致:需要配置一个可用的 ChatModel(OpenAI 或 Ark)
|
||||
与第一章一致:需要配置一个可用的 ChatModel(OpenAI 或 Ark)。
|
||||
|
||||
## 运行
|
||||
|
||||
在 `quickstart/chatwitheino` 目录下执行:
|
||||
在 `examples/quickstart/chatwitheino` 目录下执行:
|
||||
|
||||
```bash
|
||||
go run .
|
||||
@@ -48,50 +42,70 @@ go run .
|
||||
starting server on http://localhost:8080
|
||||
```
|
||||
|
||||
### (可选)启用 ch09 的 skills 能力
|
||||
启动后浏览器访问 `http://localhost:8080` 即可看到完整的 A2UI 交互界面。
|
||||
|
||||
最终 Web 版使用的 Agent 构建逻辑与 Chapter 9 对齐:当 `EINO_EXT_SKILLS_DIR` 指向一个合法 skills 目录时,会自动注册 `skill` 中间件,模型就能按需调用 `skill` 工具加载 `eino-guide` / `eino-component` / `eino-compose` / `eino-agent`。
|
||||
### (可选)启用 Skills 能力
|
||||
|
||||
最终 Web 版使用的 Agent 构建逻辑与第九章对齐:当 `EINO_EXT_SKILLS_DIR` 指向一个合法 skills 目录时,会自动注册 `skill` 中间件,模型就能按需调用 `skill` 工具加载文档。
|
||||
|
||||
```bash
|
||||
go run ./scripts/sync_eino_ext_skills.go -src /path/to/eino-ext -dest ./skills/eino-ext -clean
|
||||
EINO_EXT_SKILLS_DIR="$(pwd)/skills/eino-ext" go run .
|
||||
```
|
||||
|
||||
## 从文本到 UI:为什么需要 A2UI
|
||||
## A2UI 的定位与边界
|
||||
|
||||
前八章我们实现的 Agent 只输出文本,但现代 AI 应用需要更丰富的交互。
|
||||
> [!important] A2UI 不属于 Eino 框架本身
|
||||
|
||||
A2UI 是一个**业务层的 UI 协议/渲染方案**,不是 Eino 的核心 Component。本章把它集成进前面章节逐步构建出来的 Agent,是为了提供一个端到端、可落地的完整示例:从模型调用、工具调用、工作流编排,到最终把结果以更友好的 UI 方式呈现出来。
|
||||
|
||||
**真实业务场景中,你完全可以根据产品形态选择不同的 UI 形式:**
|
||||
|
||||
| 场景 | UI 形式 | 说明 |
|
||||
|------|---------|------|
|
||||
| Web / App | 自定义组件、表格、卡片、图表 | 最典型的 B/S 架构应用 |
|
||||
| IM / 办公套件 | 消息卡片、交互式表单 | 飞书、钉钉等平台的富消息 |
|
||||
| 命令行 | 纯文本或 TUI | Console 版 Agent 的原生形式 |
|
||||
|
||||
Eino 关注「可组合的智能执行与编排能力」,而「如何呈现给用户」属于业务层可以自由扩展的一环。
|
||||
|
||||
## 从纯文本到结构化的 UI:为什么需要 A2UI
|
||||
|
||||
> [!question] 思考一下
|
||||
>
|
||||
> 如果你要为一个 AI 聊天产品设计更丰富的交互体验,纯文本回复会遇到哪些瓶颈?
|
||||
|
||||
**纯文本输出的局限:**
|
||||
|
||||
- 无法展示结构化数据(表格、列表、卡片等)
|
||||
- 无法实时更新(进度条、状态变化等)
|
||||
- 无法嵌入交互元素(按钮、表单、链接等)
|
||||
- 无法支持多媒体(图片、视频、音频等)
|
||||
- ❌ 无法展示结构化数据(表格、列表、卡片等)
|
||||
- ❌ 无法实时更新(进度条、状态变化等)
|
||||
- ❌ 无法嵌入交互元素(按钮、表单、链接等)
|
||||
- ❌ 无法支持多媒体(图片、视频、音频等)
|
||||
|
||||
**A2UI 的定位:**
|
||||
|
||||
- **A2UI 是 Agent 到 UI 的协议**:定义了 Agent 输出如何映射到 UI 组件
|
||||
- **A2UI 支持流式渲染**:组件可以实时更新,无需等待完整响应
|
||||
- **A2UI 是声明式的**:Agent 只需声明"显示什么",UI 负责渲染
|
||||
- ✅ **协议映射**:Agent 输出 → UI 组件的声明式映射关系
|
||||
- ✅ **流式渲染**:组件实时更新,无需等待完整响应
|
||||
- ✅ **增量更新**:基于 dataKey 的数据绑定,文本流可逐 token 更新
|
||||
|
||||
**简单类比:**
|
||||
|
||||
- **纯文本输出** = "终端命令行"(只能显示文本)
|
||||
- **A2UI** = "Web 应用"(可以显示任何 UI 组件)
|
||||
|
||||
## 关键概念
|
||||
## A2UI v0.8 子集(本示例的边界)
|
||||
|
||||
### A2UI v0.8 子集(本示例的边界)
|
||||
|
||||
本 quickstart 并没有实现一个“完整的 A2UI 标准库”,而是实现了一个 **A2UI v0.8 的子集**:目标是把 Agent 的事件流,以稳定、可增量渲染的 UI 组件树方式推给浏览器。
|
||||
本 quickstart 并没有实现一个"完整的 A2UI 标准库",而是实现了一个 **A2UI v0.8 的子集**:目标是把 Agent 的事件流,以稳定、可增量渲染的 UI 组件树方式推给浏览器。
|
||||
|
||||
当前实现的 A2UI 消息类型与组件类型,以 [a2ui/types.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/a2ui/types.go) 为准。
|
||||
|
||||
### A2UI 消息:BeginRendering / SurfaceUpdate / DataModelUpdate / InterruptRequest
|
||||
### A2UI 消息类型:信封结构
|
||||
|
||||
每一行 SSE(`data: {...}`)承载一个 A2UI Message,Message 是一个“信封结构”,每次只会出现一个字段:
|
||||
每一行 SSE(`data: {...}`)承载一个 A2UI Message,Message 是一个"信封结构",每次只会出现一个字段:
|
||||
|
||||
**关键代码片段(注意:这是简化后的代码片段,不能直接运行,完整代码请参考 a2ui/types.go):**
|
||||
> [!note] 关键代码片段
|
||||
>
|
||||
> 注意:这是简化后的代码片段,不能直接运行,完整代码请参考 [a2ui/types.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/a2ui/types.go)。
|
||||
|
||||
```go
|
||||
type Message struct {
|
||||
@@ -103,52 +117,122 @@ type Message struct {
|
||||
}
|
||||
```
|
||||
|
||||
其中:
|
||||
| 消息类型 | 作用 | 触发时机 |
|
||||
|----------|------|----------|
|
||||
| `BeginRendering` | 告诉前端"开始渲染一个 surface",指定根节点 ID | 新会话开始时 |
|
||||
| `SurfaceUpdate` | 新增/更新一批组件(组件是树,用 id 互相引用) | 创建/修改 UI 结构时 |
|
||||
| `DataModelUpdate` | 更新 data bindings(用于流式文本增量渲染) | assistant 生成文本时 |
|
||||
| `InterruptRequest` | 通知前端展示批准/拒绝入口 | Agent 需要人类审批时 |
|
||||
| `DeleteSurface` | 删除某个 surface | 清理/重置会话时 |
|
||||
|
||||
- `BeginRendering`:告诉前端“开始渲染一个 surface(会话)”,并指定根节点 ID
|
||||
- `SurfaceUpdate`:新增/更新一批组件(组件是一个树,用 `id` 互相引用)
|
||||
- `DataModelUpdate`:更新 data bindings(用于把流式文本增量更新到某个 Text 组件)
|
||||
- `InterruptRequest`:当 Agent 触发 interrupt(例如审批)时,通知前端展示批准/拒绝入口
|
||||
|
||||
### A2UI 组件:Text / Column / Card / Row
|
||||
### A2UI 组件类型
|
||||
|
||||
本示例 UI 组件只实现了 4 种(见 [a2ui/types.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/a2ui/types.go)):
|
||||
|
||||
- `Text`:文本渲染(支持 `usageHint` 区分 caption/body/title);当 `dataKey` 存在时,文本来自 `DataModelUpdate`
|
||||
- `Column` / `Row`:布局(children 是组件 ID 列表)
|
||||
- `Card`:卡片容器(children 是组件 ID 列表)
|
||||
```mermaid
|
||||
classDiagram
|
||||
class ComponentTree {
|
||||
<<abstract>>
|
||||
+id string
|
||||
+children []string
|
||||
}
|
||||
class TextComponent {
|
||||
+text string
|
||||
+dataKey string
|
||||
+usageHint string
|
||||
}
|
||||
class ColumnLayout {
|
||||
+spacing float64
|
||||
+align ItemsAlign
|
||||
}
|
||||
class RowLayout {
|
||||
+spacing float64
|
||||
+align ItemsAlign
|
||||
}
|
||||
class CardContainer {
|
||||
+title string
|
||||
+border bool
|
||||
}
|
||||
ComponentTree <|-- TextComponent
|
||||
ComponentTree <|-- ColumnLayout
|
||||
ComponentTree <|-- RowLayout
|
||||
ComponentTree <|-- CardContainer
|
||||
note for TextComponent "支持 dataKey\n流式绑定"
|
||||
note for ColumnLayout "垂直布局容器"
|
||||
note for RowLayout "水平布局容器"
|
||||
note for CardContainer "内容容器\n无布局功能"
|
||||
```
|
||||
|
||||
## A2UI 的实现:把 AgentEvent 转成 A2UI SSE
|
||||
各组件职责:
|
||||
|
||||
最终 Web 版的核心链路是:
|
||||
| 组件 | 用途 | 特性 |
|
||||
|------|------|------|
|
||||
| `Text` | 文本渲染 | 支持 `usageHint`(caption/body/title),当存在 `dataKey` 时文本来自 `DataModelUpdate` |
|
||||
| `Column` | 垂直布局 | children 是组件 ID 列表 |
|
||||
| `Row` | 水平布局 | children 是组件 ID 列表 |
|
||||
| `Card` | 卡片容器 | children 是组件 ID 列表,仅做视觉分组 |
|
||||
|
||||
- 后端运行 Agent,得到 `*adk.AsyncIterator[*adk.AgentEvent]`
|
||||
- 把事件流转换为 A2UI JSONL/SSE 流输出给浏览器(见 [a2ui/streamer.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/a2ui/streamer.go))
|
||||
- 前端解析 SSE 的 `data:` 行并渲染组件树(见 [static/index.html](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/static/index.html))
|
||||
> [!warning] Card ≠ 布局容器
|
||||
>
|
||||
> `Card` 不提供任何布局控制(不排布子元素的位置),它只是一个有视觉边界的容器。如需布局请用 `Column` / `Row`。
|
||||
|
||||
## A2UI 的实现链路
|
||||
|
||||
最终 Web 版的核心链路是三阶段管道:
|
||||
|
||||
1. **后端运行 Agent**:得到 `*adk.AsyncIterator[*adk.AgentEvent]`
|
||||
2. **事件 → A2UI JSONL/SSE 流**:转换为 A2UI 消息推送给浏览器(见 [a2ui/streamer.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/a2ui/streamer.go))
|
||||
3. **前端解析并渲染**:读取 SSE 流并渲染组件树(见 [static/index.html](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/static/index.html))
|
||||
|
||||
### 服务端路由(高层)
|
||||
|
||||
与 A2UI 相关的关键接口(见 [server/server.go](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/server/server.go)):
|
||||
|
||||
- `GET /`:返回前端页面 `static/index.html`
|
||||
- `POST /sessions/:id/chat`:返回 SSE 流(A2UI messages),把 Agent 运行结果边跑边渲染到 UI
|
||||
- `GET /sessions/:id/render`:返回 JSONL(A2UI messages),用于“选中会话时回放历史”
|
||||
- `POST /sessions/:id/approve`:处理 interrupt 的批准/拒绝并继续返回 SSE 流
|
||||
| 方法 | 路径 | 响应 | 说明 |
|
||||
|------|------|------|------|
|
||||
| GET | `/` | HTML | 返回前端页面 |
|
||||
| POST | `/sessions/:id/chat` | SSE 流 | Agent 运行结果实时渲染 |
|
||||
| GET | `/sessions/:id/render` | JSONL | 回放历史消息 |
|
||||
| POST | `/sessions/:id/approve` | SSE 流 | interrupt 批准后继续执行 |
|
||||
|
||||
### 事件流转换(高层)
|
||||
### 事件流转换
|
||||
|
||||
服务端把 `Runner.Run(...)` 的事件流交给 `a2ui.StreamToWriter(...)`,后者负责:
|
||||
|
||||
- 对 user/assistant/tool 的输出做拆分
|
||||
- 把 tool call / tool result 渲染成 “chip 卡片”
|
||||
- 把 assistant 的流式 token 做成 `DataModelUpdate`,实现“边生成边渲染”
|
||||
- 遇到 interrupt 时发送 `InterruptRequest`,并暂停等待人类批准
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["AgentEvent 输入"] --> B{事件类型}
|
||||
|
||||
## 前端集成:fetch + SSE(不是 WebSocket)
|
||||
B -->|"user"| C["渲染 User 气泡"]
|
||||
B -->|"assistant"| D["创建 DataModelUpdate\n流式追加文本"]
|
||||
B -->|"tool call"| E["渲染 ToolCall Chip 卡片"]
|
||||
B -->|"tool result"| F["渲染 ToolResult Chip 卡片"]
|
||||
B -->|"interrupt"| G["发送 InterruptRequest\n暂停等待人类审批"]
|
||||
|
||||
- 前端通过 `fetch('/sessions/:id/chat')` 发起请求,然后从 `res.body` 读取流式字节,按行切分并解析 `data: {...}` 的 JSON(见 [static/index.html](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/static/index.html))。
|
||||
C --> H["SSE JSONL 输出"]
|
||||
D --> H
|
||||
E --> H
|
||||
F --> H
|
||||
G --> H
|
||||
|
||||
**关键代码片段(注意:这是简化后的代码片段,不能直接运行,完整代码请参考 static/index.html):**
|
||||
style D fill:#fff3e0
|
||||
style G fill:#fce4ec
|
||||
```
|
||||
|
||||
核心处理逻辑:
|
||||
|
||||
- **User 输出**:渲染为用户消息气泡
|
||||
- **Assistant 流式 token**:创建 `DataModelUpdate`,通过 `dataKey` 绑定到一个 `Text` 组件上,实现"边生成边渲染"
|
||||
- **Tool Call / Tool Result**:渲染为独立的 chip 卡片
|
||||
- **Interrupt**:发送 `InterruptRequest`,暂停等待人类批准后 resume
|
||||
|
||||
### 前端集成:Fetch + SSE(不是 WebSocket)
|
||||
|
||||
前端通过 `fetch('/sessions/:id/chat')` 发起请求,然后从 `res.body` 读取流式字节,按行切分并解析 `data: {...}` 的 JSON:
|
||||
|
||||
> [!note] 前端代码片段
|
||||
>
|
||||
> 注意:这是简化后的代码片段,不能直接运行,完整代码请参考 [static/index.html](https://github.com/cloudwego/eino-examples/blob/main/quickstart/chatwitheino/static/index.html)。
|
||||
|
||||
```javascript
|
||||
const res = await fetch(`/sessions/${id}/chat`, {
|
||||
@@ -176,77 +260,107 @@ while (true) {
|
||||
}
|
||||
```
|
||||
|
||||
## A2UI 流式渲染流程(概览)
|
||||
> [!tip] 为什么用 SSE 而不是 WebSocket?
|
||||
>
|
||||
> - **SSE**(Server-Sent Events)是单向的、HTTP 兼容、天然支持断线重连语义
|
||||
> - 对于"服务器推送 UI 事件,客户端只需消费"的场景,SSE 比 WebSocket 更轻量
|
||||
> - 如果未来需要双向交互(如键盘快捷键、实时光标同步),才考虑升级到 WebSocket
|
||||
|
||||
## A2UI 流式渲染流程
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant U as 用户
|
||||
participant FE as 前端浏览器
|
||||
participant BE as 后端 Server
|
||||
participant AG as Agent
|
||||
participant LM as LLM
|
||||
|
||||
U->>FE: 输入消息
|
||||
FE->>BE: POST /sessions/:id/chat
|
||||
BE->>AG: Runner.Run()
|
||||
AG->>LM: 发送请求
|
||||
LM-->>AG: token 流式返回
|
||||
loop 每个 AgentEvent
|
||||
AG-->>BE: AgentEvent
|
||||
alt assistant token
|
||||
BE->>FE: DataModelUpdate (dataKey 绑定)
|
||||
else tool call
|
||||
BE->>FE: SurfaceUpdate (Chip 卡片)
|
||||
end
|
||||
FE-->>U: UI 增量更新
|
||||
end
|
||||
AG-->>AG: 可能需要 Interrupt
|
||||
AG->>BE: InterruptRequest
|
||||
BE->>FE: InterruptRequest
|
||||
FE-->>U: 展示审批按钮
|
||||
U->>FE: 点击批准
|
||||
FE->>BE: POST /sessions/:id/approve
|
||||
BE->>AG: Resume 继续执行
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ 用户:分析这个文件 │
|
||||
└─────────────────────────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Agent 开始处理 │
|
||||
│ A2UI: AddText │
|
||||
│ "正在分析..." │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ 调用 Tool │
|
||||
│ A2UI: AddProgress │
|
||||
│ 进度: 0% │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Tool 执行中 │
|
||||
│ A2UI: UpdateProgress│
|
||||
│ 进度: 50% │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ Tool 完成 │
|
||||
│ A2UI: tool result │
|
||||
└──────────────────────┘
|
||||
↓
|
||||
┌──────────────────────┐
|
||||
│ 显示结果 │
|
||||
│ A2UI: DataModelUpdate│
|
||||
│ (流式更新 assistant)│
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
## 从 Quickstart 到生产落地
|
||||
|
||||
> [!tip] 可扩展的设计思路
|
||||
>
|
||||
> A2UI 的协议层和 Agent 层是解耦的。你可以只做其中的任意一部分。
|
||||
|
||||
| 方向 | 替换方案 | 适用场景 |
|
||||
|------|---------|----------|
|
||||
| 不同 UI 形态 | React/Vue 组件、移动端原生组件、TUI | 产品定位差异 |
|
||||
| 传输协议升级 | gRPC Streaming / GraphQL Subscription | 需要更强的双向交互 |
|
||||
| 渲染引擎切换 | 服务端 SSR → 客户端动态渲染 | CDN 加速需求 |
|
||||
| 多模态扩展 | 嵌入图片、图表、代码高亮 | 数据类/分析型 Agent |
|
||||
|
||||
## 本章小结
|
||||
|
||||
- **A2UI**:Agent 到 UI 的协议,定义了 Agent 输出如何映射到 UI 组件
|
||||
- **子集实现**:本示例只实现了 Text/Column/Card/Row 与 data binding
|
||||
- **流式输出**:后端以 SSE 推送 A2UI JSONL,前端增量渲染组件树
|
||||
- **事件到 UI**:把 `AgentEvent` 转为 `tool call / tool result / assistant stream` 的可视化输出
|
||||
| 核心概念 | 说明 | 关键点 |
|
||||
|----------|------|--------|
|
||||
| **A2UI 协议** | Agent 到 UI 的映射协议 | 声明式组件树 + 数据绑定 |
|
||||
| **消息信封** | BeginRendering / SurfaceUpdate / DataModelUpdate | 每种消息对应不同生命周期 |
|
||||
| **组件系统** | Text / Column / Card / Row | 4 种基础组件覆盖常见 UI 场景 |
|
||||
| **SSE 流** | AgentEvent → A2UI JSONL → 前端渲染 | 单向推送、增量更新 |
|
||||
| **中断协作** | InterruptRequest + approve 机制 | 人机协同的关键路径 |
|
||||
|
||||
## 系列收尾:这个 Quickstart Agent 的完整愿景
|
||||
> [!success] 学习成果
|
||||
>
|
||||
> 完成本章后,你应该能够:
|
||||
> - 理解 A2UI 协议的设计思路和适用场景
|
||||
> - 掌握 Agent 事件流到前端 UI 的完整转换链路
|
||||
> - 使用 SSE 实现增量渲染的前端集成方案
|
||||
> - 知道如何将这个骨架扩展到不同的产品形态中
|
||||
|
||||
到本章为止,我们用一个可以实际运行的 Agent 串起了 Eino 的核心能力。你可以把它理解为一个可扩展的“端到端 Agent 应用骨架”:
|
||||
## 下一章预告
|
||||
|
||||
- 运行时:Runner 驱动执行,支持流式输出与事件模型
|
||||
- 工具层:Filesystem / Shell 等 Tool 能力接入,工具错误可被安全处理
|
||||
- 中间件:可插拔的 middleware/handler,用于错误处理、重试、审批等横切能力
|
||||
- 可观测:callbacks/trace 能力把关键链路打通,便于调试与线上观测
|
||||
- 人机协作:interrupt/resume + checkpoint 支持审批、补参、分支选择等交互式流程
|
||||
- 确定性编排:compose(graph/chain/workflow)把复杂业务流程组织为可维护、可复用的执行图
|
||||
- 业务交付:像 A2UI 这样的 UI 集成,属于业务层自由选择的一环,用来把 Agent 能力以合适的产品形态呈现给用户
|
||||
这是 Quickstart 系列的终章。后续如果你想深入:
|
||||
|
||||
你可以在这个骨架上逐步替换/扩展任意环节:模型、工具、存储、工作流、前端渲染协议,而不需要推倒重来。
|
||||
- [[Eino/quick_start/chapter_09_skill_console]] — 回顾第九章的 Skill 知识注入能力
|
||||
- [[Eino/README]] — 探索 Eino 框架的系统性学习路径
|
||||
|
||||
## 扩展思考
|
||||
|
||||
**其他组件类型:**
|
||||
### 其他组件类型(可选实现方向)
|
||||
|
||||
- 图表组件(折线图、柱状图、饼图)
|
||||
- 地图组件
|
||||
- 时间线组件
|
||||
- 树形组件
|
||||
- 标签页组件
|
||||
| 组件 | 说明 | 实现难度 |
|
||||
|------|------|----------|
|
||||
| **图表组件** | 折线图、柱状图、饼图 | 中高(需接入图表库) |
|
||||
| **地图组件** | 地理信息可视化 | 中(依赖地图 SDK) |
|
||||
| **时间线组件** | 事件顺序排列展示 | 低(已有 Column 即可) |
|
||||
| **树形组件** | 层级数据结构展示 | 中(递归渲染逻辑) |
|
||||
| **标签页组件** | 多面板 Tab 切换 | 低(State 管理即可) |
|
||||
|
||||
**高级功能:**
|
||||
### 高级交互能力
|
||||
|
||||
- 组件交互(点击、拖拽、输入)
|
||||
- 条件渲染
|
||||
- 组件动画
|
||||
- 响应式布局
|
||||
| 能力 | 说明 | 技术要点 |
|
||||
|------|------|----------|
|
||||
| **组件交互** | 点击、拖拽、输入反馈 | 前端事件 → API 调用 |
|
||||
| **条件渲染** | 根据数据决定组件显隐 | 服务端根据状态发送不同 SurfaceUpdate |
|
||||
| **组件动画** | 平滑过渡效果 | CSS transition / animation |
|
||||
| **响应式布局** | 自适应屏幕尺寸 | 媒体查询 + 弹性布局 |
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[Eino/quick_start/_index]] — Quickstart 系列统一入口
|
||||
- [[Eino/quick_start/chapter_08_graph_tool]] — Graph Tool 复杂工作流编排
|
||||
- [[Eino/quick_start/chapter_09_skill_console]] — Skill 知识与指令注入
|
||||
- [[Eino/quick_start/chapter_07_interrupt_resume]] — Interrupt 与 Resume 机制
|
||||
|
||||
Reference in New Issue
Block a user