AI Agent 工程师课程
程序员进阶版

A8 · AG-UI、流式协议与产品体验深度版

把统一 Runtime Event 转换成可恢复、可 steering、可人工协作的产品体验

本模块产出ag-ui-adapter、用户可用的 Web Console · 对应总课表:第 23 周

原程序员基础版内容

2026-07-21 起整体迁移程序员进阶版。程序员基础版毕业项目改用简化 API / CLI 演示替代(展示 steering / follow-up / cancel / approval 基本流程,不要求自定义流式前端),学习目标与验收标准与修订前完全一致。

为什么选 AG-UI

它是目前最框架中立的 Agent 前端事件协议,与课程统一 AgentEvent 的映射成本最低。Vercel AI SDK UI 生态更大,但与其模型抽象耦合更深。若团队已在 AI SDK 技术栈上,可用 AI SDK UI 替代实现本模块任务,事件映射、恢复与 steering 语义要求不变。

学前自测

1. Snapshot 和 Delta 分别是什么?为什么两个都要有?

Snapshot 是完整状态,Delta 是增量补丁。只有 Delta 的话,客户端断线重连后无法重建状态;只有 Snapshot 的话,每次更新都传全量,长对话下带宽和渲染都撑不住。生产做法是首帧 Snapshot 加后续 Delta,断线重连时重新拿一次 Snapshot 再续 Delta。

2. 用户刷新页面,正在跑的 Agent 任务应该怎样?

任务继续跑,页面重新连上并恢复到当前进度。做到这一点的前提是任务状态在服务端而不是浏览器内存里,且事件流可以从某个 cursor 位置续传。很多 Demo 级实现把状态放在前端,刷新即丢,这是产品级和 Demo 级的分水岭。

3. 事件包乱序到达或者重复到达,客户端怎么保证状态一致?

靠事件序号加幂等应用。每个事件带单调递增的序号,客户端记录已应用的最大序号,重复的丢弃、乱序的缓存等待。不做这个的话,网络稍差就会出现文字重复或者顺序错乱,用户会觉得产品不稳定。

4. 什么是慢消费者问题?一个卡住的浏览器标签会怎样影响后端?

服务端产生事件的速度快于客户端消费速度,事件在服务端缓冲区堆积,最终耗尽内存或阻塞 Runtime。防的手段是 backpressure:缓冲区满了就丢弃可合并的中间事件(比如多个 text delta 合成一个)、或者断开慢客户端让它重连拿 Snapshot。前端问题拖垮后端,是流式系统的经典事故。

学习目标

把统一 Runtime Event 通过 AG-UI Adapter 转换成可恢复、可 steering、可人工协作的产品体验。

这个模块是整个课程里唯一直接面向最终用户的部分。前面所有模块的能力,用户能不能感知到、能不能用起来,取决于这一层。

课程内容

  1. AG-UI Event 与 Agent / Client State
  2. Snapshot、Delta 与 Patch
  3. Text / Thinking / Tool / State 事件
  4. Activity、Artifact、Citation 与 Custom Event
  5. SSE、WebSocket 与 transport 取舍
  6. Runtime Event 到 AG-UI Adapter
  7. Native / Pi / LangGraph / Mastra Event 归一化
  8. steering、follow-up 与 interrupt
  9. Approval、Human-in-the-loop 与 editable state
  10. reconnect、resume、event cursor 与去重
  11. optimistic UI、backpressure 与 slow consumer
  12. Conversation / Run / Session Tree UI
  13. Error Recovery、Partial Result 与 Offline State
  14. Accessibility、Sensitive Data 与前端权限边界

Snapshot、Delta 与 cursor 恢复

五类 RuntimeNative · PiLangChain · LangGraphMastra事件粒度各不相同ag-ui-adapter归一化成统一AgentEvent能力不足就显式降级发给客户端Snapshot首帧完整状态Delta ×N带单调递增序号,可去重可排序断线重连客户端记住最后的 cursor重连时带上 cursor告诉服务端我看到哪了服务端补 Snapshot再从 cursor 续 Delta状态一致任务全程没停慢消费者会拖垮后端前端渲染跟不上,事件在服务端堆积缓冲区满了就合并 text delta 丢中间帧再满就断开,让它重连拿 Snapshot敏感数据默认不下发前端只需知道调了什么工具、成没成参数细节按需授权查看和第 9 周的 Trace 脱敏是同一个原则
首帧发 Snapshot,之后只发 Delta。断线重连时带上 cursor,服务端补一个 Snapshot 再续 Delta,客户端就能重建到一致状态。只有 Delta 的实现,断一次线就再也追不回来了

实施任务

实现统一事件协议:

type AgentEvent =
  | { type: 'run.started'; runId: string }
  | { type: 'text.delta'; text: string }
  | { type: 'tool.started'; tool: string; input: unknown }
  | { type: 'tool.completed'; tool: string; output: unknown }
  | { type: 'workflow.step'; step: string; status: string }
  | { type: 'approval.required'; approvalId: string }
  | { type: 'artifact.created'; artifact: Artifact }
  | { type: 'citation'; citation: Citation }
  | { type: 'run.completed'; result: unknown }
  | { type: 'run.failed'; error: PublicError }

