ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

TEN Framework 打造 Live2D 语音助手:Agora RTC + Deepgram + OpenAI + Minimax 实时对话与音频驱动唇形同步全流程实战

TEN Framework 打造 Live2D 语音助手:Agora RTC + Deepgram + OpenAI + Minimax 实时对话与音频驱动唇形同步全流程实战 人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载本文基于 TEN Framework 开源仓库中的voice-assistant-live2d示例完整讲解如何搭建一个带 Live2D 虚拟形象、具备实时语音对话能力STT → LLM → TTS的语音助手从前置环境准备、双端环境变量配置、TEN runtime 图编排到前端角色配置、远程模型加载与音频驱动唇形同步的实现原理最后覆盖 Docker 化发布。读完本文你将掌握在 TEN 框架内复用标准语音助手后端、并叠加 Live2D 表现层的最小可运行方案与深度定制路径。项目概览与核心特性voice-assistant-live2d是 TEN Framework 仓库中ai_agents目录下的一个可直接运行的示例入口文档见 README。它的定位非常明确复用标准语音助手voice-assistant示例的后端配置见 voice-assistant 示例在其上新增一个 Live2D 感知的前端让动画角色能够随音频流水线做出同步动作——尤其是嘴部运动。该示例由以下四类技术能力拼装而成Live2D 角色集成可交互的 Live2D 模型具备音频驱动的嘴部运动lip sync与表情/动作触发链式模型语音流水线实时的 STT → LLM → TTS 对话闭环即用户语音 → 文字 → 模型回复 → 语音合成Agora RTC 流式传输通过 Agora RTC/RTM 实现双向音频流前端技术栈Next.js 15 PIXI.js pixi-live2d-display live2d-motionsync浏览器端负责模型渲染与音画同步。从目录结构看示例分为三个进程协作TEN runtimetenapp、Go 编写的 API servermain.go以及 Next.js 前端frontend。系统架构从音频流到虚拟形象的完整链路整个系统的大脑是 TEN runtime 的预定义图predefined graph定义在 tenapp/property.json 中。这张图声明了 8 个扩展节点extension node以及它们之间的数据流、音频流与命令流连接auto_start: true表示应用启动即自动拉起该图。节点清单8 个扩展各司其职节点名addon职责agora_rtcagora_rtcAgora RTC 音频收发接入用户端与 TTS 播放sttdeepgram_asr_pythonDeepgram 语音识别输出asr_resultllmopenai_llm2_pythonOpenAI 大模型对话生成ttsminimax_tts_websocket_pythonMinimax WebSocket TTS 语音合成main_controlmain_python对话状态机与调度中枢问候、打断、流转message_collectormessage_collector2收集转录消息通过 Agora 数据通道推送weatherapi_tool_pythonweatherapi_tool_python可选的天气工具节点streamid_adapterstreamid_adapter音频流 ID 适配衔接 RTC 与 STT连接关系三类消息流图中的connections定义了三种拓扑cmd命令流agora_rtc向main_control发送on_user_joined/on_user_left命令通知用户上下线weatherapi_tool_python向main_control发送tool_register注册 LLM 工具。data数据流stt的asr_result送达main_controlmessage_collector的data送达agora_rtc走数据通道推给客户端。audio_frame音频流agora_rtc的pcm_frame→streamid_adapter→stt上行用户语音进入识别tts的pcm_frame→agora_rtc下行合成语音回放给用户。之所以引入streamid_adapter是因为 Agora 的音频流需要携带正确的 stream_id 才能被 STT 正确识别为远端用户语音而非本地回声它在 RTC 与 STT 之间充当 ID 适配层。main_control对话调度的核心扩展main_control对应main_python扩展实现在 extension.py 中是 agent 模块的入口。它基于装饰器注册事件处理器用户加入_on_user_joined当 RTC 用户数从 0 变为 1 时把配置中的greeting文案同时送入 TTS 播放_send_to_tts并写入转录_send_transcript这就是角色开口打招呼的源头ASR 结果_on_asr_result收到asr_result后若为 final 或文本长度超过 2先调用_interrupt()打断当前 LLM/TTS 输出再queue_llm_input排队送入大模型——这保证了对话的低延迟与可打断性LLM 响应_on_llm_response通过parse_sentences把流式输出按句子切分逐句送 TTStext_input_endfalse最后一句标记结束实现边说边播打断机制_interrupt同时 flush LLMagent.flush_llm()、向 TTS 发送tts_flush、向agora_rtc发送flush命令三路协同清空播放队列。这种流式句子切分 三路打断的设计是让 Live2D 角色对话体验自然流畅的关键后端保障。环境准备与工具链在开始安装前请确认以下工具链齐备task CLITaskfile 驱动的任务自动化工具需 v3 或更新版本tmanTEN 包管理器需在PATH中可用若尚未安装可从仓库根目录执行task gen-tman构建Go 1.21用于构建 API server 与 TEN runtimeNode.js 20 与 npm前端基于 Next.js 15Python 3.10 与 uv默认使用uv安装 Python 依赖默认PIP_INSTALL_CMDuv pip install --system若不使用 uv请在执行task install前导出PIP_INSTALL_CMDpip install。仓库根目录的 Taskfile.yml 中定义了gen-tman等基础任务示例自身的 Taskfile.yml 则承载安装、运行、发布全流程。环境变量配置三处文件的完整对照1. 准备两个环境文件从仓库根目录执行cp ai_agents/.env.example ai_agents/.env cp ai_agents/agents/examples/voice-assistant-live2d/frontend/env.example ai_agents/agents/examples/voice-assistant-live2d/frontend/.env.local前者供后端TEN runtime API server读取后者供前端浏览器侧读取。示例的 frontend/env.example 内容如下可作为.env.local的起点# Agora Configuration NEXT_PUBLIC_AGORA_APP_IDyour_agora_app_id_here # API Configuration NEXT_PUBLIC_API_BASE_URLhttp://localhost:8080 # Live2D Assets NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URLhttps://ten-framework-assets.s3.amazonaws.com/live2d-models2. 必需环境变量ai_agents/.env变量说明AGORA_APP_IDAgora App ID用于 RTC 音频流DEEPGRAM_API_KEYDeepgram API Key用于语音识别OPENAI_API_KEYOpenAI API Key用于大模型OPENAI_MODELOpenAI 模型名例如gpt-4o或gpt-4o-miniMINIMAX_TTS_API_KEYMinimax API Key用于语音合成MINIMAX_TTS_GROUP_IDMinimax 账号的 group ID3. 可选环境变量ai_agents/.env变量说明AGORA_APP_CERTIFICATEAgora App Certificate若项目需要基于证书鉴权时填写OPENAI_PROXY_URL用于转发 OpenAI 流量的 HTTP 代理WEATHERAPI_API_KEYWeatherAPI Key填写后启用内置天气工具节点4. 前端环境变量frontend/.env.local变量说明默认值NEXT_PUBLIC_AGORA_APP_ID暴露给浏览器客户端的 Agora App ID无NEXT_PUBLIC_API_BASE_URL本地 API server 的 Base URLhttp://localhost:8080NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URL承载 Live2D 模型资源贴图、动作、预览图的 Base URLhttps://ten-framework-assets.s3.amazonaws.com/live2d-models在 property.json 中环境变量通过${env:VAR_NAME}语法注入扩展配置${env:VAR_NAME|}结尾带|表示可选变量未设置时使用空值例如app_certificate: ${env:AGORA_APP_CERTIFICATE|}与proxy_url: ${env:OPENAI_PROXY_URL|}。这是 TEN 框架在图中引用运行环境的标准做法方便在开发机与生产环境间复用同一张图。安装与运行1. 安装依赖cd ai_agents/agents/examples/voice-assistant-live2d task install该命令内部依次执行对应 Taskfile.yml 中的install任务链tman install在tenapp目录安装 TEN runtime 包./scripts/install_python_deps.sh安装 Python 依赖默认走 uvbun install --verbose在frontend目录安装前端依赖仓库使用 bun 作为包管理器go mod tidy go mod download go build -o bin/api main.go在ai_agents/server目录构建 Go API server。2. 启动四个进程分别在四个终端中运行保证各进程持续存活# 终端 1 —— TEN runtime task run-tenapp # 终端 2 —— API server task run-api-server # 终端 3 —— 前端 task run-frontend # 终端 4 ——可选TMAN Designer UI task run-gd-server对应关系同样可在 Taskfile.yml 中确认run-tenapp执行tman run start在tenapp目录由 Go 程序加载 property.json 启动运行时见 main.go 的InitPropertyFromJSONBytesrun-api-server以-tenapp_dir{{.PWD}}/tenapp参数启动 Go API serverrun-frontend执行bun run devrun-gd-server执行tman designer启动可视化设计器。3. 访问应用前端http://localhost:3000API Serverhttp://localhost:8080TMAN Designerhttp://localhost:49483前端页面中的连接面板ConnectionPanel.tsx会先调用 API server 获取 Agora 凭证fetchCredentials再建立 RTC/RTM 连接并提供一键连接/断开与麦克风开关同时通过 agent.ts 中的startAgent/stopAgent/pingAgent与/start、/stop、/ping、/list接口交互管理 agent 生命周期与状态轮询。Live2D 模型远程加载与自定义示例内置的四个角色——Kei、Mao、Kevin the Marmot土拨鼠凯文、Chubbie the Capybara水豚恰恰——其模型资源均从NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URL定义的远程地址加载默认https://ten-framework-assets.s3.amazonaws.com/live2d-models。例如 Kei 的资源位于https://ten-framework-assets.s3.amazonaws.com/live2d-models/kei_vowels_pro。在 page.tsx 中模型路径通过buildRemoteModelAssetPath(folder, fileName)拼装const remoteModelsBaseUrl ( process.env.NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URL || DEFAULT_REMOTE_MODELS_BASE_URL ).replace(/\/$/, ); const buildRemoteModelAssetPath (folder: string, fileName: string) ${remoteModelsBaseUrl}/${folder}/${fileName};添加或替换模型只需三步将完整的 Live2D 导出目录贴图、动作、物理等上传到你选择的存储桶/CDN把NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URL指向包含各模型子目录的父目录在 frontend/src/app/page.tsx 的角色配置中更新对应的目录与文件名引用。若希望完全离线开发可把模型文件放入frontend/public/models/并将NEXT_PUBLIC_LIVE2D_REMOTE_MODELS_BASE_URL设为http://localhost:3000/models这与 Next.js 默认的静态资源路径一致。Live2D 核心运行时live2dcubismcore.min.js位于 frontend/public/lib模型加载则通过 live2d-loader.ts 动态导入pixi-live2d-display/cubism4并确保 PIXI 已完成全局初始化。前端角色配置从模型到人设的完整映射每个角色在 page.tsx 中以CharacterProfile对象定义是理解前端表现层的核心。它由Live2DModel基础字段id、name、path、preview与角色化字段组合而成type CharacterProfile Live2DModel { headline: string; description: string; quote: string; voiceType: male | female; mouthConfig: MouthConfig; expressions?: ExpressionConfig[]; motions?: MotionConfig[]; backgroundTheme: BackgroundTheme; connectionGreeting?: string; agentGreeting: string; floatingElements?: FloatingElement[]; immersiveStage?: boolean; };嘴型配置 mouthConfigMouthConfig是音频驱动嘴型的关键支持两种模式定义见 Live2DCharacter.tsxexport type MouthConfig | { type: open; openId: string; formId?: string } | { type: corners; upId: string; downId: string; formId?: string };open模式驱动ParamMouthOpenY张嘴与ParamMouthForm嘴型Kei、Kevin、Chubbie 均使用此模式corners模式驱动ParamMouthUp/ParamMouthDown嘴角上下Mao 使用此模式。组件在加载模型后通过resolveMouthParameters解析这些参数优先读取配置中指定的参数 ID若模型缺少则用正则如/parammouthopeny/i、/parammouthopen/i、/mouthopen/i从getParameterIds()返回的参数列表自动兜底匹配并缓存每个参数的 min/max/default 值。表情与动作 expressions / motionsExpressionConfig与MotionConfig均支持事件绑定字段表情default默认表情、onSpeaking说话时触发例如 Mao 的gentle_smile标记为onSpeaking: true动作autoPlay自动播放的 idle 动画loop: true、onSpeakingStart说话开始瞬间播放如 Kevin 的 Snack Bite、priority动作优先级运行时映射到MotionPriorityNONE0、IDLE1、NORMAL2、FORCE3。组件加载模型后会依次执行applyDefaultExpression设置默认表情与ensureIdleMotion启动 idle 动画并在窗口上暴露window.tenLive2d[modelPath]全局 APIsetExpression、setRandomExpression、playMotion等方便页面其他模块或调试环境直接驱动角色。视觉主题 backgroundTheme 与浮动元素每个角色还带有独立的backgroundTheme基础色、主渐变、径向叠加、图案叠加、强调叠加五层 CSS 主题与floatingElements漂浮装饰元素如 Kei 的花瓣/星光/爱心、Kevin 的玉米/瓜子、Chubbie 的温泉蒸汽/柑橘片immersiveStage: true的角色Kevin、Chubbie启用沉浸式舞台布局。这些配置让不同角色拥有截然不同的视觉氛围属于纯前端表现层定制不影响后端逻辑。音频驱动的唇形同步实现原理唇形同步是 Live2D 语音助手的核心体验实现在 Live2DCharacter.tsx 中采用双路径策略MotionSync 为主、Web Audio 分析为兜底。主路径MotionSync 音画同步当 Agora 远端音频轨道到达audioTrack.getMediaStreamTrack()组件将其包装为MediaStream交给 MotionSyncconst stream new MediaStream([audioTrack.getMediaStreamTrack()]); motionSync.play(stream);MotionSync 实例在模型加载阶段创建组件先对模型路径做同目录替换.model3.json→.motionsync3.json并发 HEAD 请求探测文件是否存在存在则new MotionSync(model.internalModel)并loadMotionSyncFromUrl加载音频驱动数据。MotionSync 会根据语音内容驱动嘴型、表情甚至头身动作是效果最好的路径。兜底路径Web Audio API 音量映射若 MotionSync 文件缺失、初始化失败或运行时出错例如捕获到addLast相关异常组件自动降级为startFallbackLipSync通过AudioContext.createMediaStreamSource连接AnalyserNodefftSize1024在requestAnimationFrame循环中调用getByteTimeDomainData计算波形绝对值的平均值作为音量再经平滑系数 0.35 的指数平滑后映射到嘴部参数const target Math.min(1, Math.max(0, (average - 0.02) * 4)); const smoothed current (target - current) * 0.35;对于open模式音量直接映射ParamMouthOpenY并按比例联动ParamMouthForm对于corners模式则按参数的 min/default/max 跨度分别计算嘴角上下值。所有写入均通过setParameterValueById并做 min/max 钳制。与此同时组件还会创建一个隐藏audio元素playsInline以兼容 iOS/Safari确保声音真正播放并在轨道结束时统一重置 MotionSync、暂停并移除音频元素。健壮性设计组件在useEffect中注册了全局error与unhandledrejection监听一旦捕获 MotionSync 相关错误即禁用 MotionSync 并回退PIXI 渲染使用 Canvas 渲染器forceCanvas: true、关闭抗锯齿、powerPreference: low-power以规避 WebGL 着色器兼容问题并降低 GPU 占用卸载时按停止 → 销毁纹理 → 清理 canvas的顺序释放全部资源。这些细节使其在多种浏览器环境包括低端设备下都能稳定渲染。发布为 Docker 镜像示例提供了完整的容器化方案Dockerfile 位于 voice-assistant-live2d/Dockerfile采用两阶段构建builder 阶段基于ghcr.io/ten-framework/ten_agent_build:0.7.14完成task install、task release与前端bun run build运行阶段基于ubuntu:22.04安装运行时依赖libasound2、GStreamer、Python3、Node.js 20、Bun、Task、tman 等最终以task -t Taskfile.docker.yml run-prod启动暴露 8080API与 3000前端端口。以下命令请在填充好.env后于ai_agents目录下执行。构建镜像cd ai_agents docker build -f agents/examples/voice-assistant-live2d/Dockerfile -t voice-assistant-live2d .运行容器docker run --rm -it --env-file .env -p 8080:8080 -p 3000:3000 voice-assistant-live2d访问前端http://localhost:3000API Serverhttp://localhost:8080自定义与扩展使用 TMAN Designerhttp://localhost:49483可以可视化修改 TEN runtime 图替换 STT/LLM/TTS 供应商直接修改 tenapp/property.json 中对应节点的addon与property例如把 Deepgram 换成其他 ASR、把 Minimax 换成其他 TTS添加工具节点仿照weatherapi_tool_python注册新的 LLM 工具并在main_control的tool_registercmd 连接中挂接调整问候语同时修改llm节点与main_control节点的greeting属性注意两处需保持一致main_control的问候语会直接送 TTS 播放并写入转录llm的问候语则进入模型上下文调节对话参数llm节点中的frequency_penalty0.9、max_completion_tokens512、max_memory_length10等均可按需调整以控制回复风格、长度与记忆深度。若想自定义前端表现层核心入口是 page.tsx 中的characterOptions数组与 Live2DCharacter.tsx 的渲染逻辑后端对话调度则位于 extension.py 的MainControlExtension。仓库内进一步阅读后端图编排与全部配置参数tenapp/property.json对话调度与打断逻辑ten_packages/extension/main_python/extension.py唇形同步与 Live2D 渲染核心frontend/src/components/Live2DCharacter.tsx角色配置与视觉主题frontend/src/app/page.tsx前端与 API server 交互frontend/src/services/agent.ts安装/运行/发布任务编排Taskfile.yml 与 Dockerfile复用的标准语音助手后端voice-assistant 示例赞分享人工智能AI Agent多模态语音AI 应用【免费下载链接】ten-frameworkOpen-source framework for conversational voice AI agents项目地址https://gitcode.com/TEN-framework/ten-framework点击查看免费下载相关推荐TEN Framework Transcription 示例基于 Agora RTC Deepgram STT OpenAI LLM 的实时语音转写流水线TEN Framework Transcription 示例基于 Agora RTC Deepgram STT OpenAI LLM 的实时语音转写流人工智能AI Agent多模态语音AI 应用TEN Framework Live2D 语音助手前端实战指南基于 Next.js 15 与 Agora RTC/RTM 的实时角色交互界面TEN Framework Live2D 语音助手前端实战指南基于 Next.js 15 与 Agora RTC/RTM 的实时角色交互界面 导读 本文围绕人工智能AI Agent多模态语音AI 应用TEN Framework Voice Assistant Companion 前端实战指南基于 Agora RTC 与 Live2D 的实时语音交互界面TEN Framework Voice Assistant Companion 前端实战指南基于 Agora RTC 与 Live2D 的实时语音交互界面 本人工智能AI Agent多模态语音AI 应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表