网页端嵌入 Agent 对接前端方案

news2026/5/22 1:36:14
本文将深入探讨「网页端嵌入AI」的核心概念与实战技巧帮助你快速掌握关键要点。让我们开始吧网页端嵌入 Agent 对接前端方案1. 引言当前前端项目正从被动展示走向主动交互AI Agent 嵌入网页端可自动化 UI 操作、优化布局并辅助编码。本文聚焦如何在前端React/Vue3中集成 AI Agent涵盖客户端工具定义、安全通信及流式输出等核心环节。读完本文你将掌握React 集成 AG-UI 组件、Vue3 对接 Agent 流式输出、前端 Agent 安全通信实现、LangChain 前端 Agent 对接的基本方法。2. 核心概念AI Agent 在前端的运行模式2.1 网页端嵌入 AI Agent 前端方案的本质网页端嵌入 AI Agent 前端方案的本质是客户端与服务器之间的协同工作模式。负责推理和决策的 LLM 运行在服务端而前端主要负责 UI 交互和本地环境操作。Agent 在客户端与服务器间协同由服务器协调工具调用前端负责浏览器端特有的操作获取 GPS 位置、访问剪贴板、操作 DOM 元素、调用浏览器 API 等。以微软 AG-UI 框架为例Agent 实例在服务端创建但工具函数可能被标记为“前端执行”当 LLM 决策需要客户端能力时服务端会向客户端下发工具调用请求由前端执行后将结果返回。这种分工既利用了服务端的计算资源、保护了 API 密钥又保留了前端对浏览器环境的控制权限。在实际工程中服务端与前端通过标准协议如 JSON-RPC交换工具调用ID和参数前端无须直接暴露 API 密钥或 LLM 配置从而保障了安全性。2.2 React 集成 Agent UI 组件——AG-UI 的使用模式微软开源的microsoft/ag-ui-react库提供了一套开箱即用的 React 组件集合用于快速在 React 应用中嵌入 AI Agent 界面。它包含AIAgent、AgentConversation、AgentToolList等组件开发者只需在组件树中引入AIAgent传入必要属性即可使页面具备 Agent 对话与工具调用能力。AG-UI 的核心设计思路是声明式组件 工具函数自动路由。开发者在项目中预先定义前端工具函数如获取用户位置、切换主题、读取浏览器存储并用[Description]属性标注。通过AIFunctionFactory.Create将这些函数包装为AITool对象创建 Agent 实例时传入工具数组框架会自动确定哪些工具需要在前端执行并在对话期间接管调用与响应。此外AG-UI 提供了内置的 Agent 状态管理thinking / waiting / error结合 React Suspense 或自定义 Loading 组件可以显著减少状态边界处理的开发成本。2.3 前端 Agent 工具函数定义方法前端 Agent 工具函数是 Agent 在客户端环境中的可调用能力单元每个工具函数对应一个具体的浏览器端操作。定义方法主要有以下步骤函数签名工具函数必须是静态方法或独立函数返回类型为string或可被 JSON 序列化的对象。返回信息将直接作为 LLM 理解的结果。元数据标注通过[Description(...)]标注函数功能、参数含义、返回格式。服务端 LLM 会根据描述决定何时调用该工具。描述应精准简练例如[Description(获取用户当前地理位置返回经纬度字符串。)]。包装为 AITool使用AIFunctionFactory.Create(GetUserLocation)将普通函数转为AITool对象框架会提取其描述、参数类型约束等元数据。注册到 Agent创建 Agent 实例时将AITool[]数组传入tools属性Agent 即可在对话中识别并调度这些工具。重要原则工具函数尽量避免产生副作用或必须前置确认对话框输出结果应在合理长度内建议不超过 2000 字符避免 token 浪费。对于会修改页面状态的操作如切换主题通常不返回复杂对象只返回固定字符串例如Theme toggled successfully.。3. 实战React 中使用 AG-UI 集成 Agent3.1 项目初始化在现有 React 项目确保 React 版本 ≥ 17.0.2中安装 AG-UI 库npminstallmicrosoft/ag-ui-react microsoft/ag-client在应用入口处引入 Provider 组件用于提供 Agent 客户端实例// index.jsx import { ChatClientProvider } from microsoft/ag-ui-react; import { ChatClient } from microsoft/ag-client; import App from ./App; // 需替换为真实服务端 endpoint该 endpoint 负责连接 LLM 并协调工具调用 const chatClient new ChatClient({ endpoint: https://your-server.com/agent }); ReactDOM.render( ChatClientProvider client{chatClient} App / /ChatClientProvider, document.getElementById(root) );3.2 定义前端工具假设我们需要 Agent 能够获取用户 GPS 位置和切换深色模式。定义两个前端工具函数// 后端 C# / .NET 示例也可以在 JS/TS 中用类似方式[Description(Get the users current location from GPS.)]staticstringGetUserLocation(){// 实际应调用浏览器 Geolocation API此处仅做示意// 前端通过 Bridge 层JSInterop从浏览器获取数据returnAmsterdam, Netherlands (52.37°N, 4.90°E);}[Description(Toggle dark/light theme in current page.)]staticstringToggleDarkMode(){// 切换主题逻辑前端执行returnDark mode toggled to true.;}// 创建前端工具数组AITool[]frontendTools{AIFunctionFactory.Create(GetUserLocation),AIFunctionFactory.Create(ToggleDarkMode)};在实践中由于工具函数必须在前端浏览器环境执行通常通过 JSInterop例如 Blazor 场景或直接在前端 JavaScript 中定义对应函数然后将函数引用传递给 AG-UI 的AIFunctionFactory。React 组件内可直接定义纯前端函数。3.3 创建 Agent 实例并挂载在服务端或前端初始化时通过已配置好的chatClient创建 Agent 实例// App.jsx import { useChatClient, AIAgent, AgentConversation } from microsoft/ag-ui-react; function App() { const chatClient useChatClient(); // 创建 Agent 实例 const agent chatClient.AsAIAgent({ name: agui-client, description: An agent that can access client-side capabilities., tools: frontendTools // 上文定义的 frontendTools }); return ( div h2AI Agent 助手/h2 {/* AG-UI 内置组件自动处理对话与工具调用 */} AIAgent agent{agent} AgentConversation / /AIAgent /div ); }AG-UI 前端工具调用实战当用户输入“我在哪里”LLM 决定调用GetUserLocation工具服务端将工具调用请求带有tool_call_id下发给前端。AG-UI 组件自动执行对应的前端函数将结果如经度纬度回传给服务端最终以文本形式展示给用户。整个流程对开发者透明仅需关注工具函数的定义和描述。4. 实战Vue3 对接 Agent 流式输出SSE 实现4.1 为什么选择 SSEAI Agent 的响应通常以流式方式生成前端逐块展示 token提升用户体验。在 Vue3 项目中对接流式输出推荐使用 SSEServer-Sent Events。原因如下SSE 是浏览器原生支持的轻量文本流协议无需像 WebSocket 那样手动管理握手、帧解析和心跳它适用于常规的单向文本流场景——Agent 服务端向客户端流式发送生成结果。对于多数前端对话场景客户端的输入可通过常规 POST 请求发送不需要全双工通信。实现复杂度与维护成本均低于 WebSocket。此外SSE 天然支持断线重连Last-Event-ID这在 Agent 长回答场景中尤为重要。4.2 前端实现Vue3 Composition API ReadableStreamtemplate div div v-formsg in messages :keymsg.id strong{{ msg.role }}:/strong {{ msg.content }} /div button clickcancelRequest v-ifgenerating中止/button /div /template script setup import { ref } from vue; const messages ref([]); const generating ref(false); let abortController null; async function sendMessage(text) { // 将用户消息加入对话 messages.value.push({ role: user, content: text, id: Date.now() }); abortController new AbortController(); generating.value true; try { const response await fetch(/api/agent/chat, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ message: text, history: messages.value.slice(0, -1) }), signal: abortController.signal }); if (!response.ok) { throw new Error(HTTP ${response.status}); } // 使用 ReadableStream 逐块读取 SSE 数据流 const reader response.body.getReader(); const decoder new TextDecoder(); let assistantContent ; let assistantMsgId Date.now() 1; // 创建助理消息容器先展示空内容并动态追加 messages.value.push({ role: assistant, content: , id: assistantMsgId }); const msgIndex messages.value.length - 1; while (true) { const { done, value } await reader.read(); if (done) break; const chunk decoder.decode(value, { stream: true }); // SSE 数据格式 data: {token: ...} 每行 const lines chunk.split(\n); for (const line of lines) { if (line.startsWith(data:)) { try { const json JSON.parse(line.slice(5).trim()); if (json.token) { assistantContent json.token; // 利用 Vue3 响应式特性更新消息内容 messages.value[msgIndex].content assistantContent; } } catch (e) { // 忽略解析错误如非 JSON 行 } } } } } catch (err) { if (err.name ! AbortError) { console.error(SSE 数据接收错误:, err); } } finally { generating.value false; } } function cancelRequest() { if (abortController) { abortController.abort(); } } /script要点说明使用AbortController支持用户中止请求避免 Agent 生成过长内容时无法停止。逐块解码时设置{ stream: true }保证 UTF-8 字符边界正确。SSE 数据行格式取决于后端实现这里假设每行data: {token:xxx}后跟\n\n作为事件分隔。前端按行解析、拼接到ref中触发视图更新。注意当大量 token 连续推送时频繁触发 Vue 响应式更新可能产生性能问题可在回调中加入节流或批处理比如每50ms批量更新一次。4.3 后端配合FastAPI 示例fromfastapiimportFastAPI,Requestfromfastapi.responsesimportStreamingResponseimportasyncio appFastAPI()asyncdefagent_stream(message:str,history:list):模拟 Agent 流式生成实际调用 LLM 或 agent.invoke# 假设 agent 是一个可流式调用的实例# async for token in agent.astream(input{message: message, history: history}):# yield fdata: {json.dumps({token: token})}\n\n# await asyncio.sleep(0.01) # 控制推送速率response这是模拟的流式输出内容。 forcharinresponse:yieldfdata:{json.dumps({token:char})}\n\nawaitasyncio.sleep(0.02)app.post(/api/agent/chat)asyncdefchat(request:Request):dataawaitrequest.json()messagedata.get(message)historydata.get(history,[])returnStreamingResponse(agent_stream(message,history),media_typetext/event-stream,headers{Content-Type:text/event-stream,Cache-Control:no-cache,Connection:keep-alive,})后端必须设置Content-Type: text/event-stream否则前端ReadableStream将无法按预期工作。Java Spring Boot 中可对应使用SseEmitter。提示生产环境下对 SSE 流要进行连接数控制和超时管理。可在前端实现重连逻辑指数退避初始延迟 1s最大 30s浏览器原生EventSource可简化实现但无法自定义POST请求方法。若需要POST传用户消息体较大则推荐使用fetchReadableStream方案。5. 安全通信前端 Agent 安全通信实现5.1 核心风险识别前端 Agent 工具函数暴露了浏览器端能力引入的安全风险不可忽视。主要风险包括工具函数可能被滥用读取敏感数据如navigator.cookie、localStorage、GPS 坐标。LLM 幻觉可能导致服务器错误地调度一个工具函数如果该函数涉及写操作如修改 localStorage、建 cookie、发送 HTTP 请求可能造成用户数据损坏或隐私泄漏。中间人攻击如果通信链路未加密攻击者可能篡改服务器下发的工具调用指令诱导前端执行恶意操作。5.2 前端 Agent 安全通信实现方案5.2.1 工具白名单与权限分级所有工具函数必须注册在前端明确定义的白名单中前端绝不能执行由服务端动态注入的任意函数名。权限分级建议等级描述示例工具L0无敏感信息、任意调用获取当前时间、温度转换L1读取非私有信息需一次授权获取地理位置L2读取/写入用户数据写剪贴板、改主题L3高危操作写 cookie、发送网络请求需每次确认实现上可在工具函数定义阶段附加PermissionLevel属性框架在执行工具前检查授权状态。5.2.2 通信使用 HTTPS 签名所有 Agent 与服务器间的通信必须通过 HTTPS。关键调用如工具执行结果返回可增加签名机制服务器在下发tool_call_id时附带 HMAC 签名前端执行后返回时携带签名服务器验签通过才接受结果。这样可以防止结果被篡改或者重放攻击。5.2.3 敏感操作的用户二次确认对于需要修改用户数据或触发系统副作用的工具L2 及以上前端必须在执行前弹出确认对话框如弹窗提示“助手想要修改您的主题是否允许”。用户授权结果应短时缓存例如 5 分钟内同一工具不再重复确认避免打断交互流程。5.2.4 示例AG-UI 中的权限控制在 AG-UI 中可以通过ToolPolicy扩展实现权限控制// 伪代码示意工具权限策略consttoolPolicynewToolPolicy({onBeforeExecute:async(toolName,args,permissionLevel){if(permissionLevel2){constconfirmedawaitshowConfirmDialog(允许执行${toolName}吗);returnconfirmed;}returntrue;}});createAgent({tools:frontendTools.map(t({tool:t,policy:toolPolicy})),});6. 进阶LangChain 前端 Agent 对接教程与多 Agent 协同6.1 LangChain 前端 Agent 对接的基本方法当项目需要更灵活的前端 Agent 逻辑时例如自定义 LLM 调用、状态机管理可使用 LangChain 的 JavaScript SDK 创建前端 Agent。基本模式如下import{ChatOpenAI}fromlangchain/openai;import{AgentExecutor,createReactAgent}fromlangchain/langgraph;// 定义前端工具使用 langchain/core 的 Tool 类constgetLocationToolnewTool({name:get_location,description:获取用户当前地理位置。,func:async(){// 调用浏览器 Geolocation APIreturnnewPromise((resolve,reject){navigator.geolocation.getCurrentPosition((pos)resolve(${pos.coords.latitude},${pos.coords.longitude}),(err)reject(无法获取位置));});}});// 创建 Agent 实例前端可执行模式constagentawaitcreateReactAgent({llm:newChatOpenAI({model:gpt-4o,temperature:0}),tools:[getLocationTool],});constagentExecutornewAgentExecutor({agent});// 调用constresultawaitagentExecutor.invoke({input:我在哪里});但需要注意前端直接使用 LLM 的 API key 有暴露风险。LangChain 前端 Agent 对接时建议将ChatOpenAI的调用代理到自己后端或者使用callbacks将函数调用请求发送到后端进行推理。LangChain 新增的RemoteRun模式支持这种模式前端只定义工具执行逻辑LLM 推理全部通过后端 RemoteRunnable 完成。6.2 多 Agent 协同与路由在天猫行业中后台研发场景中参考搜索资料复杂的前端任务通常需要多个 Agent 协同一个 Agent 负责 UI 扫描与实际分析一个负责布局优化一个负责组件重构。在多 Agent 架构下前端需要管理多个 Agent 实例及其工具集。实现方案服务端路由层前端仅维护一个统一的 Agent 入口通过请求中的requestType字段让服务端路由到对应下游 Agent。服务端返回的流式数据中包含agentId标识来当前响应的 Agent 身份。前端命名空间隔离每个 Agent 对应一个工具命名空间工具函数名称加上agentId前缀以避免冲突。每个 Agent 实例独立管理对话历史和状态利用 React/Vue 的Context API或状态管理库Pinia/Zustand按agentId创建独立 store。3.踩坑点上下文串扰同一页面存在多个 Agent 实例时浏览器内存中的会话历史可能被重写。根本原因在于使用了全局共享的变量或数组存储历史。解决方案为每个 Agent 创建唯一agentId历史记录、AbortController、重连定时器等全部存储在该 ID 为 key 的 Map 中避免交叉影响。延伸阅读RAG 生产部署与性能监控Agent 开发与生产级部署RAG 实战全链路系列目录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2633236.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…