LangChain 07:前端实时 Agent 界面——消息、工具、审批与会话
1、本篇任务:做一个能解释运行状态的 Agent 界面
前端不只是逐字显示模型答案。它必须表示会话、run、消息、工具执行和审批状态,并在刷新或断线后恢复。
后端已在上一课定义公共事件。本课只依赖该合同,不直接依赖 LangGraph 内部节点名。
2、先定义 UI 状态机
idle → submitting → running → completed
├→ waiting_approval → running
├→ failed → retrying
└→ cancelled
不允许从 completed 再接收 text delta,也不允许在 waiting_approval 时显示“操作已完成”。状态机能阻止乱序事件让界面说谎。
type ViewState = {
runId?: string;
phase: "idle" | "submitting" | "running" | "waiting_approval" | "completed" | "failed";
answer: string;
lastSequence: number;
tools: Record<string, { name: string; status: "running" | "done" | "failed" }>;
approval?: RefundDraft;
error?: { code: string; retryable: boolean };
};
3、用 reducer 消费事件
function reduceEvent(state: ViewState, event: AgentEvent): ViewState {
if (event.sequence <= state.lastSequence) return state;
const base = { ...state, lastSequence: event.sequence };
switch (event.type) {
case "text.delta":
return { ...base, phase: "running", answer: state.answer + event.text };
case "approval.required":
return { ...base, phase: "waiting_approval", approval: event.action };
case "run.completed":
return { ...base, phase: "completed", answer: event.answer, approval: undefined };
case "run.failed":
return { ...base, phase: "failed", error: { code: event.code, retryable: event.retryable } };
default:
return base;
}
}
sequence 去除重连后的重复事件。服务端保存不了完整事件窗口时,客户端应重新拉取 run snapshot,而不是重新提交用户消息。
4、SSE 重连的正确行为
连接 GET /runs/:id/events?after=<lastSequence>;每收到一个合法事件,先更新 reducer,再持久化 lastSequence。连接断开时指数退避重连;run 已完成则停止;服务端返回事件窗口过期时,调用 run snapshot API 重建状态。
“点击重试”必须区分两种动作:只重连事件流不会重跑 Agent;重新执行失败 run 需要新的 run ID,并由后端判断哪些节点可安全重试。
5、工具调用应显示成卡片
只读工具显示名称、阶段和安全摘要,例如“正在查询订单 A***”;不要显示完整工具输入、内部用户 ID 或原始响应。失败时展示用户可操作的错误,例如“订单服务暂时不可用,请稍后重试”,内部错误码留在 trace。
结构化结果用受控组件渲染:订单结果映射到 OrderCard,引用映射到 SourceList。模型不能输出任意 React 组件名、HTML 或 JavaScript。
结构化数据 → Zod 校验 → 组件 allowlist → React/Vue 组件
6、审批卡必须回答五个问题
用户需要看到:将执行什么;影响哪个对象;关键参数是什么;是否可撤销;审批何时过期。按钮提交 actionId + decision,后端依据登录态确认审批人并重新读取权威参数。
按钮点击后立即禁用,显示“处理中”;网络重试仍携带同一 action ID。拒绝和编辑是正式状态,不是聊天文本。
7、Markdown 安全渲染
模型文本经过 Markdown parser 后必须 sanitize。禁用原始 HTML、事件属性、危险 URL;外链使用安全 rel;代码块只显示不执行。检索文档与工具结果可能含 prompt injection,同样按不可信文本显示。
8、前端测试
- 乱序和重复事件不会重复文本或倒退状态。
- 第十个事件后断网,重连从 sequence 10 继续。
- 刷新时仍显示待审批卡;重复批准只出现一次结果。
- 工具 500 不显示堆栈或 PII。
- 恶意 Markdown、
javascript:URL 和原始 HTML 无法执行。 - 屏幕阅读器能读出流式状态、工具进度和审批结果。
本课完成后,界面反映的是服务器运行事实。下一课处理“Agent 每一步到底应看到哪些上下文”,并安全接入 MCP。
如果您觉得这篇文章有帮助,请点个赞吧~
评论
请登录后发表评论
去登录