实现 ag-ui-adapter,将统一 AgentEvent 映射为 AG-UI snapshot / delta 事件。前端通过 cursor 恢复流,能在运行中发送 steering、排队 follow-up、完成审批,并浏览 Session branch / replay。自定义事件必须命名空间化和版本化。

动手挑战

在最差的网络条件下用一次你自己的产品。

打开浏览器开发者工具的网络限速,设成 Slow 3G,再手工制造三种异常,全程录屏:

  1. 断线重连:任务跑到一半断网三十秒再恢复,页面状态对不对?有没有丢事件或重复渲染?
  2. 多标签页:同一个任务在两个标签页打开,一边审批,另一边看到了吗?
  3. 慢消费者:打开开发者工具的 CPU 限速到最慢,让前端渲染跟不上,观察后端内存和事件缓冲区

第 3 条最容易翻车。很多实现在这里会发现服务端缓冲区无限增长,一个卡住的浏览器就能拖垮 Runtime。

录屏本身是极好的作品集素材:面试时播放一段断网三十秒后自动恢复的演示,比任何架构描述都有说服力。

Agent OS 里程碑

完成用户可用的 Web Console。

验收标准

  • 页面刷新后可恢复 Run
  • 工具调用可折叠查看
  • 审批可在 UI 完成
  • 文档引用可打开
  • 长任务可离开后返回查看
  • snapshot + delta 可在断线、重复包和乱序包后重建一致状态
  • steering、follow-up、cancel 与 approval 的语义在所有已注册 Runtime 中一致
  • 页面不直接依赖 Pi、LangGraph 或 Mastra 私有事件
  • 慢客户端不会阻塞 Runtime,敏感 Tool 输入默认不发送到浏览器
  • 通过键盘可完成运行、检查、审批和恢复流程

学后自测

1. 五个 Runtime 的事件粒度不一样,前端怎么保证体验一致?

在 Adapter 层归一化,不足的能力显式降级并让前端知道。比如某个 Runtime 不发 thinking 事件,前端就不显示思考过程区域,而不是显示一个永远空着的区域。前端绝对不能出现「if 是 LangGraph 就怎样」这种分支,那说明归一化没做到位。

2. 敏感的工具输入(比如包含用户身份证号的查询参数)要不要发到浏览器?

默认不发。前端只需要知道调用了什么工具、成功还是失败,参数细节按需授权查看。很多实现图省事把完整事件流原样推给前端,等于把脱敏工作全废了。这条和程序员基础版第 9 周的 Trace 脱敏是同一个原则在不同层的应用。

3. 你的产品能不能只用键盘完成一次完整的运行、检查、审批?

必须能。可访问性不只是合规要求,它同时也是效率要求:重度用户全都用键盘。而且键盘可达性差的界面,通常也是焦点管理混乱的界面,流式内容不断插入时会出现焦点跳走的 bug。

本模块作业

  1. packages/adapter-ag-ui/:统一 AgentEvent 到 AG-UI snapshot / delta 的映射
  2. Web Console:运行、工具折叠、审批、引用打开、Session Tree 浏览
  3. 恢复能力:cursor 续传、断线重连、乱序去重
  4. steering 与 follow-up 的前端实现,五个 Runtime 语义一致
  5. docs/streaming-resilience.md:动手挑战的三类异常测试报告 + 录屏

面试考点

这个模块对应面试里的产品工程能力,是纯后端候选人最容易丢分、也最容易差异化的地方。

  • 「你做过 AI 产品的前端吗?」:这题机会很大。播放你的断网恢复录屏,然后讲 snapshot 加 delta 加 cursor 的设计。有可演示成果的候选人在这题上是压倒性优势。
  • 「流式响应断了怎么办?」:答 cursor 续传加 Snapshot 重建,讲事件序号去重。这是流式产品的核心问题,答不好说明只做过一次性返回。
  • 「慢客户端会不会影响后端?」:答 backpressure 加可合并事件丢弃加断开慢连接。这题知道的人不多,主动讲能明显加分。
  • 「多个 Runtime 前端怎么统一?」:答 Adapter 层归一化,强调前端不能有框架判断分支。和 A5 串起来讲。
  • 「steering 和 follow-up 的区别?」:程序员基础版第 8 周学过语义,这里讲前端怎么表达这个差异:steering 要有立即生效的视觉反馈,follow-up 要显示在队列里。产品意识的直接体现。
  • 可访问性加分:主动提键盘可达和敏感数据不下发。这两点几乎没有候选人会提,提了会被记住。

复习与延伸

官方文档

本仓库对应源码

  • packages/contracts/src/event.tsAgentEvent 定义,AG-UI 映射的源头
  • 五个 Adapter 包:事件归一化的实际差异都在这里

下一步A9 · Agent 责任边界与合规

On this page