1. 引言
AI Agent 正在从独立应用走向网页端嵌入式交互。前端团队面临的核心挑战是:如何在浏览器环境中安全、高效地集成服务端的大语言模型推理能力与客户端的特有操作(如 GPS、剪贴板、DOM 操作)。本文以 React(基于 AG-UI 框架)和 Vue3 两种主流前端框架为例,说明网页端嵌入 AI Agent 前端方案的具体实现路径。
内容涵盖客户端-服务端协同原理、前端工具函数定义与执行、流式输出对接、安全通信以及多 Agent 隔离策略。阅读本文后,你将掌握:
- React AG-UI 智能体组件集成的关键步骤与配置要点
- Vue3 SSE 流式对接 Agent 的完整代码实现
- 前端工具函数的定义规范与安全执行机制
- 使用 AbortController 管理流式请求的用户中止
- 多 Agent 上下文隔离的最佳实践
2. 核心概念:网页端嵌入 AI Agent 的前端协作模式
2.1 客户端-服务端协同原理
网页端嵌入 AI Agent 前端方案的本质,是客户端与服务器之间的职责分工与协同工作。Agent 实例运行在服务端,负责调用 LLM 进行推理和决策;前端主要负责 UI 交互和浏览器环境特有的操作。
具体协作流程如下:
服务端主导推理:用户在前端输入消息,通过 API 请求发送至服务端。服务端维护 Agent 的对话上下文,并负责调用 LLM 生成回复或决策。
工具调用需要客户端能力时:当 LLM 的决策涉及浏览器特有操作(如获取位置、访问剪贴板、操作 DOM 元素),服务端不下发最终答案,而是发送一条“工具调用请求”给前端。
前端执行并返回结果:前端收到工具调用请求后,执行对应的前端函数,将结果通过协议(如 JSON-RPC)回传给服务端。
服务端继续推理:服务端将工具执行结果作为附加上下文,继续调用 LLM 生成最终回复。
以微软 AG-UI 框架为例,Agent 实例在服务端创建,但工具函数可通过 AIFunctionFactory.Create 标记为“前端执行”。当 LLM 决策需要客户端能力时,服务端向客户端下发工具调用 ID 和参数,前端执行后返回结果。这种分工既利用了服务端的计算资源、保护了 API 密钥,又保留了前端对浏览器环境的控制权限。
实际工程中,服务端与前端通过标准协议(如 JSON-RPC)交换数据,前端不直接暴露 API 密钥或 LLM 配置,从而保障了安全性。
注意:该模式要求前端与后端约定统一的通信协议,包括工具调用请求的格式、参数传递方式、结果返回格式以及错误处理。推荐在项目初期就定义好接口规范,避免后期反复调整。
2.2 前端工具函数的定义与执行机制
前端工具函数是 Agent 与浏览器环境交互的桥梁。与后端工具不同,前端工具直接操作 DOM、调用浏览器 API、读取本地状态,因此需要更严格的定义规范。在 AG-UI 示例中,前端工具的定义需遵循以下原则:
明确描述与签名:每个工具函数需附带
[Description]属性,向 LLM 说明该工具的用途、参数及触发条件。例如,GetUserLocation()的说明为“从当前浏览器获取用户的地理位置”。LLM 根据这个描述决定何时调用工具。如果描述模糊或缺失,LLM 可能不会正确调用该工具。无副作用:前端工具应避免修改全局状态或执行无法撤销的操作(如弹窗)。如果必须包含副作用,应通过异步设计并提供取消机制(如
AbortController),确保用户可以中断执行。权限分级:根据操作敏感度,将工具分为不同权限级别。例如,读取屏幕亮度为低风险操作,可直接执行;访问剪贴板或发送邮件为中风险操作,需用户二次确认;操作 DOM 结构为高风险操作,需服务端签名授权。
在 AG-UI 中,创建前端工具的代码示例如下:
1 | |
前端收到工具调用请求时,需安全执行对应函数,并将结果返回给服务端。执行过程中,应捕获所有异常,确保即使调用失败也不影响 Agent 的后续运行。
提示:工具函数的执行结果会影响 LLM 的后续推理。如果工具返回空值或错误信息,LLM 可能重复调用同一工具。建议在前端工具中设计兜底返回数据,例如获取位置失败时返回“用户拒绝了位置权限”,而非返回 null。
3. 实战:React AG-UI 集成 Agent 对话与前端工具
3.1 搭建 AG-UI 客户端并注册前端工具
React 项目集成 AG-UI 客户端需完成以下步骤:
安装依赖:在项目中引入 AG-UI 的 npm 包和相关类型定义。假设使用 AG-UI React 组件库,需安装
@agentuity/react和@agentuity/sdk。执行npm install @agentuity/react @agentuity/sdk。初始化客户端:在应用入口处创建 AG-UI 客户端实例,配置服务端地址和通信协议。通常单例模式管理客户端,避免重复实例化。
注册前端工具:为每个前端工具定义一个处理函数,并注册到客户端。AG-UI 的 React 钩子
useAgent会自动处理工具调用的分发。示例代码:
1 | |
关键说明:
- 工具处理函数必须是异步函数,返回
Promise。AG-UI 内部等待 Promise 解析后,自动将结果返回服务端。 - 工具名称(如上例中的
get_user_location)必须与服务端注册的AIFunctionFactory.Create中的函数名称一致。大小写敏感,建议统一使用小写蛇形命名。
3.2 对接流式输出与用户交互
Agent 的回复通常以流式方式返回,前端逐段渲染,以提升用户体验。AG-UI 的 useAgent 钩子内部封装了 SSE 连接,自动处理流式文本和工具调用请求。
流式渲染:
useAgent返回的messages状态会随服务器推送实时更新。每条消息包含role(user/assistant/tool)和content。渲染时只需迭代messages数组,对 assistant 类型的消息使用 Markdown 渲染组件。用户中止:调用
useAgent返回的abort函数即可中断当前流式请求。内部使用AbortController实现。当用户点击“停止”按钮时,调用abort(),前端断开 SSE 并通知服务端取消推理。工具调用 UI 反馈:当 Agent 调用前端工具时,
messages中会出现role: 'tool'的消息。建议在 UI 上展示工具调用的状态,例如显示“正在获取您的当前位置…”这样的中间提示,让用户知道 Agent 正在执行操作。
对应资源或网络请求的处理机制:
1 | |
注意:AbortController 中断的是前端侧的请求。如果服务端未实现取消机制,服务端仍可能继续推理并浪费计算资源。建议后端也监听请求取消事件,主动终止 LLM 接口调用。
4. 实战:Vue3 SSE 对接 Agent 流式输出
4.1 搭建 Vue3 项目并实现 SSE 长连接
在 Vue3 项目中,由于 AG-UI 目前主要面向 React,通常采用手动构建 SSE 或 fetch + ReadableStream 的方式对接服务端。推荐使用 fetch + ReadableStream,因为传统 EventSource 仅支持 GET 请求且无法自定义 headers,而 Agent 对话通常是 POST 请求。
以下是一个完整的 Vue3 composable 示例:
1 | |
关键说明:
使用
fetch+ReadStream的主要优势是支持 POST 请求和自定义 headers(如认证 token)。EventSource只支持 GET 请求,无法满足 Agent 对话场景。缓冲区
buffer处理分块数据。服务端推送的 SSE 消息可能跨多个数据块,buffer确保拼接完整后再解析。响应体流读取后需手动解码,否则无法正确处理中文。
decoder.decode(value, { stream: true })确保多字节字符不被截断。
使用示例:
1 | |
4.2 前端工具回调与安全通信
当服务端推送 tool_call 类型的消息时,前端需执行对应的工具函数,并将结果通过另一个 API 端点回传给服务端。这是 SSE 对接中最关键的环节,涉及跨域通信的安全问题。
工具回调的流程:
- 解析
tool_call消息,获取tool名称和arguments。 - 根据工具名称调用对应函数。建议将工具函数定义在一个对象映射中,便于维护和权限控制。
- 将工具执行结果通过
PUT /agent/tool-result或类似接口回传给服务端。 - 服务端收到结果后,继续 SSE 推送后续消息。
安全通信的三个维度:
工具白名单:前端仅执行白名单中的工具函数,杜绝执行未知函数的风险。白名单可在项目初始化时由服务端下发,前端验证后启用。
HTTPS + 签名:所有通信使用 HTTPS 加密。服务端在推送
tool_call消息时,在消息体中包含签名(如使用 HMAC-SHA256 对tool标识和agentId签名),前端验证签名通过后再执行。这防止了服务端模拟或中间人攻击。用户二次确认:对高风险操作(如修改 DOM、读取敏感数据),在工具执行前弹窗让用户确认。可在
tool_call处理函数中添加权限级别判断,根据级别决定是否弹窗。例如,读取位置只需用户确认一次,但发送剪贴板数据每次都需要确认。
Vue3 工具回调示例:
1 | |
提示:每次工具调用都需携带 toolCallId,用于服务端关联工具执行结果与 LLM 推理上下文。如果前端未能正确将 toolCallId 匹配到服务端请求,Agent 可能会错误地将结果关联到其他对话上下文中。建议在开发阶段记录工具调用的全链路日志,方便排查。
5. 进阶技巧与踩坑记录
5.1 多 Agent 协同中的上下文隔离
在同一个页面中嵌入多个 Agent(如助手、数据分析师)时,必须通过 agentId 隔离上下文,避免状态串扰。每个 Agent 实例拥有独立的对话历史、工具列表和会话状态。
设计要点:
独立实例:每个 Agent 使用独立的客户端实例或上下文对象。在 React 中,可使用多个
useAgent调用或嵌套 Provider;在 Vue3 中,为每个 Agent 创建独立的useAgentStream实例。通信隔离:后端必须有
agentId路由,前端发送请求时携带所属 Agent 的唯一标识。服务端据此区分并维护各自的上下文。前端路由代理:如果多个 Agent 使用同一个后端入口,前端需在请求路径中注入
agentId,服务端根据agentId路由到对应的 Agent 实例。例如,使用/api/agent/:agentId/stream这样的路径。命名空间工具:不同 Agent 可能同时调用同名工具(如
get_user_location),但执行结果应归属于各自上下文。前端需确保每个 Agent 的工具回调携带正确的agentId。
常见问题:如果未做上下文隔离,Agent A 的工具结果可能被 Agent B 使用,导致 B 的推理出现混乱。这在大并发或长时间运行场景下尤为明显。建议在开发时就采用严格隔离方案,避免后期重构。
5.2 常见踩坑:工具函数副作用与超时处理
前端工具执行中的常见问题及应对策略:
副作用未撤销:工具函数可能触发 UI 操作(如弹出确认框),若用户未响应或取消操作,工具状态将被挂起。解决方案:
- 所有工具函数应设计为可取消,使用
AbortController或CancelToken模式。 - 超时自动拒绝:为每个工具调用设置硬性超时时间(如 30 秒),超时后前端自动返回
timeout结果。
- 所有工具函数应设计为可取消,使用
AbortController 的正确取消方式:
- 用户点击“停止回复”时,应同时中断 SSE 流和正在执行的工具函数。
- 在
tool_call处理函数中,为每个工具调用创建一个局部的AbortController,并与主请求的signal关联。当主请求被中断时,所有子工具任务也应被取消。
- 确保前端在工具调用完成后,不再尝试向已中断的 SSE 连接发送结果,否则会触发
TypeError: Failed to fetch。
- 服务端超时后客户端状态恢复:当服务端因长时间推理或 LLM API 超时导致断开连接,客户端应自动恢复到可交互状态。具体做法:
- 在
useAgentStream的异常处理分支中,设置isStreaming.value = false并清空部分缓存。 - 为用户提供“重试”按钮,重新发送上一条消息。
- 在
建议在 messages 数组的末尾记录最后一条用户消息的用户输入内容,方便重试。
- 服务端应返回最后一条已处理的消息偏移,客户端据此恢复上下文。前端在重试时带上该偏移,服务端从断点处继续推理。
注意事项:不要在前端工具函数中直接操作服务端状态。前端工具只负责获取或修改浏览器环境的数据,服务端状态(如用户登录状态、购物车)应由 Agent 通过后端工具操作。前端工具如果错误地修改了服务端数据,可能导致数据不一致。
6. 总结与拓展
6.1 方案总结
本文详细说明了网页端嵌入 AI Agent 前端方案的实现,核心模式为“服务端推理 + 前端工具执行 + 安全通信”。两个主流框架的具体方案对比如下:
| 维度 | React AG-UI 集成 | Vue3 SSE 对接 |
|---|---|---|
| 框架封装度 | 高,AG-UI 提供完整 React 组件和钩子 | 低,需手动构建 SSE 协议和工具回调 |
| 适用场景 | 新项目重建或可引入 AG-UI 体系 | 现有 Vue3 项目,或需定制流式通信 |
| 工具执行方式 | AG-UI 自动调度工具,前端注册即可 | 需手动解析 tool_call 消息并回传结果 |
| 流式输出 | 自动处理,useAgent 返回增量 messages |
手动构建 ReadableStream 并维护消息状态 |
| 安全通信 | 框架内置签名和权限机制 | 需自行实现白名单 + HTTPS + 签名 |
选型建议:如果团队使用 React 且项目从零开始,优先选择 AG-UI;如果项目基于 Vue3 或需要高度定制通信协议,采用手写 SSE 方案更灵活。
实践落地建议:
前端工具函数务必标明描述、无副作用、权限分级,这是 Agent 正确调用工具的基础。
SSE 是前端对接 Agent 流式输出的推荐通信协议,配套
AbortController实现用户中止。安全通信需从工具白名单、HTTPS + 签名、用户二次确认三个维度保障,缺一不可。
多 Agent 协同必须用
agentId隔离上下文,避免串扰。建议在开发阶段记录工具调用日志和 SSE 消息流,便于排查问题。
6.2 拓展方向
基于当前方案,未来可探索以下方向:
WebWorker 内执行工具以提升性能:将前端工具的执行逻辑移至 WebWorker,避免工具调用阻塞 UI 线程,提升主流程的响应流畅度,尤其在多工具并行调用场景下效果明显。
多模态 Agent 前端集成:支持 Agent 生成或操作画布(如拖拽组件库、流程图编辑器),前端提供可交互的画布区域,Agent 通过工具函数读取和修改画布状态,实现更丰富的交互能力。
基于 LangChain 的通用前端 Agent 对接模式:LangChain 已提供前端工具注册和回调接口,可将其作为中间层统一管理前端 Agent。这有助于跨框架(React、Vue3、Angular)复用工具逻辑,降低后续维护成本。
状态持久化与离线能力:将 Agent 对话上下文存储到 IndexedDB 或 LocalStorage,用户刷新页面后自动恢复。配合 Service Worker,可实现有限离线场景下的 Agent 交互。
以上方向可作为下一阶段的技术探索与落地方案选型的参考。
总结
通过本文的学习,相信你已经对「网页嵌入AI」有了更深入的理解。建议结合实际项目多加练习。如有疑问,欢迎交流!