拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于 Gemini Live API 构建多模态客户服务智能体:Customer Support Demo App 实战指南

基于 Gemini Live API 构建多模态客户服务智能体Customer Support Demo App 实战指南【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai导读本指南以 customer-support-demo-app 为骨架深入讲解如何利用 Gemini Live API 通过 WebSocket 构建看得见、听得懂、能行动的下一代客户服务智能体。该 Demo 是 native-audio-websocket-demo-apps 系列中的一员完整演示了多模态输入摄像头画面 语音、情感对话情绪感知与共情回应以及实时工具调用退款处理、转接人工三大核心能力。读完本文你将掌握这套 React Python 前后端架构的搭建步骤、关键配置项含义并能基于源码理解 Live API 底层通信协议与扩展方式。Customer Support Demo App 运行界面顶部为配置、连接、媒体、聊天控制区左侧为演示高亮说明中间为聊天面板右侧为摄像头预览与控制按钮。1. 项目概览它演示了什么这是一个专门的 React 应用用于演示如何基于Gemini Live API构建未来感的客户支持交互场景智能体可以看到你所展示的内容例如对着摄像头展示要退货的商品、听出你的语气与情绪检测到沮丧时切换更共情的口吻并直接执行真实动作来即时解决问题。应用通过三大支柱能力支撑起这一体验多模态理解Multimodal Understanding智能体既能看——通过摄像头/屏幕共享获取视觉输入如退货场景中的实物外观也能听——实时解析用户的语音。共情回应Empathetic Response智能体检测用户情绪状态并据此调整语气建立更像真人的连接。该能力在源码中对应enable_affective_dialog配置见 gemini-api.js。行动执行Action Taking智能体可以调用工具完成退款处理或在复杂问题场景下转接人工坐席。1.1 核心特性清单特性说明源码位置多模态支持无缝处理音频与视频输入客户可直观演示问题加速解决media-utils.js情感对话Affective Dialogue检测用户情绪并以适当共情语气回应gemini-api.js自定义工具process_refund携带交易 ID 处理退款请求connect_to_human复杂问题转接人工tools.js实时交互基于 WebSocket 使用 Gemini Live API实现低延迟语音交互server.py2. 系统架构浏览器、代理服务器与 Gemini 的三方协作从项目结构可以看出这是一个典型的前后端分离架构Python 后端负责与 Google Cloud 的认证握手与 WebSocket 转发React 前端负责媒体采集、会话管理与 UI 展示。浏览器 (React SPA) │ WebSocket (ws://localhost:8080) ▼ server.py —— WebSocket 代理 认证处理 │ 携带 Bearer Token 的 WSS 连接 ▼ Gemini Live API (BidiGenerateContent 双向流式接口)为什么需要代理服务器浏览器端直接持有 Google Cloud 的访问令牌存在安全隐患且浏览器 WebSocket 无法方便地完成 OAuth 流程。因此server.py作为中间桥梁使用 Google 应用默认凭证Application Default Credentials在服务端获取 access token再携带Authorization: Bearer token请求头连接到 Gemini 服务端同时在浏览器与 Gemini 之间做双向消息透传。在 server.py 中generate_access_token()通过google.auth.default()读取默认凭证并在凭证失效时调用creds.refresh(Request())刷新def generate_access_token(): Retrieves an access token using Google Cloud default credentials. try: creds, _ google.auth.default() if not creds.valid: creds.refresh(Request()) return creds.token except Exception as e: print(fError generating access token: {e}) print(Make sure youre logged in with: gcloud auth application-default login) return None连接建立后create_proxy()server.py通过asyncio.create_task启动两个方向独立的转发任务proxy_task客户端→服务端与 服务端→客户端任一方向断开即取消另一个任务并关闭两端连接。同时该服务器使用certifi.where()提供的 CA 证书创建 SSL 上下文server.py确保上游 WSS 连接可被验证。值得注意的握手细节handle_websocket_client会等待客户端连接后的第一条消息超时 10 秒从中解析可选的bearer_token与必需的service_url若客户端未提供 token则服务端自动用默认凭证生成server.py。这条首条消息约定由前端sendInitialSetupMessages()配合实现。2.1 客户端初始化流程前端在 gemini-api.js 的sendInitialSetupMessages()中WebSocket 打开后依次发送两条消息服务连接消息声明目标服务 URLservice_url即wss://us-central1-aiplatform.googleapis.com/ws/google.cloud.aiplatform.v1beta1.LlmBidiService/BidiGenerateContentgemini-api.js。会话 Setup 消息声明模型 URIprojects/projectId/locations/us-central1/publishers/google/models/model、生成配置响应模态、温度、语音、系统指令、工具声明function declarations、主动音频配置以及实时输入配置自动活动检测等。const sessionSetupMessage { setup: { model: this.modelUri, generation_config: { response_modalities: this.responseModalities, // [AUDIO] temperature: this.temperature, speech_config: { voice_config: { prebuilt_voice_config: { voice_name: this.voiceName }, }, }, }, system_instruction: { parts: [{ text: this.systemInstructions }] }, tools: { function_declarations: tools }, proactivity: this.proactivity, realtime_input_config: { automatic_activity_detection: this.automaticActivityDetection, activity_handling: this.activityHandling, }, }, };从源码还可以观察到两个有意义的组合约束gemini-api.js当启用 Google Grounding联网搜索时会删除自定义 function declarations——即当前实现中 Google 搜索与自定义工具互斥选择其一。3. 快速开始从零跑通 Demo3.1 后端启动Python 代理服务器后端负责与 Google Cloud 的认证。依赖声明在 requirements.txtwebsockets12.0 google-auth2.23.0 certifi2023.7.22启动步骤# 安装依赖 pip install -r requirements.txt # 使用 Google Cloud 应用默认凭证完成认证 gcloud auth application-default login # 启动代理服务器默认监听 ws://localhost:8080 python server.py服务器启动后会打印一个包含 WebSocket 地址、认证方式提示的横幅。默认监听0.0.0.0:8080WS_PORT 8080见 server.py如需排查消息内容可把文件顶部的DEBUG变量置为True。3.2 前端启动React 应用在另一个终端中启动 React 应用。前置条件是需要安装 Node.js 与 npm请从 Node.js 官方渠道获取对应平台的安装包。# 安装 Node 依赖 npm install # 启动开发服务器 npm run dev打开浏览器访问http://localhost:5173即可看到应用界面。项目基于 Vite 构建见 vite.config.js 与 package.json前端栈为 React 19 Vite 7同时提供npm run build生产构建、npm run lintESLint 检查、npm run preview预览构建产物等脚本。3.3 首次联调要点确保python server.py正常运行且本机已完成gcloud auth application-default login否则服务端会打印Error generating access token并提示认证命令。在页面的Configuration ▾下拉框中填入你的 Google CloudProject IDProxy URL 默认已是ws://localhost:8080无需改动。点击Connect建立会话再通过Media ▾下的 Start Audio / Start Video / Share Screen 开启媒体流即可开始语音对话。4. 配置详解每个参数的作用Demo 的配置集中在页面顶部Configuration下拉框中其状态由 LiveAPIDemo.jsx 管理最终通过GeminiLiveAPI实例的属性注入到 Setup 消息中。以下是全部配置项的分类说明4.1 连接设置Connection Settings配置项默认值说明Proxy WebSocket URLws://localhost:8080本地代理服务器地址配置值会持久化到localStorageProject ID空需填写Google Cloud 项目 ID用于拼装模型 URIModel IDgemini-live-2.5-flash-native-audioGemini Live 模型UI 提示为最新 Live 预览模型可按需替换其中 Proxy URL、Project ID、Model ID 三项都会被写入localStorage下次打开页面自动恢复LiveAPIDemo.jsx。4.2 Gemini 行为Gemini BehaviorSystem Instructions系统指令Demo 中为只读展示完整提示词见下文第 6 节。其作用相当于给智能体定调礼貌专业的客服角色、退款必须索取交易 ID、转人工前先告知用户等。Voice语音可选Puck默认、Charon、Kore、Fenrir、Aoede。通过 Setup 消息中的speech_config.voice_config.prebuilt_voice_config.voice_name下发。Temperature温度滑动条范围 0.1 ~ 2.0默认 1.0控制生成随机性。Enable proactive audio主动音频默认关闭对应proactivity.proactiveAudio字段开启后模型可主动发起对话而非仅被动响应。Enable Google grounding联网检索默认关闭。开启后会在setup.tools中加入google_search但如第 2.1 节所述会移除自定义函数声明。Enable affective dialog情感对话默认开启对应 Setup 消息中的generation_config.enable_affective_dialog true让模型感知用户情绪并以合适的共情语气回应。4.3 转录设置Transcription SettingsEnable input transcription输入转录默认开启将用户的语音实时转写为文本并追加到聊天面板消息类型user-transcript。Enable output transcription输出转录默认开启将模型的语音回答实时转写显示消息类型assistant。从 gemini-api.js 可以看到转录开启时会在 Setup 消息中附加input_audio_transcription: {}/output_audio_transcription: {}。而在 LiveAPIDemo.jsx 中当输出转录开启时会忽略 TEXT 类型的消息以避免聊天区出现重复文本——这是处理流式响应时的实用细节。4.4 活动检测设置Activity Detection Settings这部分控制什么时候算说完一句话 / 何时打断对应realtime_input_config配置项默认值UI可选值说明Disable automatic activity detection关开/关关闭后不再按活动检测切分轮次Silence duration (ms)500500 ~ 10000步长 100判定静默结束说话的时长阈值Prefix padding (ms)5000 ~ 2000步长 100活动开始前预取的前缀缓冲End of speech sensitivityHighDefault / High / Low语尾检测灵敏度END_SENSITIVITY_*Start of speech sensitivityDefaultDefault / High / Low语首检测灵敏度START_SENSITIVITY_*Activity HandlingInterrupt (Barge-in)Default (Interrupts) / Interrupt / No Interruption新活动到达时的处理策略START_OF_ACTIVITY_INTERRUPTS即支持抢话注意GeminiLiveAPI类内部对这些字段有另一套默认值如silence_duration_ms: 2000、prefix_padding_ms: 500见 gemini-api.jsUI 层会在connect()时用页面上的值覆盖它们二者以最终 UI 设置为准。4.5 Setup 消息查看器连接成功后页面会展示本次会话完整的Setup Message JSONsetupJson这是调试协议字段、理解参数下发结果的直观入口对应SETUP_COMPLETE响应类型到达时保存的lastSetupMessage。5. 自定义工具让智能体真正办事工具函数调用是本 Demo 的核心亮点。前端通过 tools.js 中继承FunctionCallDefinition基类的类来声明工具基类gemini-api.js负责将声明转换为 Gemini 要求的 JSON SchemagetDefinition()并在收到模型调用时执行本地函数runFunction()。5.1 两个核心客服工具process_refund处理退款——必填参数transactionId可选reasonexport class ProcessRefundTool extends FunctionCallDefinition { constructor(onRefund) { super( process_refund, Processes a refund for a transaction, { type: object, properties: { transactionId: { type: string, description: The ID of the transaction to refund, }, reason: { type: string, description: The reason for the refund, }, }, }, [transactionId] ); this.onRefund onRefund; } functionToCall(parameters) { if (this.onRefund) { this.onRefund(parameters); } console.log( Processing refund: ${JSON.stringify(parameters)}); } }connect_to_human转接人工——必填参数reason模拟复杂问题场景下的人工坐席交接。在 LiveAPIDemo.jsx 的connect()中这两个工具被注册到客户端并通过回调弹出模态框展示结果Refund Processed 显示交易 ID 与原因Connecting to Human Agent 显示交接原因。注意只有未开启 Google Grounding时才会注册这两个自定义工具与第 2.1 节的互斥逻辑一致。5.2 工具调用的完整链路模型在回复中返回TOOL_CALL类型的消息MultimodalLiveResponseMessage解析出data.toolCallgemini-api.js。前端遍历functionCalls在聊天区追加一条️ Called tool: name记录然后调用clientRef.current.callFunction(name, args)执行本地函数LiveAPIDemo.jsx。callFunction通过functionsMap找到对应工具并执行其functionToCallgemini-api.js。若需要把执行结果回传给模型可使用sendToolResponse(toolCallId, response)gemini-api.js实现工具结果影响后续对话的闭环。5.3 更多工具示例tools.js 中还定义了其他工具类可作为扩展参考ShowModalDialogToolshow_modal展示带标题与消息的模态框AddCSSStyleTooladd_css_style向页面注入!important样式规则如高亮某个元素是智能体操作页面的示例EndConversationToolend_conversation结束会话并携带对话摘要PointToLocationToolpoint_to_location在用户画面/屏幕流中标注坐标x/y 取值 0~1000。提示从源码结构看PointToLocationTool.functionToCall中引用了this.onEnd并输出与结束会话一致的日志而构造函数保存的是this.onPoint疑似复制粘贴遗留的笔误若要基于它扩展画面标注能力需按onPoint语义修正实现。这正说明阅读源码做二次开发时需要以实际调用链为准。6. 系统提示词客服角色的人设从何而来Demo 的客服行为完全由一段内嵌的系统指令驱动LiveAPIDemo.jsx核心约束如下You are a helpful and polite Customer Service Agent. Your goal is to assist the user with their inquiries, process refunds if necessary, or connect them to a human agent if the issue is complex. Instructions: 1. Listen to the customers query. 2. If the customer asks for a refund, you MUST ask for the transaction ID. Once they provide it, you MUST call the process_refund tool with the transaction ID and a reason. 3. If the customer wants to speak to a human, you MUST call the connect_to_human tool with a reason. 4. Be professional, empathetic, and concise. 5. Always inform the user before calling a tool (e.g., Ill process that refund for you now...).这段提示词体现了三个可复用的设计手法明确触发条件把必须获取交易 ID → 调用退款工具写成强制流程减少模型自由发挥工具调用礼仪要求调用工具前先告知用户让交互更自然、可预期可用工具清单在提示词末尾重申两个工具及使用时机强化模型的工具选择正确率。7. 媒体管道音频、视频与屏幕的采集与回放媒体处理集中在 media-utils.js围绕 Gemini Live API 的格式要求设计7.1 音频采集AudioStreamer通过getUserMedia获取麦克风约束为sampleRate: 16000Gemini 要求 16kHz 输入并开启回声消除、降噪、自动增益media-utils.js加载 capture.worklet.js 音频工作节点将 Float32 数据转换为PCM16sample * 0x7fff再经 base64 编码后通过sendAudioMessage以audio/pcm类型发送media-utils.js。7.2 视频与屏幕采集VideoStreamer / ScreenCapture两者共享BaseVideoCapture基类把媒体流渲染到隐藏的video再定时用canvas抽帧为 JPEG默认 1fps、质量 0.8屏幕共享默认 1280x720 / 0.7 质量通过sendImageMessage(base64, image/jpeg)发送media-utils.jsVideoStreamer支持前后摄像头切换facingMode、指定deviceId与分辨率ScreenCapture使用getDisplayMedia并在用户主动停止共享时自动清理。7.3 音频回放AudioPlayerGemini 输出为24kHzPCM因此回放端以sampleRate: 24000创建 AudioContext加载 playback.worklet.js 工作节点media-utils.jsplay(base64Audio)将 base64 解码为 Int16Array 再归一化为 Float32Array 交给工作节点interrupt()用于打断当前播放对应INTERRUPTED响应setVolume()提供 0~1 音量控制经 GainNode 实现。7.4 会话消息处理gemini-api.js 中的MultimodalLiveResponseMessage把服务端推送统一解析为 8 种类型TEXT、AUDIO、SETUP_COMPLETE、INTERRUPTED、TURN_COMPLETE、TOOL_CALL、ERROR、INPUT_TRANSCRIPTION/OUTPUT_TRANSCRIPTION。LiveAPIDemo的handleMessage据此分流音频进播放器、转录进聊天区增量追加、工具调用进函数分发、中断时打断播放构成了完整的会话状态机。8. 项目结构速览gemini/multimodal-live-api/native-audio-websocket-demo-apps/customer-support-demo-app/ ├── server.py # WebSocket 代理与认证处理Python ├── requirements.txt # Python 依赖websockets / google-auth / certifi ├── package.json # React 19 Vite 7 前端依赖与脚本 ├── vite.config.js # Vite 配置 ├── index.html # HTML 入口 ├── eslint.config.js # ESLint 配置 ├── customer-service-agent-screenshot.png # 演示截图 └── src/ ├── App.jsx # 主布局 ├── main.jsx # React 挂载入口 ├── components/ │ └── LiveAPIDemo.jsx # 客服智能体核心逻辑与 UI连接、媒体、工具、配置 └── utils/ ├── gemini-api.js # Gemini WebSocket 客户端Setup 构建、消息解析、函数调用 ├── media-utils.js # 音频/视频/屏幕采集与音频回放 └── tools.js # 工具定义退款、转人工、模态框、样式注入、会话结束、画面标注 └── public/ └── audio-processors/ # AudioWorkletcapture.worklet.js16kHz 采集、playback.worklet.js24kHz 回放9. 试玩建议与扩展方向Demo 内置的 Try Asking 提示了四类可验证的交互路径LiveAPIDemo.jsx多模态I want to return this item, can you see it?并对着摄像头展示商品情绪感知Im really frustrated with this service!观察模型是否以更共情的语气回应退款工具Can I get a refund for my last order?触发交易 ID 索取与process_refund人工交接I need to speak to a real person.触发connect_to_human并弹出交接模态框。在此基础上可尝试的扩展方向将模态框回调替换为真实业务接口如调用退款 API参照AddCSSStyleTool实现智能体高亮页面元素的引导式客服为PointToLocationTool修正实现并叠加 AR 标注或参考本仓库 multimodal-live-api 下的其他示例如 livekit-adk 与 gradio-voice以及 intro_multimodal_live_api.ipynb将同样的 Live API 能力移植到其他前端框架或服务端场景。注意模型、接口与参数以当前仓库代码与实际 Google Cloud 服务为准生产化时还应补充鉴权加固、配额与安全策略。【免费下载链接】generative-aiSample code and notebooks for Generative AI on Google Cloud, with Gemini Enterprise Agent Platform项目地址: https://gitcode.com/GitHub_Trending/ge/generative-ai创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门