构建更佳的 Agent UX:使用 LangChain 实现流式进度、状态和文件操作

发布: (2026年1月16日 GMT+8 02:38)
3 分钟阅读
原文: Dev.to

Source: Dev.to

你将构建的内容

一个简单的模式:

  1. 你的工具在运行时发出事件(进度/状态/文件操作)
  2. 前端订阅这些事件并立即渲染
  3. 类型守卫 让 UI 逻辑安全且可预测

无需轮询循环。无需猜测。无需 “thinking…” 占位符。

1) 从工具调用中发出带类型的自定义事件

在工具调用内部,随着工作进展写入自定义事件:

config.writer?.({
  type: "progress",
  id: analysisId,          // stable id => update in place
  step: steps[i].step,
  message: steps[i].message,
  progress: Math.round(((i + 1) / steps.length) * 100),
  totalSteps: steps.length,
  currentStep: i + 1,
  toolCall: config.toolCall,
} satisfies ProgressData);

这就是关键转变:工具不只是函数——它们是事件生产者。

2) 在 React 中接收这些事件

在 UI 中,将处理函数传入流 Hook:

onCustomEvent: handleCustomEvent,

现在,工具发出的每个事件都会在客户端 实时 到达。

3) 缩窄事件类型并可预测地更新 UI 状态

将传入的事件视为 unknown,然后使用类型守卫进行缩窄,并根据 id 更新状态映射:

if (isProgressData(data)) {
  /* update progress */
} else if (isStatusData(data)) {
  /* update status */
} else if (isFileStatusData(data)) {
  /* update file ops */
}

这让前端保持稳定:

  • 进度更新 就地 进行
  • 最小化重新渲染
  • 没有字符串化的事件乱象

为什么这很重要(不仅仅是“好看的 UI”)

当 UI 真实反映执行过程时:

  • 用户对代理的信任度提升
  • 调试变得极其容易
  • 失败可以在不翻日志的情况下被理解
  • 你可以构建更好的用户体验:步骤指示器、时间线、文件操作流等

🎥 视频:

Back to Blog

相关文章

阅读更多 »