Agent 长任务页

多步 Agent 任务流的过程可视化:SSE 推送步骤事件,前端渲染 pending/running/done 时间线;串行 vs 并行墙钟对照,取消即省计费

长任务演练(可运行)

GET /api/ai/agent 推送步骤事件流;切换「串行/并行」与「跳过校验」再跑一轮,对比墙钟

  1. 规划任务等待
  2. 检索(RAG)等待
  3. 工具 · 搜索文档等待
  4. 工具 · 计算指标等待
  5. 工具 · 查询数据库等待
  6. 结果校验等待
  7. 汇总输出等待

对照提示:并行把工具阶段墙钟从 ~2.4s 压到 ~0.8s,跳过校验再省 ~0.4s —— 但跳过的代价是产出未经核对,「快但错」在 Agent 场景通常比「慢但对」更难补救

Agent 页的 UX 核心

长任务体验的两个支柱:过程可见、可取消

  • 过程可见:多步任务动辄几十秒,只转一个 loading 圈等于黑盒; 步骤时间线把「现在在干什么」摊开,等待从焦虑变成可读信息, 出错时也能定位到具体步骤
  • 可取消:长任务 + 计费场景,取消按钮是成本控制不是 UX 礼貌; 客户端 AbortController 断开后,服务端要感知 cancel 并停掉后续步骤与上游调用
  • 指标口径:TTFT(首 token)管「什么时候开始有动静」, TTFUI(首个可用 UI)管「什么时候能读能点」,墙钟管「总共等了多久」; 这套口径的系统梳理见 react-playground 练习场(port 3002) 性能分类下的 AI-Native 专题,本页只落地「墙钟对照」这一项

生产里不手写这个:AI SDK 的 data parts

手写版的价值是理解协议;生产里步骤事件交给 createUIMessageStream 的 transient data parts

// Route Handler 侧(示意,ai@7;可运行版见 /ai-native/ai-sdk 专题):
import {
    createUIMessageStream,
    createUIMessageStreamResponse,
    streamText,
    toUIMessageStream,
} from "ai";

export async function POST() {
    return createUIMessageStreamResponse({
        stream: createUIMessageStream({
            execute: async ({ writer }) => {
                // transient data part:推到前端但不进消息历史,
                // 正是本页「步骤时间线」事件的官方载体
                writer.write({
                    type: "data-step",
                    data: { step: "retrieve", status: "running" },
                    transient: true,
                });
                const result = streamText({ model, prompt });
                writer.merge(toUIMessageStream({ stream: result.stream }));
            },
        }),
    });
}

// Client 侧(示意):useChat 的 onData 回调逐条收到 data-step,
// 按 step/status 渲染时间线,替代手写的帧解析
useChat({ transport, onData: (part) => renderStep(part) });

手写仍合理的场景:教学(像本页这样把帧格式摊开)、协议定制(事件语义与 AI SDK 的消息模型不匹配)、零依赖场景(不想为一次演示引入 SDK)。 其余情况让 SDK 管帧边界、取消传播与 provider 差异,业务代码只管「发什么步骤」; 对照本站的 SDK 落地版见手写 SSE vs Vercel AI SDK专题。

什么时候别用步骤时间线

时间线是长任务的解药,也是短任务的噪音

  • 单轮问答:一轮请求-响应没有「步骤」可言, 套时间线是硬造过程感 —— 用流式文本(见流式端点专题)即可
  • 步骤粒度太细:内部重试、子调用全摊开会刷屏, 用户只关心「可解释的里程碑」;粒度以「失败时用户能理解卡在哪」为准
  • 步骤不可预知的探索型任务:步骤数与顺序由模型现场决定时, 预置时间线对不上;改用「事件流日志」形态(追加式)而不是固定骨架